forked from acouzens/open5gs
Add IMEISV Request
This commit is contained in:
parent
f3ccd71db0
commit
552305afe2
|
@ -40,6 +40,8 @@ extern "C" {
|
|||
#define OGS_MAX_IMSI_LEN \
|
||||
OGS_BCD_TO_BUFFER_LEN(OGS_MAX_IMSI_BCD_LEN)
|
||||
|
||||
#define OGS_MAX_IMEISV_BCD_LEN 16
|
||||
|
||||
#define OGS_MAX_NUM_OF_HOSTNAME 16
|
||||
#define OGS_MAX_APN_LEN 100
|
||||
#define OGS_MAX_PCO_LEN 251
|
||||
|
|
|
@ -68,6 +68,10 @@ struct dict_object *ogs_diam_s6a_priority_level = NULL;
|
|||
struct dict_object *ogs_diam_s6a_pre_emption_capability = NULL;
|
||||
struct dict_object *ogs_diam_s6a_pre_emption_vulnerability = NULL;
|
||||
|
||||
struct dict_object *ogs_diam_s6a_terminal_information = NULL;
|
||||
struct dict_object *ogs_diam_s6a_imei = NULL;
|
||||
struct dict_object *ogs_diam_s6a_software_version = NULL;
|
||||
|
||||
extern int ogs_dict_s6a_entry(char *conffile);
|
||||
|
||||
int ogs_diam_s6a_init(void)
|
||||
|
@ -127,5 +131,9 @@ int ogs_diam_s6a_init(void)
|
|||
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Access-Restriction-Data", &ogs_diam_s6a_access_restriction_data);
|
||||
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscribed-Periodic-RAU-TAU-Timer", &ogs_diam_s6a_subscribed_rau_tau_timer);
|
||||
|
||||
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Terminal-Information", &ogs_diam_s6a_terminal_information);
|
||||
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "IMEI", &ogs_diam_s6a_imei);
|
||||
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Software-Version", &ogs_diam_s6a_software_version);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -108,6 +108,10 @@ extern struct dict_object *ogs_diam_s6a_priority_level;
|
|||
extern struct dict_object *ogs_diam_s6a_pre_emption_capability;
|
||||
extern struct dict_object *ogs_diam_s6a_pre_emption_vulnerability;
|
||||
|
||||
extern struct dict_object *ogs_diam_s6a_terminal_information;
|
||||
extern struct dict_object *ogs_diam_s6a_imei;
|
||||
extern struct dict_object *ogs_diam_s6a_software_version;
|
||||
|
||||
typedef struct ogs_diam_e_utran_vector_s {
|
||||
uint8_t xres[OGS_MAX_RES_LEN];
|
||||
uint8_t xres_len;
|
||||
|
|
|
@ -77,3 +77,36 @@ void ogs_nas_imsi_to_buffer(
|
|||
ogs_warn("Spec warning : buf[%d] = 0x%x", *buf_len, buf[*buf_len]);
|
||||
}
|
||||
}
|
||||
|
||||
void ogs_nas_imeisv_to_bcd(
|
||||
ogs_nas_mobile_identity_imeisv_t *imeisv, uint8_t imeisv_len, char *bcd)
|
||||
{
|
||||
int bcd_len;
|
||||
|
||||
bcd[0] = '0' + imeisv->digit1;
|
||||
bcd[1] = '0' + imeisv->digit2;
|
||||
bcd[2] = '0' + imeisv->digit3;
|
||||
bcd[3] = '0' + imeisv->digit4;
|
||||
bcd[4] = '0' + imeisv->digit5;
|
||||
bcd[5] = '0' + imeisv->digit6;
|
||||
bcd[6] = '0' + imeisv->digit7;
|
||||
bcd[7] = '0' + imeisv->digit8;
|
||||
bcd[8] = '0' + imeisv->digit9;
|
||||
bcd[9] = '0' + imeisv->digit10;
|
||||
bcd[10] = '0' + imeisv->digit11;
|
||||
bcd[11] = '0' + imeisv->digit12;
|
||||
bcd[12] = '0' + imeisv->digit13;
|
||||
bcd[13] = '0' + imeisv->digit14;
|
||||
bcd[14] = '0' + imeisv->digit15;
|
||||
bcd[15] = '0' + imeisv->digit16;
|
||||
bcd[16] = '0' + imeisv->digit17;
|
||||
|
||||
bcd_len = imeisv_len * 2 - 1;
|
||||
if (!imeisv->odd_even) { /* if bcd length is even */
|
||||
if (bcd[bcd_len] != 0xf)
|
||||
ogs_warn("Spec warning : bcd[%d] = 0x%x", bcd_len, bcd[bcd_len]);
|
||||
(bcd_len)--;
|
||||
}
|
||||
|
||||
bcd[bcd_len] = 0;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ void ogs_nas_imsi_to_buffer(
|
|||
void ogs_nas_imsi_to_bcd(
|
||||
ogs_nas_mobile_identity_imsi_t *imsi, uint8_t imsi_len, char *bcd);
|
||||
|
||||
void ogs_nas_imeisv_to_bcd(
|
||||
ogs_nas_mobile_identity_imeisv_t *imeisv, uint8_t imeisv_len, char *bcd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -172,12 +172,35 @@ ED5(uint8_t spare:2;,
|
|||
uint8_t mbms_session_identity;
|
||||
} __attribute__ ((packed)) ogs_nas_mobile_identity_tmgi_t;
|
||||
|
||||
typedef struct ogs_nas_mobile_identity_imeisv_s {
|
||||
ED3(uint8_t digit1:4;,
|
||||
uint8_t odd_even:1;,
|
||||
uint8_t type:3;)
|
||||
ED2(uint8_t digit3:4;,
|
||||
uint8_t digit2:4;)
|
||||
ED2(uint8_t digit5:4;,
|
||||
uint8_t digit4:4;)
|
||||
ED2(uint8_t digit7:4;,
|
||||
uint8_t digit6:4;)
|
||||
ED2(uint8_t digit9:4;,
|
||||
uint8_t digit8:4;)
|
||||
ED2(uint8_t digit11:4;,
|
||||
uint8_t digit10:4;)
|
||||
ED2(uint8_t digit13:4;,
|
||||
uint8_t digit12:4;)
|
||||
ED2(uint8_t digit15:4;,
|
||||
uint8_t digit14:4;)
|
||||
ED2(uint8_t digit17:4;,
|
||||
uint8_t digit16:4;)
|
||||
} __attribute__ ((packed)) ogs_nas_mobile_identity_imeisv_t;
|
||||
|
||||
typedef struct ogs_nas_mobile_identity_s {
|
||||
uint8_t length;
|
||||
union {
|
||||
ogs_nas_mobile_identity_imsi_t imsi;
|
||||
ogs_nas_mobile_identity_tmsi_t tmsi;
|
||||
ogs_nas_mobile_identity_tmgi_t tmgi;
|
||||
ogs_nas_mobile_identity_imeisv_t imeisv;
|
||||
};
|
||||
} ogs_nas_mobile_identity_t;
|
||||
|
||||
|
@ -586,8 +609,11 @@ ED2(uint8_t spare:5;,
|
|||
* See subclause 10.5.5.10 in 3GPP TS 24.008 [13].
|
||||
* O TV 1 */
|
||||
typedef struct ogs_nas_imeisv_request_s {
|
||||
#define OGS_NAS_IMEISV_TYPE 0xc
|
||||
ED3(uint8_t type:4;,
|
||||
uint8_t spare:1;,
|
||||
#define OGS_NAS_IMEISV_NOT_REQUESTED 0
|
||||
#define OGS_NAS_IMEISV_REQUESTED 1
|
||||
uint8_t imeisv_request_value:3;)
|
||||
} __attribute__ ((packed)) ogs_nas_imeisv_request_t;
|
||||
|
||||
|
|
|
@ -248,6 +248,8 @@ int emm_build_security_mode_command(
|
|||
&security_mode_command->nas_key_set_identifier;
|
||||
ogs_nas_ue_security_capability_t *replayed_ue_security_capabilities =
|
||||
&security_mode_command->replayed_ue_security_capabilities;
|
||||
ogs_nas_imeisv_request_t *imeisv_request =
|
||||
&security_mode_command->imeisv_request;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
|
@ -305,6 +307,12 @@ int emm_build_security_mode_command(
|
|||
replayed_ue_security_capabilities->gea);
|
||||
ogs_debug(" Selected[Integrity:0x%x Encrypt:0x%x]",
|
||||
mme_ue->selected_int_algorithm, mme_ue->selected_enc_algorithm);
|
||||
|
||||
security_mode_command->presencemask |=
|
||||
OGS_NAS_SECURITY_MODE_COMMAND_IMEISV_REQUEST_PRESENT;
|
||||
imeisv_request->type = OGS_NAS_IMEISV_TYPE;
|
||||
imeisv_request->imeisv_request_value = OGS_NAS_IMEISV_REQUESTED;
|
||||
|
||||
if (mme_ue->selected_int_algorithm == OGS_NAS_SECURITY_ALGORITHMS_EIA0) {
|
||||
ogs_fatal("Encrypt[0x%x] can be skipped with EEA0, "
|
||||
"but Integrity[0x%x] cannot be bypassed with EIA0",
|
||||
|
@ -313,7 +321,6 @@ int emm_build_security_mode_command(
|
|||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
|
||||
mme_kdf_nas(MME_KDF_NAS_INT_ALG, mme_ue->selected_int_algorithm,
|
||||
mme_ue->kasme, mme_ue->knas_int);
|
||||
mme_kdf_nas(MME_KDF_NAS_ENC_ALG, mme_ue->selected_enc_algorithm,
|
||||
|
|
|
@ -152,8 +152,10 @@ int emm_handle_attach_request(
|
|||
|
||||
switch (eps_mobile_identity->imsi.type) {
|
||||
case OGS_NAS_EPS_MOBILE_IDENTITY_IMSI:
|
||||
ogs_assert(sizeof(ogs_nas_mobile_identity_imsi_t) ==
|
||||
eps_mobile_identity->length);
|
||||
memcpy(&mme_ue->nas_mobile_identity_imsi,
|
||||
&eps_mobile_identity->imsi, sizeof(ogs_nas_mobile_identity_imsi_t));
|
||||
&eps_mobile_identity->imsi, eps_mobile_identity->length);
|
||||
ogs_nas_imsi_to_bcd(
|
||||
&eps_mobile_identity->imsi, eps_mobile_identity->length,
|
||||
imsi_bcd);
|
||||
|
@ -297,8 +299,10 @@ int emm_handle_identity_response(
|
|||
if (mobile_identity->imsi.type == OGS_NAS_IDENTITY_TYPE_2_IMSI) {
|
||||
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
||||
|
||||
ogs_assert(sizeof(ogs_nas_mobile_identity_imsi_t) ==
|
||||
mobile_identity->length);
|
||||
memcpy(&mme_ue->nas_mobile_identity_imsi,
|
||||
&mobile_identity->imsi, sizeof(ogs_nas_mobile_identity_imsi_t));
|
||||
&mobile_identity->imsi, mobile_identity->length);
|
||||
ogs_nas_imsi_to_bcd(
|
||||
&mobile_identity->imsi, mobile_identity->length, imsi_bcd);
|
||||
mme_ue_set_imsi(mme_ue, imsi_bcd);
|
||||
|
@ -615,3 +619,31 @@ int emm_handle_extended_service_request(mme_ue_t *mme_ue,
|
|||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
int emm_handle_security_mode_complete(mme_ue_t *mme_ue,
|
||||
ogs_nas_security_mode_complete_t *security_mode_complete)
|
||||
{
|
||||
ogs_nas_mobile_identity_t *imeisv = &security_mode_complete->imeisv;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
if (security_mode_complete->presencemask &
|
||||
OGS_NAS_SECURITY_MODE_COMMAND_IMEISV_REQUEST_PRESENT) {
|
||||
switch (imeisv->imeisv.type) {
|
||||
case OGS_NAS_MOBILE_IDENTITY_IMEISV:
|
||||
memcpy(&mme_ue->nas_mobile_identity_imeisv,
|
||||
&imeisv->imeisv, imeisv->length);
|
||||
ogs_nas_imeisv_to_bcd(&imeisv->imeisv, imeisv->length,
|
||||
mme_ue->imeisv_bcd);
|
||||
mme_ue->imeisv_presence = true;
|
||||
break;
|
||||
default:
|
||||
ogs_warn("Invalid IMEISV Type[%d]", imeisv->imeisv.type);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ int emm_handle_tau_request(
|
|||
int emm_handle_extended_service_request(mme_ue_t *mme_ue,
|
||||
ogs_nas_extended_service_request_t *extended_service_request);
|
||||
|
||||
int emm_handle_security_mode_complete(mme_ue_t *mme_ue,
|
||||
ogs_nas_security_mode_complete_t *security_mode_complete);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -708,6 +708,14 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
|
|||
break;
|
||||
}
|
||||
|
||||
rv = emm_handle_security_mode_complete(
|
||||
mme_ue, &message->emm.security_mode_complete);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("emm_handle_security_mode_complete() failed");
|
||||
OGS_FSM_TRAN(s, emm_state_exception);
|
||||
return;
|
||||
}
|
||||
|
||||
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32,
|
||||
mme_ue->kenb);
|
||||
mme_kdf_nh(mme_ue->kasme, mme_ue->kenb, mme_ue->nh);
|
||||
|
|
|
@ -305,6 +305,10 @@ struct mme_ue_s {
|
|||
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
||||
ogs_nas_mobile_identity_imsi_t nas_mobile_identity_imsi;
|
||||
|
||||
bool imeisv_presence;
|
||||
char imeisv_bcd[OGS_MAX_IMEISV_BCD_LEN+1];
|
||||
ogs_nas_mobile_identity_imeisv_t nas_mobile_identity_imeisv;
|
||||
|
||||
mme_m_tmsi_t *m_tmsi;
|
||||
mme_p_tmsi_t p_tmsi;
|
||||
ogs_nas_guti_t guti;
|
||||
|
|
|
@ -433,7 +433,7 @@ void mme_s6a_send_ulr(mme_ue_t *mme_ue)
|
|||
int ret;
|
||||
|
||||
struct msg *req = NULL;
|
||||
struct avp *avp;
|
||||
struct avp *avp, *avpch;
|
||||
union avp_value val;
|
||||
struct sess_state *sess_data = NULL, *svg;
|
||||
struct session *session = NULL;
|
||||
|
@ -492,6 +492,33 @@ void mme_s6a_send_ulr(mme_ue_t *mme_ue)
|
|||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
/* Set the Terminal-Information AVP */
|
||||
if (mme_ue->imeisv_presence) {
|
||||
ret = fd_msg_avp_new(ogs_diam_s6a_terminal_information, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
ret = fd_msg_avp_new(ogs_diam_s6a_imei, 0, &avpch);
|
||||
ogs_assert(ret == 0);
|
||||
val.os.data = (uint8_t *)mme_ue->imeisv_bcd;
|
||||
val.os.len = 14;
|
||||
ret = fd_msg_avp_setvalue(avpch, &val);
|
||||
ogs_assert(ret == 0);
|
||||
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
ret = fd_msg_avp_new(ogs_diam_s6a_software_version, 0, &avpch);
|
||||
ogs_assert(ret == 0);
|
||||
val.os.data = (uint8_t *)mme_ue->imeisv_bcd+14;
|
||||
val.os.len = 2;
|
||||
ret = fd_msg_avp_setvalue(avpch, &val);
|
||||
ogs_assert(ret == 0);
|
||||
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
/* Set the RAT-Type */
|
||||
ret = fd_msg_avp_new(ogs_diam_s6a_rat_type, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
|
|
@ -775,8 +775,10 @@ int tests1ap_build_security_mode_complete(ogs_pkbuf_t **pkbuf, int i)
|
|||
"",
|
||||
|
||||
/* 18 */
|
||||
"000d403200000500 0000020001000800 020001001a000908 470ba943dd00075e"
|
||||
"006440080009f107 0019b01000434006 0009f1070007",
|
||||
"000d403d00000500 0000020001000800 020001001a001413 471647b75200075e"
|
||||
"2309337522002954 3118f40064400800 09f1070019b01000 4340060009f10700"
|
||||
"07",
|
||||
|
||||
"000d403400000500 00000200f8000800 048003e993001a00 090847592cf09600"
|
||||
"075e006440080027 f412000640200043 40060027f4123039",
|
||||
"",
|
||||
|
@ -813,7 +815,7 @@ int tests1ap_build_security_mode_complete(ogs_pkbuf_t **pkbuf, int i)
|
|||
0,
|
||||
0,
|
||||
|
||||
54,
|
||||
65,
|
||||
56,
|
||||
0,
|
||||
|
||||
|
|
|
@ -41,8 +41,9 @@ static void test1_func(abts_case *tc, void *data)
|
|||
"000b403800000300 0000020001000800 020001001a002524 075200aa266700bc"
|
||||
"2887354e9f87368d 5d0ae710ab857af5 5f1a8000d71e5537 4ee176e9";
|
||||
const char *_security_mode_command =
|
||||
"000b402400000300 0000020001000800 020001001a001110 378ccbca6000075d"
|
||||
"010005f0f0c04070";
|
||||
"000b4025"
|
||||
"0000030000000200 0100080002000100 1a001211379be42b 4200075d010005f0"
|
||||
"f0c04070c1";
|
||||
const char *_esm_information_request =
|
||||
"000b401d00000300 0000020001000800 020001001a000a09 27d1237969010234"
|
||||
"d9";
|
||||
|
|
|
@ -38,8 +38,9 @@ static void test1_func(abts_case *tc, void *data)
|
|||
"000b403b00000300 000005c001a00102 000800020018001a 002524075200906d"
|
||||
"231ff57ef278c719 1d170303deb610d0 7c4defa47480001f 2b5350926bdb3a";
|
||||
const char *_security_mode_command =
|
||||
"000b402400000300 000005c001a00102 000800020018001a 000e0d37c966d549"
|
||||
"00075d010002e0e0";
|
||||
"000b4025"
|
||||
"00000300000005c0 01a0010200080002 0018001a000f0e37 62522c0900075d01"
|
||||
"0002e0e0c1";
|
||||
const char *_esm_information_request =
|
||||
"000b402000000300 000005c001a00102 000800020018001a 000a0927846a01a8"
|
||||
"010201d9";
|
||||
|
|
|
@ -42,8 +42,9 @@ static void attach_test1(abts_case *tc, void *data)
|
|||
"000b403b00000300 000005c00100009d 000800020001001a 0025240752002008"
|
||||
"0c3818183b522614 162c07601d0d10f1 1b89a2a8de8000ad 0ccf7f55e8b20d";
|
||||
const char *_security_mode_command =
|
||||
"000b402700000300 000005c00100009d 000800020001001a 00111037f933b5d5"
|
||||
"00075d010005e060 c04070";
|
||||
"000b4028"
|
||||
"00000300000005c0 0100009d00080002 0001001a00121137 f497722900075d01"
|
||||
"0005e060c04070c1";
|
||||
const char *_esm_information_request =
|
||||
"000b402000000300 000005c00100009d 000800020001001a 000a092779012320"
|
||||
"010221d9";
|
||||
|
@ -760,8 +761,9 @@ static void attach_test3(abts_case *tc, void *data)
|
|||
"403b000003000000 05c0020000c80008 00020002001a0025 2407520042200639"
|
||||
"1c0021554d444928 4a1a062e10e543cb 257f1f800021f4f9 2d522a5b87";
|
||||
const char *_security_mode_command =
|
||||
"000b402400000300 000005c0020000c8 000800020002001a 000e0d37a3761a13"
|
||||
"00075d010002f0f0";
|
||||
"000b4025"
|
||||
"00000300000005c0 020000c800080002 0002001a000f0e37 c48c93b000075d01"
|
||||
"0002f0f0c1";
|
||||
|
||||
const char *_esm_information_request =
|
||||
"000b"
|
||||
|
|
Loading…
Reference in New Issue