@@ -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+
592636MODEM_CMD_DEFINE (on_cmd_atcmdinfo_attached )
593637{
594638 int error = - EAGAIN ;
@@ -609,6 +653,9 @@ MODEM_CMD_DEFINE(on_cmd_atcmdinfo_attached)
609653static 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+
612659static 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+
791886attaching :
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