Skip to content

Commit 78ce959

Browse files
tokangasrlubos
authored andcommitted
lib: lte_link_control: Add logging for LTE registration reject
Added a warning log for registration reject EMM cause from the network. Cleaned up +CEREG notification parsing. Signed-off-by: Tommi Kangas <[email protected]>
1 parent 388fc34 commit 78ce959

File tree

4 files changed

+188
-228
lines changed

4 files changed

+188
-228
lines changed

lib/lte_link_control/lte_lc.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -256,17 +256,14 @@ static void at_handler_cereg(const char *response)
256256

257257
static enum lte_lc_nw_reg_status prev_reg_status = LTE_LC_NW_REG_NOT_REGISTERED;
258258
static struct lte_lc_cell prev_cell;
259-
enum lte_lc_nw_reg_status reg_status = 0;
260-
struct lte_lc_cell cell = {0};
259+
enum lte_lc_nw_reg_status reg_status;
260+
struct lte_lc_cell cell;
261261
enum lte_lc_lte_mode lte_mode;
262-
struct lte_lc_psm_cfg psm_cfg = {
263-
.active_time = -1,
264-
.tau = -1
265-
};
262+
struct lte_lc_psm_cfg psm_cfg;
266263

267264
LOG_DBG("+CEREG notification: %.*s", strlen(response) - strlen("\r\n"), response);
268265

