drivers: modem: gsm: wait for cellular registration
The driver should check for cellular registration before attempting to attach to packet service, otherwise it will just fails. This patch waits for registration for 300 seconds, configurable by CONFIG_MODEM_GSM_REGISTER_TIMEOUT, if it isn't registered by then, it would toggle the airplane mode using AT+CFUN & wait again, until it is registered, or `gsm_ppp_stop` is invoked. Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
This commit is contained in:
parent
b64a83822c
commit
9ee8c12a24
2 changed files with 88 additions and 0 deletions
|
@ -81,6 +81,14 @@ config MODEM_GSM_ATTACH_TIMEOUT
|
|||
using AT+CGATT. This setting dictates how much time in seconds
|
||||
we give the modem before giving up.
|
||||
|
||||
config MODEM_GSM_REGISTER_TIMEOUT
|
||||
int "Timeout for registering to cellular tower"
|
||||
default 300
|
||||
help
|
||||
Before attachment to packet service, modem is checked if it is
|
||||
connected to the cellular tower. This setting dictates how much
|
||||
time in seconds we give the modem before giving up.
|
||||
|
||||
config MODEM_GSM_MANUAL_MCCMNO
|
||||
string "MCC/MNO for establishing network connection"
|
||||
help
|
||||
|
|
|
@ -39,6 +39,7 @@ LOG_MODULE_REGISTER(modem_gsm, CONFIG_MODEM_LOG_LEVEL);
|
|||
#define GSM_RECV_MAX_BUF 30
|
||||
#define GSM_RECV_BUF_SIZE 128
|
||||
#define GSM_ATTACH_RETRY_DELAY_MSEC 1000
|
||||
#define GSM_REGISTER_DELAY_MSEC 1000
|
||||
#define GSM_RETRY_DELAY K_SECONDS(1)
|
||||
|
||||
#define GSM_RSSI_RETRY_DELAY_MSEC 2000
|
||||
|
@ -51,6 +52,17 @@ LOG_MODULE_REGISTER(modem_gsm, CONFIG_MODEM_LOG_LEVEL);
|
|||
#define GSM_RSSI_MAXVAL -51
|
||||
#endif
|
||||
|
||||
/* Modem network registration state */
|
||||
enum network_state {
|
||||
GSM_NET_INIT = -1,
|
||||
GSM_NET_NOT_REGISTERED,
|
||||
GSM_NET_HOME_NETWORK,
|
||||
GSM_NET_SEARCHING,
|
||||
GSM_NET_REGISTRATION_DENIED,
|
||||
GSM_NET_UNKNOWN,
|
||||
GSM_NET_ROAMING,
|
||||
};
|
||||
|
||||
/* During the modem setup, we first create DLCI control channel and then
|
||||
* PPP and AT channels. Currently the modem does not create possible GNSS
|
||||
* channel.
|
||||
|
@ -91,6 +103,9 @@ static struct gsm_modem {
|
|||
struct k_work_delayable rssi_work_handle;
|
||||
struct gsm_ppp_modem_info minfo;
|
||||
|
||||
enum network_state net_state;
|
||||
|
||||
int register_retries;
|
||||
int rssi_retries;
|
||||
int attach_retries;
|
||||
bool mux_enabled : 1;
|
||||
|
@ -321,6 +336,36 @@ MODEM_CMD_DEFINE(on_cmd_atcmdinfo_iccid)
|
|||
}
|
||||
#endif /* CONFIG_MODEM_SIM_NUMBERS */
|
||||
|
||||
MODEM_CMD_DEFINE(on_cmd_net_reg_sts)
|
||||
{
|
||||
gsm.net_state = (enum network_state)atoi(argv[1]);
|
||||
|
||||
switch (gsm.net_state) {
|
||||
case GSM_NET_NOT_REGISTERED:
|
||||
LOG_INF("Network %s.", "not registered");
|
||||
break;
|
||||
case GSM_NET_HOME_NETWORK:
|
||||
LOG_INF("Network %s.", "registered, home network");
|
||||
break;
|
||||
case GSM_NET_SEARCHING:
|
||||
LOG_INF("Searching for network...");
|
||||
break;
|
||||
case GSM_NET_REGISTRATION_DENIED:
|
||||
LOG_INF("Network %s.", "registration denied");
|
||||
break;
|
||||
case GSM_NET_UNKNOWN:
|
||||
LOG_INF("Network %s.", "unknown");
|
||||
break;
|
||||
case GSM_NET_ROAMING:
|
||||
LOG_INF("Network %s.", "registered, roaming");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MODEM_CELL_INFO)
|
||||
|
||||
/*
|
||||
|
@ -461,6 +506,9 @@ MODEM_CMD_DEFINE(on_cmd_atcmdinfo_attached)
|
|||
static const struct modem_cmd read_cops_cmd =
|
||||
MODEM_CMD_ARGS_MAX("+COPS:", on_cmd_atcmdinfo_cops, 1U, 4U, ",");
|
||||
|
||||
static const struct modem_cmd check_net_reg_cmd =
|
||||
MODEM_CMD("+CREG: ", on_cmd_net_reg_sts, 2U, ",");
|
||||
|
||||
static const struct modem_cmd check_attached_cmd =
|
||||
MODEM_CMD("+CGATT:", on_cmd_atcmdinfo_attached, 1U, ",");
|
||||
|
||||
|
@ -617,6 +665,11 @@ static void gsm_finalize_connection(struct k_work *work)
|
|||
goto attaching;
|
||||
}
|
||||
|
||||
/* If modem is searching for network, we should skip the setup step */
|
||||
if (gsm->register_retries) {
|
||||
goto registering;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_GSM_MUX)) {
|
||||
ret = modem_cmd_send_nolock(&gsm->context.iface,
|
||||
&gsm->context.cmd_handler,
|
||||
|
@ -668,6 +721,30 @@ static void gsm_finalize_connection(struct k_work *work)
|
|||
return;
|
||||
}
|
||||
|
||||
registering:
|
||||
/* Wait for cell tower registration */
|
||||
ret = modem_cmd_send_nolock(&gsm->context.iface,
|
||||
&gsm->context.cmd_handler,
|
||||
&check_net_reg_cmd, 1,
|
||||
"AT+CREG?",
|
||||
&gsm->sem_response,
|
||||
GSM_CMD_SETUP_TIMEOUT);
|
||||
if ((ret < 0) || ((gsm->net_state != GSM_NET_ROAMING) &&
|
||||
(gsm->net_state != GSM_NET_HOME_NETWORK))) {
|
||||
if (!gsm->register_retries) {
|
||||
gsm->register_retries = CONFIG_MODEM_GSM_REGISTER_TIMEOUT *
|
||||
MSEC_PER_SEC / GSM_REGISTER_DELAY_MSEC;
|
||||
} else {
|
||||
gsm->register_retries--;
|
||||
}
|
||||
|
||||
(void)gsm_work_reschedule(&gsm->gsm_configure_work,
|
||||
K_MSEC(GSM_REGISTER_DELAY_MSEC));
|
||||
return;
|
||||
}
|
||||
|
||||
gsm->register_retries = 0;
|
||||
|
||||
attaching:
|
||||
/* Don't initialize PPP until we're attached to packet service */
|
||||
ret = modem_cmd_send_nolock(&gsm->context.iface,
|
||||
|
@ -1066,6 +1143,7 @@ void gsm_ppp_stop(const struct device *dev)
|
|||
}
|
||||
|
||||
gsm->attached = false;
|
||||
gsm->net_state = GSM_NET_INIT;
|
||||
}
|
||||
|
||||
void gsm_ppp_register_modem_power_callback(const struct device *dev,
|
||||
|
@ -1165,6 +1243,8 @@ static int gsm_init(const struct device *dev)
|
|||
return r;
|
||||
}
|
||||
|
||||
gsm->net_state = GSM_NET_INIT;
|
||||
|
||||
LOG_DBG("iface->read %p iface->write %p",
|
||||
gsm->context.iface.read, gsm->context.iface.write);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue