espressif / esp-protocols

Collection of ESP-IDF components related to networking protocols
180 stars 124 forks source link

PPPos seems to use some non generic AT command, making it incompatible with others LTE modems, defeating the purpose of PPPos. (IDFGH-13334) #623

Open 0x0fe opened 1 month ago

0x0fe commented 1 month ago

Answers checklist.

General issue report

So, the target is ESP32C3, i tried to use PPPos with and AIR724UG, an LTE CAT1 modem based on RDA8910 , at first everything works, the network is attached and i get an IP, however as soon as we reach get_network_system_mode it fails, this command is non standard and seems specific to SIMCOM, when i looked up AT+CNSMOD i could see it is a SIMCOM command, it doesnt exist in AIR724 (and presumably others CAT1 modems).

https://github.com/espressif/esp-protocols/blob/5964eadbf5591e8c12ffa5c724c7ace083423239/components/esp_modem/src/esp_modem_command_library.cpp#L565C39-L565C49

I have tested with different modem settings, BG96, SIM7600, GENERIC and it always fails here. Now i wonder why this command was used, provided that it is not generic, and it could easily be replaced by a generic command, supported by all modems, doing the same thing. I understand not all modems can be supported, but it would be better if at least only generic commands were used, it would increase the chances of being compatible with most LTE modems, after all PPPos is a generic interface and it should work with any modern CAT1 / CAT4 modem, that is the purpose.

Also, there should be a simple way to pass a list of commands to use for connection of any modem, that is how it works on windows or linux, we can pass the list of commands required for a particular modem and it will always work. Here i did not found any way to make it work with other modems than SIM7xxx or BG96. The GENERIC mode still use the SIMCOM command CNSMOD for example, which is strange.

Now, i wonder how to fix this problem, there is an "user side" PPP library in the ESP32 core V3, but unfortunately it seems to only be a wrapper for the IDF library and i see no way to add, or better overwrite some functions to make it work with the AIR724UG or other modems. How should i proceed to make this possible? Here is the log, we can see the network is attached, i get an IP (presumably) but then it fails as soon as it tried to call CNSMOD, and finally the IP gets lost after a while, presumably because the network stack stopped responding acks or something.

Starting the modem. It might take a while!
[  3443][V][PPP.cpp:281] begin(): Resetting the modem
[  3443][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type GPIO (1) successfully set to 0x420071be
[  3444][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 7 successfully set to type GPIO (1) with bus 0x8
[  3445][V][esp32-hal-periman.c:174] perimanSetPinBusExtraType(): Successfully set extra_type PPP_MODEM_RST for pin 7
[ 11546][V][PPP.cpp:306] begin(): Waiting for response from the modem
[ 11595][V][NetworkEvents.cpp:119] checkForEvent(): Network Event: 43 - PPP_START
[ 11596][V][PPP.cpp:99] _onPppArduinoEvent(): PPP Arduino Event 43: PPP_START
PPP Started
Manufacturer: +CGMI: "AirM2M"
Model: +CGMM: "Air724UG"
IMEI: xxxxxxxxxxxxxxxxxxxxx
Attached: 1
State: 1
Operator: 2xxx5
IMSI: xxxxxxxxxxxxxxxxxx
RSSI: 19
BER: 99
NetMode: [ 13397][E][PPP.cpp:634] networkMode(): esp_modem_get_network_system_mode failed with -1 ESP_FAIL
-1
Switching to data mode...
Failed to connect to internet!
0x0fe commented 1 month ago

i tried to force the result of the function to 8, a valid value, it passes this error but stil fails at the next step:

int PPPClass::networkMode() const {
  if (_dce == NULL) {
    return -1;
  }

  if (_mode == ESP_MODEM_MODE_DATA) {
    log_e("Wrong modem mode. Should be ESP_MODEM_MODE_COMMAND");
    return -1;
  }

  int m = 8;
  // esp_err_t err = esp_modem_get_network_system_mode(_dce, m);
  // if (err != ESP_OK) {
  //   log_e("esp_modem_get_network_system_mode failed with %d %s", err, esp_err_to_name(err));
  //   return -1;
  // }
  return m;
}
Starting the modem. It might take a while!
[  3389][V][PPP.cpp:281] begin(): Resetting the modem
[  3389][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type GPIO (1) successfully set to 0x42007154
[  3390][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 7 successfully set to type GPIO (1) with bus 0x8
[  3390][V][esp32-hal-periman.c:174] perimanSetPinBusExtraType(): Successfully set extra_type PPP_MODEM_RST for pin 7
[ 11492][V][PPP.cpp:306] begin(): Waiting for response from the modem
[ 14979][V][NetworkEvents.cpp:119] checkForEvent(): Network Event: 43 - PPP_START
[ 14980][V][PPP.cpp:99] _onPppArduinoEvent(): PPP Arduino Event 43: PPP_START
PPP Started
Manufacturer: +CGMI: "AirM2M"
Model: +CGMM: "Air724UG"
IMEI: xxxxxxxxxxxxxxxxxxx
Waiting to connect to network..2.0s
Attached: 1
State: 1
Operator: 2xxx5
IMSI: xxxxxxxxxxxxxxxxxxx
RSSI: 20
BER: 99
NetMode: 8
Switching to data mode...
Failed to connect to internet!
[ 81232][V][NetworkInterface.cpp:85] _onIpEvent(): ppp Lost IP
[ 81233][V][NetworkEvents.cpp:119] checkForEvent(): Network Event: 48 - PPP_LOST_IP
[ 81233][V][PPP.cpp:99] _onPppArduinoEvent(): PPP Arduino Event 48: PPP_LOST_IP
PPP Lost IP
david-cermak commented 1 month ago

Do you really need to call AT+CNSMOD when setting up the connection? I think the solution would be to create a custom device and override the get_network_system_mode() command.

About the last failure, I'd suggest checking the APN settings with your provider.

0x0fe commented 1 month ago

actually i am not explixitely calling AT+CNSMOD, this is called by the PPP wrapper of the ESP32 core, which calls get_network_system_mode from esp_modem_command_library.cpp. That is why i wonder how PPP relies on this non generic command.

Regarding the APN, i did set it here https://github.com/espressif/arduino-esp32/blob/0fa4aa632c6dcb7736a291a33fb9f0a25614d6d0/libraries/PPP/examples/PPP_Basic/PPP_Basic.ino#L3

I run this example as is, after adjusting GPIOS, APN and modem type to GENERIC (i tested all others, too)

The APN is correct, and i have tested the modem with AT command, everything works fine, including MQTT, it connects and get an IP in 2 seconds or less.

I set the debug level to verbose, still i do not get much, i would have expect a lot more debug messages during the PPP connection setup.

0x0fe commented 1 month ago

And just for the check, still with the ESP32C3 i tested another modem : AIR780, based on the excellent Eigencomm EC618, this time another (presumably non generic) AT command fails and the PPP does not get a chance to be set up.

Manufacturer: +CGMI: "AirM2M"
Model: +CGMM: "Air780E"
IMEI: xxxxxxxxxxxxxxxxxxx
Attached: 1
State: 1
Operator: 2xxx5
IMSI: xxxxxxxxxxxxxxxxx
RSSI: 21
Switching to data mode...
[ 14691][E][PPP.cpp:459] mode(): esp_modem_set_mode failed with -1 ESP_FAIL
Failed to connect to internet!

Here again, the APN is correct and it has been tested to connect and work fine when controled with AT commands.