drivers: modem_cellular: fix handling of +C*REG answers

`+C*REG:` may be received as AT read command answer
or unsolicited notification.
Their syntax differs, and even the overall parameter count varies
depending on what `<n>` is used in the `AT+CEREG=` write command.

To handle all cases properly, check the parameter count and
the presence of the `<tac>` parameter (which is a string and
thus begins with `"`) to figure out what is the position of `<stat>`.

Signed-off-by: Tomi Fontanilles <tomi.fontanilles@nordicsemi.no>
This commit is contained in:
Tomi Fontanilles 2024-10-28 13:50:19 +02:00 committed by Mahesh Mahadevan
parent a30e41f4d7
commit f380fcc52f

View file

@ -460,10 +460,15 @@ static void modem_cellular_chat_on_cxreg(struct modem_chat *chat, char **argv, u
struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
enum cellular_registration_status registration_status = 0;
if (argc == 2) {
registration_status = atoi(argv[1]);
} else if (argc == 3 || argc == 6) {
/* This receives both +C*REG? read command answers and unsolicited notifications.
* Their syntax differs in that the former has one more parameter, <n>, which is first.
*/
if (argc >= 3 && argv[2][0] != '"') {
/* +CEREG: <n>,<stat>[,<tac>[...]] */
registration_status = atoi(argv[2]);
} else if (argc >= 2) {
/* +CEREG: <stat>[,<tac>[...]] */
registration_status = atoi(argv[1]);
} else {
return;
}
@ -472,7 +477,7 @@ static void modem_cellular_chat_on_cxreg(struct modem_chat *chat, char **argv, u
data->registration_status_gsm = registration_status;
} else if (strcmp(argv[0], "+CGREG: ") == 0) {
data->registration_status_gprs = registration_status;
} else {
} else { /* CEREG */
data->registration_status_lte = registration_status;
}