269-
err = parse_cereg(response, true, &reg_status, &cell, &lte_mode, &psm_cfg);
266+
err = parse_cereg(response, &reg_status, &cell, &lte_mode, &psm_cfg);
270267
if (err) {
271268
LOG_ERR("Failed to parse notification (error %d): %s",
272269
err, response);

lib/lte_link_control/lte_lc_helpers.c

Lines changed: 90 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -243,39 +243,6 @@ bool response_is_valid(const char *response, size_t response_len,
243243
return true;
244244
}
245245

246-
/* Get network registration status from CEREG response list.
247-
* Returns the (positive) registration value if it's found, otherwise a negative
248-
* error code.
249-
*/
250-
static int get_nw_reg_status(struct at_param_list *list, bool is_notif)
251-
{
252-
int err, reg_status;
253-
size_t reg_status_index = is_notif ? AT_CEREG_REG_STATUS_INDEX :
254-
AT_CEREG_READ_REG_STATUS_INDEX;
255-
256-
err = at_params_int_get(list, reg_status_index, &reg_status);
257-
if (err) {
258-
return err;
259-
}
260-
261-
/* Check if the parsed value maps to a valid registration status */
262-
switch (reg_status) {
263-
case LTE_LC_NW_REG_NOT_REGISTERED:
264-
case LTE_LC_NW_REG_REGISTERED_HOME:
265-
case LTE_LC_NW_REG_SEARCHING:
266-
case LTE_LC_NW_REG_REGISTRATION_DENIED:
267-
case LTE_LC_NW_REG_UNKNOWN:
268-
case LTE_LC_NW_REG_REGISTERED_ROAMING:
269-
case LTE_LC_NW_REG_UICC_FAIL:
270-
break;
271-
default:
272-
LOG_ERR("Invalid network registration status: %d", reg_status);
273-
return -EINVAL;
274-
}
275-
276-
return reg_status;
277-
}
278-
279246
int string_to_int(const char *str_buf, int base, int *output)
280247
{
281248
int temp;
@@ -702,19 +669,32 @@ int parse_rrc_mode(const char *at_response,
702669
}
703670

704671
int parse_cereg(const char *at_response,
705-
bool is_notif,
706672
enum lte_lc_nw_reg_status *reg_status,
707673
struct lte_lc_cell *cell,
708674
enum lte_lc_lte_mode *lte_mode,
709675
struct lte_lc_psm_cfg *psm_cfg)
710676
{
711-
int err, status;
677+
int err, temp;
712678
struct at_param_list resp_list;
713679
char str_buf[10];
714680
char response_prefix[sizeof(AT_CEREG_RESPONSE_PREFIX)] = {0};
715681
size_t response_prefix_len = sizeof(response_prefix);
716682
size_t len = sizeof(str_buf) - 1;
717683

684+
__ASSERT_NO_MSG(reg_status != NULL);
685+
__ASSERT_NO_MSG(cell != NULL);
686+
__ASSERT_NO_MSG(lte_mode != NULL);
687+
__ASSERT_NO_MSG(psm_cfg != NULL);
688+
689+
/* Initialize all return values. */
690+
*reg_status = LTE_LC_NW_REG_UNKNOWN;
691+
(void)memset(cell, 0, sizeof(struct lte_lc_cell));
692+
cell->id = LTE_LC_CELL_EUTRAN_ID_INVALID;
693+
cell->tac = LTE_LC_CELL_TAC_INVALID;
694+
*lte_mode = LTE_LC_LTE_MODE_NONE;
695+
psm_cfg->active_time = -1;
696+
psm_cfg->tau = -1;
697+
718698
err = at_params_list_init(&resp_list, AT_CEREG_PARAMS_COUNT_MAX);
719699
if (err) {
720700
LOG_ERR("Could not init AT params list, error: %d", err);
@@ -749,31 +729,21 @@ int parse_cereg(const char *at_response,
749729
}
750730

751731
/* Get network registration status */
752-
status = get_nw_reg_status(&resp_list, is_notif);
753-
if (status < 0) {
754-
LOG_ERR("Could not get registration status, error: %d", status);
755-
err = status;
732+
err = at_params_int_get(&resp_list, AT_CEREG_REG_STATUS_INDEX, &temp);
733+
if (err) {
734+
LOG_ERR("Could not get registration status, error: %d", err);
756735
goto clean_exit;
757736
}
758737

759-
if (reg_status) {
760-
*reg_status = status;
761-
762-
LOG_DBG("Network registration status: %d", *reg_status);
763-
}
764-
738+
*reg_status = temp;
739+
LOG_DBG("Network registration status: %d", *reg_status);
765740

766-
if (cell && (status != LTE_LC_NW_REG_UICC_FAIL) &&
741+
if ((*reg_status != LTE_LC_NW_REG_UICC_FAIL) &&
767742
(at_params_valid_count_get(&resp_list) > AT_CEREG_CELL_ID_INDEX)) {
768743
/* Parse tracking area code */
769-
err = at_params_string_get(
770-
&resp_list,
771-
is_notif ? AT_CEREG_TAC_INDEX :
772-
AT_CEREG_READ_TAC_INDEX,
773-
str_buf, &len);
744+
err = at_params_string_get(&resp_list, AT_CEREG_TAC_INDEX, str_buf, &len);
774745
if (err) {
775746
LOG_DBG("Could not get tracking area code, error: %d", err);
776-
cell->tac = LTE_LC_CELL_TAC_INVALID;
777747
} else {
778748
str_buf[len] = '\0';
779749
cell->tac = strtoul(str_buf, NULL, 16);
@@ -782,101 +752,95 @@ int parse_cereg(const char *at_response,
782752
/* Parse cell ID */
783753
len = sizeof(str_buf) - 1;
784754

785-
err = at_params_string_get(&resp_list,
786-
is_notif ? AT_CEREG_CELL_ID_INDEX :
787-
AT_CEREG_READ_CELL_ID_INDEX,
788-
str_buf, &len);
755+
err = at_params_string_get(&resp_list, AT_CEREG_CELL_ID_INDEX, str_buf, &len);
789756
if (err) {
790757
LOG_DBG("Could not get cell ID, error: %d", err);
791-
cell->id = LTE_LC_CELL_EUTRAN_ID_INVALID;
792758
} else {
793759
str_buf[len] = '\0';
794760
cell->id = strtoul(str_buf, NULL, 16);
795761
}
796-
} else if (cell) {
797-
cell->tac = LTE_LC_CELL_TAC_INVALID;
798-
cell->id = LTE_LC_CELL_EUTRAN_ID_INVALID;
799762
}
800763

801-
if (lte_mode) {
802-
int mode;
764+
/* Get currently active LTE mode. */
765+
err = at_params_int_get(&resp_list, AT_CEREG_ACT_INDEX, &temp);
766+
if (err) {
767+
LOG_DBG("LTE mode not found, error code: %d", err);
803768

804-
/* Get currently active LTE mode. */
805-
err = at_params_int_get(&resp_list,
806-
is_notif ? AT_CEREG_ACT_INDEX :
807-
AT_CEREG_READ_ACT_INDEX,
808-
&mode);
809-
if (err) {
810-
LOG_DBG("LTE mode not found, error code: %d", err);
811-
*lte_mode = LTE_LC_LTE_MODE_NONE;
769+
/* This is not an error that should be returned, as it's
770+
* expected in some situations that LTE mode is not available.
771+
*/
772+
err = 0;
773+
} else {
774+
*lte_mode = temp;
775+
LOG_DBG("LTE mode: %d", *lte_mode);
776+
}
812777

813-
/* This is not an error that should be returned, as it's
814-
* expected in some situations that LTE mode is not
815-
* available.
816-
*/
817-
err = 0;
818-
} else {
819-
*lte_mode = mode;
778+
#if defined(CONFIG_LOG)
779+
int cause_type;
780+
int reject_cause;
820781

821-
LOG_DBG("LTE mode: %d", *lte_mode);
822-
}
782+
/* Log reject cause if present. */
783+
err = at_params_int_get(&resp_list, AT_CEREG_CAUSE_TYPE_INDEX, &cause_type);
784+
err |= at_params_int_get(&resp_list, AT_CEREG_REJECT_CAUSE_INDEX, &reject_cause);
785+
if (!err && cause_type == 0 /* EMM cause */) {
786+
LOG_WRN("Registration rejected, EMM cause: %d, Cell ID: %d, Tracking area: %d, "
787+
"LTE mode: %d",
788+
reject_cause, cell->id, cell->tac, *lte_mode);
823789
}
790+
/* Absence of reject cause is not considered an error. */
791+
err = 0;
792+
#endif /* CONFIG_LOG */
824793

825794
/* Check PSM parameters only if we are connected */
826-
if ((status != LTE_LC_NW_REG_REGISTERED_HOME) &&
827-
(status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
795+
if ((*reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
796+
(*reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
828797
goto clean_exit;
829798
}
830799

831-
if (psm_cfg != NULL) {
832-
char active_time_str[9] = {0};
833-
char tau_ext_str[9] = {0};
834-
int str_len = 8;
835-
int err_active_time;
836-
int err_tau;
837-
838-
psm_cfg->active_time = -1;
839-
psm_cfg->tau = -1;
840-
841-
/* Get active time */
842-
err_active_time = at_params_string_get(
843-
&resp_list,
844-
is_notif ? AT_CEREG_ACTIVE_TIME_INDEX :
845-
AT_CEREG_READ_ACTIVE_TIME_INDEX,
846-
active_time_str, &str_len);
847-
if (err_active_time) {
848-
LOG_DBG("Active time not found, error: %d", err_active_time);
849-
} else {
850-
LOG_DBG("Active time: %s", active_time_str);
851-
}
800+
char active_time_str[9] = {0};
801+
char tau_ext_str[9] = {0};
802+
int str_len = 8;
803+
int err_active_time;
804+
int err_tau;
852805

853-
/* Get Periodic-TAU-ext */
854-
err_tau = at_params_string_get(
855-
&resp_list,
856-
is_notif ? AT_CEREG_TAU_INDEX :
857-
AT_CEREG_READ_TAU_INDEX,
858-
tau_ext_str, &str_len);
859-
if (err_tau) {
860-
LOG_DBG("TAU not found, error: %d", err_tau);
861-
} else {
862-
LOG_DBG("TAU: %s", tau_ext_str);
863-
}
806+
/* Get active time */
807+
err_active_time = at_params_string_get(
808+
&resp_list,
809+
AT_CEREG_ACTIVE_TIME_INDEX,
810+
active_time_str,
811+
&str_len);
812+
if (err_active_time) {
813+
LOG_DBG("Active time not found, error: %d", err_active_time);
814+
} else {
815+
LOG_DBG("Active time: %s", active_time_str);
816+
}
864817

865-
if (err_active_time == 0 && err_tau == 0) {
866-
/* Legacy TAU is not requested because we do not get it from CEREG.
867-
* If extended TAU is not set, TAU will be set to inactive so
868-
* caller can then make its conclusions.
869-
*/
870-
err = parse_psm(active_time_str, tau_ext_str, NULL, psm_cfg);
871-
if (err) {
872-
LOG_ERR("Failed to parse PSM configuration, error: %d", err);
873-
}
874-
}
875-
/* The notification does not always contain PSM parameters,
876-
* so this is not considered an error
818+
/* Get Periodic-TAU-ext */
819+
err_tau = at_params_string_get(
820+
&resp_list,
821+
AT_CEREG_TAU_INDEX,
822+
tau_ext_str,
823+
&str_len);
824+
if (err_tau) {
825+
LOG_DBG("TAU not found, error: %d", err_tau);
826+
} else {
827+
LOG_DBG("TAU: %s", tau_ext_str);
828+
}
829+
830+
if (err_active_time == 0 && err_tau == 0) {
831+
/* Legacy TAU is not requested because we do not get it from CEREG.
832+
* If extended TAU is not set, TAU will be set to inactive so
833+
* caller can then make its conclusions.
877834
*/
878-
err = 0;
835+
err = parse_psm(active_time_str, tau_ext_str, NULL, psm_cfg);
836+
if (err) {
837+
LOG_ERR("Failed to parse PSM configuration, error: %d", err);
838+
}
879839
}
840+
/* The notification does not always contain PSM parameters,
841+
* so this is not considered an error
842+
*/
843+
err = 0;
880844

881845
clean_exit:
882846
at_params_list_free(&resp_list);

lib/lte_link_control/lte_lc_helpers.h

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,18 @@
2121
#define AT_CFUN_RESPONSE_PREFIX "+CFUN"
2222
#define AT_CFUN_MODE_INDEX 1
2323
#define AT_CFUN_PARAMS_COUNT 2
24-
#define AT_CFUN_RESPONSE_MAX_LEN 20
2524
#define AT_CEREG_5 "AT+CEREG=5"
2625
#define AT_CEREG_READ "AT+CEREG?"
2726
#define AT_CEREG_RESPONSE_PREFIX "+CEREG"
2827
#define AT_CEREG_PARAMS_COUNT_MAX 11
2928
#define AT_CEREG_REG_STATUS_INDEX 1
30-
#define AT_CEREG_READ_REG_STATUS_INDEX 2
3129
#define AT_CEREG_TAC_INDEX 2
32-
#define AT_CEREG_READ_TAC_INDEX 3
3330
#define AT_CEREG_CELL_ID_INDEX 3
34-
#define AT_CEREG_READ_CELL_ID_INDEX 4
3531
#define AT_CEREG_ACT_INDEX 4
36-
#define AT_CEREG_READ_ACT_INDEX 5
32+
#define AT_CEREG_CAUSE_TYPE_INDEX 5
33+
#define AT_CEREG_REJECT_CAUSE_INDEX 6
3734
#define AT_CEREG_ACTIVE_TIME_INDEX 7
38-
#define AT_CEREG_READ_ACTIVE_TIME_INDEX 8
3935
#define AT_CEREG_TAU_INDEX 8
40-
#define AT_CEREG_READ_TAU_INDEX 9
41-
#define AT_CEREG_RESPONSE_MAX_LEN 80
4236
#define AT_XSYSTEMMODE_READ "AT%XSYSTEMMODE?"
4337
#define AT_XSYSTEMMODE_RESPONSE_PREFIX "%XSYSTEMMODE"
4438
#define AT_XSYSTEMMODE_PROTO "AT%%XSYSTEMMODE=%d,%d,%d,%d"
@@ -49,7 +43,6 @@
4943
#define AT_XSYSTEMMODE_READ_GPS_INDEX 3
5044
#define AT_XSYSTEMMODE_READ_PREFERENCE_INDEX 4
5145
#define AT_XSYSTEMMODE_PARAMS_COUNT 5
52-
#define AT_XSYSTEMMODE_RESPONSE_MAX_LEN 30
5346

5447
/* CEDRXS command parameters */
5548
#define AT_CEDRXS_MODE_INDEX
@@ -120,7 +113,6 @@
120113
#define AT_CONEVAL_READ "AT%CONEVAL"
121114
#define AT_CONEVAL_RESPONSE_PREFIX "%CONEVAL"
122115
#define AT_CONEVAL_PREFIX_INDEX 0
123-
#define AT_CONEVAL_RESPONSE_MAX_LEN 110
124116
#define AT_CONEVAL_PARAMS_MAX 19
125117
#define AT_CONEVAL_RESULT_INDEX 1
126118
#define AT_CONEVAL_RRC_STATE_INDEX 2
@@ -220,21 +212,19 @@ int parse_psm(const char *active_time_str, const char *tau_ext_str,
220212
*/
221213
int encode_psm(char *tau_ext_str, char *active_time_str, int rptau, int rat);
222214

223-
/* @brief Parses an CEREG response and returns network registration status,
224-
* cell information, LTE mode and pSM configuration.
215+
/* @brief Parses a +CEREG notification and returns network registration status,
216+
* cell information, LTE mode and PSM configuration. The function always
217+
* initializes the return values. The destination pointers must be non-NULL.
225218
*
226-
* @param at_response Pointer to buffer with AT response.
227-
* @param is_notif The buffer in at_response is a notification.
228-
* @param reg_status Pointer to where the registration status is stored.
229-
* Can be NULL.
230-
* @param cell Pointer to cell information struct. Can be NULL.
231-
* @param lte_mode Pointer to LTE mode struct. Can be NULL.
232-
* @param psm_cfg Pointer to PSM configuration struct. Can be NULL.
219+
* @param[in] at_response AT notification.
220+
* @param[out] reg_status Registration status.
221+
* @param[out] cell Cell information.
222+
* @param[out] lte_mode LTE mode.
223+
* @param[out] psm_cfg PSM configuration.
233224
*
234225
* @return Zero on success or (negative) error code otherwise.
235226
*/
236227
int parse_cereg(const char *at_response,
237-
bool is_notif,
238228
enum lte_lc_nw_reg_status *reg_status,
239229
struct lte_lc_cell *cell,
240230
enum lte_lc_lte_mode *lte_mode,

0 commit comments

Comments
 (0)