NAS encoding

This commit is contained in:
Sukchan Lee 2017-02-16 18:11:01 +09:00
parent 6afbafc73d
commit d8eec46c03
5 changed files with 581 additions and 61 deletions

View File

@ -20,7 +20,7 @@ status_t nas_decode_device_properties(
* See subclause 10.5.1.3 in 3GPP TS 24.008 [13]
* O TV 6 */
status_t nas_decode_location_area_identification(
nas_location_area_identification_t *old_location_area_identification,
nas_location_area_identification_t *location_area_identification,
pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
@ -28,10 +28,10 @@ status_t nas_decode_location_area_identification(
size = sizeof(nas_location_area_identification_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
memcpy(old_location_area_identification, pkbuf->payload - size, size);
memcpy(location_area_identification, pkbuf->payload - size, size);
old_location_area_identification->lac =
ntohs(old_location_area_identification->lac);
location_area_identification->lac =
ntohs(location_area_identification->lac);
return CORE_OK;
}
@ -84,19 +84,19 @@ status_t nas_decode_mobile_station_classmark_3(
* See subclause 10.5.4.32 in 3GPP TS 24.008 [13].
* O TLV 5-n */
status_t nas_decode_supported_codec_list(
nas_supported_codec_list_t *supported_codecs, pkbuf_t *pkbuf)
nas_supported_codec_list_t *supported_codec_list, pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
nas_supported_codec_list_t *source = pkbuf->payload;
supported_codecs->length = source->length;
size = supported_codecs->length +
sizeof(supported_codecs->length);
supported_codec_list->length = source->length;
size = supported_codec_list->length +
sizeof(supported_codec_list->length);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
memcpy(supported_codecs, pkbuf->payload - size,
memcpy(supported_codec_list, pkbuf->payload - size,
c_min(size, sizeof(nas_supported_codec_list_t)));
return CORE_OK;
@ -131,15 +131,15 @@ status_t nas_decode_drx_parameter(
* M V 1/2
* 9.9.3.21 NAS key set identifier
* M V 1/2 */
status_t nas_decode_attach_info(
nas_attach_info_t *attach_info, pkbuf_t *pkbuf)
status_t nas_decode_attach_type(
nas_attach_type_t *attach_type, pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
size = sizeof(nas_attach_info_t);
size = sizeof(nas_attach_type_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
memcpy(attach_info, pkbuf->payload - size, size);
memcpy(attach_type, pkbuf->payload - size, size);
return CORE_OK;
}
@ -189,21 +189,45 @@ status_t nas_decode_esm_message_container(
return CORE_OK;
}
c_int32_t nas_encode_esm_message_container(
pkbuf_t *pkbuf, nas_esm_message_container_t *esm_message_container)
{
c_uint16_t size = 0;
c_uint16_t tmp;
d_assert(esm_message_container, return -1, "Null param");
d_assert(esm_message_container->buffer, return -1, "Null param");
size = sizeof(esm_message_container->length);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
tmp = htons(esm_message_container->length);
memcpy(pkbuf->payload - size, &tmp, size);
size = esm_message_container->length;
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
memcpy(pkbuf->payload - size, esm_message_container->buffer, size);
return esm_message_container->length +
sizeof(esm_message_container->length);
}
/* 9.9.3.16A GPRS timer 2
* See subclause 10.5.7.4 in 3GPP TS 24.008 [13].
* O TLV 3 */
status_t nas_decode_gprs_timer_2(
nas_gprs_timer_2_t *t3324_value, pkbuf_t *pkbuf)
nas_gprs_timer_2_t *gprs_timer_2, pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
nas_gprs_timer_2_t *source = pkbuf->payload;
t3324_value->length = source->length;
size = t3324_value->length + sizeof(t3324_value->length);
gprs_timer_2->length = source->length;
size = gprs_timer_2->length + sizeof(gprs_timer_2->length);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
memcpy(t3324_value, pkbuf->payload - size, size);
memcpy(gprs_timer_2, pkbuf->payload - size, size);
return CORE_OK;
}
@ -212,17 +236,17 @@ status_t nas_decode_gprs_timer_2(
* See subclause 10.5.7.4a in 3GPP TS 24.008 [13].
* O TLV 3 */
CORE_DECLARE(status_t) nas_decode_gprs_timer_3(
nas_gprs_timer_3_t *t3412_extended_value, pkbuf_t *pkbuf)
nas_gprs_timer_3_t *gprs_timer_3, pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
nas_gprs_timer_3_t *source = pkbuf->payload;
t3412_extended_value->length = source->length;
size = t3412_extended_value->length + sizeof(t3412_extended_value->length);
gprs_timer_3->length = source->length;
size = gprs_timer_3->length + sizeof(gprs_timer_3->length);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
memcpy(t3412_extended_value, pkbuf->payload - size, size);
memcpy(gprs_timer_3, pkbuf->payload - size, size);
return CORE_OK;
}
@ -264,19 +288,19 @@ status_t nas_decode_ms_network_feature_support(
* See subclause 10.5.5.31 in 3GPP TS 24.008 [13].
* O TLV 4 */
status_t nas_decode_network_resource_identifier_container(
nas_network_resource_identifier_container_t *tmsi_based_nri_container,
nas_network_resource_identifier_container_t *network_resource_identifier_container,
pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
nas_network_resource_identifier_container_t *source = pkbuf->payload;
tmsi_based_nri_container->length = source->length;
size = tmsi_based_nri_container->length +
sizeof(tmsi_based_nri_container->length);
network_resource_identifier_container->length = source->length;
size = network_resource_identifier_container->length +
sizeof(network_resource_identifier_container->length);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
memcpy(tmsi_based_nri_container, pkbuf->payload - size, size);
memcpy(network_resource_identifier_container, pkbuf->payload - size, size);
return CORE_OK;
}
@ -285,16 +309,16 @@ status_t nas_decode_network_resource_identifier_container(
* See subclause 10.5.5.8 in 3GPP TS 24.008
* O TV 4 */
status_t nas_decode_p_tmsi_signature(
nas_p_tmsi_signature_t *old_p_tmsi_signature, pkbuf_t *pkbuf)
nas_p_tmsi_signature_t *p_tmsi_signature, pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
size = 3;
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
memcpy(old_p_tmsi_signature, pkbuf->payload - size, size);
memcpy(p_tmsi_signature, pkbuf->payload - size, size);
*old_p_tmsi_signature = ntohl(*old_p_tmsi_signature);
*p_tmsi_signature = ntohl(*p_tmsi_signature);
return CORE_OK;
}
@ -314,16 +338,16 @@ status_t nas_decode_tmsi_status(
/* 9.9.3.32 Tracking area identity
* O TV 6 */
status_t nas_decode_tracking_area_identity(
nas_tracking_area_identity_t *last_visited_registered_tai, pkbuf_t *pkbuf)
nas_tracking_area_identity_t *tracking_area_identity, pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
size = sizeof(nas_tracking_area_identity_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
memcpy(last_visited_registered_tai, pkbuf->payload - size, size);
memcpy(tracking_area_identity, pkbuf->payload - size, size);
last_visited_registered_tai->tac = ntohs(last_visited_registered_tai->tac);
tracking_area_identity->tac = ntohs(tracking_area_identity->tac);
return CORE_OK;
}
@ -372,11 +396,11 @@ status_t nas_decode_voice_domain_preference_and_ue_usage_setting(
/* 9.9.3.45 GUTI type
* O TV 1 */
status_t nas_decode_guti_type(nas_guti_type_t *old_guti_type, pkbuf_t *pkbuf)
status_t nas_decode_guti_type(nas_guti_type_t *guti_type, pkbuf_t *pkbuf)
{
c_uint16_t size = 1;
memcpy(old_guti_type, pkbuf->payload - size, size);
memcpy(guti_type, pkbuf->payload - size, size);
return CORE_OK;
}
@ -399,3 +423,86 @@ status_t nas_decode_extended_drx_parameters(
return CORE_OK;
}
/* 9.9.3.10 * EPS attach result
* M V 1/2 */
c_int32_t nas_encode_attach_result(
pkbuf_t *pkbuf, nas_attach_result_t *attach_result)
{
c_uint16_t size = 0;
d_assert(attach_result, return -1, "Null param");
size = sizeof(nas_attach_result_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
memcpy(pkbuf->payload - size, attach_result, size);
return size;
}
/* 9.9.3.16 GPRS timer
* See subclause 10.5.7.3 in 3GPP TS 24.008 [13].
* M V 1 or O TV 2
*
* Note : Other values shall be interpreted as multiples of 1 minute
* in this version of the protocol. */
c_int32_t nas_encode_gprs_timer(pkbuf_t *pkbuf, nas_gprs_timer_t *gprs_timer)
{
c_uint16_t size = 0;
size = sizeof(nas_gprs_timer_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
memcpy(pkbuf->payload - size, gprs_timer, size);
return size;
}
c_int32_t nas_encode_tracking_area_identity_list(
pkbuf_t *pkbuf,
nas_tracking_area_identity_list_t *tracking_area_identity_list)
{
c_uint16_t size = 0;
int i = 0;
nas_tracking_area_identity_list_t tmp;
d_assert(tracking_area_identity_list, return -1, "Null param");
memcpy(&tmp, tracking_area_identity_list,
sizeof(nas_tracking_area_identity_list_t));
size = tracking_area_identity_list->length +
sizeof(tracking_area_identity_list->length);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
if (tmp.type_of_list ==
NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_NON_CONSECUTIVE_TACS)
{
for (i = 0; i < tmp.number_of_elements + 1&&
i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)
{
tmp.u.type0.tac[i] = htons(tmp.u.type0.tac[i]);
}
}
else if (tmp.type_of_list ==
NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_CONSECUTIVE_TACS)
{
tmp.u.type1.tac = htons(tmp.u.type1.tac);
}
else if (tmp.type_of_list ==
NAS_TRACKING_AREA_IDENTITY_LIST_MANY_PLMNS)
{
for (i = 0; i < tmp.number_of_elements + 1 &&
i < NAS_MAX_TRACKING_AREA_IDENTITY; i++)
{
tmp.u.type2.tai[i].tac = htons(tmp.u.type2.tai[i].tac);
}
}
else
return -1;
memcpy(pkbuf->payload - size, &tmp, size);
return size;
}

View File

@ -33,7 +33,7 @@ ED2(c_uint8_t mnc_digit2:4;,
} __attribute__ ((packed)) nas_location_area_identification_t;
CORE_DECLARE(status_t) nas_decode_location_area_identification(
nas_location_area_identification_t *old_location_area_identification,
nas_location_area_identification_t *location_area_identification,
pkbuf_t *pkbuf);
/* 9.9.2.4 Mobile station classmark 2
@ -99,14 +99,14 @@ typedef struct _nas_supported_codec_item_t {
c_uint16_t codec_bitmap;
} __attribute__ ((packed)) nas_supported_codec_item_t;
#define NAS_MAX_SUPPORTED_CODECS 4
#define NAS_MAX_SUPPORTED_CODECS 8
typedef struct _nas_supported_codec_list_t {
c_uint8_t length;
nas_supported_codec_item_t item[NAS_MAX_SUPPORTED_CODECS];
} __attribute__ ((packed)) nas_supported_codec_list_t;
CORE_DECLARE(status_t) nas_decode_supported_codec_list(
nas_supported_codec_list_t *supported_codecs, pkbuf_t *pkbuf);
nas_supported_codec_list_t *supported_codec_list, pkbuf_t *pkbuf);
/* 9.9.3.0B Additional update type
* O TV 1 */
@ -162,15 +162,15 @@ CORE_DECLARE(status_t) nas_decode_drx_parameter(
#define NAS_ATTACH_TYPE_COMBINED_EPS_IMSI_ATTAACH 2
#define NAS_ATTACH_TYPE_EPS_ERMERGENCY_ATTCH 3
#define NAS_ATTACH_TYPE_RESERVED 4
typedef struct _nas_attach_info_t {
typedef struct _nas_attach_type_t {
ED4(c_uint8_t tsc:1;,
c_uint8_t nas_key_set_identifier:3;,
c_uint8_t spare:1;,
c_uint8_t attach_type:3;)
} __attribute__ ((packed)) nas_attach_info_t;
} __attribute__ ((packed)) nas_attach_type_t;
CORE_DECLARE(status_t) nas_decode_attach_info(
nas_attach_info_t *attach_info, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) nas_decode_attach_type(
nas_attach_type_t *attach_type, pkbuf_t *pkbuf);
/* 9.9.3.12 EPS mobile identity
* M LV 5-12 */
@ -235,6 +235,8 @@ typedef struct _nas_esm_message_container_t {
CORE_DECLARE(status_t) nas_decode_esm_message_container(
nas_esm_message_container_t *esm_message_container, pkbuf_t *pkbuf);
CORE_DECLARE(c_int32_t) nas_encode_esm_message_container(
pkbuf_t *pkbuf, nas_esm_message_container_t *esm_message_container);
/* 9.9.3.16A GPRS timer 2
* See subclause 10.5.7.4 in 3GPP TS 24.008 [13].
@ -245,7 +247,7 @@ typedef struct _nas_gprs_timer_2_t {
} __attribute__ ((packed)) nas_gprs_timer_2_t;
CORE_DECLARE(status_t) nas_decode_gprs_timer_2(
nas_gprs_timer_2_t *t3324_value, pkbuf_t *pkbuf);
nas_gprs_timer_2_t *gprs_timer_2, pkbuf_t *pkbuf);
/* 9.9.3.16B GPRS timer 3
* See subclause 10.5.7.4a in 3GPP TS 24.008 [13].
@ -266,7 +268,7 @@ ED2(c_uint8_t unit:3;,
} __attribute__ ((packed)) nas_gprs_timer_3_t;
CORE_DECLARE(status_t) nas_decode_gprs_timer_3(
nas_gprs_timer_3_t *t3412_extended_value, pkbuf_t *pkbuf);
nas_gprs_timer_3_t *gprs_timer_3, pkbuf_t *pkbuf);
/* 9.9.3.20 MS network capability
* See subclause 10.5.5.12 in 3GPP TS 24.008
@ -332,7 +334,8 @@ ED2(c_uint8_t nri_container_value2:2;,
} __attribute__ ((packed)) nas_network_resource_identifier_container_t;
CORE_DECLARE(status_t) nas_decode_network_resource_identifier_container(
nas_network_resource_identifier_container_t *tmsi_based_nri_container,
nas_network_resource_identifier_container_t *
network_resource_identifier_container,
pkbuf_t *pkbuf);
/* 9.9.3.26 P-TMSI signature
@ -341,7 +344,7 @@ CORE_DECLARE(status_t) nas_decode_network_resource_identifier_container(
typedef c_uint32_t nas_p_tmsi_signature_t; /* TV : 4bytes */
CORE_DECLARE(status_t) nas_decode_p_tmsi_signature(
nas_p_tmsi_signature_t *old_p_tmsi_signature, pkbuf_t *pkbuf);
nas_p_tmsi_signature_t *p_tmsi_signature, pkbuf_t *pkbuf);
/* 9.9.3.31 TMSI status
* See subclause 10.5.5.4 in 3GPP TS 24.008 [13]
@ -368,7 +371,7 @@ ED2(c_uint8_t mnc_digit2:4;,
} __attribute__ ((packed)) nas_tracking_area_identity_t;
CORE_DECLARE(status_t) nas_decode_tracking_area_identity(
nas_tracking_area_identity_t *last_visited_registered_tai, pkbuf_t *pkbuf);
nas_tracking_area_identity_t *tracking_area_identity, pkbuf_t *pkbuf);
/* 9.9.3.34 UE network capability
* M LV 3-14 */
@ -453,7 +456,7 @@ ED3(c_uint8_t type:4;,
} __attribute__ ((packed)) nas_guti_type_t;
CORE_DECLARE(status_t) nas_decode_guti_type(
nas_guti_type_t *old_guti_type, pkbuf_t *pkbuf);
nas_guti_type_t *guti_type, pkbuf_t *pkbuf);
/* 9.9.3.46 Extended DRX parameters
* See subclause 10.5.5.32 in 3GPP TS 24.008 [13].
@ -467,6 +470,192 @@ ED2(c_uint8_t paging_time_window:4;,
CORE_DECLARE(status_t) nas_decode_extended_drx_parameters(
nas_extended_drx_parameters_t *extended_drx_parameters, pkbuf_t *pkbuf);
/* 9.9.3.10 * EPS attach result
* M V 1/2 */
#define NAS_ATTACH_RESULT_EPS_ONLY 1
#define NAS_ATTACH_RESULT_COMBINED_EPS_IMSI_ATTACH 2
typedef struct _nas_attach_result_t {
ED2(c_uint8_t spare:5;,
c_uint8_t result:3;)
} __attribute__ ((packed)) nas_attach_result_t;
CORE_DECLARE(c_int32_t) nas_encode_attach_result(
pkbuf_t *pkbuf, nas_attach_result_t *attach_result);
/* 9.9.3.33 Tracking area identity list
* M LV 7-97 */
#define NAS_MAX_TRACKING_AREA_IDENTITY 16
#define NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_NON_CONSECUTIVE_TACS 0
#define NAS_TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_CONSECUTIVE_TACS 1
#define NAS_TRACKING_AREA_IDENTITY_LIST_MANY_PLMNS 2
typedef struct _nas_tracking_area_identity_type0 {
ED2(c_uint8_t mcc_digit2:4;,
c_uint8_t mcc_digit1:4;)
ED2(c_uint8_t mnc_digit3:4;,
c_uint8_t mcc_digit3:4;)
ED2(c_uint8_t mnc_digit2:4;,
c_uint8_t mnc_digit1:4;)
c_uint16_t tac[NAS_MAX_TRACKING_AREA_IDENTITY];
} __attribute__ ((packed)) nas_tracking_area_identity_type0;
typedef struct _nas_tracking_area_identity_type1 {
ED2(c_uint8_t mcc_digit2:4;,
c_uint8_t mcc_digit1:4;)
ED2(c_uint8_t mnc_digit3:4;,
c_uint8_t mcc_digit3:4;)
ED2(c_uint8_t mnc_digit2:4;,
c_uint8_t mnc_digit1:4;)
c_uint16_t tac;
} __attribute__ ((packed)) nas_tracking_area_identity_type1;
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;,
c_uint8_t type_of_list:2;,
c_uint8_t number_of_elements:5;)
union {
nas_tracking_area_identity_type0 type0;
nas_tracking_area_identity_type1 type1;
nas_tracking_area_identity_type2 type2;
} u;
} __attribute__ ((packed)) nas_tracking_area_identity_list_t;
CORE_DECLARE(c_int32_t) nas_encode_tracking_area_identity_list(
pkbuf_t *pkbuf,
nas_tracking_area_identity_list_t *tracking_area_identity_list);
/* 9.9.3.16 GPRS timer
* See subclause 10.5.7.3 in 3GPP TS 24.008 [13].
* O TV 2
*
* Note : Other values shall be interpreted as multiples of 1 minute
* in this version of the protocol. */
#define NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_2_SS 0
#define NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM 1
#define NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH 2
#define NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM_3 3
#define NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM_4 4
#define NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM_5 5
#define NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM_6 6
#define NAS_GRPS_TIMER_UNIT_DEACTIVATED 7
typedef struct _nas_gprs_timer_t {
ED2(c_uint8_t unit:3;,
c_uint8_t timer_value:5;)
} __attribute__ ((packed)) nas_gprs_timer_t;
CORE_DECLARE(c_int32_t) nas_encode_gprs_timer(
pkbuf_t *pkbuf, nas_gprs_timer_t *gprs_timer);
/* 9.9.2.3 Mobile identity
* See subclause 10.5.1.4 in 3GPP TS 24.008 [13].
* O TLV 7-10 */
typedef nas_eps_mobile_identity_t nas_mobile_identity_t;
CORE_DECLARE(c_int32_t) nas_encode_mobile_identity(
pkbuf_t *pkbuf, nas_mobile_identity_t *mobile_identity);
/* 9.9.3.9 EMM cause
* O TV 2 */
#define NAS_EMM_CAUSE_IMSI_UNKNOWN_IN_HSS 0b00000010
#define NAS_EMM_CAUSE_ILLEGAL_UE 0b00000011
#define NAS_EMM_CAUSE_IMEI_NOT_ACCEPTED 0b00000101
#define NAS_EMM_CAUSE_ILLEGAL_ME 0b00000110
#define NAS_EMM_CAUSE_EPS_SERVICES_NOT_ALLOWED 0b00000111
#define NAS_EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED 0b00001000
#define NAS_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK 0b00001001
#define NAS_EMM_CAUSE_IMPLICITLY_DETACHED 0b00001010
#define NAS_EMM_CAUSE_PLMN_NOT_ALLOWED 0b00001011
#define NAS_EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED 0b00001100
#define NAS_EMM_CAUSE_ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA 0b00001101
#define NAS_EMM_CAUSE_EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN 0b00001110
#define NAS_EMM_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA 0b00001111
#define NAS_EMM_CAUSE_MSC_TEMPORARILY_NOT_REACHABLE 0b00010000
#define NAS_EMM_CAUSE_NETWORK_FAILURE 0b00010001
#define NAS_EMM_CAUSE_CS_DOMAIN_NOT_AVAILABLE 0b00010010
#define NAS_EMM_CAUSE_ESM_FAILURE 0b00010011
#define NAS_EMM_CAUSE_MAC_FAILURE 0b00010100
#define NAS_EMM_CAUSE_SYNCH_FAILURE 0b00010101
#define NAS_EMM_CAUSE_CONGESTION 0b00010110
#define NAS_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH 0b00010111
#define NAS_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED 0b00011000
#define NAS_EMM_CAUSE_NOT_AUTHORIZED_FOR_THIS_CSG 0b00011001
#define NAS_EMM_CAUSE_NON_EPS_AUTHENTICATION_UNACCEPTABLE 0b00011010
#define NAS_EMM_CAUSE_REQUESTED_SERVICE_OPTION_NOT_AUTHORIZED_IN_THIS_PLMN 0b00100011
#define NAS_EMM_CAUSE_CS_SERVICE_TEMPORARILY_NOT_AVAILABLE 0b00100111
#define NAS_EMM_CAUSE_NO_EPS_BEARER_CONTEXT_ACTIVATED 0b00101000
#define NAS_EMM_CAUSE_SEVERE_NETWORK_FAILURE 0b00101010
#define NAS_EMM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE 0b01011111
#define NAS_EMM_CAUSE_INVALID_MANDATORY_INFORMATION 0b01100000
#define NAS_EMM_CAUSE_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED 0b01100001
#define NAS_EMM_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_THE_PROTOCOL_STATE 0b01100010
#define NAS_EMM_CAUSE_INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED 0b01100011
#define NAS_EMM_CAUSE_CONDITIONAL_IE_ERROR 0b01100100
#define NAS_EMM_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_THE_PROTOCOL_STATE 0b01100101
#define NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED 0b01101111
typedef c_uint8_t nas_emm_cause_t;
CORE_DECLARE(c_int32_t) nas_encode_emm_cause(
pkbuf_t *pkbuf, nas_emm_cause_t *emm_cause);
/* 9.9.2.8 PLMN list
* See subclause 10.5.1.13 in 3GPP TS 24.008 [13].
* O TLV 5-47 */
#define NAS_MAX_PLMN 15
typedef struct _nas_plmn_t {
ED2(c_uint8_t mcc_digit2:4;,
c_uint8_t mcc_digit1:4;)
ED2(c_uint8_t mnc_digit3:4;,
c_uint8_t mcc_digit3:4;)
ED2(c_uint8_t mnc_digit2:4;,
c_uint8_t mnc_digit1:4;)
} __attribute__ ((packed)) nas_plmn_t;
typedef struct _nas_plmn_list_t {
c_uint8_t length;
nas_plmn_t plmn[NAS_MAX_PLMN];
} __attribute__ ((packed)) nas_plmn_list_t;
CORE_DECLARE(status_t) nas_encode_plmn_list(
pkbuf_t *pkbuf, nas_plmn_list_t *plmn_list);
/* 9.9.3.12A EPS network feature support
* O TLV 3 */
typedef struct _nas_eps_network_feature_support_t {
c_uint8_t length;
ED7(c_uint8_t cp_ciot:1;,
c_uint8_t erw_opdn:1;,
c_uint8_t esr_ps:1;,
c_uint8_t cs_lcs:2;,
c_uint8_t epc_lcs:1;,
c_uint8_t emc_bs:1;,
c_uint8_t ims_vops:1;)
ED5(c_uint8_t spare:4;,
c_uint8_t e_pco:1;,
c_uint8_t hc_cp_ciot:1;,
c_uint8_t s1_u_data:1;,
c_uint8_t up_ciot :1;)
} __attribute__ ((packed)) nas_eps_network_feature_support_t;
CORE_DECLARE(c_int32_t) nas_encode_eps_network_feature_support(
pkbuf_t *pkbuf,
nas_eps_network_feature_support_t *eps_network_feature_support);
/* 9.9.3.0A Additional update result
* O TV 1 */
typedef struct _nas_additional_update_result_t {
ED3(c_uint8_t type:4;,
c_uint8_t spare:2;,
c_uint8_t additional_update_result_value:2;)
} __attribute__ ((packed)) nas_additional_update_result_t;
CORE_DECLARE(c_int32_t) nas_encode_additional_update_result(
pkbuf_t *pkbuf,
nas_additional_update_result_t *additional_update_result);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -8,7 +8,7 @@ status_t nas_decode_attach_request(nas_message_t *message, pkbuf_t *pkbuf)
nas_attach_request_t *attach_request = &message->emm.attach_request;
status_t rv;
rv = nas_decode_attach_info(&attach_request->attach_info, pkbuf);
rv = nas_decode_attach_type(&attach_request->attach_type, pkbuf);
d_assert(rv == CORE_OK, return CORE_ERROR, "decode failed");
rv = nas_decode_eps_mobile_identity(
@ -171,8 +171,8 @@ status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf)
{
status_t rv = CORE_ERROR;
nas_security_header_t *security_header = NULL;
nas_header_t *header = NULL;
c_uint16_t length = pkbuf->len;
c_uint16_t decoded = pkbuf->len;
c_uint16_t size = 0;
d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(pkbuf->payload, return CORE_ERROR, "Null param");
@ -184,12 +184,15 @@ status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf)
rv = pkbuf_header(pkbuf, -(c_int16_t)(sizeof(nas_security_header_t)));
d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error");
}
header = pkbuf->payload;
rv = pkbuf_header(pkbuf, -(c_int16_t)(sizeof(nas_header_t)));
d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error");
memset(message, 0, sizeof(nas_message_t));
switch(header->message_type)
size = sizeof(nas_header_t);
rv = pkbuf_header(pkbuf, -size);
d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error");
memcpy(&message->h, pkbuf->payload - size, size);
switch(message->h.message_type)
{
case NAS_ATTACH_REQUEST:
rv = nas_decode_attach_request(message, pkbuf);
@ -250,11 +253,128 @@ status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf)
break;
default:
d_error("Unknown message type (%d) or not implemented",
header->message_type);
message->h.message_type);
break;
}
rv = pkbuf_header(pkbuf, length);
rv = pkbuf_header(pkbuf, decoded);
d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error");
return CORE_OK;
}
c_int32_t nas_encode_attach_accept(pkbuf_t *pkbuf, nas_message_t *message)
{
nas_attach_accept_t *attach_accept = &message->emm.attach_accept;
c_int32_t size = 0;
c_int32_t encoded = 0;
size = nas_encode_attach_result(pkbuf, &attach_accept->attach_result);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
size = nas_encode_gprs_timer(pkbuf, &attach_accept->t3412_value);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
size = nas_encode_tracking_area_identity_list(pkbuf,
&attach_accept->tai_list);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
size = nas_encode_esm_message_container(pkbuf,
&attach_accept->esm_message_container);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
return encoded;
}
status_t nas_encode_pdu(pkbuf_t **pkbuf, nas_message_t *message)
{
status_t rv = CORE_ERROR;
c_int32_t size = 0;
c_int32_t encoded = 0;
d_assert(message, return CORE_ERROR, "Null param");
*pkbuf = pkbuf_alloc(0, NAS_SDU_SIZE);
d_assert(*pkbuf, return -1, "Null Param");
size = sizeof(nas_header_t);
rv = pkbuf_header(*pkbuf, -size);
d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error");
memcpy((*pkbuf)->payload - size, &message->h, size);
encoded += size;
switch(message->h.message_type)
{
case NAS_ATTACH_REQUEST:
break;
case NAS_ATTACH_ACCEPT:
size = nas_encode_attach_accept(*pkbuf, message);
d_assert(size >= 0, return CORE_ERROR, "decode error");
encoded += size;
break;
case NAS_ATTACH_COMPLETE:
case NAS_ATTACH_REJECT:
case NAS_DETACH_REQUEST:
case NAS_DETACH_ACCEPT:
case NAS_TRACKING_AREA_UPDATE_REQUEST:
case NAS_TRACKING_AREA_UPDATE_ACCEPT:
case NAS_TRACKING_AREA_UPDATE_COMPLETE:
case NAS_TRACKING_AREA_UPDATE_REJECT:
case NAS_EXTENDED_SERVICE_REQUEST:
case NAS_SERVICE_REJECT:
case NAS_GUTI_REALLOCATION_COMMAND:
case NAS_GUTI_REALLOCATION_COMPLETE:
case NAS_AUTHENTICATION_REQUEST:
case NAS_AUTHENTICATION_RESPONSE:
case NAS_AUTHENTICATION_REJECT:
case NAS_AUTHENTICATION_FAILURE:
case NAS_IDENTITY_REQUEST:
case NAS_IDENTITY_RESPONSE:
case NAS_SECURITY_MODE_COMMAND:
case NAS_SECURITY_MODE_COMPLETE:
case NAS_SECURITY_MODE_REJECT:
case NAS_EMM_STATUS:
case NAS_EMM_INFORMATION:
case NAS_DOWNLINK_NAS_TRANSPORT:
case NAS_UPLINK_NAS_TRANSPORT:
case NAS_CS_SERVICE_NOTIFICATION:
case NAS_DOWNLINK_GENERIC_NAS_TRANSPORT:
case NAS_UPLINK_GENERIC_NAS_TRANSPORT:
case NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST:
case NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT:
case NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT:
case NAS_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST:
case NAS_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT:
case NAS_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT:
case NAS_MODIFY_EPS_BEARER_CONTEXT_REQUEST:
case NAS_MODIFY_EPS_BEARER_CONTEXT_ACCEPT:
case NAS_MODIFY_EPS_BEARER_CONTEXT_REJECT:
case NAS_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST:
case NAS_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT:
case NAS_PDN_CONNECTIVITY_REQUEST:
case NAS_PDN_CONNECTIVITY_REJECT:
case NAS_PDN_DISCONNECT_REQUEST:
case NAS_PDN_DISCONNECT_REJECT:
case NAS_BEARER_RESOURCE_ALLOCATION_REQUEST:
case NAS_BEARER_RESOURCE_ALLOCATION_REJECT:
case NAS_BEARER_RESOURCE_MODIFICATION_REQUEST:
case NAS_BEARER_RESOURCE_MODIFICATION_REJECT:
case NAS_ESM_INFORMATION_REQUEST:
case NAS_ESM_INFORMATION_RESPONSE:
case NAS_ESM_STATUS:
break;
default:
d_error("Unknown message type (%d) or not implemented",
message->h.message_type);
break;
}
rv = pkbuf_header(*pkbuf, encoded);
d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error");
return CORE_OK;

View File

@ -87,6 +87,65 @@ ED2(c_uint8_t security_header_type:4;,
#define NAS_ESM_INFORMATION_RESPONSE 218
#define NAS_ESM_STATUS 232
#define NAS_ATTACH_ACCEPT_GUTI_PRESENT (1<<0)
#define NAS_ATTACH_ACCEPT_LOCATION_AREA_IDENTIFICATION_PRESENT (1<<1)
#define NAS_ATTACH_ACCEPT_MS_IDENTITY_PRESENT (1<<2)
#define NAS_ATTACH_ACCEPT_EMM_CAUSE_PRESENT (1<<3)
#define NAS_ATTACH_ACCEPT_T3402_VALUE_PRESENT (1<<4)
#define NAS_ATTACH_ACCEPT_T3423_VALUE_PRESENT (1<<5)
#define NAS_ATTACH_ACCEPT_EQUIVALENT_PLMNS_PRESENT (1<<6)
#define NAS_ATTACH_ACCEPT_EMERGENCY_NUMBER_LIST_PRESENT (1<<7)
#define NAS_ATTACH_ACCEPT_EPS_NETWORK_FEATURE_SUPPORT_PRESENT (1<<8)
#define NAS_ATTACH_ACCEPT_ADDITIONAL_UPDATE_RESULT_PRESENT (1<<9)
#define NAS_ATTACH_ACCEPT_T3412_EXTENDED_VALUE_PRESENT (1<<10)
#define NAS_ATTACH_ACCEPT_T3324_VALUE_PRESENT (1<<11)
#define NAS_ATTACH_ACCEPT_EXTENDED_DRX_PARAMETERS_PRESENT (1<<12)
#define NAS_ATTACH_ACCEPT_GUTI_IEI 0x50
#define NAS_ATTACH_ACCEPT_LOCATION_AREA_IDENTIFICATION_IEI 0x13
#define NAS_ATTACH_ACCEPT_MS_IDENTITY_IEI 0x23
#define NAS_ATTACH_ACCEPT_EMM_CAUSE_IEI 0x53
#define NAS_ATTACH_ACCEPT_T3402_VALUE_IEI 0x17
#define NAS_ATTACH_ACCEPT_T3423_VALUE_IEI 0x59
#define NAS_ATTACH_ACCEPT_EQUIVALENT_PLMNS_IEI 0x4A
#define NAS_ATTACH_ACCEPT_EMERGENCY_NUMBER_LIST_IEI 0x34
#define NAS_ATTACH_ACCEPT_EPS_NETWORK_FEATURE_SUPPORT_IEI 0x64
#define NAS_ATTACH_ACCEPT_ADDITIONAL_UPDATE_RESULT_IEI 0xF0
#define NAS_ATTACH_ACCEPT_T3412_EXTENDED_VALUE_IEI 0x5E
#define NAS_ATTACH_ACCEPT_T3324_VALUE_IEI 0x6A
#define NAS_ATTACH_ACCEPT_EXTENDED_DRX_PARAMETERS_IEI 0x6E
/* 8.2.1 Attach accept */
typedef struct _nas_attach_accept_t {
/* Mandatory fields */
nas_attach_result_t attach_result;
nas_gprs_timer_t t3412_value;
nas_tracking_area_identity_list_t tai_list;
nas_esm_message_container_t esm_message_container;
/* Optional fields */
c_uint32_t presencemask;
nas_eps_mobile_identity_t guti;
nas_location_area_identification_t location_area_identification;
nas_mobile_identity_t ms_identity;
nas_emm_cause_t emm_cause;
nas_gprs_timer_t t3402_value;
nas_gprs_timer_t t3423_value;
nas_plmn_list_t equivalent_plmns;
/* 9.9.3.37 Emergency number list
* See subclause 10.5.3.13 in 3GPP TS 24.008 [13].
* O TLV 5-50
nas_emergency_number_list_t emergency_number_list; */
nas_eps_network_feature_support_t eps_network_feature_support;
nas_additional_update_result_t additional_update_result;
nas_gprs_timer_3_t t3412_extended_value;
nas_gprs_timer_2_t t3324_value;
nas_extended_drx_parameters_t extended_drx_parameters;
} nas_attach_accept_t;
/* 8.2.4 Attach request */
#define NAS_ATTACH_REQUEST_OLD_P_TMSI_SIGNATURE_PRESENT (1<<0)
#define NAS_ATTACH_REQUEST_ADDITIONAL_GUTI_PRESENT (1<<1)
#define NAS_ATTACH_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT (1<<2)
@ -103,9 +162,9 @@ ED2(c_uint8_t security_header_type:4;,
#define NAS_ATTACH_REQUEST_OLD_GUTI_TYPE_PRESENT (1<<13)
#define NAS_ATTACH_REQUEST_MS_NETWORK_FEATURE_SUPPORT_PRESENT (1<<14)
#define NAS_ATTACH_REQUEST_TMSI_BASED_NRI_CONTAINER_PRESENT (1<<15)
#define NAS_ATTACH_REQUEST_T3324_VALUE_PRESENT (1<16)
#define NAS_ATTACH_REQUEST_T3412_EXTENDED_VALUE_PRESENT (1<17)
#define NAS_ATTACH_REQUEST_EXTENDED_DRX_PARAMETERS_PRESENT (1<18)
#define NAS_ATTACH_REQUEST_T3324_VALUE_PRESENT (1<<16)
#define NAS_ATTACH_REQUEST_T3412_EXTENDED_VALUE_PRESENT (1<<17)
#define NAS_ATTACH_REQUEST_EXTENDED_DRX_PARAMETERS_PRESENT (1<<18)
#define NAS_ATTACH_REQUEST_OLD_P_TMSI_SIGNATURE_IEI 0x19
#define NAS_ATTACH_REQUEST_ADDITIONAL_GUTI_IEI 0x50
@ -129,7 +188,7 @@ ED2(c_uint8_t security_header_type:4;,
typedef struct _nas_attach_request_t {
/* Mandatory fields */
nas_attach_info_t attach_info;
nas_attach_type_t attach_type;
nas_eps_mobile_identity_t eps_mobile_identity;
nas_ue_network_capability_t ue_network_capability;
nas_esm_message_container_t esm_message_container;
@ -158,9 +217,11 @@ typedef struct _nas_attach_request_t {
nas_extended_drx_parameters_t extended_drx_parameters;
} nas_attach_request_t;
typedef union _nas_message_t {
typedef struct _nas_message_t {
nas_header_t h;
union {
nas_attach_request_t attach_request;
nas_attach_accept_t attach_accept;
} emm;
} nas_message_t;

View File

@ -32,11 +32,54 @@ static void nas_message_test1(abts_case *tc, void *data)
pkbuf_free(pkbuf);
}
static void nas_message_test2(abts_case *tc, void *data)
{
/* Attach Accept */
char *payload[] = {
"\x07\x42\x02\x23\x06\x00\x14\xf7\x99\x30\x39\x00\x32\x52\x01\xc1\x01\x09\x09\x08\x69\x6e\x74\x65\x72\x6e\x65\x74\x05\x01\x0a\xe1\x00\x0a\x27\x1b\x80\x80\x21\x10\x02\x02\x00\x10\x81\x06\xc0\xa8\xa8\x01\x83\x06\xc0\xa8\xa8\x01\x00\x0d\x04\xc0\xa8\xa8\x01\x50\x0b\xf6\x14\xf7\x99\x23\x45\xe1\x00\x00\x04\x56\x13\x00\xf1\x20\xff\xfd\x23\x05\xf4\x00\xe1\x02\xd4\x64\x01\x23"
};
char *esm_payload[] = {
"\x52\x01\xc1\x01\x09\x09\x08\x69\x6e\x74\x65\x72\x6e\x65\x74\x05\x01\x0a\xe1\x00\x0a\x27\x1b\x80\x80\x21\x10\x02\x02\x00\x10\x81\x06\xc0\xa8\xa8\x01\x83\x06\xc0\xa8\xa8\x01\x00\x0d\x04\xc0\xa8\xa8\x01"
};
nas_message_t message;
nas_attach_accept_t *attach_accept = &message.emm.attach_accept;
pkbuf_t *pkbuf = NULL;
status_t rv;
memset(&message, 0, sizeof(message));
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.h.message_type = NAS_ATTACH_ACCEPT;
attach_accept->attach_result.result =
NAS_ATTACH_RESULT_COMBINED_EPS_IMSI_ATTACH;
attach_accept->t3412_value.unit =
NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM;
attach_accept->t3412_value.timer_value = 3;
attach_accept->tai_list.length = 6;
attach_accept->tai_list.u.type0.mcc_digit1 = 4;
attach_accept->tai_list.u.type0.mcc_digit2 = 1;
attach_accept->tai_list.u.type0.mcc_digit3 = 7;
attach_accept->tai_list.u.type0.mnc_digit1 = 9;
attach_accept->tai_list.u.type0.mnc_digit2 = 9;
attach_accept->tai_list.u.type0.mnc_digit2 = 0xf;
attach_accept->tai_list.u.type0.tac[0] = 12345;
attach_accept->esm_message_container.length = 50;
attach_accept->esm_message_container.buffer = (c_uint8_t*)esm_payload[0];
rv = nas_encode_pdu(&pkbuf, &message);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
pkbuf_free(pkbuf);
}
abts_suite *test_nas_message(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, nas_message_test1, NULL);
abts_run_test(suite, nas_message_test2, NULL);
return suite;
}