Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Michael Black
OpenXG-RAN
Commits
7340b5e0
Commit
7340b5e0
authored
Jul 12, 2016
by
Frédéric Leroy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
UE/EMM: move _plmn_list to nas_user_t
parent
2d7f557a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
232 additions
and
217 deletions
+232
-217
openair3/NAS/UE/EMM/IdleMode.c
openair3/NAS/UE/EMM/IdleMode.c
+136
-177
openair3/NAS/UE/EMM/IdleMode.h
openair3/NAS/UE/EMM/IdleMode.h
+11
-11
openair3/NAS/UE/EMM/IdleMode_defs.h
openair3/NAS/UE/EMM/IdleMode_defs.h
+52
-0
openair3/NAS/UE/EMM/emm_main.c
openair3/NAS/UE/EMM/emm_main.c
+23
-21
openair3/NAS/UE/EMM/emm_main.h
openair3/NAS/UE/EMM/emm_main.h
+4
-4
openair3/NAS/UE/EMM/emm_proc.h
openair3/NAS/UE/EMM/emm_proc.h
+1
-1
openair3/NAS/UE/nas_proc.c
openair3/NAS/UE/nas_proc.c
+3
-3
openair3/NAS/UE/user_defs.h
openair3/NAS/UE/user_defs.h
+2
-0
No files found.
openair3/NAS/UE/EMM/IdleMode.c
View file @
7340b5e0
...
...
@@ -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
;
// LG
emm_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
;
}
...
...
openair3/NAS/UE/EMM/IdleMode.h
View file @
7340b5e0
...
...
@@ -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__*/
openair3/NAS/UE/EMM/IdleMode_defs.h
0 → 100644
View file @
7340b5e0
#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
openair3/NAS/UE/EMM/emm_main.c
View file @
7340b5e0
...
...
@@ -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:
...
...
openair3/NAS/UE/EMM/emm_main.h
View file @
7340b5e0
...
...
@@ -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
);
...
...
openair3/NAS/UE/EMM/emm_proc.h
View file @
7340b5e0
...
...
@@ -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__*/
openair3/NAS/UE/nas_proc.c
View file @
7340b5e0
...
...
@@ -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
);
}
...
...
openair3/NAS/UE/user_defs.h
View file @
7340b5e0
...
...
@@ -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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment