UE/EMM: move _plmn_list to nas_user_t
This commit is contained in:
+136
-177
@@ -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 _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);
|
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 */
|
/* Callback executed whenever a network indication is received */
|
||||||
static IdleMode_callback_t _emm_indication_notify;
|
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)
|
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 */
|
/* Initialize the list of available PLMNs */
|
||||||
_emm_plmn_list.n_plmns = 0;
|
emm_plmn_list->n_plmns = 0;
|
||||||
_emm_plmn_list.index = 0;
|
emm_plmn_list->index = 0;
|
||||||
_emm_plmn_list.hplmn = -1;
|
emm_plmn_list->hplmn = -1;
|
||||||
_emm_plmn_list.fplmn = -1;
|
emm_plmn_list->fplmn = -1;
|
||||||
_emm_plmn_list.splmn = -1;
|
emm_plmn_list->splmn = -1;
|
||||||
_emm_plmn_list.rplmn = -1;
|
emm_plmn_list->rplmn = -1;
|
||||||
|
|
||||||
/* Initialize the network notification handler */
|
/* Initialize the network notification handler */
|
||||||
_emm_indication_notify = *cb;
|
_emm_indication_notify = *cb;
|
||||||
@@ -190,9 +148,9 @@ void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb)
|
|||||||
** Others: None **
|
** 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 **
|
** 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 **
|
** 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. **
|
** available PLMNs. **
|
||||||
** **
|
** **
|
||||||
** Inputs: None **
|
** Inputs: None **
|
||||||
** Others: _emm_plmn_list **
|
|
||||||
** **
|
** **
|
||||||
** Outputs: None **
|
** Outputs: None **
|
||||||
** Return: The index of the selected PLMN in the list **
|
** Return: The index of the selected PLMN in the list **
|
||||||
** Others: None **
|
** 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 **
|
** tors present in the network **
|
||||||
** **
|
** **
|
||||||
** Inputs: i: Index of the first operator to update **
|
** Inputs: i: Index of the first operator to update **
|
||||||
** Others: _emm_plmn_list **
|
|
||||||
** **
|
** **
|
||||||
** Outputs: None **
|
** Outputs: None **
|
||||||
** Return: The size of the list in bytes **
|
** 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 offset = 0;
|
||||||
int n = 1;
|
int n = 1;
|
||||||
|
|
||||||
while ( (i < _emm_plmn_list.n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) {
|
while ( (i < emm_plmn_list->n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) {
|
||||||
struct plmn_param_t *plmn = &(_emm_plmn_list.param[i++]);
|
struct plmn_param_t *plmn = &(emm_plmn_list->param[i++]);
|
||||||
|
|
||||||
if (n++ > 1) {
|
if (n++ > 1) {
|
||||||
offset += snprintf(emm_data->plist.buffer + offset,
|
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 **
|
** 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)
|
size_t *len)
|
||||||
{
|
{
|
||||||
if (index < _emm_plmn_list.n_plmns) {
|
if (index < emm_plmn_list->n_plmns) {
|
||||||
assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) );
|
assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) );
|
||||||
*len = strlen(_emm_plmn_list.param[index].fullname);
|
*len = strlen(emm_plmn_list->param[index].fullname);
|
||||||
return _emm_plmn_list.param[index].fullname;
|
return emm_plmn_list->param[index].fullname;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -348,13 +304,13 @@ const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index,
|
|||||||
** Others: None **
|
** 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)
|
size_t *len)
|
||||||
{
|
{
|
||||||
if (index < _emm_plmn_list.n_plmns) {
|
if (index < emm_plmn_list->n_plmns) {
|
||||||
assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) );
|
assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) );
|
||||||
*len = strlen(_emm_plmn_list.param[index].shortname);
|
*len = strlen(emm_plmn_list->param[index].shortname);
|
||||||
return _emm_plmn_list.param[index].shortname;
|
return emm_plmn_list->param[index].shortname;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -378,12 +334,12 @@ const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index,
|
|||||||
** Others: None **
|
** 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) {
|
if (index < emm_plmn_list->n_plmns) {
|
||||||
assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) );
|
assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) );
|
||||||
*len = strlen(_emm_plmn_list.param[index].num);
|
*len = strlen(emm_plmn_list->param[index].num);
|
||||||
return _emm_plmn_list.param[index].num;
|
return emm_plmn_list->param[index].num;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -405,13 +361,13 @@ const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len)
|
|||||||
** Others: None **
|
** 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;
|
int index;
|
||||||
|
|
||||||
/* Get the index of the PLMN identifier with specified full name */
|
/* Get the index of the PLMN identifier with specified full name */
|
||||||
for (index = 0; index < _emm_plmn_list.n_plmns; index++) {
|
for (index = 0; index < emm_plmn_list->n_plmns; index++) {
|
||||||
if ( strncmp(plmn, _emm_plmn_list.param[index].fullname,
|
if ( strncmp(plmn, emm_plmn_list->param[index].fullname,
|
||||||
NET_FORMAT_LONG_SIZE) != 0 ) {
|
NET_FORMAT_LONG_SIZE) != 0 ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -438,13 +394,13 @@ int IdleMode_get_plmn_fullname_index(const char *plmn)
|
|||||||
** Others: None **
|
** 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;
|
int index;
|
||||||
|
|
||||||
/* Get the index of the PLMN identifier with specified short name */
|
/* Get the index of the PLMN identifier with specified short name */
|
||||||
for (index = 0; index < _emm_plmn_list.n_plmns; index++) {
|
for (index = 0; index < emm_plmn_list->n_plmns; index++) {
|
||||||
if ( !strncmp(plmn, _emm_plmn_list.param[index].shortname,
|
if ( !strncmp(plmn, emm_plmn_list->param[index].shortname,
|
||||||
NET_FORMAT_SHORT_SIZE) ) {
|
NET_FORMAT_SHORT_SIZE) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -471,13 +427,13 @@ int IdleMode_get_plmn_shortname_index(const char *plmn)
|
|||||||
** Others: None **
|
** 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;
|
int index;
|
||||||
|
|
||||||
/* Get the index of the PLMN identifier with specified numeric identifier */
|
/* Get the index of the PLMN identifier with specified numeric identifier */
|
||||||
for (index = 0; index < _emm_plmn_list.n_plmns; index++) {
|
for (index = 0; index < emm_plmn_list->n_plmns; index++) {
|
||||||
if ( !strncmp(plmn, _emm_plmn_list.param[index].num,
|
if ( !strncmp(plmn, emm_plmn_list->param[index].num,
|
||||||
NET_FORMAT_LONG_SIZE) ) {
|
NET_FORMAT_LONG_SIZE) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -516,6 +472,7 @@ int emm_proc_initialize(nas_user_t *user)
|
|||||||
emm_sap_t emm_sap;
|
emm_sap_t emm_sap;
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
|
emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list;
|
||||||
|
|
||||||
if (!user->emm_data->usim_is_valid) {
|
if (!user->emm_data->usim_is_valid) {
|
||||||
/* The USIM application is not present or not 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 available, or the last registered PLMN */
|
||||||
if (user->emm_data->nvdata.eplmn.n_plmns > 0) {
|
if (user->emm_data->nvdata.eplmn.n_plmns > 0) {
|
||||||
for (i=0; i < user->emm_data->nvdata.eplmn.n_plmns; i++) {
|
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];
|
&user->emm_data->nvdata.eplmn.plmn[i];
|
||||||
}
|
}
|
||||||
} else if ( PLMN_IS_VALID(user->emm_data->nvdata.rplmn) ) {
|
} 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;
|
&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
|
* When switched on, the UE will try to automatically register
|
||||||
* to each previous PLMN within the ordered list of available
|
* to each previous PLMN within the ordered list of available
|
||||||
* PLMNs regardless of the network selection mode of operation */
|
* PLMNs regardless of the network selection mode of operation */
|
||||||
_emm_plmn_list.hplmn = _emm_plmn_list.n_plmns - 1;
|
emm_plmn_list->hplmn = emm_plmn_list->n_plmns - 1;
|
||||||
// LG_emm_plmn_list.hplmn = _emm_plmn_list.n_plmns;
|
// LGemm_plmn_list->hplmn = emm_plmn_list->n_plmns;
|
||||||
|
|
||||||
/* Add the highest priority PLMN in the list of "equivalent HPLMNs"
|
/* Add the highest priority PLMN in the list of "equivalent HPLMNs"
|
||||||
if present and not empty, or the HPLMN derived from the IMSI */
|
if present and not empty, or the HPLMN derived from the IMSI */
|
||||||
if (user->emm_data->ehplmn.n_plmns > 0) {
|
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];
|
&user->emm_data->ehplmn.plmn[0];
|
||||||
} else {
|
} 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
|
/* Each PLMN/access technology combination in the "User
|
||||||
* Controlled PLMN Selector with Access Technology" */
|
* Controlled PLMN Selector with Access Technology" */
|
||||||
for (i=0; i < user->emm_data->plmn.n_plmns; i++) {
|
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];
|
&user->emm_data->plmn.plmn[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Each PLMN/access technology combination in the "Operator
|
/* Each PLMN/access technology combination in the "Operator
|
||||||
* Controlled PLMN Selector with Access Technology" */
|
* Controlled PLMN Selector with Access Technology" */
|
||||||
for (i=0; i < user->emm_data->oplmn.n_plmns; i++) {
|
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];
|
&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) */
|
/* TODO: Schedule periodic network selection attemps (hpplmn timer) */
|
||||||
|
|
||||||
/* Initialize the PLMNs' parameters */
|
/* Initialize the PLMNs' parameters */
|
||||||
for (i=0; i < _emm_plmn_list.n_plmns; i++) {
|
for (i=0; i < emm_plmn_list->n_plmns; i++) {
|
||||||
struct plmn_param_t *plmn = &(_emm_plmn_list.param[i]);
|
struct plmn_param_t *plmn = &(emm_plmn_list->param[i]);
|
||||||
int id = _IldlMode_get_opnn_id(user, _emm_plmn_list.plmn[i]);
|
int id = _IldlMode_get_opnn_id(user->emm_data, emm_plmn_list->plmn[i]);
|
||||||
|
|
||||||
if (id < 0) {
|
if (id < 0) {
|
||||||
plmn->fullname[0] = '\0';
|
plmn->fullname[0] = '\0';
|
||||||
@@ -587,7 +544,7 @@ int emm_proc_initialize(nas_user_t *user)
|
|||||||
NET_FORMAT_SHORT_SIZE);
|
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->stat = NET_OPER_UNKNOWN;
|
||||||
plmn->tac = 0;
|
plmn->tac = 0;
|
||||||
plmn->ci = 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",
|
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 */
|
/* Notify EMM that PLMN selection procedure has to be executed */
|
||||||
emm_sap.primitive = EMMREG_REGISTER_REQ;
|
emm_sap.primitive = EMMREG_REGISTER_REQ;
|
||||||
@@ -630,31 +587,33 @@ int emm_proc_initialize(nas_user_t *user)
|
|||||||
** **
|
** **
|
||||||
** Outputs: None **
|
** Outputs: None **
|
||||||
** Return: None **
|
** Return: None **
|
||||||
** Others: _emm_plmn_list.index **
|
** Others: emm_plmn_list->index **
|
||||||
** **
|
** **
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int emm_proc_plmn_selection(nas_user_t *user, int index)
|
int emm_proc_plmn_selection(nas_user_t *user, int index)
|
||||||
{
|
{
|
||||||
LOG_FUNC_IN;
|
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;
|
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
|
* 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
|
* 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
|
* The user did not select any PLMN yet; display the ordered
|
||||||
* list of available PLMNs to the user
|
* list of available PLMNs to the user
|
||||||
*/
|
*/
|
||||||
index = -1;
|
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) {
|
if (rc != RETURNok) {
|
||||||
LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify "
|
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
|
* 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
|
* or any other PLMN in the ordered list of available PLMNs in
|
||||||
* automatic mode.
|
* automatic mode.
|
||||||
*/
|
*/
|
||||||
_emm_plmn_list.index = index;
|
emm_plmn_list->index = index;
|
||||||
rc = _IdleMode_get_suitable_cell(user, 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 **
|
** ci: The identifier of the cell **
|
||||||
** rat: The radio access technology supported by **
|
** rat: The radio access technology supported by **
|
||||||
** the cell **
|
** the cell **
|
||||||
** Others: _emm_plmn_list, user->emm_data-> **
|
|
||||||
** **
|
** **
|
||||||
** Outputs: None **
|
** Outputs: None **
|
||||||
** Return: 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)
|
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;
|
emm_sap_t emm_sap;
|
||||||
int rc = RETURNerror;
|
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;
|
int select_next_plmn = FALSE;
|
||||||
|
|
||||||
LOG_TRACE(INFO, "EMM-IDLE - %s cell found for PLMN %d in %s mode",
|
LOG_TRACE(INFO, "EMM-IDLE - %s cell found for PLMN %d in %s mode",
|
||||||
(found)? "One" : "No", index,
|
(found)? "One" : "No", index,
|
||||||
(user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" :
|
(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_MANUAL)? "Manual" :
|
||||||
"Automatic/manual");
|
"Automatic/manual");
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
int is_forbidden = FALSE;
|
int is_forbidden = FALSE;
|
||||||
|
|
||||||
/* Select the PLMN of which a suitable cell has been found */
|
/* 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 */
|
/* Update the selected PLMN's parameters */
|
||||||
_emm_plmn_list.param[index].tac = tac;
|
emm_plmn_list->param[index].tac = tac;
|
||||||
_emm_plmn_list.param[index].ci = ci;
|
emm_plmn_list->param[index].ci = ci;
|
||||||
_emm_plmn_list.param[index].rat = rat;
|
emm_plmn_list->param[index].rat = rat;
|
||||||
|
|
||||||
/* Update the location data and notify EMM that data have changed */
|
/* 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) {
|
if (rc != RETURNok) {
|
||||||
LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify location update");
|
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
|
* 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;
|
int i;
|
||||||
|
|
||||||
/* Check if the selected PLMN is in the forbidden list */
|
/* Check if the selected PLMN is in the forbidden list */
|
||||||
for (i = 0; i < user->emm_data->fplmn.n_plmns; i++) {
|
for (i = 0; i < emm_data->fplmn.n_plmns; i++) {
|
||||||
if (PLMNS_ARE_EQUAL(user->emm_data->splmn, user->emm_data->fplmn.plmn[i])) {
|
if (PLMNS_ARE_EQUAL(emm_data->splmn, emm_data->fplmn.plmn[i])) {
|
||||||
is_forbidden = TRUE;
|
is_forbidden = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_forbidden) {
|
if (!is_forbidden) {
|
||||||
for (i = 0; i < user->emm_data->fplmn_gprs.n_plmns; i++) {
|
for (i = 0; i < emm_data->fplmn_gprs.n_plmns; i++) {
|
||||||
if (PLMNS_ARE_EQUAL(user->emm_data->splmn,
|
if (PLMNS_ARE_EQUAL(emm_data->splmn,
|
||||||
user->emm_data->fplmn_gprs.plmn[i])) {
|
emm_data->fplmn_gprs.plmn[i])) {
|
||||||
is_forbidden = TRUE;
|
is_forbidden = TRUE;
|
||||||
break;
|
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
|
/* Check if the selected PLMN belongs to a forbidden
|
||||||
* tracking area */
|
* tracking area */
|
||||||
tai_t tai;
|
tai_t tai;
|
||||||
tai.plmn = user->emm_data->splmn;
|
tai.plmn = emm_data->splmn;
|
||||||
tai.tac = tac;
|
tai.tac = tac;
|
||||||
|
|
||||||
if (!is_forbidden) {
|
if (!is_forbidden) {
|
||||||
for (i = 0; i < user->emm_data->ftai.n_tais; i++) {
|
for (i = 0; i < emm_data->ftai.n_tais; i++) {
|
||||||
if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai.tai[i])) {
|
if (TAIS_ARE_EQUAL(tai, emm_data->ftai.tai[i])) {
|
||||||
is_forbidden = TRUE;
|
is_forbidden = TRUE;
|
||||||
break;
|
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) {
|
if (!is_forbidden) {
|
||||||
for (i = 0; i < user->emm_data->ftai_roaming.n_tais; i++) {
|
for (i = 0; i < emm_data->ftai_roaming.n_tais; i++) {
|
||||||
if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai_roaming.tai[i])) {
|
if (TAIS_ARE_EQUAL(tai, emm_data->ftai_roaming.tai[i])) {
|
||||||
is_forbidden = TRUE;
|
is_forbidden = TRUE;
|
||||||
break;
|
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");
|
LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this acceptable cell for limited services");
|
||||||
|
|
||||||
/* Save the index of the first forbidden PLMN */
|
/* Save the index of the first forbidden PLMN */
|
||||||
if (_emm_plmn_list.fplmn < 0) {
|
if (emm_plmn_list->fplmn < 0) {
|
||||||
_emm_plmn_list.fplmn = index;
|
emm_plmn_list->fplmn = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
_emm_plmn_list.param[index].stat = NET_OPER_FORBIDDEN;
|
emm_plmn_list->param[index].stat = NET_OPER_FORBIDDEN;
|
||||||
} else {
|
} else {
|
||||||
/* A suitable cell has been found and the PLMN or tracking area
|
/* A suitable cell has been found and the PLMN or tracking area
|
||||||
* is not in the forbidden list */
|
* is not in the forbidden list */
|
||||||
LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this suitable cell for normal services");
|
LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this suitable cell for normal services");
|
||||||
_emm_plmn_list.fplmn = -1;
|
emm_plmn_list->fplmn = -1;
|
||||||
_emm_plmn_list.param[index].stat = NET_OPER_CURRENT;
|
emm_plmn_list->param[index].stat = NET_OPER_CURRENT;
|
||||||
emm_sap.primitive = EMMREG_REGISTER_CNF;
|
emm_sap.primitive = EMMREG_REGISTER_CNF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplicate the new selected PLMN at the end of the ordered list */
|
/* 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
|
* 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;
|
select_next_plmn = TRUE;
|
||||||
|
|
||||||
/* Bypass the previously selected PLMN */
|
/* Bypass the previously selected PLMN */
|
||||||
if (index == _emm_plmn_list.splmn) {
|
if (index == emm_plmn_list->splmn) {
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (user->emm_data->plmn_index < 0) {
|
else if (emm_data->plmn_index < 0) {
|
||||||
/*
|
/*
|
||||||
* Manual or manual/automatic mode of operation
|
* 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;
|
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
|
* 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
|
* Attempt to find a suitable cell of the PLMN selected by the user
|
||||||
* failed; Try to automatically select another PLMN
|
* failed; Try to automatically select another PLMN
|
||||||
*/
|
*/
|
||||||
user->emm_data->plmn_mode = EMM_DATA_PLMN_AUTO;
|
emm_data->plmn_mode = EMM_DATA_PLMN_AUTO;
|
||||||
index = _emm_plmn_list.hplmn;
|
index = emm_plmn_list->hplmn;
|
||||||
select_next_plmn = TRUE;
|
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
|
* Force an attempt to register to the next PLMN
|
||||||
*/
|
*/
|
||||||
if (select_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 */
|
/* The last attempt was to register the previously selected PLMN */
|
||||||
last_plmn_index += 1;
|
last_plmn_index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < last_plmn_index) {
|
if (index < last_plmn_index) {
|
||||||
/* Try to select the next PLMN in the list of available PLMNs */
|
/* 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);
|
rc = emm_proc_plmn_selection(user, index);
|
||||||
} else {
|
} else {
|
||||||
/* No suitable cell of any PLMN within the ordered list
|
/* 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
|
* Or terminate the PLMN selection procedure
|
||||||
*/
|
*/
|
||||||
if (!select_next_plmn) {
|
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,
|
/* There were one or more PLMNs which were available and allowable,
|
||||||
* but an LR failure made registration on those PLMNs unsuccessful
|
* but an LR failure made registration on those PLMNs unsuccessful
|
||||||
* or an entry in any of the forbidden area lists prevented a
|
* or an entry in any of the forbidden area lists prevented a
|
||||||
* registration attempt; select the first such PLMN and enters a
|
* registration attempt; select the first such PLMN and enters a
|
||||||
* limited service state. */
|
* limited service state. */
|
||||||
index = _emm_plmn_list.fplmn;
|
index = emm_plmn_list->fplmn;
|
||||||
_emm_plmn_list.fplmn = -1;
|
emm_plmn_list->fplmn = -1;
|
||||||
emm_sap.primitive = EMMREG_REGISTER_REJ;
|
emm_sap.primitive = EMMREG_REGISTER_REJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the availability indicator of the previously selected PLMN */
|
/* Update the availability indicator of the previously selected PLMN */
|
||||||
if (_emm_plmn_list.splmn != -1) {
|
if (emm_plmn_list->splmn != -1) {
|
||||||
_emm_plmn_list.param[_emm_plmn_list.splmn].stat = NET_OPER_UNKNOWN;
|
emm_plmn_list->param[emm_plmn_list->splmn].stat = NET_OPER_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the index of the new selected PLMN */
|
/* Update the index of the new selected PLMN */
|
||||||
if (emm_sap.primitive != EMMREG_NO_CELL) {
|
if (emm_sap.primitive != EMMREG_NO_CELL) {
|
||||||
_emm_plmn_list.splmn = index;
|
emm_plmn_list->splmn = index;
|
||||||
} else {
|
} 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);
|
rc = emm_sap_send(user, &emm_sap);
|
||||||
|
|
||||||
if (_emm_plmn_list.splmn != -1) {
|
if (emm_plmn_list->splmn != -1) {
|
||||||
if (_emm_plmn_list.splmn == _emm_plmn_list.rplmn) {
|
if (emm_plmn_list->splmn == emm_plmn_list->rplmn) {
|
||||||
/* The selected PLMN is the registered PLMN */
|
/* The selected PLMN is the registered PLMN */
|
||||||
LOG_TRACE(INFO, "EMM-IDLE - 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;
|
emm_data->is_rplmn = TRUE;
|
||||||
} else if (_emm_plmn_list.splmn < _emm_plmn_list.hplmn) {
|
} else if (emm_plmn_list->splmn < emm_plmn_list->hplmn) {
|
||||||
/* The selected PLMN is in the list of equivalent PLMNs */
|
/* 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");
|
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-> **
|
** 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;
|
LOG_FUNC_IN;
|
||||||
|
|
||||||
/* Update the list of operators present in the network */
|
/* 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 */
|
/* Notify EMM that data has changed */
|
||||||
int rc = (*_emm_indication_notify)(emm_data, size);
|
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 **
|
** tor network name records **
|
||||||
** **
|
** **
|
||||||
** Inputs: plmn: The PLMN identifier **
|
** Inputs: plmn: The PLMN identifier **
|
||||||
** Others: user->emm_data-> **
|
|
||||||
** **
|
** **
|
||||||
** Outputs: None **
|
** Outputs: None **
|
||||||
** Return: The index of the PLMN if found in the list **
|
** 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 **
|
** 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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < user->emm_data->n_opnns; i++) {
|
for (i = 0; i < emm_data->n_opnns; i++) {
|
||||||
if (plmn->MCCdigit1 != user->emm_data->opnn[i].plmn->MCCdigit1) {
|
if (plmn->MCCdigit1 != emm_data->opnn[i].plmn->MCCdigit1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plmn->MCCdigit2 != user->emm_data->opnn[i].plmn->MCCdigit2) {
|
if (plmn->MCCdigit2 != emm_data->opnn[i].plmn->MCCdigit2) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plmn->MCCdigit3 != user->emm_data->opnn[i].plmn->MCCdigit3) {
|
if (plmn->MCCdigit3 != emm_data->opnn[i].plmn->MCCdigit3) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plmn->MNCdigit1 != user->emm_data->opnn[i].plmn->MNCdigit1) {
|
if (plmn->MNCdigit1 != emm_data->opnn[i].plmn->MNCdigit1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plmn->MNCdigit2 != user->emm_data->opnn[i].plmn->MNCdigit2) {
|
if (plmn->MNCdigit2 != emm_data->opnn[i].plmn->MNCdigit2) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plmn->MNCdigit3 != user->emm_data->opnn[i].plmn->MNCdigit3) {
|
if (plmn->MNCdigit3 != emm_data->opnn[i].plmn->MNCdigit3) {
|
||||||
continue;
|
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 **
|
** Inputs: index: Index of the selected PLMN in the ordered **
|
||||||
** list of available PLMNs **
|
** list of available PLMNs **
|
||||||
** Others: _emm_plmn_list.plmn **
|
|
||||||
** **
|
** **
|
||||||
** Outputs: None **
|
** Outputs: None **
|
||||||
** Return: RETURNok, RETURNerror **
|
** 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)
|
static int _IdleMode_get_suitable_cell(nas_user_t *user, int index)
|
||||||
{
|
{
|
||||||
emm_sap_t emm_sap;
|
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 "
|
LOG_TRACE(INFO, "EMM-IDLE - Trying to search a suitable cell "
|
||||||
"of PLMN %d in %s mode", index,
|
"of PLMN %d in %s mode", index,
|
||||||
(user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" :
|
(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_MANUAL)? "Manual" :
|
||||||
"Automatic/manual");
|
"Automatic/manual");
|
||||||
/*
|
/*
|
||||||
* Notify EMM-AS SAP that cell information related to the given
|
* 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.n_plmns = 1;
|
||||||
emm_sap.u.emm_as.u.cell_info.plmnIDs.plmn[0] = *plmn;
|
emm_sap.u.emm_as.u.cell_info.plmnIDs.plmn[0] = *plmn;
|
||||||
|
|
||||||
if (user->emm_data->plmn_rat != NET_ACCESS_UNAVAILABLE) {
|
if (emm_data->plmn_rat != NET_ACCESS_UNAVAILABLE) {
|
||||||
emm_sap.u.emm_as.u.cell_info.rat = (1 << user->emm_data->plmn_rat);
|
emm_sap.u.emm_as.u.cell_info.rat = (1 << emm_data->plmn_rat);
|
||||||
} else {
|
} else {
|
||||||
emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE;
|
emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb);
|
||||||
|
|
||||||
int IdleMode_get_nb_plmns(void);
|
int IdleMode_get_nb_plmns(emm_plmn_list_t *emm_plmn_list);
|
||||||
int IdleMode_get_hplmn_index(void);
|
int IdleMode_get_hplmn_index(emm_plmn_list_t *emm_plmn_list);
|
||||||
int IdleMode_get_rplmn_index(void);
|
int IdleMode_get_rplmn_index(emm_plmn_list_t *emm_plmn_list);
|
||||||
int IdleMode_get_splmn_index(void);
|
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);
|
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);
|
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_fullname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn);
|
||||||
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 IdleMode_get_plmn_id_index(const char *plmn);
|
int IdleMode_get_plmn_id_index(emm_plmn_list_t *emm_plmn_list, const char *plmn);
|
||||||
|
|
||||||
#endif /* __IDLEMODE_H__*/
|
#endif /* __IDLEMODE_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
|
||||||
@@ -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 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);
|
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
|
* USIM application data
|
||||||
@@ -538,12 +538,14 @@ const msisdn_t *emm_main_get_msisdn(void)
|
|||||||
** Others: user->emm_data-> **
|
** 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)
|
const network_plmn_t *plmn, int rat)
|
||||||
{
|
{
|
||||||
LOG_FUNC_IN;
|
LOG_FUNC_IN;
|
||||||
|
|
||||||
int index;
|
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, "
|
LOG_TRACE(INFO, "EMM-MAIN - PLMN selection: mode=%d, format=%d, plmn=%s, "
|
||||||
"rat=%d", mode, format, (const char *)&plmn->id, rat);
|
"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) {
|
if (mode != EMM_DATA_PLMN_AUTO) {
|
||||||
/* Get the index of the PLMN in the list of available PLMNs */
|
/* 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) {
|
if (index < 0) {
|
||||||
LOG_TRACE(WARNING, "EMM-MAIN - PLMN %s not available",
|
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
|
* register to when switched on; the equivalent PLMNs list shall not be
|
||||||
* applied to the user reselection in Automatic Network Selection Mode.
|
* 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);
|
LOG_FUNC_RETURN (index);
|
||||||
@@ -609,11 +611,11 @@ int emm_main_get_plmn_selection_mode(emm_data_t *emm_data)
|
|||||||
** Others: None **
|
** 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;
|
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;
|
*plist = emm_data->plist.buffer;
|
||||||
|
|
||||||
LOG_FUNC_RETURN (size);
|
LOG_FUNC_RETURN (size);
|
||||||
@@ -635,7 +637,7 @@ int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist)
|
|||||||
** Others: None **
|
** 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;
|
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
|
* 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) ) {
|
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);
|
format, &size);
|
||||||
|
|
||||||
if (size > 0) {
|
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 **
|
** 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;
|
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
|
* 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) ) {
|
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);
|
index, format, &size);
|
||||||
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
@@ -952,24 +954,24 @@ static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2)
|
|||||||
** Others: None **
|
** 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)
|
int format, size_t *size)
|
||||||
{
|
{
|
||||||
if ( PLMN_IS_VALID(*plmn) ) {
|
if ( PLMN_IS_VALID(*plmn) ) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case NET_FORMAT_LONG:
|
case NET_FORMAT_LONG:
|
||||||
/* Get the long alpha-numeric representation of the PLMN */
|
/* 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;
|
break;
|
||||||
|
|
||||||
case NET_FORMAT_SHORT:
|
case NET_FORMAT_SHORT:
|
||||||
/* Get the short alpha-numeric representation of the PLMN */
|
/* 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;
|
break;
|
||||||
|
|
||||||
case NET_FORMAT_NUM:
|
case NET_FORMAT_NUM:
|
||||||
/* Get the numeric representation of the PLMN */
|
/* 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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1002,24 +1004,24 @@ static const char *_emm_main_get_plmn(const plmn_t *plmn, int index,
|
|||||||
** Others: None **
|
** 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;
|
int index = -1;
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case NET_FORMAT_LONG:
|
case NET_FORMAT_LONG:
|
||||||
/* Get the index of the long alpha-numeric PLMN identifier */
|
/* 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;
|
break;
|
||||||
|
|
||||||
case NET_FORMAT_SHORT:
|
case NET_FORMAT_SHORT:
|
||||||
/* Get the index of the short alpha-numeric PLMN identifier */
|
/* 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;
|
break;
|
||||||
|
|
||||||
case NET_FORMAT_NUM:
|
case NET_FORMAT_NUM:
|
||||||
/* Get the index of the numeric PLMN identifier */
|
/* 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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -80,18 +80,18 @@ const imsi_t *emm_main_get_imsi(emm_data_t *emm_data);
|
|||||||
const msisdn_t *emm_main_get_msisdn(void);
|
const msisdn_t *emm_main_get_msisdn(void);
|
||||||
|
|
||||||
/* User's getter/setter for network selection */
|
/* 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);
|
const network_plmn_t *plmn, int rat);
|
||||||
int emm_main_get_plmn_selection_mode(emm_data_t *emm_data);
|
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);
|
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_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);
|
||||||
|
|
||||||
/* User's getter for network registration */
|
/* User's getter for network registration */
|
||||||
Stat_t emm_main_get_plmn_status(emm_data_t *emm_data);
|
Stat_t emm_main_get_plmn_status(emm_data_t *emm_data);
|
||||||
tac_t emm_main_get_plmn_tac(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);
|
ci_t emm_main_get_plmn_ci(emm_data_t *emm_data);
|
||||||
AcT_t emm_main_get_plmn_rat(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 */
|
/* User's getter for network attachment */
|
||||||
int emm_main_is_attached(emm_data_t *emm_data);
|
int emm_main_is_attached(emm_data_t *emm_data);
|
||||||
|
|||||||
@@ -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_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_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__*/
|
#endif /* __EMM_PROC_H__*/
|
||||||
|
|||||||
@@ -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
|
* 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) ) {
|
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);
|
*mode = emm_main_get_plmn_selection_mode(user->emm_data);
|
||||||
|
|
||||||
/* Get the currently selected operator */
|
/* 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) {
|
if (oper_name != NULL) {
|
||||||
/* An operator is currently selected */
|
/* 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;
|
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);
|
LOG_FUNC_RETURN (size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ Description NAS type definition to manage a user equipment
|
|||||||
#include "esm_pt_defs.h"
|
#include "esm_pt_defs.h"
|
||||||
#include "EMM/emm_fsm_defs.h"
|
#include "EMM/emm_fsm_defs.h"
|
||||||
#include "EMM/emmData.h"
|
#include "EMM/emmData.h"
|
||||||
|
#include "EMM/IdleMode_defs.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int fd;
|
int fd;
|
||||||
@@ -59,6 +60,7 @@ typedef struct {
|
|||||||
esm_ebr_data_t *esm_ebr_data; // EPS bearer contexts
|
esm_ebr_data_t *esm_ebr_data; // EPS bearer contexts
|
||||||
emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status
|
emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status
|
||||||
emm_data_t *emm_data; // EPS mobility management data
|
emm_data_t *emm_data; // EPS mobility management data
|
||||||
|
emm_plmn_list_t *emm_plmn_list; // list of PLMN identities
|
||||||
} nas_user_t;
|
} nas_user_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user