ESP32 and PPP not working
I am trying to raise a PPP connection with a modem (two different ones actually, an EG91 and a BG95)
Once the modem is registered into the network, I start the data call with AT commands, and after the "CONNECT" string is received, do the following code in MicroPython:
my_log.info("Starting Data Call", fn="main")
modem.startDataCall()
my_log.info("Creating PPP object", fn="main")
sleep(5)
ppp = network.PPP(modem.getSerialPort())
ppp.active(True)
ppp.connect(authmode=ppp.AUTH_CHAP,username ="", password="")
I am monitoring the PPP frames in the serial line, and I can see the following:
- the ESP32 sends the first ConfRequest
- the moddem replies with the ACK and its own ConfRequest
- but the ESP32 does not reply anything for about 6 seconds, and in the meantime the modem sends new ConfRequests
- after 6 seconds, the ESP32 seems to process all the requests and ACK them, but this causes abnormal transitions from the PPP FSM.
- The modem replies the ConfRequest, but again nothing happens for another 6 seconds.
- The modem times out every second, and sends a new ConfRequest that causes the same problem again and again, until one or both of the parts give up
I enabled LWIP and PPP logs. It seems to me the problem is the UART object is not passing the data received in the serial port to the PPP object straight away, but only after a timeout. I played a bit with some of the hardcoded values (like FSMTIMEOUT), that seems to confirm the guess.
Unfortunately I am unable to find what mechanism will pass the data from the UART object ot the PPP object - all I can see is there is a task created that waits to be notified, but cannot find what's sending such notification.
I am using latest micropython version (master branch, commit 2111ca0b8fdcbef6177a8d37fde53085de2a798a) , and building with ESP-IDF 4.4
any help would be appreciated, I can supply the logs (or enable more segments and capture more if it helps)
network_ppp: Stop polling if stream or PPP PCB are removed.
Summary
Two small fixes that improve when the poll() method stops looping trying to read more data from the stream:
- When the stream is set to
None.- This was already intended and the case in the ESP32 version when I initially implemented support for the setting
streamto None, but I didn't correctly port it over to the extmod version. And then later I brought the bug from the extmod version back to the ESP32 version. 😞
- This was already intended and the case in the ESP32 version when I initially implemented support for the setting
- When PPP is disconnected.
- When disconnecting from PPP the modem sends a confirmation. This message is received, like all messages, through the
poll()method. lwIP may then immediately call our status callback with codePPPERR_USERto indicate the connection was closed. Our callback then immediately proceeds to free the PCB. Thus, during each new iteration of the loop inpoll()we must check if we haven't disconnected in the meantime to prevent calling thepppos_input_tcpipwith a PCB that is now NULL.
- When disconnecting from PPP the modem sends a confirmation. This message is received, like all messages, through the
Testing
Tested on the ESP32 by disconnecting and observing we no longer crash due to self->pcb being NULL.
Updated the extmod version to keep the two versions in sync. Haven't tested it on a port using the extmod version, but it looks like a correct condition to check there as well.