Skip to content

Commit 1f90e3e

Browse files
committed
driver: modem: gsm_ppp: Wait for cell registration before attaching
1 parent 1bdc0af commit 1f90e3e

File tree

2 files changed

+107
-2
lines changed

2 files changed

+107
-2
lines changed

drivers/modem/Kconfig.gsm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ config GSM_PPP_AUTOSTART
6262
modem connects to network. See contents of "drivers/gsm_ppp.h"
6363
to get an idea of the API.
6464

65+
config MODEM_GSM_REGISTER_TIMEOUT
66+
int "Timeout for registering to cell tower"
67+
default 60
68+
help
69+
Before attaching to packet service, the cell tower registration is
70+
checked using AT+CREG. This setting dictates how much time in seconds
71+
we give the modem before giving up.
72+
6573
config MODEM_GSM_ATTACH_TIMEOUT
6674
int "Timeout for attaching to packet service"
6775
default 30

drivers/modem/gsm_ppp.c

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ LOG_MODULE_REGISTER(modem_gsm, CONFIG_MODEM_LOG_LEVEL);
3535
#define GSM_RX_STACK_SIZE CONFIG_MODEM_GSM_RX_STACK_SIZE
3636
#define GSM_RECV_MAX_BUF 30
3737
#define GSM_RECV_BUF_SIZE 128
38+
#define GSM_REGISTER_DELAY_MSEC 1000
3839
#define GSM_ATTACH_RETRY_DELAY_MSEC 1000
3940

4041
#define GSM_RSSI_RETRY_DELAY_MSEC 2000
@@ -69,6 +70,16 @@ static const char TIME_STRING_FORMAT[] = "\"yy/MM/dd,hh:mm:ss?zz\"";
6970
#define SIZE_OF_NUL 1
7071
#endif
7172

73+
/* Modem network registration state */
74+
enum network_state {
75+
GSM_NOT_REGISTERED = 0,
76+
GSM_HOME_NETWORK,
77+
GSM_SEARCHING,
78+
GSM_REGISTRATION_DENIED,
79+
GSM_UNKNOWN,
80+
GSM_ROAMING,
81+
};
82+
7283
/* During the modem setup, we first create DLCI control channel and then
7384
* PPP and AT channels. Currently the modem does not create possible GNSS
7485
* channel.
@@ -95,6 +106,9 @@ static struct gsm_modem {
95106
uint8_t *ppp_recv_buf;
96107
size_t ppp_recv_buf_len;
97108

109+
enum network_state net_state;
110+
int register_retries;
111+
98112
enum setup_state state;
99113
const struct device *ppp_dev;
100114
const struct device *at_dev;
@@ -464,8 +478,8 @@ static const struct setup_cmd setup_cmds[] = {
464478
SETUP_CMD("AT+CGSN", "", on_cmd_atcmdinfo_imei, 0U, ""),
465479
#endif
466480

467-
/* disable unsolicited network registration codes */
468-
SETUP_CMD_NOHANDLE("AT+CREG=0"),
481+
/* enable network registration report */
482+
SETUP_CMD_NOHANDLE("AT+CREG=1"),
469483

470484
/* create PDP context */
471485
SETUP_CMD_NOHANDLE("AT+CGDCONT=1,\"IP\",\"" CONFIG_MODEM_GSM_APN "\""),
@@ -589,6 +603,36 @@ int32_t gsm_ppp_get_local_time(const struct device *dev, struct tm *tm, int32_t
589603
}
590604
#endif /* CONFIG_NEWLIB_LIBC */
591605

