I am porting the cellular interface for Thales Cinterion PLS63 Modem and I have been observing a consistent issues on the following case:
- Device is in airplane mode.
- AT+CFUN=1 command is sent.
- Modem Responds with “\r\nOK\r\n\r\n^SYSSTART\r\n”.
- OK Response is handled on loop inside _handleAllReceived function under cellular_pktio.c.
NOTE: The pCpmtext->pktRespQueue gets a message about the response value here.
- Line containing ^SYSSTART is handled but pContext->PktioAtCmdType still points to the old value since the caller thread haven’t run yet to receive the pktRespQueue message and cleanup the PktioAtCmdType and prefixes and callbacks etc.
Because of this if ^SYSSTART is not found on the URC tables (CellularUrcTokenWoPrefixTable or CellularUrcHandlerTable) it is marked as AT_SOLICITED by _getMsgType function and because it doesn’t match anything on the tokens _processIntermediateResponse does the incorrect thing.
NOTE: I am not sure why the default case here saves the string to a pResp. I think that case should log and break instead of trying to save data.
- pResp contains a not null line and pktStatus says pending buffer .
- A command with single line of response is called ( AT+COPS? etc.) first line of pResp contains data. Command fails to parse properly and times out after the maximum amount of time.
I hope this explanation is clear enough.
Took me debugging couple hours to understand what is going on.
Basically there are two problems in my opinion.
- PktioAtCmdType has a data race from being accessed by receiver thread and caller thread. Even when the pResp is queued to be sent back to the caller thread that doesn’t mean cmd type gets cleared since receiver thread might be running on a higher priority. (I didn’t see any note on priorities but please direct me if I missed anything)
I believe as the Error or Okay response is received cmd type variable on context should be cleared by receiver thread.
- _processIntermediateResponse saves At Data even when the cmd type requires a single line or no command. I believe this can result in erroneous saves. I know there are cases where URC handlers can have multiple lines and need to be processed when they end but I am not sure how this case gets handled by the library yet (Haven’t tested any SMS commands that work like this.)
But I don’t understand why a line that doesn’t match anything gets saved at all instead of dropped.
I definitely understand that having synchronous and asynchronous responses make things more complicated. However, the library seems to be making lots of incomplete,incorrect assumptions when it comes to determining the nature of the responses and how to handle them. Is there documentation on some sort of a sequence diagram that goes over the implementation details of how the receive logic is handled? Debugging gives information but a more cohesive documentation would be a valuable asset.