[Top][All Lists]

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

Re: [lwip-users] PPP with NO_SYS=1 in an interrupt context

From: David Empson
Subject: Re: [lwip-users] PPP with NO_SYS=1 in an interrupt context
Date: Thu, 16 Jun 2011 10:41:44 +1200

Mehmet Ali Ekici wrote:
I have checked it with 9600 baud too there is no framing errors for the port. Here is the logs.
We are using  SIM900D from simcom as GPRS modem.

I expect fcs to be "6b e4" but log says 0x70d6. How can fcs be calculated over the received frame to check if fcs correct or not ?

7e ff 03 c0 21 0a 08 6b e4 7e
pppInProc[0]: got 10 bytes
pppInProc[0]: Dropping bad fcs 0x70d6 proto=0xc021

For that particular packet, the FCS really is wrong, so the PPP driver was correct to drop it.

The printed sequence of bytes above the "pppInProc[0]: got NN bytes" line indicates the bytes received by the PPP driver from the serial driver. In some cases this is not a complete packet and you might have to look back in the log for earlier receive bursts to find the rest of the packet. In this case it is complete.

All PPP packets start and end with 0x7E (FLAG). (In theory, two adjacent packets could share an opening and closing FLAG but I don't know if PPP ever makes use of that.)

The 0x7E byte is not allowed to appear in the transmitted data within a packet, so in order to protect against that, an 0x7E data byte is encoded for transmission by sending two bytes: 0x7D (CTRL-ESCAPE) followed by 0x5E (which is 0x7E XOR 0x20). The same CTRL-ESCAPE mechanism is used to protect an 0x7D data byte (which is sent as 0x7D 0x5D), and may be used to protect control characters in the 0x00 to 0x1F range (so they are transmitted as 0x7D 0x20 through 0x7D 0x1F), since some serial transmission mechanisms might interpret control characters specially. At the start of PPP communication, all control characters are protected by this, and the two stations negotiate whether to keep protecting certain control characters or let them through unmodified (by setting the "transmit async control character map" and "receive async control chacter map").

In order to calculate the FCS manually, you need to reverse all of these modifications, and only look at the decoded data bytes between the FLAGs. In this case, there are no CTRL-ESCAPE (0x7D) bytes, so the data can be read directly:

ff 03 c0 21 0a 08 6b e4

The last two bytes are the transmitted FCS, so the data bytes in this case are ff 03 c0 1 0a 08.

The FCS calculation is done using the standard CRC-CCITT polynomial x^16 + x^12 + x^5 + 1. The remainder is initialized to 0xFFFF and each data byte is fed through the CRC calculation. When all data bytes have been processed, the remainder is complemented prior to being transmitted. The typical implementation is to do the CRC calculation using 0x8408 as the generator, and transmitting the remainder low byte first.

When the entire packet (including complemented remainder) is fed into the CRC calculation at the receiving end, the result is supposed to be a constant: 0xF0B8. If the result does not match, the packet contains an error. In this case, the result of the FCS calculation was 0x70D6 instead of 0xF0B8, so the packet was invalid.

Decoding the packet data:

ff is the correct HDLC address field (broadcast)

03 is the correct HDLC control field (unnumbered information frame)

c0 21 is the correct PPP data to indicate that this is a LCP (Link Control Protocol) frame.

0a is the LCP packet type "Echo-Reply". This is valid, as there was previously an "Echo-Request" packet transmitted.

08 is not valid. There should be a 00 byte here (identifier), to match the Echo-Request packet.

Here is the echo request sent by LWIP for comparison:

7e ff 03 c0 21 09 00 00 08 00 00 00 00 bb 6e 7e fsm_sdata(LCP): Sent code 9,0,8.

Note the 09 (Echo-Request) is followed by two 00 bytes, then 08 (packet length), then four more zero bytes. The packet length is calculated starting from the bytes after 0xC0 0x21.

Given the evidence, I strongly suspect that your serial driver is discarding received 0x00 bytes. This was the first packet received after PPP had negotiated to disable the use of the CTRL-ESCAPE to protect control characters. In earlier packets, 0x00 bytes arrived encoded as 0x7D 0x20, so passed through your driver without problems.

The problem might be further upstream, e.g. it could be the transmitting station unable to send 0x00 bytes, or some device passing data between the other station's transmitter and your receiver which is discarding 0x00 bytes. It is only affecting data in one direction, since an attempt was made to respond to the Echo-Request packet, which means the other station must have received that packet correctly (with zero bytes intact).

If you are unable to locate or fix the source of the 0x00 bytes being dropped, a workaround would be to adjust the PPP configuration used by LWIP so that it leaves 0x00 bytes in the receive direction protected via the async control character map, so that the other station will continue to use 0x7D 0x20 when it wants to send a 0x00 byte. This will be inefficient, so it would be better to track down and fix the problem.

reply via email to

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