606+
MODEM_CMD_DEFINE(on_cmd_net_reg_sts)
607+
{
608+
enum network_state net_sts = (enum network_state)atoi(argv[1]);
609+
610+
switch (net_sts) {
611+
case GSM_NOT_REGISTERED:
612+
LOG_INF("Network not registered.");
613+
break;
614+
case GSM_HOME_NETWORK:
615+
LOG_INF("Network registered, home network.");
616+
break;
617+
case GSM_SEARCHING:
618+
LOG_INF("Searching for network...");
619+
break;
620+
case GSM_REGISTRATION_DENIED:
621+
LOG_INF("Network registration denied.");
622+
break;
623+
case GSM_UNKNOWN:
624+
LOG_INF("Network unknown.");
625+
break;
626+
case GSM_ROAMING:
627+
LOG_INF("Network registered, roaming.");
628+
break;
629+
}
630+
631+
gsm.net_state = net_sts;
632+
633+
return 0;
634+
}
635+
592636
MODEM_CMD_DEFINE(on_cmd_atcmdinfo_attached)
593637
{
594638
int error = -EAGAIN;
@@ -609,6 +653,9 @@ MODEM_CMD_DEFINE(on_cmd_atcmdinfo_attached)
609653
static const struct modem_cmd read_cops_cmd =
610654
MODEM_CMD("+COPS", on_cmd_atcmdinfo_cops, 3U, ",");
611655

656+
static const struct modem_cmd check_net_reg_cmd =
657+
MODEM_CMD("+CREG: ", on_cmd_net_reg_sts, 2U, ",");
658+
612659
static const struct modem_cmd check_attached_cmd =
613660
MODEM_CMD("+CGATT:", on_cmd_atcmdinfo_attached, 1U, ",");
614661

@@ -733,6 +780,11 @@ static void gsm_finalize_connection(struct gsm_modem *gsm)
733780
goto attached;
734781
}
735782

783+
/* If modem is searching for network, we should skip the setup step */
784+
if ((gsm->net_state == GSM_SEARCHING) && gsm->register_retries) {
785+
goto registering;
786+
}
787+
736788
/* If attach check failed, we should not redo every setup step */
737789
if (gsm->attach_retries) {
738790
goto attaching;
@@ -788,6 +840,49 @@ static void gsm_finalize_connection(struct gsm_modem *gsm)
788840
return;
789841
}
790842

843+
registering:
844+
/* Wait for cell tower registration */
845+
ret = modem_cmd_send_nolock(&gsm->context.iface,
846+
&gsm->context.cmd_handler,
847+
&check_net_reg_cmd, 1,
848+
"AT+CREG?",
849+
&gsm->sem_response,
850+
GSM_CMD_SETUP_TIMEOUT);
851+
if ((ret < 0) || ((gsm->net_state != GSM_ROAMING) &&
852+
(gsm->net_state != GSM_HOME_NETWORK))) {
853+
if (!gsm->register_retries) {
854+
gsm->register_retries = CONFIG_MODEM_GSM_REGISTER_TIMEOUT *
855+
MSEC_PER_SEC / GSM_REGISTER_DELAY_MSEC;
856+
} else {
857+
gsm->register_retries--;
858+
859+
/* Reset RF if timed out */
860+
if (!gsm->register_retries) {
861+
(void)modem_cmd_send_nolock(
862+
&gsm->context.iface,
863+
&gsm->context.cmd_handler,
864+
&response_cmds[0],
865+
ARRAY_SIZE(response_cmds),
866+
"AT+CFUN=0", &gsm->sem_response,
867+
GSM_CMD_AT_TIMEOUT);
868+
869+
k_sleep(K_SECONDS(1));
870+
871+
(void)modem_cmd_send_nolock(
872+
&gsm->context.iface,
873+
&gsm->context.cmd_handler,
874+
&response_cmds[0],
875+
ARRAY_SIZE(response_cmds),
876+
"AT+CFUN=1", &gsm->sem_response,
877+
GSM_CMD_AT_TIMEOUT);
878+
}
879+
}
880+
881+
(void)k_work_reschedule(&gsm->gsm_configure_work,
882+
K_MSEC(GSM_REGISTER_DELAY_MSEC));
883+
return;
884+
}
885+
791886
attaching:
792887
/* Don't initialize PPP until we're attached to packet service */
793888
ret = modem_cmd_send_nolock(&gsm->context.iface,
@@ -1229,6 +1324,8 @@ static int gsm_init(const struct device *dev)
12291324
gsm, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
12301325
k_thread_name_set(&gsm_rx_thread, "gsm_rx");
12311326

1327+
gsm->net_state = GSM_NOT_REGISTERED;
1328+
12321329
gsm->iface = ppp_net_if();
12331330
if (!gsm->iface) {
12341331
LOG_ERR("Couldn't find ppp net_if!");

0 commit comments

Comments
 (0)