lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Re: PPP negotiate process


From: yueyue papa
Subject: Re: [lwip-users] Re: PPP negotiate process
Date: Wed, 8 Apr 2009 12:47:10 +0800

thank you very much.

I fixed the problem, and then I found your answer.

You are exactly correct !!!!

It is my fault. I use printf("%c", xxx), to send the data. The 0xa is processed as 0x0d 0x0a

I changed the  code, and every thing works.

Your detailed explanation is great.

On Wed, Apr 8, 2009 at 7:18 AM, David Empson <address@hidden> wrote:
yueyue papa <mailto:address@hidden> wrote:
Based on the PPP spec:

Address: In HDLC this is the address of the destination of the frame. But
in PPP we are dealing
with a direct link between two devices, so this field has no real meaning.
It is thus always set to
"11111111" (0xFF or 255 decimal), which is equivalent to a broadcast (it
means "all stations").

After the GPRS module CHAP negotiate

#####################

fsm_sdata(IPCP): Sent code 1,1,22.
IPCP: sending Configure-Request, id 1
IPCP: open state 2 (LS_CLOSED) -> 6 (LS_REQSENT)
Read 10 bytes:
7e 80 21 01 00 00 04 67 c3 7e ~.!....g.~
#######################

The address changed to 80.

PPP can negotiate compression of some fields which always appear in frames.
In particular, it can eliminate the HDLC address and control fields, which
would normally be 0xFF and 0x03. It is also possible to compress some values of the "protocol" field from two bytes to one byte.

When a PPP frame is compressed in either of these ways, the FCS calculation
is done over the compressed frame (as transmitted), not the original frame.
(This is specified in RFC1661, which is or was the standard for PPP.)

That 0x80 is actually the first byte of the PPP "protocol" field (0x8021 is
the IP Control Protocol). The address and control fields (0xFF 0x03) have
been deleted.


Whether it will impact the fcs  check?

It won't. The frame you quoted above has the correct FCS. (I checked it.)

By comparison, this one which you listed in your previous message DOES have
a bad FCS.


#########################
fsm_sdata(IPCP): Sent code 1,2,14.
IPCP: sending Configure-Request, id 2
Read 21 bytes:
7e 80 21 04 02 00 0e 01 0d 0a 00 00 00 00 00 00     ~.!.............
00 00 66 f7 7e                                      ..f.~

pppInProc[0]: got 21 bytes
pppInProc[0]: Dropping bad fcs 0xFC02 proto=0x8021
#########################

Breaking down the IPCP packet we have:

80 21    PPP protocol identifier for IPCP
04         IPCP packet type: Configure-Reject
02         Identifier (used to associate commands and responses)
00 0e    Total length of packet data starting with the packet type field

The length field reveals that there is an extra byte somewhere in the frame,
as I count 15 bytes between the 8021 and FCS, but the length says there are
14 bytes.

01         IPCP option type: IP-addresses
0d         Length of this option (including option type and length fields).

This 0x0D byte is incorrect and appears to have been inserted into the
frame. The length of this option is supposed to be 10 (0x0A).

0a         Actual length of this option
Eight 00 bytes are the option values.

If I recalculate the FCS for this frame by omitting the inserted 0x0D byte,
the FCS is correct. The actual frame should be this:

7e 80 21 04 02 00 0e 01 0a 00 00 00 00 00 00 00 00 66 f7 7e

The question is how an extra byte mysteriously appeared in the middle of the
frame. Looking at the specific values, I see a very likely explanation:

0x0A is an ASCII line feed (LF).
0x0D is an ASCII carriage return (CR).

The frame appears to have passed through something which converted from
UNIX-style line endings (LF only) to MS-DOS-style line endings (CR LF),
between the point the FCS was generated and the frame was transmitted. The
receiver is not reversing this conversion, so it calculates a different FCS
and rejects the frame.

This conversion is standard behaviour for C applications on MS-DOS and
Windows computers if they open a file using the OS or standard C library
open() or fopen() call without specifying binary mode. In the default text
I/O mode, the C application deals with '\n' (0x0A, LF) as its end of line
character, while MS-DOS and Windows text files use '\r\n' (0x0D 0x0A, CR
LF), and the C library converts between the two conventions.

This would qualify as a bug in a PPP implementation running on MS-DOS or
Windows. It should specify binary mode when opening the serial port, by
using O_BINARY in the mode for open(), or including "b" in the mode string
for fopen().

A related possibility is that the CR/LF conversion is happening at the
receive end, or somewhere in the middle. If so, it is necessary to adjust
the use of the PPP "Async Control Character Map" (ACCM) option to say that
it is not safe to send 0x0A without escaping it.

When a PPP connection starts, the ACCM defaults to escaping all control
characters (0x00 through 0x1F) by sending them as 0x7D followed by the
control character XOR 0x20. For example, 0x0A would be sent as 0x7D 0x2A.
You can see this in the early frames in your previous long examples.

Whatever the explanation, a similar problem is likely to happen in the other direction, but will be less frequent. If the byte pair 0x0D 0x0A really does appear in the transmit data stream, it will be converted to 0x0A by a device doing MS-DOS to UNIX end of line conversion (e.g. a Windows application with the serial port open in text mode). This would also cause an FCS error and the frame would be rejected.



_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users


reply via email to

[Prev in Thread] Current Thread [Next in Thread]