diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index c9ebc40b7a52805b5a588543c75b1c79f691de7f..efecf7d321bed086d48bad93e070401fe869de46 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -78,57 +78,9 @@ Description Defines EMM procedures executed by the Non-Access Stratum /****************************************************************************/ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn); -static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn); +static int _IldlMode_get_opnn_id(emm_data_t *emm_data, const plmn_t *plmn); static int _IdleMode_get_suitable_cell(nas_user_t *user, int index); -/* - * A list of PLMN identities in priority order is maintained locally - * to perform the PLMN selection procedure. - * - * In automatic mode of operation, this list is used for PLMN selection when - * the UE is switched on, or upon recovery from lack of coverage, or when the - * user requests the UE to initiate PLMN reselection, and registration. - * In manual mode of operation, this list is displayed to the user that may - * select an available PLMN and initiate registration. - * - * The list may contain PLMN identifiers in the following order: - * - The last registered PLMN or each equivalent PLMN present in the list of - * "equivalent PLMNs" (EPLMN_MAX), when UE is switched on or following - * recovery from lack of coverage; - * - The highest priority PLMN in the list of "equivalent HPLMNs" or the - * HPLMN derived from the IMSI (1) - * - Each PLMN/access technology combination in the "User Controlled PLMN - * Selector with Access Technology" (PLMN_MAX) - * - Each PLMN/access technology combination in the "Operator Controlled PLMN - * Selector with Access Technology" (OPLMN_MAX) - * - Other PLMN/access technology combinations with received high quality - * signal in random order (TODO) - * - Other PLMN/access technology combinations in order of decreasing signal - * quality (TODO) - * - The last selected PLMN again (1) - */ -static struct { - int n_plmns; -#define EMM_PLMN_LIST_SIZE (EMM_DATA_EPLMN_MAX + EMM_DATA_PLMN_MAX + \ - EMM_DATA_OPLMN_MAX + 2) - plmn_t *plmn[EMM_PLMN_LIST_SIZE]; - int index; /* Index of the PLMN for which selection is ongoing */ - int hplmn; /* Index of the home PLMN or the highest priority - * equivalent home PLMN */ - int fplmn; /* Index of the first forbidden PLMN */ - int splmn; /* Index of the currently selected PLMN */ - int rplmn; /* Index of the currently registered PLMN */ - struct plmn_param_t { - char fullname[NET_FORMAT_LONG_SIZE+1]; /* PLMN full identifier */ - char shortname[NET_FORMAT_SHORT_SIZE+1]; /* PLMN short identifier */ - char num[NET_FORMAT_NUM_SIZE+1]; /* PLMN numeric identifier */ - int stat; /* Indication of the PLMN availability */ - int tac; /* Location/Tracking Area Code */ - int ci; /* Serving cell identifier */ - int rat; /* Radio Access Technology supported by the serving cell */ - } param[EMM_PLMN_LIST_SIZE]; -} _emm_plmn_list; - /* Callback executed whenever a network indication is received */ static IdleMode_callback_t _emm_indication_notify; @@ -154,13 +106,19 @@ static IdleMode_callback_t _emm_indication_notify; ***************************************************************************/ void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb) { + emm_plmn_list_t *emm_plmn_list = calloc(1, sizeof(emm_plmn_list_t)); + if ( emm_plmn_list == NULL ) { + LOG_TRACE(ERROR, "EMM - Can't alloc emm_plmn_list"); + // FIXME stop here + } + user->emm_plmn_list = emm_plmn_list; /* Initialize the list of available PLMNs */ - _emm_plmn_list.n_plmns = 0; - _emm_plmn_list.index = 0; - _emm_plmn_list.hplmn = -1; - _emm_plmn_list.fplmn = -1; - _emm_plmn_list.splmn = -1; - _emm_plmn_list.rplmn = -1; + emm_plmn_list->n_plmns = 0; + emm_plmn_list->index = 0; + emm_plmn_list->hplmn = -1; + emm_plmn_list->fplmn = -1; + emm_plmn_list->splmn = -1; + emm_plmn_list->rplmn = -1; /* Initialize the network notification handler */ _emm_indication_notify = *cb; @@ -190,9 +148,9 @@ void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_nb_plmns(void) +int IdleMode_get_nb_plmns(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.n_plmns; + return emm_plmn_list->n_plmns; } /**************************************************************************** @@ -211,9 +169,9 @@ int IdleMode_get_nb_plmns(void) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_hplmn_index(void) +int IdleMode_get_hplmn_index(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.hplmn; + return emm_plmn_list->hplmn; } /**************************************************************************** @@ -232,9 +190,9 @@ int IdleMode_get_hplmn_index(void) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_rplmn_index(void) +int IdleMode_get_rplmn_index(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.rplmn; + return emm_plmn_list->rplmn; } /**************************************************************************** @@ -245,16 +203,15 @@ int IdleMode_get_rplmn_index(void) ** available PLMNs. ** ** ** ** Inputs: None ** - ** Others: _emm_plmn_list ** ** ** ** Outputs: None ** ** Return: The index of the selected PLMN in the list ** ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_splmn_index(void) +int IdleMode_get_splmn_index(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.splmn; + return emm_plmn_list->splmn; } /**************************************************************************** @@ -265,19 +222,18 @@ int IdleMode_get_splmn_index(void) ** tors present in the network ** ** ** ** Inputs: i: Index of the first operator to update ** - ** Others: _emm_plmn_list ** ** ** ** Outputs: None ** ** Return: The size of the list in bytes ** ** ** ***************************************************************************/ -int IdleMode_update_plmn_list(emm_data_t *emm_data, int i) +int IdleMode_update_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int i) { int offset = 0; int n = 1; - while ( (i < _emm_plmn_list.n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) { - struct plmn_param_t *plmn = &(_emm_plmn_list.param[i++]); + while ( (i < emm_plmn_list->n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) { + struct plmn_param_t *plmn = &(emm_plmn_list->param[i++]); if (n++ > 1) { offset += snprintf(emm_data->plist.buffer + offset, @@ -319,13 +275,13 @@ int IdleMode_update_plmn_list(emm_data_t *emm_data, int i) ** Others: None ** ** ** ***************************************************************************/ -const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_fullname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len) { - if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].fullname); - return _emm_plmn_list.param[index].fullname; + if (index < emm_plmn_list->n_plmns) { + assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) ); + *len = strlen(emm_plmn_list->param[index].fullname); + return emm_plmn_list->param[index].fullname; } return NULL; @@ -348,13 +304,13 @@ const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, ** Others: None ** ** ** ***************************************************************************/ -const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_shortname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len) { - if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].shortname); - return _emm_plmn_list.param[index].shortname; + if (index < emm_plmn_list->n_plmns) { + assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) ); + *len = strlen(emm_plmn_list->param[index].shortname); + return emm_plmn_list->param[index].shortname; } return NULL; @@ -378,12 +334,12 @@ const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, ** Others: None ** ** ** ***************************************************************************/ -const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len) +const char *IdleMode_get_plmn_id(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len) { - if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].num); - return _emm_plmn_list.param[index].num; + if (index < emm_plmn_list->n_plmns) { + assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) ); + *len = strlen(emm_plmn_list->param[index].num); + return emm_plmn_list->param[index].num; } return NULL; @@ -405,13 +361,13 @@ const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_fullname_index(const char *plmn) +int IdleMode_get_plmn_fullname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn) { int index; /* Get the index of the PLMN identifier with specified full name */ - for (index = 0; index < _emm_plmn_list.n_plmns; index++) { - if ( strncmp(plmn, _emm_plmn_list.param[index].fullname, + for (index = 0; index < emm_plmn_list->n_plmns; index++) { + if ( strncmp(plmn, emm_plmn_list->param[index].fullname, NET_FORMAT_LONG_SIZE) != 0 ) { continue; } @@ -438,13 +394,13 @@ int IdleMode_get_plmn_fullname_index(const char *plmn) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_shortname_index(const char *plmn) +int IdleMode_get_plmn_shortname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn) { int index; /* Get the index of the PLMN identifier with specified short name */ - for (index = 0; index < _emm_plmn_list.n_plmns; index++) { - if ( !strncmp(plmn, _emm_plmn_list.param[index].shortname, + for (index = 0; index < emm_plmn_list->n_plmns; index++) { + if ( !strncmp(plmn, emm_plmn_list->param[index].shortname, NET_FORMAT_SHORT_SIZE) ) { continue; } @@ -471,13 +427,13 @@ int IdleMode_get_plmn_shortname_index(const char *plmn) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_id_index(const char *plmn) +int IdleMode_get_plmn_id_index(emm_plmn_list_t *emm_plmn_list, const char *plmn) { int index; /* Get the index of the PLMN identifier with specified numeric identifier */ - for (index = 0; index < _emm_plmn_list.n_plmns; index++) { - if ( !strncmp(plmn, _emm_plmn_list.param[index].num, + for (index = 0; index < emm_plmn_list->n_plmns; index++) { + if ( !strncmp(plmn, emm_plmn_list->param[index].num, NET_FORMAT_LONG_SIZE) ) { continue; } @@ -516,6 +472,7 @@ int emm_proc_initialize(nas_user_t *user) emm_sap_t emm_sap; int rc; int i; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; if (!user->emm_data->usim_is_valid) { /* The USIM application is not present or not valid */ @@ -526,11 +483,11 @@ int emm_proc_initialize(nas_user_t *user) * if available, or the last registered PLMN */ if (user->emm_data->nvdata.eplmn.n_plmns > 0) { for (i=0; i < user->emm_data->nvdata.eplmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->nvdata.eplmn.plmn[i]; } } else if ( PLMN_IS_VALID(user->emm_data->nvdata.rplmn) ) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->nvdata.rplmn; } @@ -538,29 +495,29 @@ int emm_proc_initialize(nas_user_t *user) * When switched on, the UE will try to automatically register * to each previous PLMN within the ordered list of available * PLMNs regardless of the network selection mode of operation */ - _emm_plmn_list.hplmn = _emm_plmn_list.n_plmns - 1; - // LG_emm_plmn_list.hplmn = _emm_plmn_list.n_plmns; + emm_plmn_list->hplmn = emm_plmn_list->n_plmns - 1; + // LGemm_plmn_list->hplmn = emm_plmn_list->n_plmns; /* Add the highest priority PLMN in the list of "equivalent HPLMNs" if present and not empty, or the HPLMN derived from the IMSI */ if (user->emm_data->ehplmn.n_plmns > 0) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->ehplmn.plmn[0]; } else { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = &user->emm_data->hplmn; + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->hplmn; } /* Each PLMN/access technology combination in the "User * Controlled PLMN Selector with Access Technology" */ for (i=0; i < user->emm_data->plmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->plmn.plmn[i]; } /* Each PLMN/access technology combination in the "Operator * Controlled PLMN Selector with Access Technology" */ for (i=0; i < user->emm_data->oplmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->oplmn.plmn[i]; } @@ -573,9 +530,9 @@ int emm_proc_initialize(nas_user_t *user) /* TODO: Schedule periodic network selection attemps (hpplmn timer) */ /* Initialize the PLMNs' parameters */ - for (i=0; i < _emm_plmn_list.n_plmns; i++) { - struct plmn_param_t *plmn = &(_emm_plmn_list.param[i]); - int id = _IldlMode_get_opnn_id(user, _emm_plmn_list.plmn[i]); + for (i=0; i < emm_plmn_list->n_plmns; i++) { + struct plmn_param_t *plmn = &(emm_plmn_list->param[i]); + int id = _IldlMode_get_opnn_id(user->emm_data, emm_plmn_list->plmn[i]); if (id < 0) { plmn->fullname[0] = '\0'; @@ -587,7 +544,7 @@ int emm_proc_initialize(nas_user_t *user) NET_FORMAT_SHORT_SIZE); } - (void)_IdleMode_plmn_str(plmn->num, _emm_plmn_list.plmn[i]); + (void)_IdleMode_plmn_str(plmn->num, emm_plmn_list->plmn[i]); plmn->stat = NET_OPER_UNKNOWN; plmn->tac = 0; plmn->ci = 0; @@ -595,7 +552,7 @@ int emm_proc_initialize(nas_user_t *user) } LOG_TRACE(INFO, "EMM-IDLE - %d PLMNs available for network selection", - _emm_plmn_list.n_plmns); + emm_plmn_list->n_plmns); /* Notify EMM that PLMN selection procedure has to be executed */ emm_sap.primitive = EMMREG_REGISTER_REQ; @@ -630,31 +587,33 @@ int emm_proc_initialize(nas_user_t *user) ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_plmn_list.index ** + ** Others: emm_plmn_list->index ** ** ** ***************************************************************************/ int emm_proc_plmn_selection(nas_user_t *user, int index) { LOG_FUNC_IN; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; int rc = RETURNok; - if (user->emm_data->plmn_mode != EMM_DATA_PLMN_AUTO) { + if (emm_data->plmn_mode != EMM_DATA_PLMN_AUTO) { /* * Manual or manual/automatic mode of operation * -------------------------------------------- */ - if (index >= _emm_plmn_list.hplmn) { + if (index >= emm_plmn_list->hplmn) { /* * Selection of the last registered or equivalent PLMNs failed */ - if (user->emm_data->plmn_index < 0) { + if (emm_data->plmn_index < 0) { /* * The user did not select any PLMN yet; display the ordered * list of available PLMNs to the user */ index = -1; - rc = emm_proc_network_notify(user->emm_data, _emm_plmn_list.hplmn); + rc = emm_proc_network_notify(emm_plmn_list, emm_data, emm_plmn_list->hplmn); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify " @@ -664,7 +623,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) /* * Try to register to the PLMN manually selected by the user */ - index = user->emm_data->plmn_index; + index = emm_data->plmn_index; } } } @@ -677,7 +636,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) * or any other PLMN in the ordered list of available PLMNs in * automatic mode. */ - _emm_plmn_list.index = index; + emm_plmn_list->index = index; rc = _IdleMode_get_suitable_cell(user, index); } @@ -713,11 +672,9 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) ** ci: The identifier of the cell ** ** rat: The radio access technology supported by ** ** the cell ** - ** Others: _emm_plmn_list, user->emm_data-> ** ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_plmn_list, user->emm_data-> ** ** ** ***************************************************************************/ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat) @@ -726,34 +683,36 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, emm_sap_t emm_sap; int rc = RETURNerror; - int index = _emm_plmn_list.index; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; + int index = emm_plmn_list->index; int select_next_plmn = FALSE; LOG_TRACE(INFO, "EMM-IDLE - %s cell found for PLMN %d in %s mode", (found)? "One" : "No", index, - (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : "Automatic/manual"); if (found) { int is_forbidden = FALSE; /* Select the PLMN of which a suitable cell has been found */ - user->emm_data->splmn = *_emm_plmn_list.plmn[index]; + emm_data->splmn = *emm_plmn_list->plmn[index]; /* Update the selected PLMN's parameters */ - _emm_plmn_list.param[index].tac = tac; - _emm_plmn_list.param[index].ci = ci; - _emm_plmn_list.param[index].rat = rat; + emm_plmn_list->param[index].tac = tac; + emm_plmn_list->param[index].ci = ci; + emm_plmn_list->param[index].rat = rat; /* Update the location data and notify EMM that data have changed */ - rc = emm_proc_location_notify(user->emm_data, tac, ci , rat); + rc = emm_proc_location_notify(emm_data, tac, ci , rat); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify location update"); } - if (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { + if (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { /* * Automatic mode of operation * --------------------------- @@ -761,17 +720,17 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, int i; /* Check if the selected PLMN is in the forbidden list */ - for (i = 0; i < user->emm_data->fplmn.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(user->emm_data->splmn, user->emm_data->fplmn.plmn[i])) { + for (i = 0; i < emm_data->fplmn.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(emm_data->splmn, emm_data->fplmn.plmn[i])) { is_forbidden = TRUE; break; } } if (!is_forbidden) { - for (i = 0; i < user->emm_data->fplmn_gprs.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(user->emm_data->splmn, - user->emm_data->fplmn_gprs.plmn[i])) { + for (i = 0; i < emm_data->fplmn_gprs.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(emm_data->splmn, + emm_data->fplmn_gprs.plmn[i])) { is_forbidden = TRUE; break; } @@ -781,12 +740,12 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, /* Check if the selected PLMN belongs to a forbidden * tracking area */ tai_t tai; - tai.plmn = user->emm_data->splmn; + tai.plmn = emm_data->splmn; tai.tac = tac; if (!is_forbidden) { - for (i = 0; i < user->emm_data->ftai.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai.tai[i])) { + for (i = 0; i < emm_data->ftai.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, emm_data->ftai.tai[i])) { is_forbidden = TRUE; break; } @@ -794,8 +753,8 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, } if (!is_forbidden) { - for (i = 0; i < user->emm_data->ftai_roaming.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai_roaming.tai[i])) { + for (i = 0; i < emm_data->ftai_roaming.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, emm_data->ftai_roaming.tai[i])) { is_forbidden = TRUE; break; } @@ -809,25 +768,25 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this acceptable cell for limited services"); /* Save the index of the first forbidden PLMN */ - if (_emm_plmn_list.fplmn < 0) { - _emm_plmn_list.fplmn = index; + if (emm_plmn_list->fplmn < 0) { + emm_plmn_list->fplmn = index; } - _emm_plmn_list.param[index].stat = NET_OPER_FORBIDDEN; + emm_plmn_list->param[index].stat = NET_OPER_FORBIDDEN; } else { /* A suitable cell has been found and the PLMN or tracking area * is not in the forbidden list */ LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this suitable cell for normal services"); - _emm_plmn_list.fplmn = -1; - _emm_plmn_list.param[index].stat = NET_OPER_CURRENT; + emm_plmn_list->fplmn = -1; + emm_plmn_list->param[index].stat = NET_OPER_CURRENT; emm_sap.primitive = EMMREG_REGISTER_CNF; } /* Duplicate the new selected PLMN at the end of the ordered list */ - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns] = &user->emm_data->splmn; + emm_plmn_list->plmn[emm_plmn_list->n_plmns] = &emm_data->splmn; } - else if (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { + else if (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { /* * Automatic mode of operation * --------------------------- @@ -838,12 +797,12 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, select_next_plmn = TRUE; /* Bypass the previously selected PLMN */ - if (index == _emm_plmn_list.splmn) { + if (index == emm_plmn_list->splmn) { index += 1; } } - else if (user->emm_data->plmn_index < 0) { + else if (emm_data->plmn_index < 0) { /* * Manual or manual/automatic mode of operation * -------------------------------------------- @@ -854,7 +813,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, select_next_plmn = TRUE; } - else if (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL) { + else if (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL) { /* * Manual mode of operation * ------------------------ @@ -870,8 +829,8 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Attempt to find a suitable cell of the PLMN selected by the user * failed; Try to automatically select another PLMN */ - user->emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; - index = _emm_plmn_list.hplmn; + emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; + index = emm_plmn_list->hplmn; select_next_plmn = TRUE; } @@ -879,16 +838,16 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Force an attempt to register to the next PLMN */ if (select_next_plmn) { - int last_plmn_index = _emm_plmn_list.n_plmns; + int last_plmn_index = emm_plmn_list->n_plmns; - if (_emm_plmn_list.splmn != -1) { + if (emm_plmn_list->splmn != -1) { /* The last attempt was to register the previously selected PLMN */ last_plmn_index += 1; } if (index < last_plmn_index) { /* Try to select the next PLMN in the list of available PLMNs */ - _emm_plmn_list.index = index; + emm_plmn_list->index = index; rc = emm_proc_plmn_selection(user, index); } else { /* No suitable cell of any PLMN within the ordered list @@ -902,27 +861,27 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Or terminate the PLMN selection procedure */ if (!select_next_plmn) { - if (_emm_plmn_list.fplmn >= 0) { + if (emm_plmn_list->fplmn >= 0) { /* There were one or more PLMNs which were available and allowable, * but an LR failure made registration on those PLMNs unsuccessful * or an entry in any of the forbidden area lists prevented a * registration attempt; select the first such PLMN and enters a * limited service state. */ - index = _emm_plmn_list.fplmn; - _emm_plmn_list.fplmn = -1; + index = emm_plmn_list->fplmn; + emm_plmn_list->fplmn = -1; emm_sap.primitive = EMMREG_REGISTER_REJ; } /* Update the availability indicator of the previously selected PLMN */ - if (_emm_plmn_list.splmn != -1) { - _emm_plmn_list.param[_emm_plmn_list.splmn].stat = NET_OPER_UNKNOWN; + if (emm_plmn_list->splmn != -1) { + emm_plmn_list->param[emm_plmn_list->splmn].stat = NET_OPER_UNKNOWN; } /* Update the index of the new selected PLMN */ if (emm_sap.primitive != EMMREG_NO_CELL) { - _emm_plmn_list.splmn = index; + emm_plmn_list->splmn = index; } else { - _emm_plmn_list.splmn = -1; + emm_plmn_list->splmn = -1; } /* @@ -930,15 +889,15 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, */ rc = emm_sap_send(user, &emm_sap); - if (_emm_plmn_list.splmn != -1) { - if (_emm_plmn_list.splmn == _emm_plmn_list.rplmn) { + if (emm_plmn_list->splmn != -1) { + if (emm_plmn_list->splmn == emm_plmn_list->rplmn) { /* The selected PLMN is the registered PLMN */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is the registered PLMN"); - user->emm_data->is_rplmn = TRUE; - } else if (_emm_plmn_list.splmn < _emm_plmn_list.hplmn) { + emm_data->is_rplmn = TRUE; + } else if (emm_plmn_list->splmn < emm_plmn_list->hplmn) { /* The selected PLMN is in the list of equivalent PLMNs */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is in the list of equivalent PLMNs"); - user->emm_data->is_eplmn = TRUE; + emm_data->is_eplmn = TRUE; } /* @@ -1046,12 +1005,12 @@ int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_network_notify(emm_data_t *emm_data, int index) +int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int index) { LOG_FUNC_IN; /* Update the list of operators present in the network */ - int size = IdleMode_update_plmn_list(emm_data, index); + int size = IdleMode_update_plmn_list(emm_plmn_list, emm_data, index); /* Notify EMM that data has changed */ int rc = (*_emm_indication_notify)(emm_data, size); @@ -1122,7 +1081,6 @@ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn) ** tor network name records ** ** ** ** Inputs: plmn: The PLMN identifier ** - ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: The index of the PLMN if found in the list ** @@ -1131,32 +1089,32 @@ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn) ** Others: None ** ** ** ***************************************************************************/ -static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn) +static int _IldlMode_get_opnn_id(emm_data_t *emm_data, const plmn_t *plmn) { int i; - for (i = 0; i < user->emm_data->n_opnns; i++) { - if (plmn->MCCdigit1 != user->emm_data->opnn[i].plmn->MCCdigit1) { + for (i = 0; i < emm_data->n_opnns; i++) { + if (plmn->MCCdigit1 != emm_data->opnn[i].plmn->MCCdigit1) { continue; } - if (plmn->MCCdigit2 != user->emm_data->opnn[i].plmn->MCCdigit2) { + if (plmn->MCCdigit2 != emm_data->opnn[i].plmn->MCCdigit2) { continue; } - if (plmn->MCCdigit3 != user->emm_data->opnn[i].plmn->MCCdigit3) { + if (plmn->MCCdigit3 != emm_data->opnn[i].plmn->MCCdigit3) { continue; } - if (plmn->MNCdigit1 != user->emm_data->opnn[i].plmn->MNCdigit1) { + if (plmn->MNCdigit1 != emm_data->opnn[i].plmn->MNCdigit1) { continue; } - if (plmn->MNCdigit2 != user->emm_data->opnn[i].plmn->MNCdigit2) { + if (plmn->MNCdigit2 != emm_data->opnn[i].plmn->MNCdigit2) { continue; } - if (plmn->MNCdigit3 != user->emm_data->opnn[i].plmn->MNCdigit3) { + if (plmn->MNCdigit3 != emm_data->opnn[i].plmn->MNCdigit3) { continue; } @@ -1177,7 +1135,6 @@ static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn) ** ** ** Inputs: index: Index of the selected PLMN in the ordered ** ** list of available PLMNs ** - ** Others: _emm_plmn_list.plmn ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** @@ -1187,12 +1144,14 @@ static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn) static int _IdleMode_get_suitable_cell(nas_user_t *user, int index) { emm_sap_t emm_sap; - const plmn_t *plmn = _emm_plmn_list.plmn[index]; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; + const plmn_t *plmn = emm_plmn_list->plmn[index]; LOG_TRACE(INFO, "EMM-IDLE - Trying to search a suitable cell " "of PLMN %d in %s mode", index, - (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : "Automatic/manual"); /* * Notify EMM-AS SAP that cell information related to the given @@ -1202,8 +1161,8 @@ static int _IdleMode_get_suitable_cell(nas_user_t *user, int index) emm_sap.u.emm_as.u.cell_info.plmnIDs.n_plmns = 1; emm_sap.u.emm_as.u.cell_info.plmnIDs.plmn[0] = *plmn; - if (user->emm_data->plmn_rat != NET_ACCESS_UNAVAILABLE) { - emm_sap.u.emm_as.u.cell_info.rat = (1 << user->emm_data->plmn_rat); + if (emm_data->plmn_rat != NET_ACCESS_UNAVAILABLE) { + emm_sap.u.emm_as.u.cell_info.rat = (1 << emm_data->plmn_rat); } else { emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE; } diff --git a/openair3/NAS/UE/EMM/IdleMode.h b/openair3/NAS/UE/EMM/IdleMode.h index 17b0eabee5b20ee5e0dab278ea248da85a8ae5da..e92e14f5cb93c919caa68855d6b124cceea0df09 100644 --- a/openair3/NAS/UE/EMM/IdleMode.h +++ b/openair3/NAS/UE/EMM/IdleMode.h @@ -63,21 +63,21 @@ typedef int (*IdleMode_callback_t) (emm_data_t *emm_data, int); void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb); -int IdleMode_get_nb_plmns(void); -int IdleMode_get_hplmn_index(void); -int IdleMode_get_rplmn_index(void); -int IdleMode_get_splmn_index(void); +int IdleMode_get_nb_plmns(emm_plmn_list_t *emm_plmn_list); +int IdleMode_get_hplmn_index(emm_plmn_list_t *emm_plmn_list); +int IdleMode_get_rplmn_index(emm_plmn_list_t *emm_plmn_list); +int IdleMode_get_splmn_index(emm_plmn_list_t *emm_plmn_list); -int IdleMode_update_plmn_list(emm_data_t *emm_data, int i); +int IdleMode_update_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int i); -const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_fullname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len); -const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_shortname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len); -const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len); +const char *IdleMode_get_plmn_id(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len); -int IdleMode_get_plmn_fullname_index(const char *plmn); -int IdleMode_get_plmn_shortname_index(const char *plmn); -int IdleMode_get_plmn_id_index(const char *plmn); +int IdleMode_get_plmn_fullname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn); +int IdleMode_get_plmn_shortname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn); +int IdleMode_get_plmn_id_index(emm_plmn_list_t *emm_plmn_list, const char *plmn); #endif /* __IDLEMODE_H__*/ diff --git a/openair3/NAS/UE/EMM/IdleMode_defs.h b/openair3/NAS/UE/EMM/IdleMode_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..8ef6c8e86d407ec9813537f8c88745438a51fa94 --- /dev/null +++ b/openair3/NAS/UE/EMM/IdleMode_defs.h @@ -0,0 +1,52 @@ +#ifndef _IDLEMODE_DEFS_H +#define _IDLEMODE_DEFS_H + +/* + * A list of PLMN identities in priority order is maintained locally + * to perform the PLMN selection procedure. + * + * In automatic mode of operation, this list is used for PLMN selection when + * the UE is switched on, or upon recovery from lack of coverage, or when the + * user requests the UE to initiate PLMN reselection, and registration. + * In manual mode of operation, this list is displayed to the user that may + * select an available PLMN and initiate registration. + * + * The list may contain PLMN identifiers in the following order: + * - The last registered PLMN or each equivalent PLMN present in the list of + * "equivalent PLMNs" (EPLMN_MAX), when UE is switched on or following + * recovery from lack of coverage; + * - The highest priority PLMN in the list of "equivalent HPLMNs" or the + * HPLMN derived from the IMSI (1) + * - Each PLMN/access technology combination in the "User Controlled PLMN + * Selector with Access Technology" (PLMN_MAX) + * - Each PLMN/access technology combination in the "Operator Controlled PLMN + * Selector with Access Technology" (OPLMN_MAX) + * - Other PLMN/access technology combinations with received high quality + * signal in random order (TODO) + * - Other PLMN/access technology combinations in order of decreasing signal + * quality (TODO) + * - The last selected PLMN again (1) + */ +typedef struct { + int n_plmns; +#define EMM_PLMN_LIST_SIZE (EMM_DATA_EPLMN_MAX + EMM_DATA_PLMN_MAX + \ + EMM_DATA_OPLMN_MAX + 2) + plmn_t *plmn[EMM_PLMN_LIST_SIZE]; + int index; /* Index of the PLMN for which selection is ongoing */ + int hplmn; /* Index of the home PLMN or the highest priority + * equivalent home PLMN */ + int fplmn; /* Index of the first forbidden PLMN */ + int splmn; /* Index of the currently selected PLMN */ + int rplmn; /* Index of the currently registered PLMN */ + struct plmn_param_t { + char fullname[NET_FORMAT_LONG_SIZE+1]; /* PLMN full identifier */ + char shortname[NET_FORMAT_SHORT_SIZE+1]; /* PLMN short identifier */ + char num[NET_FORMAT_NUM_SIZE+1]; /* PLMN numeric identifier */ + int stat; /* Indication of the PLMN availability */ + int tac; /* Location/Tracking Area Code */ + int ci; /* Serving cell identifier */ + int rat; /* Radio Access Technology supported by the serving cell */ + } param[EMM_PLMN_LIST_SIZE]; +} emm_plmn_list_t; + +#endif diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 591c9e6b0fe93b27946fc1e0dd87314a1fe4d042..a1d42609234be985cd36ad6250fce5d99a6d57a5 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -63,10 +63,10 @@ static int _emm_main_get_imei(imei_t *imei, const char *imei_str); static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2); -static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, +static const char *_emm_main_get_plmn(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, int format, size_t *size); -static int _emm_main_get_plmn_index(const char *plmn, int format); +static int _emm_main_get_plmn_index(emm_plmn_list_t *emm_plmn_list, const char *plmn, int format); /* * USIM application data @@ -538,12 +538,14 @@ const msisdn_t *emm_main_get_msisdn(void) ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, +int emm_main_set_plmn_selection_mode(nas_user_t *user, int mode, int format, const network_plmn_t *plmn, int rat) { LOG_FUNC_IN; int index; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; LOG_TRACE(INFO, "EMM-MAIN - PLMN selection: mode=%d, format=%d, plmn=%s, " "rat=%d", mode, format, (const char *)&plmn->id, rat); @@ -552,7 +554,7 @@ int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, if (mode != EMM_DATA_PLMN_AUTO) { /* Get the index of the PLMN in the list of available PLMNs */ - index = _emm_main_get_plmn_index((const char *)&plmn->id, format); + index = _emm_main_get_plmn_index(emm_plmn_list, (const char *)&plmn->id, format); if (index < 0) { LOG_TRACE(WARNING, "EMM-MAIN - PLMN %s not available", @@ -568,7 +570,7 @@ int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, * register to when switched on; the equivalent PLMNs list shall not be * applied to the user reselection in Automatic Network Selection Mode. */ - index = IdleMode_get_hplmn_index(); + index = IdleMode_get_hplmn_index(emm_plmn_list); } LOG_FUNC_RETURN (index); @@ -609,11 +611,11 @@ int emm_main_get_plmn_selection_mode(emm_data_t *emm_data) ** Others: None ** ** ** ***************************************************************************/ -int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist) +int emm_main_get_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, const char **plist) { LOG_FUNC_IN; - int size = IdleMode_update_plmn_list(emm_data, 0); + int size = IdleMode_update_plmn_list(emm_plmn_list, emm_data, 0); *plist = emm_data->plist.buffer; LOG_FUNC_RETURN (size); @@ -635,7 +637,7 @@ int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist) ** Others: None ** ** ** ***************************************************************************/ -const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format) +const char *emm_main_get_selected_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -643,10 +645,10 @@ const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plm /* * Get the identifier of the selected PLMN in the list of available PLMNs */ - int index = IdleMode_get_splmn_index(); + int index = IdleMode_get_splmn_index(emm_plmn_list); if ( !(index < 0) ) { - const char *name = _emm_main_get_plmn(&emm_data->splmn, index, + const char *name = _emm_main_get_plmn(emm_plmn_list, &emm_data->splmn, index, format, &size); if (size > 0) { @@ -673,7 +675,7 @@ const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plm ** Others: None ** ** ** ***************************************************************************/ -const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format) +const char *emm_main_get_registered_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -682,10 +684,10 @@ const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *p /* * Get the identifier of the registered PLMN in the list of available PLMNs */ - int index = IdleMode_get_rplmn_index(); + int index = IdleMode_get_rplmn_index(emm_plmn_list); if ( !(index < 0) ) { - const char *name = _emm_main_get_plmn(&emm_data->nvdata.rplmn, + const char *name = _emm_main_get_plmn(emm_plmn_list, &emm_data->nvdata.rplmn, index, format, &size); if (size > 0) { @@ -952,24 +954,24 @@ static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2) ** Others: None ** ** ** ***************************************************************************/ -static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, +static const char *_emm_main_get_plmn(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, int format, size_t *size) { if ( PLMN_IS_VALID(*plmn) ) { switch (format) { case NET_FORMAT_LONG: /* Get the long alpha-numeric representation of the PLMN */ - return IdleMode_get_plmn_fullname(plmn, index, size); + return IdleMode_get_plmn_fullname(emm_plmn_list, plmn, index, size); break; case NET_FORMAT_SHORT: /* Get the short alpha-numeric representation of the PLMN */ - return IdleMode_get_plmn_shortname(plmn, index, size); + return IdleMode_get_plmn_shortname(emm_plmn_list, plmn, index, size); break; case NET_FORMAT_NUM: /* Get the numeric representation of the PLMN */ - return IdleMode_get_plmn_id(plmn, index, size); + return IdleMode_get_plmn_id(emm_plmn_list, plmn, index, size); break; default: @@ -1002,24 +1004,24 @@ static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_main_get_plmn_index(const char *plmn, int format) +static int _emm_main_get_plmn_index(emm_plmn_list_t *emm_plmn_list, const char *plmn, int format) { int index = -1; switch (format) { case NET_FORMAT_LONG: /* Get the index of the long alpha-numeric PLMN identifier */ - index = IdleMode_get_plmn_fullname_index(plmn); + index = IdleMode_get_plmn_fullname_index(emm_plmn_list, plmn); break; case NET_FORMAT_SHORT: /* Get the index of the short alpha-numeric PLMN identifier */ - index = IdleMode_get_plmn_shortname_index(plmn); + index = IdleMode_get_plmn_shortname_index(emm_plmn_list, plmn); break; case NET_FORMAT_NUM: /* Get the index of the numeric PLMN identifier */ - index = IdleMode_get_plmn_id_index(plmn); + index = IdleMode_get_plmn_id_index(emm_plmn_list, plmn); break; default: diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index dfb8049f07f10f38df16d1395bff1d96f84a1073..90b5be0b8cf69497a812021a0e66a8fbac4378ce 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -80,18 +80,18 @@ const imsi_t *emm_main_get_imsi(emm_data_t *emm_data); const msisdn_t *emm_main_get_msisdn(void); /* User's getter/setter for network selection */ -int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, +int emm_main_set_plmn_selection_mode(nas_user_t *user, int mode, int format, const network_plmn_t *plmn, int rat); int emm_main_get_plmn_selection_mode(emm_data_t *emm_data); -int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist); -const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format); +int emm_main_get_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, const char **plist); +const char *emm_main_get_selected_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network registration */ Stat_t emm_main_get_plmn_status(emm_data_t *emm_data); tac_t emm_main_get_plmn_tac(emm_data_t *emm_data); ci_t emm_main_get_plmn_ci(emm_data_t *emm_data); AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data); -const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format); +const char *emm_main_get_registered_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network attachment */ int emm_main_is_attached(emm_data_t *emm_data); diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 0aaf76dfa093362247f14cf1691968bb7621275e..0a5827021623fa1a67b8b7607de3d4ae881a92f6 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -185,6 +185,6 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, in */ int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status); int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat); -int emm_proc_network_notify(emm_data_t *emm_data, int index); +int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int index); #endif /* __EMM_PROC_H__*/ diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index ee7b4f52c0fa5a3404ff96dea5c32406a52383fc..f707c983d2cbfc4208203ea131b352655860ead8 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -386,7 +386,7 @@ int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn /* * Set the PLMN selection mode of operation */ - int index = emm_main_set_plmn_selection_mode(user->emm_data, mode, format, oper, AcT); + int index = emm_main_set_plmn_selection_mode(user, mode, format, oper, AcT); if ( !(index < 0) ) { /* @@ -455,7 +455,7 @@ int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format *mode = emm_main_get_plmn_selection_mode(user->emm_data); /* Get the currently selected operator */ - const char *oper_name = emm_main_get_selected_plmn(user->emm_data, oper, format); + const char *oper_name = emm_main_get_selected_plmn(user->emm_plmn_list, user->emm_data, oper, format); if (oper_name != NULL) { /* An operator is currently selected */ @@ -489,7 +489,7 @@ int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list) { LOG_FUNC_IN; - int size = emm_main_get_plmn_list(user->emm_data, oper_list); + int size = emm_main_get_plmn_list(user->emm_plmn_list, user->emm_data, oper_list); LOG_FUNC_RETURN (size); } diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 05ce952f2200faa0bd0f765b9e0a0b0543acaf03..7a2851ae5ef53a54805ccd4a3cb1b8e3a12e9cc5 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -50,6 +50,7 @@ Description NAS type definition to manage a user equipment #include "esm_pt_defs.h" #include "EMM/emm_fsm_defs.h" #include "EMM/emmData.h" +#include "EMM/IdleMode_defs.h" typedef struct { int fd; @@ -59,6 +60,7 @@ typedef struct { esm_ebr_data_t *esm_ebr_data; // EPS bearer contexts emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status emm_data_t *emm_data; // EPS mobility management data + emm_plmn_list_t *emm_plmn_list; // list of PLMN identities } nas_user_t; #endif