Multiple TAI list
Configuration Parer, Message Build is added
This commit is contained in:
parent
178678c216
commit
521d7877b4
|
@ -73,6 +73,8 @@ CORE_DECLARE(c_uint16_t) plmn_id_mnc_len(plmn_id_t *plmn_id);
|
||||||
CORE_DECLARE(void *) plmn_id_build(plmn_id_t *plmn_id,
|
CORE_DECLARE(void *) plmn_id_build(plmn_id_t *plmn_id,
|
||||||
c_uint16_t mcc, c_uint16_t mnc, c_uint16_t mnc_len);
|
c_uint16_t mcc, c_uint16_t mnc, c_uint16_t mnc_len);
|
||||||
|
|
||||||
|
#define MAX_NUM_OF_TAI 16
|
||||||
|
|
||||||
typedef struct _tai_t {
|
typedef struct _tai_t {
|
||||||
plmn_id_t plmn_id;
|
plmn_id_t plmn_id;
|
||||||
c_uint16_t tac;
|
c_uint16_t tac;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
||||||
* Please do not modify this file but regenerate it via script.
|
* Please do not modify this file but regenerate it via script.
|
||||||
* Created on: 2017-12-08 15:47:05.461966 by acetcom
|
* Created on: 2017-12-10 14:27:23.972133 by acetcom
|
||||||
* from 24301-d80.docx
|
* from 24301-d80.docx
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
||||||
* Please do not modify this file but regenerate it via script.
|
* Please do not modify this file but regenerate it via script.
|
||||||
* Created on: 2017-12-08 15:47:05.494259 by acetcom
|
* Created on: 2017-12-10 14:27:23.999892 by acetcom
|
||||||
* from 24301-d80.docx
|
* from 24301-d80.docx
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
||||||
* Please do not modify this file but regenerate it via script.
|
* Please do not modify this file but regenerate it via script.
|
||||||
* Created on: 2017-12-08 15:47:05.418551 by acetcom
|
* Created on: 2017-12-10 14:27:23.929926 by acetcom
|
||||||
* from 24301-d80.docx
|
* from 24301-d80.docx
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -1466,20 +1466,6 @@ c_int16_t nas_decode_tracking_area_identity_list(nas_tracking_area_identity_list
|
||||||
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK, return -1, "pkbuf_header error");
|
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK, return -1, "pkbuf_header error");
|
||||||
memcpy(tracking_area_identity_list, pkbuf->payload - size, size);
|
memcpy(tracking_area_identity_list, pkbuf->payload - size, size);
|
||||||
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_NON_CONSECUTIVE_TACS)
|
|
||||||
for (i = 0; i < tracking_area_identity_list->num + 1 && i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)
|
|
||||||
tracking_area_identity_list->type0.tac[i] = ntohs(tracking_area_identity_list->type0.tac[i]);
|
|
||||||
else if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_CONSECUTIVE_TACS)
|
|
||||||
tracking_area_identity_list->type1.tac = ntohs(tracking_area_identity_list->type1.tac);
|
|
||||||
else if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_MANY_PLMNS)
|
|
||||||
for (i = 0; i < tracking_area_identity_list->num + 1 && i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)
|
|
||||||
tracking_area_identity_list->type2.tai[i].tac = ntohs(tracking_area_identity_list->type2.tai[i].tac);
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
d_trace(5, " TRACKING_AREA_IDENTITY_LIST - ");
|
d_trace(5, " TRACKING_AREA_IDENTITY_LIST - ");
|
||||||
d_trace_hex(5, pkbuf->payload - size, size);
|
d_trace_hex(5, pkbuf->payload - size, size);
|
||||||
|
|
||||||
|
@ -1492,20 +1478,6 @@ c_int16_t nas_encode_tracking_area_identity_list(pkbuf_t *pkbuf, nas_tracking_ar
|
||||||
nas_tracking_area_identity_list_t target;
|
nas_tracking_area_identity_list_t target;
|
||||||
|
|
||||||
memcpy(&target, tracking_area_identity_list, sizeof(nas_tracking_area_identity_list_t));
|
memcpy(&target, tracking_area_identity_list, sizeof(nas_tracking_area_identity_list_t));
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_NON_CONSECUTIVE_TACS)
|
|
||||||
for (i = 0; i < tracking_area_identity_list->num + 1 && i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)
|
|
||||||
target.type0.tac[i] = htons(tracking_area_identity_list->type0.tac[i]);
|
|
||||||
else if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_CONSECUTIVE_TACS)
|
|
||||||
target.type1.tac = htons(tracking_area_identity_list->type1.tac);
|
|
||||||
else if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_MANY_PLMNS)
|
|
||||||
for (i = 0; i < tracking_area_identity_list->num + 1 && i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)
|
|
||||||
target.type2.tai[i].tac = htons(tracking_area_identity_list->type2.tai[i].tac);
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK, return -1, "pkbuf_header error");
|
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK, return -1, "pkbuf_header error");
|
||||||
memcpy(pkbuf->payload - size, &target, size);
|
memcpy(pkbuf->payload - size, &target, size);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
||||||
* Please do not modify this file but regenerate it via script.
|
* Please do not modify this file but regenerate it via script.
|
||||||
* Created on: 2017-12-08 15:47:05.412576 by acetcom
|
* Created on: 2017-12-10 14:27:23.924792 by acetcom
|
||||||
* from 24301-d80.docx
|
* from 24301-d80.docx
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
* This file had been created by gtpv2c_tlv.py script v0.1.0
|
||||||
* Please do not modify this file but regenerate it via script.
|
* Please do not modify this file but regenerate it via script.
|
||||||
* Created on: 2017-12-08 15:47:05.438977 by acetcom
|
* Created on: 2017-12-10 14:27:23.947739 by acetcom
|
||||||
* from 24301-d80.docx
|
* from 24301-d80.docx
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -220,3 +220,68 @@ void eps_qos_build(nas_eps_quality_of_service_t *eps_qos, c_uint8_t qci,
|
||||||
|
|
||||||
eps_qos->length = length*4+1;
|
eps_qos->length = length*4+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nas_tai_list_build(
|
||||||
|
nas_tracking_area_identity_list_t *target,
|
||||||
|
tai0_list_t *source0, tai2_list_t *source2)
|
||||||
|
{
|
||||||
|
int i = 0, j = 0, length = 0;
|
||||||
|
tai0_list_t *target0 = NULL;
|
||||||
|
tai2_list_t *target2 = NULL;
|
||||||
|
|
||||||
|
d_assert(target, return,);
|
||||||
|
d_assert(source0, return,);
|
||||||
|
d_assert(source2, return,);
|
||||||
|
|
||||||
|
|
||||||
|
target0 = &target->list0;
|
||||||
|
memset(target0, 0, sizeof(tai0_list_t));
|
||||||
|
|
||||||
|
for (i = 0; source0->tai[i].num; i++)
|
||||||
|
{
|
||||||
|
d_assert(source0->tai[i].type == TAI0_TYPE,
|
||||||
|
return, "type = %d", source0->tai[i].type);
|
||||||
|
target0->tai[i].type = source0->tai[i].type;
|
||||||
|
|
||||||
|
/* <Spec> target->num = source->num - 1 */
|
||||||
|
d_assert(source0->tai[i].num < MAX_NUM_OF_TAI,
|
||||||
|
return, "num = %d", source0->tai[i].num);
|
||||||
|
target0->tai[i].num = source0->tai[i].num - 1;
|
||||||
|
|
||||||
|
memcpy(&target0->tai[i].plmn_id,
|
||||||
|
&source0->tai[i].plmn_id, PLMN_ID_LEN);
|
||||||
|
for (j = 0; j < source0->tai[i].num; j++)
|
||||||
|
{
|
||||||
|
target0->tai[i].tac[j] = htons(source0->tai[i].tac[j]);
|
||||||
|
}
|
||||||
|
length += (1 + 3 + 2 * source0->tai[i].num);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source2->num)
|
||||||
|
{
|
||||||
|
if (source0->tai[0].num)
|
||||||
|
target2 = &target->both.list2;
|
||||||
|
else
|
||||||
|
target2 = &target->list2;
|
||||||
|
memset(target2, 0, sizeof(tai2_list_t));
|
||||||
|
|
||||||
|
d_assert(source2->type == TAI1_TYPE || source2->type == TAI2_TYPE,
|
||||||
|
return, "type = %d", source2->type);
|
||||||
|
target2->type = source2->type;
|
||||||
|
|
||||||
|
/* <Spec> target->num = source->num - 1 */
|
||||||
|
d_assert(source2->num < MAX_NUM_OF_TAI,
|
||||||
|
return, "num = %d", source2->num);
|
||||||
|
target2->num = source2->num - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < source2->num; i++)
|
||||||
|
{
|
||||||
|
memcpy(&target2->tai[i].plmn_id,
|
||||||
|
&source2->tai[i].plmn_id, PLMN_ID_LEN);
|
||||||
|
target2->tai[i].tac = htons(source2->tai[i].tac);
|
||||||
|
}
|
||||||
|
length += (1 + 3 + 2 * source2->num);
|
||||||
|
}
|
||||||
|
|
||||||
|
target->length = length;
|
||||||
|
}
|
||||||
|
|
|
@ -733,33 +733,42 @@ typedef tai_t nas_tracking_area_identity_t;
|
||||||
|
|
||||||
/* 9.9.3.33 Tracking area identity list
|
/* 9.9.3.33 Tracking area identity list
|
||||||
* M LV 7-97 */
|
* M LV 7-97 */
|
||||||
#define NAS_MAX_TRACKING_AREA_IDENTITY 16
|
#define TAI0_TYPE 0
|
||||||
#define NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_NON_CONSECUTIVE_TACS 0
|
#define TAI1_TYPE 1
|
||||||
#define NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_CONSECUTIVE_TACS 1
|
#define TAI2_TYPE 2
|
||||||
#define NAS_TRACKING_AREA_IDENTITY_LIST_MANY_PLMNS 2
|
typedef struct _tai0_list_t {
|
||||||
typedef struct _nas_tracking_area_identity_type0 {
|
struct {
|
||||||
plmn_id_t plmn_id;
|
ED3(c_uint8_t spare:1;,
|
||||||
c_uint16_t tac[NAS_MAX_TRACKING_AREA_IDENTITY];
|
c_uint8_t type:2;,
|
||||||
} __attribute__ ((packed)) nas_tracking_area_identity_type0;
|
c_uint8_t num:5;)
|
||||||
|
plmn_id_t plmn_id;
|
||||||
|
c_uint16_t tac[MAX_NUM_OF_TAI];
|
||||||
|
} __attribute__ ((packed)) tai[MAX_NUM_OF_TAI];
|
||||||
|
} __attribute__ ((packed)) tai0_list_t;
|
||||||
|
|
||||||
typedef nas_tracking_area_identity_t nas_tracking_area_identity_type1;
|
typedef struct _tai2_list_t {
|
||||||
|
|
||||||
typedef struct _nas_tracking_area_identity_type2 {
|
|
||||||
nas_tracking_area_identity_type1 tai[NAS_MAX_TRACKING_AREA_IDENTITY];
|
|
||||||
} __attribute__ ((packed)) nas_tracking_area_identity_type2;
|
|
||||||
|
|
||||||
typedef struct nas_tracking_area_identity_list_t {
|
|
||||||
c_uint8_t length;
|
|
||||||
ED3(c_uint8_t spare:1;,
|
ED3(c_uint8_t spare:1;,
|
||||||
c_uint8_t type:2;,
|
c_uint8_t type:2;,
|
||||||
c_uint8_t num:5;)
|
c_uint8_t num:5;)
|
||||||
|
tai_t tai[MAX_NUM_OF_TAI];
|
||||||
|
} __attribute__ ((packed)) tai2_list_t;
|
||||||
|
|
||||||
|
typedef struct _nas_tracking_area_identity_list_t {
|
||||||
|
c_uint8_t length;
|
||||||
union {
|
union {
|
||||||
nas_tracking_area_identity_type0 type0;
|
tai0_list_t list0;
|
||||||
nas_tracking_area_identity_type1 type1;
|
tai2_list_t list2;
|
||||||
nas_tracking_area_identity_type2 type2;
|
struct {
|
||||||
|
tai0_list_t list0;
|
||||||
|
tai2_list_t list2;
|
||||||
|
} __attribute__ ((packed)) both;
|
||||||
};
|
};
|
||||||
} __attribute__ ((packed)) nas_tracking_area_identity_list_t;
|
} __attribute__ ((packed)) nas_tracking_area_identity_list_t;
|
||||||
|
|
||||||
|
CORE_DECLARE(void) nas_tai_list_build(
|
||||||
|
nas_tracking_area_identity_list_t *target,
|
||||||
|
tai0_list_t *source0, tai2_list_t *source2);
|
||||||
|
|
||||||
/* 9.9.3.34 UE network capability
|
/* 9.9.3.34 UE network capability
|
||||||
* M LV 3-14 */
|
* M LV 3-14 */
|
||||||
typedef struct _nas_ue_network_capability_t {
|
typedef struct _nas_ue_network_capability_t {
|
||||||
|
|
|
@ -13,35 +13,6 @@ type_list["Tracking area identity"]["decode"] = \
|
||||||
type_list["Tracking area identity"]["encode"] = \
|
type_list["Tracking area identity"]["encode"] = \
|
||||||
" target.tac = htons(tracking_area_identity->tac);\n\n"
|
" target.tac = htons(tracking_area_identity->tac);\n\n"
|
||||||
|
|
||||||
type_list["Tracking area identity list"]["decode"] = \
|
|
||||||
" {\n" \
|
|
||||||
" int i = 0;\n" \
|
|
||||||
" if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_NON_CONSECUTIVE_TACS)\n" \
|
|
||||||
" for (i = 0; i < tracking_area_identity_list->num + 1 && i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)\n" \
|
|
||||||
" tracking_area_identity_list->type0.tac[i] = ntohs(tracking_area_identity_list->type0.tac[i]);\n" \
|
|
||||||
" else if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_CONSECUTIVE_TACS)\n" \
|
|
||||||
" tracking_area_identity_list->type1.tac = ntohs(tracking_area_identity_list->type1.tac);\n" \
|
|
||||||
" else if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_MANY_PLMNS)\n" \
|
|
||||||
" for (i = 0; i < tracking_area_identity_list->num + 1 && i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)\n" \
|
|
||||||
" tracking_area_identity_list->type2.tai[i].tac = ntohs(tracking_area_identity_list->type2.tai[i].tac);\n" \
|
|
||||||
" else\n" \
|
|
||||||
" return -1;\n" \
|
|
||||||
" }\n\n"
|
|
||||||
type_list["Tracking area identity list"]["encode"] = \
|
|
||||||
" {\n" \
|
|
||||||
" int i = 0;\n" \
|
|
||||||
" if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_NON_CONSECUTIVE_TACS)\n" \
|
|
||||||
" for (i = 0; i < tracking_area_identity_list->num + 1 && i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)\n" \
|
|
||||||
" target.type0.tac[i] = htons(tracking_area_identity_list->type0.tac[i]);\n" \
|
|
||||||
" else if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_CONSECUTIVE_TACS)\n" \
|
|
||||||
" target.type1.tac = htons(tracking_area_identity_list->type1.tac);\n" \
|
|
||||||
" else if (tracking_area_identity_list->type == NAS_TRACKING_AREA_IDENTITY_LIST_MANY_PLMNS)\n" \
|
|
||||||
" for (i = 0; i < tracking_area_identity_list->num + 1 && i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)\n" \
|
|
||||||
" target.type2.tai[i].tac = htons(tracking_area_identity_list->type2.tai[i].tac);\n" \
|
|
||||||
" else\n" \
|
|
||||||
" return -1;\n" \
|
|
||||||
" }\n\n"
|
|
||||||
|
|
||||||
type_list["Mobile identity"]["decode"] = \
|
type_list["Mobile identity"]["decode"] = \
|
||||||
" if (mobile_identity->tmsi.type == NAS_MOBILE_IDENTITY_TMSI)\n" \
|
" if (mobile_identity->tmsi.type == NAS_MOBILE_IDENTITY_TMSI)\n" \
|
||||||
" {\n" \
|
" {\n" \
|
||||||
|
|
|
@ -17,7 +17,8 @@ status_t emm_build_attach_accept(
|
||||||
nas_eps_attach_result_t *eps_attach_result =
|
nas_eps_attach_result_t *eps_attach_result =
|
||||||
&attach_accept->eps_attach_result;
|
&attach_accept->eps_attach_result;
|
||||||
nas_gprs_timer_t *t3412_value = &attach_accept->t3412_value;
|
nas_gprs_timer_t *t3412_value = &attach_accept->t3412_value;
|
||||||
nas_tracking_area_identity_list_t *tai_list = &attach_accept->tai_list;
|
tai0_list_t tai0_list;
|
||||||
|
tai2_list_t tai2_list;
|
||||||
nas_eps_mobile_identity_t *guti = &attach_accept->guti;
|
nas_eps_mobile_identity_t *guti = &attach_accept->guti;
|
||||||
nas_gprs_timer_t *t3402_value = &attach_accept->t3402_value;
|
nas_gprs_timer_t *t3402_value = &attach_accept->t3402_value;
|
||||||
nas_gprs_timer_t *t3423_value = &attach_accept->t3423_value;
|
nas_gprs_timer_t *t3423_value = &attach_accept->t3423_value;
|
||||||
|
@ -40,10 +41,12 @@ status_t emm_build_attach_accept(
|
||||||
t3412_value->unit = NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH;
|
t3412_value->unit = NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH;
|
||||||
t3412_value->value = 9;
|
t3412_value->value = 9;
|
||||||
|
|
||||||
tai_list->length = 6;
|
memset(&tai0_list, 0, sizeof(tai0_list_t));
|
||||||
tai_list->type = 2;
|
memset(&tai2_list, 0, sizeof(tai2_list_t));
|
||||||
tai_list->num = 0; /* +1 = 1 elements */
|
tai2_list.type = TAI2_TYPE;
|
||||||
memcpy(&tai_list->type2.tai[0], &mme_ue->tai, sizeof(tai_t));
|
tai2_list.num = 1;
|
||||||
|
memcpy(&tai2_list.tai[0], &mme_ue->tai, sizeof(tai_t));
|
||||||
|
nas_tai_list_build(&attach_accept->tai_list, &tai0_list, &tai2_list);
|
||||||
|
|
||||||
attach_accept->esm_message_container.buffer = esmbuf->payload;
|
attach_accept->esm_message_container.buffer = esmbuf->payload;
|
||||||
attach_accept->esm_message_container.length = esmbuf->len;
|
attach_accept->esm_message_container.length = esmbuf->len;
|
||||||
|
@ -281,6 +284,8 @@ status_t emm_build_tau_accept(pkbuf_t **emmbuf, mme_ue_t *mme_ue)
|
||||||
nas_message_t message;
|
nas_message_t message;
|
||||||
nas_tracking_area_update_accept_t *tau_accept =
|
nas_tracking_area_update_accept_t *tau_accept =
|
||||||
&message.emm.tracking_area_update_accept;
|
&message.emm.tracking_area_update_accept;
|
||||||
|
tai0_list_t tai0_list;
|
||||||
|
tai2_list_t tai2_list;
|
||||||
|
|
||||||
memset(&message, 0, sizeof(message));
|
memset(&message, 0, sizeof(message));
|
||||||
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
|
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
|
||||||
|
@ -300,11 +305,12 @@ status_t emm_build_tau_accept(pkbuf_t **emmbuf, mme_ue_t *mme_ue)
|
||||||
tau_accept->presencemask |=
|
tau_accept->presencemask |=
|
||||||
NAS_TRACKING_AREA_UPDATE_ACCEPT_TAI_LIST_PRESENT;
|
NAS_TRACKING_AREA_UPDATE_ACCEPT_TAI_LIST_PRESENT;
|
||||||
|
|
||||||
tau_accept->tai_list.length = 6;
|
memset(&tai0_list, 0, sizeof(tai0_list_t));
|
||||||
tau_accept->tai_list.type = 2;
|
memset(&tai2_list, 0, sizeof(tai2_list_t));
|
||||||
tau_accept->tai_list.num = 0; /* +1 = 1 elements */
|
tai2_list.type = TAI2_TYPE;
|
||||||
|
tai2_list.num = 1;
|
||||||
memcpy(&tau_accept->tai_list.type2.tai[0], &mme_ue->tai, sizeof(tai_t));
|
memcpy(&tai2_list.tai[0], &mme_ue->tai, sizeof(tai_t));
|
||||||
|
nas_tai_list_build(&tau_accept->tai_list, &tai0_list, &tai2_list);
|
||||||
|
|
||||||
/* Set EPS bearer context status */
|
/* Set EPS bearer context status */
|
||||||
tau_accept->presencemask |=
|
tau_accept->presencemask |=
|
||||||
|
|
|
@ -199,13 +199,64 @@ static status_t mme_context_validation()
|
||||||
return CORE_ERROR;
|
return CORE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.max_num_of_served_tai == 0)
|
if (self.num_of_served_tai == 0)
|
||||||
{
|
{
|
||||||
d_error("No mme.tai in '%s'",
|
d_error("No mme.tai in '%s'",
|
||||||
context_self()->config.path);
|
context_self()->config.path);
|
||||||
return CORE_ERROR;
|
return CORE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* For debuggin, will be removed */
|
||||||
|
{
|
||||||
|
int i = 0, j = 0, k = 0;
|
||||||
|
for (k = 0; k < self.num_of_served_tai; k++)
|
||||||
|
{
|
||||||
|
tai0_list_t *list0 = &self.served_tai[k].list0;
|
||||||
|
d_assert(list0, return CORE_ERROR,);
|
||||||
|
tai2_list_t *list2 = &self.served_tai[k].list2;
|
||||||
|
d_assert(list2, return CORE_ERROR,);
|
||||||
|
|
||||||
|
for (i = 0; list0->tai[i].num; i++)
|
||||||
|
{
|
||||||
|
d_assert(list0->tai[i].type == TAI0_TYPE,
|
||||||
|
return CORE_ERROR, "type = %d", list0->tai[i].type);
|
||||||
|
printf("i:%d ", i);
|
||||||
|
printf("type: %d ", list0->tai[i].type);
|
||||||
|
|
||||||
|
d_assert(list0->tai[i].num < MAX_NUM_OF_TAI,
|
||||||
|
return CORE_ERROR, "num = %d", list0->tai[i].num);
|
||||||
|
printf("num: %d ", list0->tai[i].num);
|
||||||
|
|
||||||
|
printf("tac: ");
|
||||||
|
for (j = 0; j < list0->tai[i].num; j++)
|
||||||
|
{
|
||||||
|
printf("%d, ", list0->tai[i].tac[j]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list2->num)
|
||||||
|
{
|
||||||
|
d_assert(list2->type == TAI1_TYPE || list2->type == TAI2_TYPE,
|
||||||
|
return CORE_ERROR, "type = %d", list2->type);
|
||||||
|
printf("type: %d ", list2->type);
|
||||||
|
|
||||||
|
/* <Spec> target->num = source->num - 1 */
|
||||||
|
d_assert(list2->num < MAX_NUM_OF_TAI,
|
||||||
|
return CORE_ERROR, "num = %d", list2->num);
|
||||||
|
printf("num: %d ", list2->num);
|
||||||
|
|
||||||
|
printf("tac: ");
|
||||||
|
for (i = 0; i < list2->num; i++)
|
||||||
|
{
|
||||||
|
printf("%d, ", list2->tai[i].tac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (self.num_of_integrity_order == 0)
|
if (self.num_of_integrity_order == 0)
|
||||||
{
|
{
|
||||||
d_error("No mme.security.integrity_order in '%s'",
|
d_error("No mme.security.integrity_order in '%s'",
|
||||||
|
@ -750,21 +801,24 @@ status_t mme_context_parse_config()
|
||||||
}
|
}
|
||||||
else if (!strcmp(mme_key, "tai"))
|
else if (!strcmp(mme_key, "tai"))
|
||||||
{
|
{
|
||||||
|
int num_of_list0 = 0;
|
||||||
|
tai0_list_t *list0 = NULL;
|
||||||
|
tai2_list_t *list2 = NULL;
|
||||||
|
|
||||||
|
d_assert(self.num_of_served_tai <=
|
||||||
|
MAX_NUM_OF_SERVED_TAI, return CORE_ERROR,);
|
||||||
|
list0 = &self.served_tai[self.num_of_served_tai].list0;
|
||||||
|
d_assert(list0, return CORE_ERROR,);
|
||||||
|
list2 = &self.served_tai[self.num_of_served_tai].list2;
|
||||||
|
d_assert(list2, return CORE_ERROR,);
|
||||||
|
|
||||||
yaml_iter_t tai_array, tai_iter;
|
yaml_iter_t tai_array, tai_iter;
|
||||||
yaml_iter_recurse(&mme_iter, &tai_array);
|
yaml_iter_recurse(&mme_iter, &tai_array);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
tai_t *tai = NULL;
|
|
||||||
plmn_id_t *plmn_id = NULL;
|
|
||||||
const char *mcc = NULL, *mnc = NULL;
|
const char *mcc = NULL, *mnc = NULL;
|
||||||
|
c_uint16_t tac[MAX_NUM_OF_TAI];
|
||||||
d_assert(self.max_num_of_served_tai <=
|
int num_of_tac = 0;
|
||||||
MAX_NUM_OF_SERVED_TAI, return CORE_ERROR,);
|
|
||||||
tai = &self.served_tai[
|
|
||||||
self.max_num_of_served_tai];
|
|
||||||
d_assert(tai, return CORE_ERROR,);
|
|
||||||
plmn_id = &tai->plmn_id;
|
|
||||||
d_assert(plmn_id, return CORE_ERROR,);
|
|
||||||
|
|
||||||
if (yaml_iter_type(&tai_array) == YAML_MAPPING_NODE)
|
if (yaml_iter_type(&tai_array) == YAML_MAPPING_NODE)
|
||||||
{
|
{
|
||||||
|
@ -802,42 +856,92 @@ status_t mme_context_parse_config()
|
||||||
return CORE_ERROR,);
|
return CORE_ERROR,);
|
||||||
if (!strcmp(plmn_id_key, "mcc"))
|
if (!strcmp(plmn_id_key, "mcc"))
|
||||||
{
|
{
|
||||||
mcc =
|
mcc = yaml_iter_value(&plmn_id_iter);
|
||||||
yaml_iter_value(&plmn_id_iter);
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(plmn_id_key, "mnc"))
|
else if (!strcmp(plmn_id_key, "mnc"))
|
||||||
{
|
{
|
||||||
mnc =
|
mnc = yaml_iter_value(&plmn_id_iter);
|
||||||
yaml_iter_value(&plmn_id_iter);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mcc && mnc)
|
|
||||||
{
|
|
||||||
plmn_id_build(plmn_id,
|
|
||||||
atoi(mcc), atoi(mnc), strlen(mnc));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(tai_key, "tac"))
|
else if (!strcmp(tai_key, "tac"))
|
||||||
{
|
{
|
||||||
const char *v = yaml_iter_value(&tai_iter);
|
yaml_iter_t tac_iter;
|
||||||
if (v) tai->tac = atoi(v);
|
yaml_iter_recurse(&tai_iter, &tac_iter);
|
||||||
|
d_assert(yaml_iter_type(&tac_iter) !=
|
||||||
|
YAML_MAPPING_NODE, return CORE_ERROR,);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const char *v = NULL;
|
||||||
|
|
||||||
|
d_assert(num_of_tac <=
|
||||||
|
MAX_NUM_OF_TAI, return CORE_ERROR,);
|
||||||
|
if (yaml_iter_type(&tac_iter) ==
|
||||||
|
YAML_SEQUENCE_NODE)
|
||||||
|
{
|
||||||
|
if (!yaml_iter_next(&tac_iter))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = yaml_iter_value(&tac_iter);
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
tac[num_of_tac] = atoi(v);
|
||||||
|
num_of_tac++;
|
||||||
|
}
|
||||||
|
} while(
|
||||||
|
yaml_iter_type(&tac_iter) ==
|
||||||
|
YAML_SEQUENCE_NODE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
d_warn("unknown key `%s`", tai_key);
|
d_warn("unknown key `%s`", tai_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mcc && mnc && tai->tac)
|
if (mcc && mnc && num_of_tac)
|
||||||
{
|
{
|
||||||
self.max_num_of_served_tai++;
|
if (num_of_tac == 1)
|
||||||
|
{
|
||||||
|
plmn_id_build(
|
||||||
|
&list2->tai[list2->num].plmn_id,
|
||||||
|
atoi(mcc), atoi(mnc), strlen(mnc));
|
||||||
|
list2->tai[list2->num].tac = tac[0];
|
||||||
|
|
||||||
|
list2->num++;
|
||||||
|
if (list2->num > 1)
|
||||||
|
list2->type = TAI2_TYPE;
|
||||||
|
else
|
||||||
|
list2->type = TAI1_TYPE;
|
||||||
|
}
|
||||||
|
else if (num_of_tac > 1)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
plmn_id_build(
|
||||||
|
&list0->tai[num_of_list0].plmn_id,
|
||||||
|
atoi(mcc), atoi(mnc), strlen(mnc));
|
||||||
|
for (i = 0; i < num_of_tac; i++)
|
||||||
|
{
|
||||||
|
list0->tai[num_of_list0].tac[i] = tac[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
list0->tai[num_of_list0].num = num_of_tac;
|
||||||
|
list0->tai[num_of_list0].type = TAI0_TYPE;
|
||||||
|
|
||||||
|
num_of_list0++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d_warn("Ignore tai : mcc(%p), mnc(%p), tac(%d)",
|
d_warn("Ignore tai : mcc(%p), mnc(%p), "
|
||||||
mcc, mnc, tai->tac);
|
"num_of_tac(%d)", mcc, mnc, num_of_tac);
|
||||||
}
|
}
|
||||||
} while(yaml_iter_type(&tai_array) ==
|
} while(yaml_iter_type(&tai_array) ==
|
||||||
YAML_SEQUENCE_NODE);
|
YAML_SEQUENCE_NODE);
|
||||||
|
|
||||||
|
if (list2->num || num_of_list0)
|
||||||
|
{
|
||||||
|
self.num_of_served_tai++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp(mme_key, "security"))
|
else if (!strcmp(mme_key, "security"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,6 @@ extern "C" {
|
||||||
#define MAX_NUM_OF_SERVED_GUMMEI 8
|
#define MAX_NUM_OF_SERVED_GUMMEI 8
|
||||||
#define MAX_NUM_OF_ALGORITHM 8
|
#define MAX_NUM_OF_ALGORITHM 8
|
||||||
|
|
||||||
#define MAX_NUM_OF_TAC 256
|
|
||||||
#define MAX_NUM_OF_BPLMN 6
|
#define MAX_NUM_OF_BPLMN 6
|
||||||
|
|
||||||
typedef struct _enb_ue_t enb_ue_t;
|
typedef struct _enb_ue_t enb_ue_t;
|
||||||
|
@ -72,12 +71,16 @@ typedef struct _mme_context_t {
|
||||||
c_sockaddr_t *pgw_addr; /* First IPv4 Address Selected */
|
c_sockaddr_t *pgw_addr; /* First IPv4 Address Selected */
|
||||||
c_sockaddr_t *pgw_addr6; /* First IPv6 Address Selected */
|
c_sockaddr_t *pgw_addr6; /* First IPv6 Address Selected */
|
||||||
|
|
||||||
msgq_id queue_id; /* Queue for processing MME control plane */
|
/* Served GUMME */
|
||||||
tm_service_t tm_service; /* Timer Service */
|
c_uint8_t max_num_of_served_gummei;
|
||||||
|
served_gummei_t served_gummei[MAX_NUM_OF_SERVED_GUMMEI];
|
||||||
|
|
||||||
/* Generator for unique identification */
|
/* Served TAI */
|
||||||
c_uint32_t mme_ue_s1ap_id; /* mme_ue_s1ap_id generator */
|
c_uint8_t num_of_served_tai;
|
||||||
c_uint32_t m_tmsi; /* m_tmsi generator */
|
struct {
|
||||||
|
tai0_list_t list0;
|
||||||
|
tai2_list_t list2;
|
||||||
|
} served_tai[MAX_NUM_OF_SERVED_TAI];
|
||||||
|
|
||||||
/* defined in 'nas_ies.h'
|
/* defined in 'nas_ies.h'
|
||||||
* #define NAS_SECURITY_ALGORITHMS_EIA0 0
|
* #define NAS_SECURITY_ALGORITHMS_EIA0 0
|
||||||
|
@ -94,17 +97,15 @@ typedef struct _mme_context_t {
|
||||||
c_uint8_t num_of_integrity_order;
|
c_uint8_t num_of_integrity_order;
|
||||||
c_uint8_t integrity_order[MAX_NUM_OF_ALGORITHM];
|
c_uint8_t integrity_order[MAX_NUM_OF_ALGORITHM];
|
||||||
|
|
||||||
/* S1SetupRequest */
|
|
||||||
c_uint8_t max_num_of_served_tai;
|
|
||||||
tai_t served_tai[MAX_NUM_OF_SERVED_TAI];
|
|
||||||
|
|
||||||
/* S1SetupResponse */
|
/* S1SetupResponse */
|
||||||
c_uint8_t max_num_of_served_gummei;
|
|
||||||
served_gummei_t served_gummei[MAX_NUM_OF_SERVED_GUMMEI];
|
|
||||||
c_uint8_t relative_capacity;
|
c_uint8_t relative_capacity;
|
||||||
|
|
||||||
/* Timer value */
|
/* Timer value */
|
||||||
c_uint32_t t3413_value; /* Paging retry timer */
|
c_uint32_t t3413_value; /* Paging retry timer */
|
||||||
|
|
||||||
|
/* Generator for unique identification */
|
||||||
|
c_uint32_t mme_ue_s1ap_id; /* mme_ue_s1ap_id generator */
|
||||||
|
c_uint32_t m_tmsi; /* m_tmsi generator */
|
||||||
|
|
||||||
hash_t *enb_sock_hash; /* hash table for ENB Socket */
|
hash_t *enb_sock_hash; /* hash table for ENB Socket */
|
||||||
hash_t *enb_addr_hash; /* hash table for ENB Address */
|
hash_t *enb_addr_hash; /* hash table for ENB Address */
|
||||||
|
@ -112,6 +113,10 @@ typedef struct _mme_context_t {
|
||||||
hash_t *mme_ue_s1ap_id_hash; /* hash table for MME-UE-S1AP-ID */
|
hash_t *mme_ue_s1ap_id_hash; /* hash table for MME-UE-S1AP-ID */
|
||||||
hash_t *imsi_ue_hash; /* hash table (IMSI : MME_UE) */
|
hash_t *imsi_ue_hash; /* hash table (IMSI : MME_UE) */
|
||||||
hash_t *guti_ue_hash; /* hash table (GUTI : MME_UE) */
|
hash_t *guti_ue_hash; /* hash table (GUTI : MME_UE) */
|
||||||
|
|
||||||
|
/* System */
|
||||||
|
msgq_id queue_id; /* Queue for processing MME control plane */
|
||||||
|
tm_service_t tm_service; /* Timer Service */
|
||||||
} mme_context_t;
|
} mme_context_t;
|
||||||
|
|
||||||
typedef struct _mme_enb_t {
|
typedef struct _mme_enb_t {
|
||||||
|
@ -125,7 +130,7 @@ typedef struct _mme_enb_t {
|
||||||
c_sockaddr_t *addr; /* eNB S1AP Address */
|
c_sockaddr_t *addr; /* eNB S1AP Address */
|
||||||
|
|
||||||
c_uint8_t num_of_tai;
|
c_uint8_t num_of_tai;
|
||||||
tai_t tai[MAX_NUM_OF_TAC * MAX_NUM_OF_BPLMN];
|
tai_t tai[MAX_NUM_OF_TAI * MAX_NUM_OF_BPLMN];
|
||||||
|
|
||||||
list_t enb_ue_list;
|
list_t enb_ue_list;
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,8 @@ static void nas_message_test2(abts_case *tc, void *data)
|
||||||
|
|
||||||
nas_message_t message;
|
nas_message_t message;
|
||||||
nas_attach_accept_t *attach_accept = &message.emm.attach_accept;
|
nas_attach_accept_t *attach_accept = &message.emm.attach_accept;
|
||||||
|
tai0_list_t tai0_list;
|
||||||
|
tai2_list_t tai2_list;
|
||||||
|
|
||||||
pkbuf_t *pkbuf = NULL;
|
pkbuf_t *pkbuf = NULL;
|
||||||
status_t rv;
|
status_t rv;
|
||||||
|
@ -67,9 +69,15 @@ static void nas_message_test2(abts_case *tc, void *data)
|
||||||
attach_accept->t3412_value.unit =
|
attach_accept->t3412_value.unit =
|
||||||
NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM;
|
NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM;
|
||||||
attach_accept->t3412_value.value = 3;
|
attach_accept->t3412_value.value = 3;
|
||||||
attach_accept->tai_list.length = 6;
|
|
||||||
plmn_id_build(&attach_accept->tai_list.type0.plmn_id, 417, 99, 2);
|
memset(&tai0_list, 0, sizeof(tai0_list_t));
|
||||||
attach_accept->tai_list.type0.tac[0] = 12345;
|
memset(&tai2_list, 0, sizeof(tai2_list_t));
|
||||||
|
tai0_list.tai[0].type = TAI0_TYPE;
|
||||||
|
tai0_list.tai[0].num = 1;
|
||||||
|
plmn_id_build(&tai0_list.tai[0].plmn_id, 417, 99, 2);
|
||||||
|
tai0_list.tai[0].tac[0] = 12345;
|
||||||
|
nas_tai_list_build(&attach_accept->tai_list, &tai0_list, &tai2_list);
|
||||||
|
|
||||||
attach_accept->esm_message_container.length = sizeof(esm_buffer);
|
attach_accept->esm_message_container.length = sizeof(esm_buffer);
|
||||||
attach_accept->esm_message_container.buffer =
|
attach_accept->esm_message_container.buffer =
|
||||||
CORE_HEX(esm_payload, strlen(esm_payload), esm_buffer);
|
CORE_HEX(esm_payload, strlen(esm_payload), esm_buffer);
|
||||||
|
|
Loading…
Reference in New Issue