modem_cellular: add registration status API

This commit implements a network registration status API,
including return of reject cause in case of denial.

Signed-off-by: Emil Lindqvist <emil@lindq.gr>
This commit is contained in:
Emil Lindqvist 2024-01-15 13:43:37 +01:00 committed by Fabio Baltieri
parent 7d1edd1fcb
commit b610312314
2 changed files with 80 additions and 13 deletions

View file

@ -102,9 +102,9 @@ struct modem_cellular_data {
uint8_t *chat_argv[32];
/* Status */
uint8_t registration_status_gsm;
uint8_t registration_status_gprs;
uint8_t registration_status_lte;
enum cellular_registration_status registration_status_gsm;
enum cellular_registration_status registration_status_gprs;
enum cellular_registration_status registration_status_lte;
uint8_t rssi;
uint8_t rsrp;
uint8_t rsrq;
@ -376,22 +376,19 @@ static void modem_cellular_chat_on_imsi(struct modem_chat *chat, char **argv, ui
static bool modem_cellular_is_registered(struct modem_cellular_data *data)
{
return (data->registration_status_gsm == 1)
|| (data->registration_status_gsm == 5)
|| (data->registration_status_gprs == 1)
|| (data->registration_status_gprs == 5)
|| (data->registration_status_lte == 1)
|| (data->registration_status_lte == 5);
return (data->registration_status_gsm == CELLULAR_REGISTRATION_REGISTERED_HOME)
|| (data->registration_status_gsm == CELLULAR_REGISTRATION_REGISTERED_ROAMING)
|| (data->registration_status_gprs == CELLULAR_REGISTRATION_REGISTERED_HOME)
|| (data->registration_status_gprs == CELLULAR_REGISTRATION_REGISTERED_ROAMING)
|| (data->registration_status_lte == CELLULAR_REGISTRATION_REGISTERED_HOME)
|| (data->registration_status_lte == CELLULAR_REGISTRATION_REGISTERED_ROAMING);
}
static void modem_cellular_chat_on_cxreg(struct modem_chat *chat, char **argv, uint16_t argc,
void *user_data)
{
struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
uint8_t registration_status;
bool is_registered;
is_registered = modem_cellular_is_registered(data);
enum cellular_registration_status registration_status = 0;
if (argc == 2) {
registration_status = atoi(argv[1]);
@ -1410,10 +1407,40 @@ static int modem_cellular_get_modem_info(const struct device *dev,
return ret;
}
static int modem_cellular_get_registration_status(const struct device *dev,
enum cellular_access_technology tech,
enum cellular_registration_status *status)
{
int ret = 0;
struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
switch (tech) {
case CELLULAR_ACCESS_TECHNOLOGY_GSM:
*status = data->registration_status_gsm;
break;
case CELLULAR_ACCESS_TECHNOLOGY_GPRS:
case CELLULAR_ACCESS_TECHNOLOGY_UMTS:
case CELLULAR_ACCESS_TECHNOLOGY_EDGE:
*status = data->registration_status_gprs;
break;
case CELLULAR_ACCESS_TECHNOLOGY_LTE:
case CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M1:
case CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M2:
case CELLULAR_ACCESS_TECHNOLOGY_NB_IOT:
*status = data->registration_status_lte;
break;
default:
ret = -ENODATA;
break;
}
return ret;
}
const static struct cellular_driver_api modem_cellular_api = {
.get_signal = modem_cellular_get_signal,
.get_modem_info = modem_cellular_get_modem_info,
.get_registration_status = modem_cellular_get_registration_status,
};
#ifdef CONFIG_PM_DEVICE

View file

@ -76,6 +76,15 @@ enum cellular_modem_info_type {
CELLULAR_MODEM_INFO_SIM_ICCID,
};
enum cellular_registration_status {
CELLULAR_REGISTRATION_NOT_REGISTERED = 0,
CELLULAR_REGISTRATION_REGISTERED_HOME,
CELLULAR_REGISTRATION_SEARCHING,
CELLULAR_REGISTRATION_DENIED,
CELLULAR_REGISTRATION_UNKNOWN,
CELLULAR_REGISTRATION_REGISTERED_ROAMING,
};
/** API for configuring networks */
typedef int (*cellular_api_configure_networks)(const struct device *dev,
const struct cellular_network *networks,
@ -95,12 +104,18 @@ typedef int (*cellular_api_get_modem_info)(const struct device *dev,
const enum cellular_modem_info_type type,
char *info, size_t size);
/** API for getting registration status */
typedef int (*cellular_api_get_registration_status)(const struct device *dev,
enum cellular_access_technology tech,
enum cellular_registration_status *status);
/** Cellular driver API */
__subsystem struct cellular_driver_api {
cellular_api_configure_networks configure_networks;
cellular_api_get_supported_networks get_supported_networks;
cellular_api_get_signal get_signal;
cellular_api_get_modem_info get_modem_info;
cellular_api_get_registration_status get_registration_status;
};
/**
@ -210,6 +225,31 @@ static inline int cellular_get_modem_info(const struct device *dev,
return api->get_modem_info(dev, type, info, size);
}
/**
* @brief Get network registration status for the device
*
* @param dev Cellular network device instance
* @param tech Which access technology to get status for
* @param status Registration status for given access technology
*
* @retval 0 if successful.
* @retval -ENOSYS if API is not supported by cellular network device.
* @retval -ENODATA if modem does not provide info requested
* @retval Negative errno-code from chat module otherwise.
*/
static inline int cellular_get_registration_status(const struct device *dev,
enum cellular_access_technology tech,
enum cellular_registration_status *status)
{
const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api;
if (api->get_registration_status == NULL) {
return -ENOSYS;
}
return api->get_registration_status(dev, tech, status);
}
#ifdef __cplusplus
}
#endif