diff --git a/lib/nas/5gs/types.h b/lib/nas/5gs/types.h index f643cd21c..42dfdbeff 100644 --- a/lib/nas/5gs/types.h +++ b/lib/nas/5gs/types.h @@ -728,8 +728,52 @@ ED3(uint8_t type:4;, /* 9.11.4.12 QoS flow descriptions * O TLV-E 6-65535 */ +typedef struct ogs_nas_qos_flow_parameter_s { +#define OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI 1 +#define OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_UPLINK 2 +#define OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_DOWNLINK 3 +#define OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_UPLINK 4 +#define OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_DOWNLINK 5 +#define OGS_NAX_QOS_FLOW_PARAMETER_ID_AVERAGING_WINDOW 6 +#define OGS_NAX_QOS_FLOW_PARAMETER_ID_EPS_BEARER_IDENTITY 7 + uint8_t identifier; + uint8_t len; +#define OGS_NAS_MAX_QOS_FLOW_PARAEMTER_LEN 255 + uint8_t content[OGS_NAS_MAX_QOS_FLOW_PARAEMTER_LEN]; +} ogs_nas_qos_flow_parameter_t; + +typedef struct ogs_nas_qos_flow_description_s { +ED2(uint8_t spare1:2;, + uint8_t identifier:6;) +#define OGS_NAS_CREATE_NEW_QOS_FLOW_DESCRIPTION 1 +#define OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION 2 +#define OGS_NAS_MODIFY_NEW_QOS_FLOW_DESCRIPTION 3 +ED2(uint8_t code:3;, + uint8_t spare2:5;) +ED3(uint8_t spare3:1;, +/* + * For the "create new QoS flow description" operation, + * the E bit is encoded as follows: + * 0 reserved + * 1 parameters list is included + * + * For the "Delete existing QoS flow description" operation, + * 0 parameters list is not included + * 1 reserved + * + * For the "modify existing QoS flow description" operation, + * 0 extension of previously provided parameters + * 1 replacement of all previously provided parameters + */ + uint8_t E:1;, + uint8_t num_of_parameter:6;) + +#define OGS_NAS_MAX_NUM_OF_QOS_FLOW_PARAMETER 8 + ogs_nas_qos_flow_parameter_t param[OGS_NAS_MAX_NUM_OF_QOS_FLOW_PARAMETER]; +} ogs_nas_qos_flow_description_t; + typedef struct ogs_nas_qos_flow_descriptions_s { - uint8_t length; + uint16_t length; void *buffer; } ogs_nas_qos_flow_descriptions_t; diff --git a/lib/nas/common/types.h b/lib/nas/common/types.h index ec6713b6f..1b29ebb4d 100644 --- a/lib/nas/common/types.h +++ b/lib/nas/common/types.h @@ -64,8 +64,6 @@ extern "C" { memcpy((__dST)->buffer, (__sRC)->buffer, (__dST)->length); \ } while(0) -#define OGS_NAS_KSI_NO_KEY_IS_AVAILABLE 0x7 - /**************************** * NAS Security Header Type */ typedef struct ogs_nas_security_header_type_s { @@ -311,6 +309,7 @@ ED3(uint8_t type:4;, typedef struct ogs_nas_key_set_identifier_s { ED3(uint8_t type:4;, uint8_t tsc:1;, +#define OGS_NAS_KSI_NO_KEY_IS_AVAILABLE 0x7 uint8_t value:3;) } __attribute__ ((packed)) ogs_nas_key_set_identifier_t; @@ -463,23 +462,29 @@ typedef struct ogs_nas_ue_network_capability_s { }; uint8_t uia; }; -ED8(uint8_t prose_dd:1;, +ED8(uint8_t prose_direct_discovery:1;, uint8_t prose:1;, - uint8_t h_245_ash:1;, - uint8_t acc_csfb:1;, - uint8_t lpp:1;, - uint8_t lcs:1;, - uint8_t srvcc:1;, - uint8_t nf:1;) -ED8(uint8_t epco:1;, - uint8_t hc_cp_ciot:1;, - uint8_t erw_opdn:1;, - uint8_t s1u_data:1;, - uint8_t up_ciot:1;, - uint8_t cp_ciot:1;, - uint8_t prose_relay:1;, - uint8_t prose_dc:1;) -ED2(uint8_t spare:7;, + uint8_t h_245_after_srvcc_handover:1;, + uint8_t access_class_control_for_csdb:1;, + uint8_t lte_positioning_protocol:1;, + uint8_t location_service_notification_mechanisms:1;, + uint8_t srvcc_from_e_utran_to_cdma2000:1;, + uint8_t notification_procedure:1;) +ED8(uint8_t extended_protocol_configuration_options:1;, + uint8_t hedaer_compression_for_control_plane_ciot_eps_optimization:1;, + uint8_t emm_registered_without_pdn_connectivity:1;, + uint8_t s1_u_data_transfer:1;, + uint8_t user_plane_ciot_eps_optimization:1;, + uint8_t control_plane_ciot_eps_optimization:1;, + uint8_t prose_ue_to_network_relay:1;, + uint8_t prose_direct_communication:1;) +ED8(uint8_t signalling_for_a_maximum_number_of_15_eps_bearer_contexts:1;, + uint8_t service_gap_control:1;, + uint8_t n1_mode:1;, + uint8_t dual_connectivity_with_nr:1;, + uint8_t control_plane_data_backoff:1;, + uint8_t retstriction_on_use_of_enhanced_coverage:1;, + uint8_t v2x_communication_over_pc5:1;, uint8_t multiple_drb:1;) } __attribute__ ((packed)) ogs_nas_ue_network_capability_t; diff --git a/src/amf/context.c b/src/amf/context.c index f92f944fb..b1a88676d 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -1568,7 +1568,7 @@ int amf_find_served_tai(ogs_5gs_tai_t *tai) } ogs_s_nssai_t *amf_find_s_nssai( - ogs_plmn_id_t *served_plmn_id, ogs_nas_s_nssai_t *s_nssai) + ogs_plmn_id_t *served_plmn_id, ogs_s_nssai_t *s_nssai) { int i, j; @@ -1584,8 +1584,9 @@ ogs_s_nssai_t *amf_find_s_nssai( if (amf_self()->plmn_support[i].s_nssai[j].sst != s_nssai->sst) continue; - if (s_nssai->length > 1 && - s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) { + if (amf_self()->plmn_support[i].s_nssai[j].sd.v != + OGS_S_NSSAI_NO_SD_VALUE && + s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) { if (amf_self()->plmn_support[i].s_nssai[j].sd.v != s_nssai->sd.v) continue; diff --git a/src/amf/context.h b/src/amf/context.h index 58a40c54a..a34c353b3 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -144,7 +144,15 @@ typedef struct amf_gnb_s { uint8_t num_of_supported_ta_list; - ogs_5gs_tai_t supported_ta_list[OGS_MAX_NUM_OF_TAI*OGS_MAX_NUM_OF_BPLMN]; + struct { + ogs_uint24_t tac; + uint8_t num_of_bplmn_list; + struct { + ogs_plmn_id_t plmn_id; + uint8_t num_of_s_nssai; + ogs_s_nssai_t s_nssai[OGS_MAX_NUM_OF_S_NSSAI]; + } bplmn_list[OGS_MAX_NUM_OF_BPLMN]; + } supported_ta_list[OGS_MAX_NUM_OF_TAI]; ogs_list_t ran_ue_list; @@ -274,6 +282,7 @@ struct amf_ue_s { /* Security Context */ ogs_nas_ue_security_capability_t ue_security_capability; + ogs_nas_ue_network_capability_t ue_network_capability; char *confirmation_url_for_5g_aka; uint8_t rand[OGS_RAND_LEN]; uint8_t autn[OGS_AUTN_LEN]; @@ -511,7 +520,7 @@ amf_sess_t *amf_sess_find_by_dnn(amf_ue_t *amf_ue, char *dnn); int amf_find_served_tai(ogs_5gs_tai_t *tai); ogs_s_nssai_t *amf_find_s_nssai( - ogs_plmn_id_t *served_plmn_id, ogs_nas_s_nssai_t *s_nssai); + ogs_plmn_id_t *served_plmn_id, ogs_s_nssai_t *s_nssai); int amf_m_tmsi_pool_generate(void); amf_m_tmsi_t *amf_m_tmsi_alloc(void); diff --git a/src/amf/gmm-build.c b/src/amf/gmm-build.c index 68983df98..ebe9b7ed7 100644 --- a/src/amf/gmm-build.c +++ b/src/amf/gmm-build.c @@ -26,16 +26,21 @@ ogs_pkbuf_t *gmm_build_registration_accept(amf_ue_t *amf_ue) { - ogs_nas_5gs_message_t message; + int i, j; + int served_tai_index = 0; ogs_pkbuf_t *pkbuf = NULL; - ogs_nas_5gs_registration_accept_t *registration_accept = &message.gmm.registration_accept; + + ogs_nas_5gs_message_t message; + ogs_nas_5gs_registration_accept_t *registration_accept = + &message.gmm.registration_accept; ogs_nas_5gs_registration_result_t *registration_result = ®istration_accept->registration_result; - ogs_nas_5gs_mobile_identity_t *mobile_identity = ®istration_accept->guti; + ogs_nas_5gs_mobile_identity_t *mobile_identity = + ®istration_accept->guti; ogs_nas_5gs_mobile_identity_guti_t mobile_identity_guti; - int served_tai_index = 0; ogs_nas_nssai_t *allowed_nssai = ®istration_accept->allowed_nssai; - int i, j; + ogs_nas_5gs_network_feature_support_t *network_feature_support = + ®istration_accept->network_feature_support; ogs_nas_gprs_timer_3_t *t3512_value = ®istration_accept->t3512_value; ogs_assert(amf_ue); @@ -127,6 +132,12 @@ ogs_pkbuf_t *gmm_build_registration_accept(amf_ue_t *amf_ue) registration_accept->presencemask |= OGS_NAS_5GS_REGISTRATION_ACCEPT_ALLOWED_NSSAI_PRESENT; } + /* 5GS network feature support */ + registration_accept->presencemask |= + OGS_NAS_5GS_REGISTRATION_ACCEPT_5GS_NETWORK_FEATURE_SUPPORT_PRESENT; + network_feature_support->length = 1; + network_feature_support->ims_vops_3gpp = 1; + /* Set T3512 */ registration_accept->presencemask |= OGS_NAS_5GS_REGISTRATION_ACCEPT_T3512_VALUE_PRESENT; t3512_value->length = 1; @@ -284,7 +295,6 @@ ogs_pkbuf_t *gmm_build_security_mode_command(amf_ue_t *amf_ue) sizeof(replayed_ue_security_capabilities->nia) + sizeof(replayed_ue_security_capabilities->eps_ea) + sizeof(replayed_ue_security_capabilities->eps_ia); - replayed_ue_security_capabilities->length = 8; ogs_debug(" Replayed UE SEC[LEN:%d NEA:0x%x NIA:0x%x EEA:0x%x EIA:0x%x", replayed_ue_security_capabilities->length, replayed_ue_security_capabilities->nea, diff --git a/src/amf/gmm-handler.c b/src/amf/gmm-handler.c index 04994e89f..35a20084a 100644 --- a/src/amf/gmm-handler.c +++ b/src/amf/gmm-handler.c @@ -39,6 +39,7 @@ int gmm_handle_registration_request(amf_ue_t *amf_ue, ogs_nas_5gs_mobile_identity_t *mobile_identity = NULL; ogs_nas_5gs_mobile_identity_header_t *mobile_identity_header = NULL; ogs_nas_5gs_mobile_identity_guti_t *mobile_identity_guti = NULL; + ogs_nas_ue_security_capability_t *ue_security_capability = NULL; ogs_nas_5gs_guti_t nas_guti; ogs_assert(amf_ue); @@ -50,6 +51,8 @@ int gmm_handle_registration_request(amf_ue_t *amf_ue, ogs_assert(registration_type); mobile_identity = ®istration_request->mobile_identity; ogs_assert(mobile_identity); + ue_security_capability = ®istration_request->ue_security_capability; + ogs_assert(ue_security_capability); if (!mobile_identity->length || !mobile_identity->buffer) { ogs_error("No Mobile Identity"); @@ -178,16 +181,25 @@ int gmm_handle_registration_request(amf_ue_t *amf_ue, if (registration_request->presencemask & OGS_NAS_5GS_REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT) { - memcpy(&amf_ue->ue_security_capability, + memcpy(&amf_ue->ue_security_capability, ®istration_request->ue_security_capability, - ogs_min(sizeof(amf_ue->ue_security_capability), - registration_request->ue_security_capability.length)); + registration_request->ue_security_capability.length + + sizeof(registration_request->ue_security_capability.length)); + } + + if (registration_request->presencemask & + OGS_NAS_5GS_REGISTRATION_REQUEST_S1_UE_NETWORK_CAPABILITY_PRESENT) { + memcpy(&amf_ue->ue_network_capability, + ®istration_request->s1_ue_network_capability, + registration_request->s1_ue_network_capability.length + + sizeof(registration_request->s1_ue_network_capability.length)); } if (amf_selected_int_algorithm(amf_ue) == OGS_NAS_SECURITY_ALGORITHMS_NIA0) { - ogs_warn("[%s] NEA0 can be used in Encrypt[0x%x], " + ogs_error("[%s] [UE:0x%x:0x%x], NEA0 can be used in Encrypt[0x%x], " "but Integrity[0x%x] cannot be bypassed with NIA0", amf_ue->suci, + ue_security_capability->nea, ue_security_capability->nia, amf_selected_enc_algorithm(amf_ue), amf_selected_int_algorithm(amf_ue)); nas_5gs_send_registration_reject(amf_ue, @@ -765,7 +777,7 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue, ogs_nas_payload_container_type_t *payload_container_type = NULL; ogs_nas_payload_container_t *payload_container = NULL; ogs_nas_pdu_session_identity_2_t *pdu_session_id = NULL; - ogs_nas_s_nssai_t *s_nssai = NULL; + ogs_nas_s_nssai_t *nas_s_nssai = NULL; ogs_s_nssai_t *selected_s_nssai = NULL; ogs_nas_dnn_t *dnn = NULL; @@ -798,8 +810,8 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue, case OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION: pdu_session_id = &ul_nas_transport->pdu_session_id; ogs_assert(pdu_session_id); - s_nssai = &ul_nas_transport->s_nssai; - ogs_assert(s_nssai); + nas_s_nssai = &ul_nas_transport->s_nssai; + ogs_assert(nas_s_nssai); dnn = &ul_nas_transport->dnn; ogs_assert(dnn); @@ -833,8 +845,13 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue, if (ul_nas_transport->presencemask & OGS_NAS_5GS_UL_NAS_TRANSPORT_S_NSSAI_PRESENT) { - s_nssai->sd = ogs_be24toh(s_nssai->sd); - selected_s_nssai = amf_find_s_nssai(&amf_ue->tai.plmn_id, s_nssai); + ogs_s_nssai_t s_nssai; + s_nssai.sst = nas_s_nssai->sst; + if (nas_s_nssai->length > 1) + s_nssai.sd = ogs_be24toh(nas_s_nssai->sd); + else + s_nssai.sd.v = OGS_S_NSSAI_NO_SD_VALUE; + selected_s_nssai = amf_find_s_nssai(&amf_ue->tai.plmn_id, &s_nssai); } if (!selected_s_nssai) { diff --git a/src/amf/nausf-handler.c b/src/amf/nausf-handler.c index 227c37a7b..ce4fb34c3 100644 --- a/src/amf/nausf-handler.c +++ b/src/amf/nausf-handler.c @@ -103,6 +103,9 @@ int amf_nausf_auth_handle_authenticate( ogs_ascii_to_hex(AV5G_AKA->autn, strlen(AV5G_AKA->autn), amf_ue->autn, sizeof(amf_ue->autn)); + if (amf_ue->nas.ksi == OGS_NAS_KSI_NO_KEY_IS_AVAILABLE) + amf_ue->nas.ksi = 0; + nas_5gs_send_authentication_request(amf_ue); return OGS_OK; diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index 37f8f9949..b5437c22b 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -22,15 +22,59 @@ static bool served_tai_is_found(amf_gnb_t *gnb) { - int i; + int i, j; int served_tai_index; for (i = 0; i < gnb->num_of_supported_ta_list; i++) { - served_tai_index = amf_find_served_tai(&gnb->supported_ta_list[i]); - if (served_tai_index >= 0 && - served_tai_index < OGS_MAX_NUM_OF_SERVED_TAI) { - ogs_debug(" SERVED_TAI_INDEX[%d]", served_tai_index); - return true; + for (j = 0; j < gnb->supported_ta_list[i].num_of_bplmn_list; j++) { + ogs_5gs_tai_t tai; + memcpy(&tai.plmn_id, + &gnb->supported_ta_list[i].bplmn_list[j].plmn_id, + OGS_PLMN_ID_LEN); + tai.tac.v = gnb->supported_ta_list[i].tac.v; + served_tai_index = amf_find_served_tai(&tai); + if (served_tai_index >= 0 && + served_tai_index < OGS_MAX_NUM_OF_SERVED_TAI) { + ogs_debug(" TAC[%d]", gnb->supported_ta_list[i].tac.v); + ogs_debug(" PLMN_ID[MCC:%d MNC:%d]", + ogs_plmn_id_mcc(&gnb->supported_ta_list[i]. + bplmn_list[j].plmn_id), + ogs_plmn_id_mnc(&gnb->supported_ta_list[i]. + bplmn_list[j].plmn_id)); + ogs_debug(" SERVED_TAI_INDEX[%d]", served_tai_index); + return true; + } + } + } + + return false; +} + +static bool s_nssai_is_found(amf_gnb_t *gnb) +{ + int i, j, k; + ogs_s_nssai_t *s_nssai = NULL; + + for (i = 0; i < gnb->num_of_supported_ta_list; i++) { + for (j = 0; j < gnb->supported_ta_list[i].num_of_bplmn_list; j++) { + for (k = 0; k < gnb->supported_ta_list[i]. + bplmn_list[j].num_of_s_nssai; k++) { + s_nssai = amf_find_s_nssai( + &gnb->supported_ta_list[i].bplmn_list[j].plmn_id, + &gnb->supported_ta_list[i].bplmn_list[j].s_nssai[k]); + if (s_nssai) { + ogs_debug(" PLMN_ID[MCC:%d MNC:%d]", + ogs_plmn_id_mcc(&gnb->supported_ta_list[i]. + bplmn_list[j].plmn_id), + ogs_plmn_id_mnc(&gnb->supported_ta_list[i]. + bplmn_list[j].plmn_id)); + ogs_debug(" S_NSSAI[SST:%d SD:0x%x]", + gnb->supported_ta_list[i].bplmn_list[j].s_nssai[k].sst, + gnb->supported_ta_list[i].bplmn_list[j]. + s_nssai[k].sd.v); + return true; + } + } } } @@ -54,7 +98,7 @@ static bool maximum_number_of_gnbs_is_reached(void) void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message) { char buf[OGS_ADDRSTRLEN]; - int i, j; + int i, j, k; NGAP_InitiatingMessage_t *initiatingMessage = NULL; NGAP_NGSetupRequest_t *NGSetupRequest = NULL; @@ -129,42 +173,102 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message) if (PagingDRX) ogs_debug(" PagingDRX[%ld]", *PagingDRX); - amf_gnb_set_gnb_id(gnb, gnb_id); - /* Parse Supported TA */ - gnb->num_of_supported_ta_list = 0; - for (i = 0; i < SupportedTAList->list.count; i++) { + for (i = 0, gnb->num_of_supported_ta_list = 0; + i < SupportedTAList->list.count && + gnb->num_of_supported_ta_list < OGS_MAX_NUM_OF_TAI; + i++) { NGAP_SupportedTAItem_t *SupportedTAItem = NULL; SupportedTAItem = (NGAP_SupportedTAItem_t *) SupportedTAList->list.array[i]; - ogs_assert(SupportedTAItem); + if (!SupportedTAItem) { + ogs_error("No SupportedTAItem"); + group = NGAP_Cause_PR_protocol; + cause = NGAP_CauseProtocol_semantic_error; + ngap_send_ng_setup_failure(gnb, group, cause); + return; + } + + ogs_asn_OCTET_STRING_to_uint24(&SupportedTAItem->tAC, + &gnb->supported_ta_list[i].tac); + + ogs_debug(" TAC[%d]", gnb->supported_ta_list[i].tac.v); + + for (j = 0, gnb->supported_ta_list[i].num_of_bplmn_list = 0; + j < SupportedTAItem->broadcastPLMNList.list.count && + gnb->supported_ta_list[i].num_of_bplmn_list < + OGS_MAX_NUM_OF_BPLMN; + j++) { - for (j = 0; j < SupportedTAItem->broadcastPLMNList.list.count; j++) { NGAP_BroadcastPLMNItem_t *BroadcastPLMNItem = NULL; NGAP_PLMNIdentity_t *pLMNIdentity = NULL; BroadcastPLMNItem = (NGAP_BroadcastPLMNItem_t *) - SupportedTAItem->broadcastPLMNList.list.array[i]; - ogs_assert(BroadcastPLMNItem); + SupportedTAItem->broadcastPLMNList.list.array[j]; + if (!BroadcastPLMNItem) { + ogs_error("No BroadcastPLMNItem"); + group = NGAP_Cause_PR_protocol; + cause = NGAP_CauseProtocol_semantic_error; + ngap_send_ng_setup_failure(gnb, group, cause); + return; + } + pLMNIdentity = (NGAP_PLMNIdentity_t *) &BroadcastPLMNItem->pLMNIdentity; ogs_assert(pLMNIdentity); - ogs_asn_OCTET_STRING_to_uint24(&SupportedTAItem->tAC, - &gnb->supported_ta_list[gnb->num_of_supported_ta_list].tac); - - memcpy(&gnb->supported_ta_list - [gnb->num_of_supported_ta_list].plmn_id, + memcpy(&gnb->supported_ta_list[i].bplmn_list[j].plmn_id, pLMNIdentity->buf, sizeof(ogs_plmn_id_t)); - ogs_debug(" PLMN_ID[MCC:%d MNC:%d] TAC[%d]", - ogs_plmn_id_mcc(&gnb->supported_ta_list - [gnb->num_of_supported_ta_list].plmn_id), - ogs_plmn_id_mnc(&gnb->supported_ta_list - [gnb->num_of_supported_ta_list].plmn_id), - gnb->supported_ta_list[gnb->num_of_supported_ta_list].tac.v); - gnb->num_of_supported_ta_list++; + ogs_debug(" PLMN_ID[MCC:%d MNC:%d]", + ogs_plmn_id_mcc(&gnb->supported_ta_list[i]. + bplmn_list[j].plmn_id), + ogs_plmn_id_mnc(&gnb->supported_ta_list[i]. + bplmn_list[j].plmn_id)); + + for (k = 0, gnb->supported_ta_list[i]. + bplmn_list[j].num_of_s_nssai = 0; + k < BroadcastPLMNItem->tAISliceSupportList.list.count && + gnb->supported_ta_list[i].bplmn_list[j].num_of_s_nssai < + OGS_MAX_NUM_OF_S_NSSAI; + k++) { + NGAP_SliceSupportItem_t *SliceSupportItem = NULL; + NGAP_S_NSSAI_t *s_NSSAI = NULL; + + SliceSupportItem = (NGAP_SliceSupportItem_t *) + BroadcastPLMNItem->tAISliceSupportList.list.array[k]; + if (!SliceSupportItem) { + ogs_error("No SliceSupportItem"); + group = NGAP_Cause_PR_protocol; + cause = NGAP_CauseProtocol_semantic_error; + ngap_send_ng_setup_failure(gnb, group, cause); + return; + } + + s_NSSAI = &SliceSupportItem->s_NSSAI; + ogs_assert(s_NSSAI); + + ogs_asn_OCTET_STRING_to_uint8(&s_NSSAI->sST, + &gnb->supported_ta_list[i].bplmn_list[j].s_nssai[k].sst); + if (!s_NSSAI->sD) { + gnb->supported_ta_list[i].bplmn_list[j].s_nssai[k].sd.v = + OGS_S_NSSAI_NO_SD_VALUE; + } else { + ogs_asn_OCTET_STRING_to_uint24(s_NSSAI->sD, + &gnb->supported_ta_list[i].bplmn_list[j].s_nssai[k].sd); + } + + ogs_debug(" S_NSSAI[SST:%d SD:0x%x]", + gnb->supported_ta_list[i].bplmn_list[j].s_nssai[k].sst, + gnb->supported_ta_list[i].bplmn_list[j].s_nssai[k].sd.v); + + gnb->supported_ta_list[i].bplmn_list[j].num_of_s_nssai++; + } + + gnb->supported_ta_list[i].num_of_bplmn_list++; } + + gnb->num_of_supported_ta_list++; } if (maximum_number_of_gnbs_is_reached()) { @@ -197,6 +301,19 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message) return; } + if (!s_nssai_is_found(gnb)) { + ogs_warn("NG-Setup failure:"); + ogs_warn(" Cannot find S_NSSAI. " + "Check 'amf.plmn.s_nssai' configuration"); + group = NGAP_Cause_PR_misc; + cause = NGAP_CauseMisc_unknown_PLMN; + + ngap_send_ng_setup_failure(gnb, group, cause); + return; + } + + amf_gnb_set_gnb_id(gnb, gnb_id); + gnb->state.ng_setup_success = true; ngap_send_ng_setup_response(gnb); } diff --git a/src/mme/emm-build.c b/src/mme/emm-build.c index 2ce92dea5..d4970d819 100644 --- a/src/mme/emm-build.c +++ b/src/mme/emm-build.c @@ -104,6 +104,7 @@ ogs_pkbuf_t *emm_build_attach_accept( attach_accept->presencemask |= OGS_NAS_EPS_ATTACH_ACCEPT_T3423_VALUE_PRESENT; attach_accept->t3423_value.unit = OGS_NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH; attach_accept->t3423_value.value = 9; + attach_accept->presencemask |= OGS_NAS_EPS_ATTACH_ACCEPT_EPS_NETWORK_FEATURE_SUPPORT_PRESENT; eps_network_feature_support->length = 1; @@ -181,19 +182,23 @@ ogs_pkbuf_t *emm_build_identity_request(mme_ue_t *mme_ue) return ogs_nas_eps_plain_encode(&message); } -ogs_pkbuf_t *emm_build_authentication_request( +ogs_pkbuf_t *emm_build_authentication_request(mme_ue_t *mme_ue, ogs_diam_e_utran_vector_t *e_utran_vector) { ogs_nas_eps_message_t message; ogs_nas_eps_authentication_request_t *authentication_request = &message.emm.authentication_request; + ogs_assert(mme_ue); ogs_assert(e_utran_vector); memset(&message, 0, sizeof(message)); message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM; message.emm.h.message_type = OGS_NAS_EPS_AUTHENTICATION_REQUEST; + authentication_request->nas_key_set_identifierasme.tsc = 0; + authentication_request->nas_key_set_identifierasme.value = + mme_ue->nas_eps.ksi; memcpy(authentication_request->authentication_parameter_rand.rand, e_utran_vector->rand, OGS_RAND_LEN); memcpy(authentication_request->authentication_parameter_autn.autn, @@ -277,7 +282,8 @@ ogs_pkbuf_t *emm_build_security_mode_command(mme_ue_t *mme_ue) sizeof(replayed_ue_security_capabilities->uea) + sizeof(replayed_ue_security_capabilities->uia) + sizeof(replayed_ue_security_capabilities->gea); - ogs_debug(" Replayed UE SEC[LEN:%d EEA:0x%x EIA:0x%x UEA:0x%x UIA:0x%x GEA:0x%x]", + ogs_debug(" Replayed UE SEC[LEN:%d EEA:0x%x EIA:0x%x UEA:0x%x " + "UIA:0x%x GEA:0x%x]", replayed_ue_security_capabilities->length, replayed_ue_security_capabilities->eea, replayed_ue_security_capabilities->eia, diff --git a/src/mme/emm-build.h b/src/mme/emm-build.h index 1a3efd018..8c32a5c08 100644 --- a/src/mme/emm-build.h +++ b/src/mme/emm-build.h @@ -34,7 +34,7 @@ ogs_pkbuf_t *emm_build_attach_reject( ogs_pkbuf_t *emm_build_identity_request(mme_ue_t *mme_ue); ogs_pkbuf_t *emm_build_security_mode_command(mme_ue_t *mme_ue); -ogs_pkbuf_t *emm_build_authentication_request( +ogs_pkbuf_t *emm_build_authentication_request(mme_ue_t *mme_ue, ogs_diam_e_utran_vector_t *e_utran_vector); ogs_pkbuf_t *emm_build_authentication_reject(void); diff --git a/src/mme/mme-s6a-handler.c b/src/mme/mme-s6a-handler.c index 78d2c3e51..e425a31ea 100644 --- a/src/mme/mme-s6a-handler.c +++ b/src/mme/mme-s6a-handler.c @@ -40,6 +40,9 @@ void mme_s6a_handle_aia(mme_ue_t *mme_ue, CLEAR_MME_UE_TIMER(mme_ue->t3460); + if (mme_ue->nas_eps.ksi == OGS_NAS_KSI_NO_KEY_IS_AVAILABLE) + mme_ue->nas_eps.ksi = 0; + nas_eps_send_authentication_request(mme_ue, e_utran_vector); } diff --git a/src/mme/nas-path.c b/src/mme/nas-path.c index 48fc2b7a3..bb52bfdf2 100644 --- a/src/mme/nas-path.c +++ b/src/mme/nas-path.c @@ -185,7 +185,7 @@ void nas_eps_send_authentication_request( ogs_expect_or_return(emmbuf); } else { ogs_assert(e_utran_vector); - emmbuf = emm_build_authentication_request(e_utran_vector); + emmbuf = emm_build_authentication_request(mme_ue, e_utran_vector); ogs_expect_or_return(emmbuf); } diff --git a/src/smf/context.c b/src/smf/context.c index 98b734f34..0811408e2 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -1307,9 +1307,11 @@ void smf_sess_remove(smf_sess_t *sess) ogs_fsm_fini(&sess->sm, &e); ogs_fsm_delete(&sess->sm); - OGS_TLV_CLEAR_DATA(&sess->ue_pco); - OGS_TLV_CLEAR_DATA(&sess->user_location_information); - OGS_TLV_CLEAR_DATA(&sess->ue_timezone); + OGS_TLV_CLEAR_DATA(&sess->gtp.ue_pco); + OGS_TLV_CLEAR_DATA(&sess->gtp.user_location_information); + OGS_TLV_CLEAR_DATA(&sess->gtp.ue_timezone); + + OGS_NAS_CLEAR_DATA(&sess->nas.ue_pco); for (i = 0; i < sess->num_of_pcc_rule; i++) OGS_PCC_RULE_FREE(&sess->pcc_rule[i]); @@ -1693,3 +1695,171 @@ smf_pf_t *smf_pf_next(smf_pf_t *pf) { return ogs_list_next(pf); } + +int smf_pco_build(uint8_t *pco_buf, uint8_t *buffer, int length) +{ + int rv; + ogs_pco_t ue, smf; + ogs_pco_ipcp_t pco_ipcp; + ogs_ipsubnet_t dns_primary, dns_secondary, dns6_primary, dns6_secondary; + ogs_ipsubnet_t p_cscf, p_cscf6; + int size = 0; + int i = 0; + uint16_t mtu = 0; + + ogs_assert(pco_buf); + ogs_assert(buffer); + ogs_assert(length); + + size = ogs_pco_parse(&ue, buffer, length); + ogs_assert(size); + + memset(&smf, 0, sizeof(ogs_pco_t)); + smf.ext = ue.ext; + smf.configuration_protocol = ue.configuration_protocol; + + for (i = 0; i < ue.num_of_id; i++) { + uint8_t *data = ue.ids[i].data; + switch(ue.ids[i].id) { + case OGS_PCO_ID_CHALLENGE_HANDSHAKE_AUTHENTICATION_PROTOCOL: + if (data[0] == 2) { /* Code : Response */ + smf.ids[smf.num_of_id].id = ue.ids[i].id; + smf.ids[smf.num_of_id].len = 4; + smf.ids[smf.num_of_id].data = + (uint8_t *)"\x03\x00\x00\x04"; /* Code : Success */ + smf.num_of_id++; + } + break; + case OGS_PCO_ID_INTERNET_PROTOCOL_CONTROL_PROTOCOL: + if (data[0] == 1) { /* Code : Configuration Request */ + uint16_t len = 0; + + ogs_assert(smf_self()->dns[0] || smf_self()->dns[1]); + + memset(&pco_ipcp, 0, sizeof(ogs_pco_ipcp_t)); + pco_ipcp.code = 2; /* Code : Configuration Ack */ + pco_ipcp.len = htobe16(len); + + len = 4; + /* Primary DNS Server IP Address */ + if (smf_self()->dns[0]) { + rv = ogs_ipsubnet( + &dns_primary, smf_self()->dns[0], NULL); + ogs_assert(rv == OGS_OK); + pco_ipcp.options[0].type = 129; + pco_ipcp.options[0].len = 6; + pco_ipcp.options[0].addr = dns_primary.sub[0]; + len += 6; + } + + /* Secondary DNS Server IP Address */ + if (smf_self()->dns[1]) { + rv = ogs_ipsubnet( + &dns_secondary, smf_self()->dns[1], NULL); + ogs_assert(rv == OGS_OK); + pco_ipcp.options[1].type = 131; + pco_ipcp.options[1].len = 6; + pco_ipcp.options[1].addr = dns_secondary.sub[0]; + len += 6; + } + + pco_ipcp.len = htobe16(len); + + smf.ids[smf.num_of_id].id = ue.ids[i].id; + smf.ids[smf.num_of_id].len = len; + smf.ids[smf.num_of_id].data = (uint8_t *)&pco_ipcp; + + smf.num_of_id++; + } + break; + case OGS_PCO_ID_DNS_SERVER_IPV4_ADDRESS_REQUEST: + if (smf_self()->dns[0]) { + rv = ogs_ipsubnet( + &dns_primary, smf_self()->dns[0], NULL); + ogs_assert(rv == OGS_OK); + smf.ids[smf.num_of_id].id = ue.ids[i].id; + smf.ids[smf.num_of_id].len = OGS_IPV4_LEN; + smf.ids[smf.num_of_id].data = dns_primary.sub; + smf.num_of_id++; + } + + if (smf_self()->dns[1]) { + rv = ogs_ipsubnet( + &dns_secondary, smf_self()->dns[1], NULL); + ogs_assert(rv == OGS_OK); + smf.ids[smf.num_of_id].id = ue.ids[i].id; + smf.ids[smf.num_of_id].len = OGS_IPV4_LEN; + smf.ids[smf.num_of_id].data = dns_secondary.sub; + smf.num_of_id++; + } + break; + case OGS_PCO_ID_DNS_SERVER_IPV6_ADDRESS_REQUEST: + if (smf_self()->dns6[0]) { + rv = ogs_ipsubnet( + &dns6_primary, smf_self()->dns6[0], NULL); + ogs_assert(rv == OGS_OK); + smf.ids[smf.num_of_id].id = ue.ids[i].id; + smf.ids[smf.num_of_id].len = OGS_IPV6_LEN; + smf.ids[smf.num_of_id].data = dns6_primary.sub; + smf.num_of_id++; + } + + if (smf_self()->dns6[1]) { + rv = ogs_ipsubnet( + &dns6_secondary, smf_self()->dns6[1], NULL); + ogs_assert(rv == OGS_OK); + smf.ids[smf.num_of_id].id = ue.ids[i].id; + smf.ids[smf.num_of_id].len = OGS_IPV6_LEN; + smf.ids[smf.num_of_id].data = dns6_secondary.sub; + smf.num_of_id++; + } + break; + case OGS_PCO_ID_P_CSCF_IPV4_ADDRESS_REQUEST: + if (smf_self()->num_of_p_cscf) { + rv = ogs_ipsubnet(&p_cscf, + smf_self()->p_cscf[smf_self()->p_cscf_index], NULL); + ogs_assert(rv == OGS_OK); + smf.ids[smf.num_of_id].id = ue.ids[i].id; + smf.ids[smf.num_of_id].len = OGS_IPV4_LEN; + smf.ids[smf.num_of_id].data = p_cscf.sub; + smf.num_of_id++; + + smf_self()->p_cscf_index++; + smf_self()->p_cscf_index %= smf_self()->num_of_p_cscf; + } + break; + case OGS_PCO_ID_P_CSCF_IPV6_ADDRESS_REQUEST: + if (smf_self()->num_of_p_cscf6) { + rv = ogs_ipsubnet(&p_cscf6, + smf_self()->p_cscf6[smf_self()->p_cscf6_index], NULL); + ogs_assert(rv == OGS_OK); + smf.ids[smf.num_of_id].id = ue.ids[i].id; + smf.ids[smf.num_of_id].len = OGS_IPV6_LEN; + smf.ids[smf.num_of_id].data = p_cscf6.sub; + smf.num_of_id++; + + smf_self()->p_cscf6_index++; + smf_self()->p_cscf6_index %= smf_self()->num_of_p_cscf6; + } + break; + case OGS_PCO_ID_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING: + /* TODO */ + break; + case OGS_PCO_ID_IPV4_LINK_MTU_REQUEST: + if (smf_self()->mtu) { + mtu = htons(smf_self()->mtu); + smf.ids[smf.num_of_id].id = ue.ids[i].id; + smf.ids[smf.num_of_id].len = sizeof(uint16_t); + smf.ids[smf.num_of_id].data = &mtu; + smf.num_of_id++; + } + break; + default: + ogs_warn("Unknown PCO ID:(0x%x)", ue.ids[i].id); + } + } + + size = ogs_pco_build(pco_buf, OGS_MAX_PCO_LEN, &smf); + return size; +} + diff --git a/src/smf/context.h b/src/smf/context.h index ddd6c5929..69ac7ad3c 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -188,9 +188,15 @@ typedef struct smf_sess_s { ogs_pfcp_ue_ip_t *ipv4; ogs_pfcp_ue_ip_t *ipv6; - ogs_tlv_octet_t ue_pco; /* Saved from S5-C */ - ogs_tlv_octet_t user_location_information; /* Saved from S5-C */ - ogs_tlv_octet_t ue_timezone; /* Saved from S5-C */ + struct { + ogs_tlv_octet_t ue_pco; + ogs_tlv_octet_t user_location_information; + ogs_tlv_octet_t ue_timezone; + } gtp; /* Saved from S5-C */ + + struct { + ogs_nas_extended_protocol_configuration_options_t ue_pco; + } nas; /* Saved from NAS-5GS */ ogs_pcc_rule_t pcc_rule[OGS_MAX_NUM_OF_PCC_RULE]; /* Saved from Gx */ int num_of_pcc_rule; @@ -325,8 +331,7 @@ smf_pf_t *smf_pf_find_by_id(smf_bearer_t *smf_bearer, uint8_t id); smf_pf_t *smf_pf_first(smf_bearer_t *bearer); smf_pf_t *smf_pf_next(smf_pf_t *pf); -void stats_add_session(void); -void stats_remove_session(void); +int smf_pco_build(uint8_t *pco_buf, uint8_t *buffer, int length); #ifdef __cplusplus } diff --git a/src/smf/fd-path.c b/src/smf/fd-path.c index 70c194bee..95f6cfcee 100644 --- a/src/smf/fd-path.c +++ b/src/smf/fd-path.c @@ -386,19 +386,20 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact, ogs_assert(ret == 0); /* Set 3GPP-User-Location-Info */ - if (sess->user_location_information.presence) { + if (sess->gtp.user_location_information.presence) { ogs_gtp_uli_t uli; int16_t uli_len; uint8_t uli_buf[OGS_GTP_MAX_ULI_LEN]; - uli_len = ogs_gtp_parse_uli(&uli, &sess->user_location_information); - ogs_assert(sess->user_location_information.len == uli_len); + uli_len = ogs_gtp_parse_uli( + &uli, &sess->gtp.user_location_information); + ogs_assert(sess->gtp.user_location_information.len == uli_len); - ogs_assert(sess->user_location_information.data); - ogs_assert(sess->user_location_information.len); - memcpy(&uli_buf, sess->user_location_information.data, - sess->user_location_information.len); + ogs_assert(sess->gtp.user_location_information.data); + ogs_assert(sess->gtp.user_location_information.len); + memcpy(&uli_buf, sess->gtp.user_location_information.data, + sess->gtp.user_location_information.len); /* Update Gx ULI Type */ if (uli.flags.tai && uli.flags.e_cgi) @@ -414,7 +415,7 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact, ogs_diam_gx_3gpp_user_location_info, 0, &avp); ogs_assert(ret == 0); val.os.data = (uint8_t *)&uli_buf; - val.os.len = sess->user_location_information.len; + val.os.len = sess->gtp.user_location_information.len; ret = fd_msg_avp_setvalue(avp, &val); ogs_assert(ret == 0); ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp); @@ -423,12 +424,12 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact, } /* Set 3GPP-MS-Timezone */ - if (sess->ue_timezone.presence && - sess->ue_timezone.len && sess->ue_timezone.data) { + if (sess->gtp.ue_timezone.presence && + sess->gtp.ue_timezone.len && sess->gtp.ue_timezone.data) { ret = fd_msg_avp_new(ogs_diam_gx_3gpp_ms_timezone, 0, &avp); ogs_assert(ret == 0); - val.os.data = sess->ue_timezone.data; - val.os.len = sess->ue_timezone.len; + val.os.data = sess->gtp.ue_timezone.data; + val.os.len = sess->gtp.ue_timezone.len; ret = fd_msg_avp_setvalue(avp, &val); ogs_assert(ret == 0); ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp); diff --git a/src/smf/gsm-build.c b/src/smf/gsm-build.c index a6ddcd761..1ca6fad0e 100644 --- a/src/smf/gsm-build.c +++ b/src/smf/gsm-build.c @@ -25,6 +25,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) { ogs_pkbuf_t *pkbuf = NULL; + ogs_nas_5gs_message_t message; ogs_nas_5gs_pdu_session_establishment_accept_t * pdu_session_establishment_accept = @@ -33,10 +34,19 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) ogs_nas_pdu_session_type_t *selected_pdu_session_type = NULL; ogs_nas_qos_rules_t *authorized_qos_rules = NULL; ogs_nas_session_ambr_t *session_ambr = NULL; - ogs_nas_pdu_address_t *pdu_address = NULL; ogs_nas_5gsm_cause_t *gsm_cause = NULL; + ogs_nas_pdu_address_t *pdu_address = NULL; + ogs_nas_s_nssai_t *nas_s_nssai = NULL; + ogs_nas_qos_flow_descriptions_t *authorized_qos_flow_descriptions = NULL; + ogs_nas_extended_protocol_configuration_options_t + *extended_protocol_configuration_options = NULL; + ogs_nas_dnn_t *dnn = NULL; ogs_nas_qos_rule_t qos_rule[OGS_NAS_MAX_NUM_OF_QOS_RULE]; + ogs_nas_qos_flow_description_t qos_flow_description; + + uint8_t pco_buf[OGS_MAX_PCO_LEN]; + int16_t pco_len; selected_pdu_session_type = &pdu_session_establishment_accept-> selected_pdu_session_type; @@ -50,6 +60,17 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) ogs_assert(pdu_address); gsm_cause = &pdu_session_establishment_accept->gsm_cause; ogs_assert(gsm_cause); + nas_s_nssai = &pdu_session_establishment_accept->s_nssai; + ogs_assert(nas_s_nssai); + authorized_qos_flow_descriptions = + &pdu_session_establishment_accept->authorized_qos_flow_descriptions; + ogs_assert(authorized_qos_flow_descriptions); + extended_protocol_configuration_options = + &pdu_session_establishment_accept-> + extended_protocol_configuration_options; + ogs_assert(extended_protocol_configuration_options); + dnn = &pdu_session_establishment_accept->dnn; + ogs_assert(dnn); memset(&message, 0, sizeof(message)); message.gsm.h.extended_protocol_discriminator = @@ -73,7 +94,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) qos_rule[0].pf[0].length = 1; qos_rule[0].pf[0].num_of_component = 1; qos_rule[0].pf[0].component[0].type = OGS_PACKET_FILTER_MATCH_ALL; - qos_rule[0].precedence = 1; /* lowest precedence */ + qos_rule[0].precedence = 255; /* lowest precedence */ qos_rule[0].flow.segregation = 0; qos_rule[0].flow.identifier = 1; @@ -121,6 +142,52 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) } } + /* S-NSSAI */ + pdu_session_establishment_accept->presencemask |= + OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT_S_NSSAI_PRESENT; + if (sess->s_nssai.sd.v == OGS_S_NSSAI_NO_SD_VALUE) { + nas_s_nssai->length = 1; + nas_s_nssai->sst = sess->s_nssai.sst; + } else { + nas_s_nssai->length = 4; + nas_s_nssai->sst = sess->s_nssai.sst; + nas_s_nssai->sd.v = sess->s_nssai.sd.v; + } + + /* QoS flow descriptions */ + memset(&qos_flow_description, 0, sizeof(qos_flow_description)); + qos_flow_description.identifier = 1; + qos_flow_description.code = OGS_NAS_CREATE_NEW_QOS_FLOW_DESCRIPTION; + qos_flow_description.E = 1; + qos_flow_description.num_of_parameter = 1; + qos_flow_description.param[0].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI; + qos_flow_description.param[0].len = 1; + qos_flow_description.param[0].content[0] = sess->pdn.qos.qci; + + pdu_session_establishment_accept->presencemask |= + OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT_AUTHORIZED_QOS_FLOW_DESCRIPTIONS_PRESENT; + authorized_qos_flow_descriptions->length = 6; + authorized_qos_flow_descriptions->buffer = &qos_flow_description; + + /* Extended protocol configuration options */ + if (sess->nas.ue_pco.buffer && sess->nas.ue_pco.length) { + pco_len = smf_pco_build(pco_buf, + sess->nas.ue_pco.buffer, sess->nas.ue_pco.length); + ogs_assert(pco_len > 0); + pdu_session_establishment_accept->presencemask |= + OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT; + extended_protocol_configuration_options->buffer = pco_buf; + extended_protocol_configuration_options->length = pco_len; + } + + /* DNN */ + pdu_session_establishment_accept->presencemask |= + OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT_DNN_PRESENT; + dnn->length = strlen(sess->pdn.dnn); + ogs_cpystrn(dnn->value, sess->pdn.dnn, + ogs_min(dnn->length, OGS_MAX_DNN_LEN) + 1); + pkbuf = ogs_nas_5gs_plain_encode(&message); ogs_assert(pkbuf); diff --git a/src/smf/gsm-handler.c b/src/smf/gsm-handler.c index 4ca04c078..890267bb5 100644 --- a/src/smf/gsm-handler.c +++ b/src/smf/gsm-handler.c @@ -57,6 +57,14 @@ int gsm_handle_pdu_session_establishment_request(smf_sess_t *sess, OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST_SSC_MODE_PRESENT) sess->ue_ssc_mode = ssc_mode->value; + if (pdu_session_establishment_request->presencemask & + OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT) { + OGS_NAS_STORE_DATA(&sess->nas.ue_pco, + &pdu_session_establishment_request-> + extended_protocol_configuration_options); + } + + smf_sbi_discover_and_send(OpenAPI_nf_type_UDM, sess, (char *)OGS_SBI_RESOURCE_NAME_SM_DATA, smf_nudm_sdm_build_get); diff --git a/src/smf/ngap-build.c b/src/smf/ngap-build.c index bb98efd6c..0358b4353 100644 --- a/src/smf/ngap-build.c +++ b/src/smf/ngap-build.c @@ -28,6 +28,7 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( NGAP_PDUSessionResourceSetupRequestTransfer_t message; NGAP_PDUSessionResourceSetupRequestTransferIEs_t *ie = NULL; + NGAP_PDUSessionAggregateMaximumBitRate_t *PDUSessionAggregateMaximumBitRate; NGAP_UPTransportLayerInformation_t *UPTransportLayerInformation = NULL; NGAP_GTPTunnel_t *gTPTunnel = NULL; NGAP_PDUSessionType_t *PDUSessionType = NULL; @@ -46,6 +47,24 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( ogs_debug("PDUSessionResourceSetupRequestTransfer"); memset(&message, 0, sizeof(NGAP_PDUSessionResourceSetupRequestTransfer_t)); + if (sess->pdn.ambr.downlink || sess->pdn.ambr.uplink) { + ie = CALLOC(1, + sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t)); + ASN_SEQUENCE_ADD(&message.protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_PDUSessionAggregateMaximumBitRate; + + PDUSessionAggregateMaximumBitRate = + &ie->value.choice.PDUSessionAggregateMaximumBitRate; + + asn_uint642INTEGER(&PDUSessionAggregateMaximumBitRate-> + pDUSessionAggregateMaximumBitRateUL, sess->pdn.ambr.uplink); + asn_uint642INTEGER(&PDUSessionAggregateMaximumBitRate-> + pDUSessionAggregateMaximumBitRateDL, sess->pdn.ambr.downlink); + } + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t)); ASN_SEQUENCE_ADD(&message.protocolIEs, ie); @@ -55,24 +74,6 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( UPTransportLayerInformation = &ie->value.choice.UPTransportLayerInformation; - ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t)); - ASN_SEQUENCE_ADD(&message.protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionType; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_PDUSessionType; - - PDUSessionType = &ie->value.choice.PDUSessionType; - - ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t)); - ASN_SEQUENCE_ADD(&message.protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_QosFlowSetupRequestList; - - QosFlowSetupRequestList = &ie->value.choice.QosFlowSetupRequestList; - gTPTunnel = CALLOC(1, sizeof(struct NGAP_GTPTunnel)); UPTransportLayerInformation->present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; @@ -82,6 +83,15 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( ogs_asn_ip_to_BIT_STRING(&upf_n3_ip, &gTPTunnel->transportLayerAddress); ogs_asn_uint32_to_OCTET_STRING(bearer->upf_n3_teid, &gTPTunnel->gTP_TEID); + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t)); + ASN_SEQUENCE_ADD(&message.protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionType; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_PDUSessionType; + + PDUSessionType = &ie->value.choice.PDUSessionType; + *PDUSessionType = OGS_PDU_SESSION_TYPE_IPV4; switch (sess->pdn.pdn_type) { case OGS_PDU_SESSION_TYPE_IPV4 : @@ -98,6 +108,15 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( ogs_assert_if_reached(); } + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t)); + ASN_SEQUENCE_ADD(&message.protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_QosFlowSetupRequestList; + + QosFlowSetupRequestList = &ie->value.choice.QosFlowSetupRequestList; + QosFlowSetupRequestItem = CALLOC(1, sizeof(struct NGAP_QosFlowSetupRequestItem)); ASN_SEQUENCE_ADD(&QosFlowSetupRequestList->list, QosFlowSetupRequestItem); diff --git a/src/smf/s5c-build.c b/src/smf/s5c-build.c index 1cc962e01..73cd1dd88 100644 --- a/src/smf/s5c-build.c +++ b/src/smf/s5c-build.c @@ -22,8 +22,6 @@ #include "ipfw/ipfw2.h" -static int16_t smf_pco_build(uint8_t *pco_buf, ogs_gtp_tlv_pco_t *tlv_pco); - ogs_pkbuf_t *smf_s5c_build_create_session_response( uint8_t type, smf_sess_t *sess) { @@ -94,8 +92,10 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response( * if PCRF changes APN-AMBR, this should be included. */ /* PCO */ - if (sess->ue_pco.presence && sess->ue_pco.len && sess->ue_pco.data) { - pco_len = smf_pco_build(pco_buf, &sess->ue_pco); + if (sess->gtp.ue_pco.presence && + sess->gtp.ue_pco.len && sess->gtp.ue_pco.data) { + pco_len = smf_pco_build( + pco_buf, sess->gtp.ue_pco.data, sess->gtp.ue_pco.len); ogs_assert(pco_len > 0); rsp->protocol_configuration_options.presence = 1; rsp->protocol_configuration_options.data = pco_buf; @@ -155,8 +155,10 @@ ogs_pkbuf_t *smf_s5c_build_delete_session_response( /* Recovery */ /* PCO */ - if (sess->ue_pco.presence && sess->ue_pco.len && sess->ue_pco.data) { - pco_len = smf_pco_build(pco_buf, &sess->ue_pco); + if (sess->gtp.ue_pco.presence && + sess->gtp.ue_pco.len && sess->gtp.ue_pco.data) { + pco_len = smf_pco_build( + pco_buf, sess->gtp.ue_pco.data, sess->gtp.ue_pco.len); ogs_assert(pco_len > 0); rsp->protocol_configuration_options.presence = 1; rsp->protocol_configuration_options.data = pco_buf; @@ -367,169 +369,3 @@ ogs_pkbuf_t *smf_s5c_build_delete_bearer_request( gtp_message.h.type = type; return ogs_gtp_build_msg(>p_message); } - -static int16_t smf_pco_build(uint8_t *pco_buf, ogs_gtp_tlv_pco_t *tlv_pco) -{ - int rv; - ogs_pco_t ue, smf; - ogs_pco_ipcp_t pco_ipcp; - ogs_ipsubnet_t dns_primary, dns_secondary, dns6_primary, dns6_secondary; - ogs_ipsubnet_t p_cscf, p_cscf6; - int size = 0; - int i = 0; - uint16_t mtu = 0; - - ogs_assert(pco_buf); - ogs_assert(tlv_pco); - - size = ogs_pco_parse(&ue, tlv_pco->data, tlv_pco->len); - ogs_assert(size); - - memset(&smf, 0, sizeof(ogs_pco_t)); - smf.ext = ue.ext; - smf.configuration_protocol = ue.configuration_protocol; - - for (i = 0; i < ue.num_of_id; i++) { - uint8_t *data = ue.ids[i].data; - switch(ue.ids[i].id) { - case OGS_PCO_ID_CHALLENGE_HANDSHAKE_AUTHENTICATION_PROTOCOL: - if (data[0] == 2) { /* Code : Response */ - smf.ids[smf.num_of_id].id = ue.ids[i].id; - smf.ids[smf.num_of_id].len = 4; - smf.ids[smf.num_of_id].data = - (uint8_t *)"\x03\x00\x00\x04"; /* Code : Success */ - smf.num_of_id++; - } - break; - case OGS_PCO_ID_INTERNET_PROTOCOL_CONTROL_PROTOCOL: - if (data[0] == 1) { /* Code : Configuration Request */ - uint16_t len = 0; - - ogs_assert(smf_self()->dns[0] || smf_self()->dns[1]); - - memset(&pco_ipcp, 0, sizeof(ogs_pco_ipcp_t)); - pco_ipcp.code = 2; /* Code : Configuration Ack */ - pco_ipcp.len = htobe16(len); - - len = 4; - /* Primary DNS Server IP Address */ - if (smf_self()->dns[0]) { - rv = ogs_ipsubnet( - &dns_primary, smf_self()->dns[0], NULL); - ogs_assert(rv == OGS_OK); - pco_ipcp.options[0].type = 129; - pco_ipcp.options[0].len = 6; - pco_ipcp.options[0].addr = dns_primary.sub[0]; - len += 6; - } - - /* Secondary DNS Server IP Address */ - if (smf_self()->dns[1]) { - rv = ogs_ipsubnet( - &dns_secondary, smf_self()->dns[1], NULL); - ogs_assert(rv == OGS_OK); - pco_ipcp.options[1].type = 131; - pco_ipcp.options[1].len = 6; - pco_ipcp.options[1].addr = dns_secondary.sub[0]; - len += 6; - } - - pco_ipcp.len = htobe16(len); - - smf.ids[smf.num_of_id].id = ue.ids[i].id; - smf.ids[smf.num_of_id].len = len; - smf.ids[smf.num_of_id].data = (uint8_t *)&pco_ipcp; - - smf.num_of_id++; - } - break; - case OGS_PCO_ID_DNS_SERVER_IPV4_ADDRESS_REQUEST: - if (smf_self()->dns[0]) { - rv = ogs_ipsubnet( - &dns_primary, smf_self()->dns[0], NULL); - ogs_assert(rv == OGS_OK); - smf.ids[smf.num_of_id].id = ue.ids[i].id; - smf.ids[smf.num_of_id].len = OGS_IPV4_LEN; - smf.ids[smf.num_of_id].data = dns_primary.sub; - smf.num_of_id++; - } - - if (smf_self()->dns[1]) { - rv = ogs_ipsubnet( - &dns_secondary, smf_self()->dns[1], NULL); - ogs_assert(rv == OGS_OK); - smf.ids[smf.num_of_id].id = ue.ids[i].id; - smf.ids[smf.num_of_id].len = OGS_IPV4_LEN; - smf.ids[smf.num_of_id].data = dns_secondary.sub; - smf.num_of_id++; - } - break; - case OGS_PCO_ID_DNS_SERVER_IPV6_ADDRESS_REQUEST: - if (smf_self()->dns6[0]) { - rv = ogs_ipsubnet( - &dns6_primary, smf_self()->dns6[0], NULL); - ogs_assert(rv == OGS_OK); - smf.ids[smf.num_of_id].id = ue.ids[i].id; - smf.ids[smf.num_of_id].len = OGS_IPV6_LEN; - smf.ids[smf.num_of_id].data = dns6_primary.sub; - smf.num_of_id++; - } - - if (smf_self()->dns6[1]) { - rv = ogs_ipsubnet( - &dns6_secondary, smf_self()->dns6[1], NULL); - ogs_assert(rv == OGS_OK); - smf.ids[smf.num_of_id].id = ue.ids[i].id; - smf.ids[smf.num_of_id].len = OGS_IPV6_LEN; - smf.ids[smf.num_of_id].data = dns6_secondary.sub; - smf.num_of_id++; - } - break; - case OGS_PCO_ID_P_CSCF_IPV4_ADDRESS_REQUEST: - if (smf_self()->num_of_p_cscf) { - rv = ogs_ipsubnet(&p_cscf, - smf_self()->p_cscf[smf_self()->p_cscf_index], NULL); - ogs_assert(rv == OGS_OK); - smf.ids[smf.num_of_id].id = ue.ids[i].id; - smf.ids[smf.num_of_id].len = OGS_IPV4_LEN; - smf.ids[smf.num_of_id].data = p_cscf.sub; - smf.num_of_id++; - - smf_self()->p_cscf_index++; - smf_self()->p_cscf_index %= smf_self()->num_of_p_cscf; - } - break; - case OGS_PCO_ID_P_CSCF_IPV6_ADDRESS_REQUEST: - if (smf_self()->num_of_p_cscf6) { - rv = ogs_ipsubnet(&p_cscf6, - smf_self()->p_cscf6[smf_self()->p_cscf6_index], NULL); - ogs_assert(rv == OGS_OK); - smf.ids[smf.num_of_id].id = ue.ids[i].id; - smf.ids[smf.num_of_id].len = OGS_IPV6_LEN; - smf.ids[smf.num_of_id].data = p_cscf6.sub; - smf.num_of_id++; - - smf_self()->p_cscf6_index++; - smf_self()->p_cscf6_index %= smf_self()->num_of_p_cscf6; - } - break; - case OGS_PCO_ID_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING: - /* TODO */ - break; - case OGS_PCO_ID_IPV4_LINK_MTU_REQUEST: - if (smf_self()->mtu) { - mtu = htons(smf_self()->mtu); - smf.ids[smf.num_of_id].id = ue.ids[i].id; - smf.ids[smf.num_of_id].len = sizeof(uint16_t); - smf.ids[smf.num_of_id].data = &mtu; - smf.num_of_id++; - } - break; - default: - ogs_warn("Unknown PCO ID:(0x%x)", ue.ids[i].id); - } - } - - size = ogs_pco_build(pco_buf, OGS_MAX_PCO_LEN, &smf); - return size; -} diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c index 480e0cf8f..7da3c29dc 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -154,18 +154,19 @@ void smf_s5c_handle_create_session_request( /* PCO */ if (req->protocol_configuration_options.presence) { - OGS_TLV_STORE_DATA(&sess->ue_pco, &req->protocol_configuration_options); + OGS_TLV_STORE_DATA(&sess->gtp.ue_pco, + &req->protocol_configuration_options); } /* Set User Location Information */ if (req->user_location_information.presence) { - OGS_TLV_STORE_DATA(&sess->user_location_information, + OGS_TLV_STORE_DATA(&sess->gtp.user_location_information, &req->user_location_information); } /* Set UE Timezone */ if (req->ue_time_zone.presence) { - OGS_TLV_STORE_DATA(&sess->ue_timezone, &req->ue_time_zone); + OGS_TLV_STORE_DATA(&sess->gtp.ue_timezone, &req->ue_time_zone); } smf_gx_send_ccr(sess, xact, diff --git a/tests/common/gmm-build.c b/tests/common/gmm-build.c index a3746951e..f2aea9e31 100644 --- a/tests/common/gmm-build.c +++ b/tests/common/gmm-build.c @@ -35,6 +35,8 @@ ogs_pkbuf_t *testgmm_build_registration_request( ®istration_request->gmm_capability; ogs_nas_ue_security_capability_t *ue_security_capability = ®istration_request->ue_security_capability; + ogs_nas_s1_ue_network_capability_t *s1_ue_network_capability = + ®istration_request->s1_ue_network_capability; ogs_nas_uplink_data_status_t *uplink_data_status = ®istration_request->uplink_data_status; ogs_nas_5gs_mobile_identity_guti_t mobile_identity_guti; @@ -81,17 +83,27 @@ ogs_pkbuf_t *testgmm_build_registration_request( registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT; gmm_capability->length = 1; - gmm_capability->lte_positioning_protocol_capability = 1; + gmm_capability->lte_positioning_protocol_capability = 0; gmm_capability->ho_attach = 1; gmm_capability->s1_mode = 1; registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT; - ue_security_capability->length = 8; - ue_security_capability->nea = 0xff; - ue_security_capability->nia = 0xff; - ue_security_capability->eps_ea = 0xff; - ue_security_capability->eps_ia = 0xff; + ue_security_capability->length = 2; + ue_security_capability->nea = 0xf0; + ue_security_capability->nia = 0xf0; + + registration_request->presencemask |= + OGS_NAS_5GS_REGISTRATION_REQUEST_S1_UE_NETWORK_CAPABILITY_PRESENT; + s1_ue_network_capability->length = 7; + s1_ue_network_capability->eea = 0xf0; + s1_ue_network_capability->eia = 0xf0; + s1_ue_network_capability->uea = 0xc0; + s1_ue_network_capability->uia = 0x40; + s1_ue_network_capability->notification_procedure = 1; + s1_ue_network_capability->extended_protocol_configuration_options = 1; + s1_ue_network_capability->n1_mode = 1; + s1_ue_network_capability->dual_connectivity_with_nr = 1; if (update) return test_nas_5gs_security_encode(test_ue, &message); @@ -388,7 +400,10 @@ ogs_pkbuf_t *testgmm_build_ul_nas_transport(test_sess_t *test_sess, ogs_nas_payload_container_t *payload_container = NULL; ogs_nas_pdu_session_identity_2_t *pdu_session_id = NULL; ogs_nas_request_type_t *request_type = NULL; +#define S_NSSAI_PRECENSE 0 +#if S_NSSAI_PRECENSE ogs_nas_s_nssai_t *s_nssai = NULL; +#endif ogs_assert(test_sess); test_ue = test_sess->test_ue; @@ -400,7 +415,9 @@ ogs_pkbuf_t *testgmm_build_ul_nas_transport(test_sess_t *test_sess, payload_container = &ul_nas_transport->payload_container; pdu_session_id = &ul_nas_transport->pdu_session_id; request_type = &ul_nas_transport->request_type; +#if S_NSSAI_PRECENSE s_nssai = &ul_nas_transport->s_nssai; +#endif memset(&message, 0, sizeof(message)); message.h.security_header_type = @@ -425,11 +442,19 @@ ogs_pkbuf_t *testgmm_build_ul_nas_transport(test_sess_t *test_sess, OGS_NAS_5GS_UL_NAS_TRANSPORT_REQUEST_TYPE_PRESENT; request_type->value = OGS_NAS_5GS_REQUEST_TYPE_INITIAL; +#if S_NSSAI_PRECENSE ul_nas_transport->presencemask |= OGS_NAS_5GS_UL_NAS_TRANSPORT_S_NSSAI_PRESENT; - s_nssai->length = 4; - s_nssai->sst = test_self()->plmn_support[0].s_nssai[0].sst; - s_nssai->sd = ogs_htobe24(test_self()->plmn_support[0].s_nssai[0].sd); + if (test_self()->plmn_support[0].s_nssai[0].sd.v == + OGS_S_NSSAI_NO_SD_VALUE) { + s_nssai->length = 1; + s_nssai->sst = test_self()->plmn_support[0].s_nssai[0].sst; + } else { + s_nssai->length = 4; + s_nssai->sst = test_self()->plmn_support[0].s_nssai[0].sst; + s_nssai->sd = ogs_htobe24(test_self()->plmn_support[0].s_nssai[0].sd); + } +#endif ul_nas_transport->presencemask |= OGS_NAS_5GS_UL_NAS_TRANSPORT_DNN_PRESENT; diff --git a/tests/common/gsm-build.c b/tests/common/gsm-build.c index 45b6ff939..11bd9a610 100644 --- a/tests/common/gsm-build.c +++ b/tests/common/gsm-build.c @@ -29,6 +29,13 @@ ogs_pkbuf_t *testgsm_build_pdu_session_establishment_request( ogs_nas_integrity_protection_maximum_data_rate_t *integrity_protection_maximum_data_rate = NULL; ogs_nas_pdu_session_type_t *pdu_session_type = NULL; +#define ADD_SSC_MODE 1 +#if ADD_SSC_MODE + ogs_nas_ssc_mode_t *ssc_mode = NULL; +#endif + ogs_nas_extended_protocol_configuration_options_t + *extended_protocol_configuration_options = NULL; + uint8_t ue_pco[10] = "\x80\x00\x0a\x00\x00\x03\x00\x00\x0d\x00"; ogs_s_nssai_t *s_nssai = NULL; @@ -42,8 +49,13 @@ ogs_pkbuf_t *testgsm_build_pdu_session_establishment_request( integrity_protection_maximum_data_rate = &pdu_session_establishment_request-> integrity_protection_maximum_data_rate; - pdu_session_type = &pdu_session_establishment_request->pdu_session_type; +#if ADD_SSC_MODE + ssc_mode = &pdu_session_establishment_request->ssc_mode; +#endif + extended_protocol_configuration_options = + &pdu_session_establishment_request-> + extended_protocol_configuration_options; memset(&message, 0, sizeof(message)); @@ -60,6 +72,17 @@ ogs_pkbuf_t *testgsm_build_pdu_session_establishment_request( OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST_PDU_SESSION_TYPE_PRESENT; pdu_session_type->value = test_sess->pdu_session_type; +#if ADD_SSC_MODE + pdu_session_establishment_request->presencemask |= + OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST_SSC_MODE_PRESENT; + ssc_mode->value = OGS_NAS_SSC_MODE_1; +#endif + + pdu_session_establishment_request->presencemask |= + OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST_EXTENDED_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT; + extended_protocol_configuration_options->length = 10; + extended_protocol_configuration_options->buffer = ue_pco; + s_nssai = &test_self()->plmn_support[0].s_nssai[0]; ogs_assert(s_nssai); diff --git a/tests/common/ngap-build.c b/tests/common/ngap-build.c index 9059b738f..cd1e573f1 100644 --- a/tests/common/ngap-build.c +++ b/tests/common/ngap-build.c @@ -27,6 +27,7 @@ ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id) ogs_pkbuf_t *pkbuf = NULL; int i, j; ogs_plmn_id_t *plmn_id = NULL; + const char *ran_node_name = "5G gNB-CU"; NGAP_NGAP_PDU_t pdu; NGAP_InitiatingMessage_t *initiatingMessage = NULL; @@ -34,6 +35,7 @@ ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id) NGAP_NGSetupRequestIEs_t *ie = NULL; NGAP_GlobalRANNodeID_t *GlobalRANNodeID = NULL; + NGAP_RANNodeName_t *RANNodeName = NULL; NGAP_GlobalGNB_ID_t *globalGNB_ID = NULL; NGAP_SupportedTAList_t *SupportedTAList = NULL; NGAP_SupportedTAItem_t *SupportedTAItem = NULL; @@ -75,6 +77,15 @@ ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id) ie = CALLOC(1, sizeof(NGAP_NGSetupRequestIEs_t)); ASN_SEQUENCE_ADD(&NGSetupRequest->protocolIEs, ie); + ie->id = NGAP_ProtocolIE_ID_id_RANNodeName; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_NGSetupRequestIEs__value_PR_RANNodeName; + + RANNodeName = &ie->value.choice.RANNodeName; + + ie = CALLOC(1, sizeof(NGAP_NGSetupRequestIEs_t)); + ASN_SEQUENCE_ADD(&NGSetupRequest->protocolIEs, ie); + ie->id = NGAP_ProtocolIE_ID_id_SupportedTAList; ie->criticality = NGAP_Criticality_reject; ie->value.present = NGAP_NGSetupRequestIEs__value_PR_SupportedTAList; @@ -93,6 +104,9 @@ ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id) GlobalRANNodeID->present = NGAP_GlobalRANNodeID_PR_globalGNB_ID; GlobalRANNodeID->choice.globalGNB_ID = globalGNB_ID; + ogs_asn_buffer_to_OCTET_STRING((char*)ran_node_name, + strlen(ran_node_name), RANNodeName); + SupportedTAItem = CALLOC(1, sizeof(NGAP_SupportedTAItem_t)); if (test_self()->served_tai[0].list2.num) ogs_asn_uint24_to_OCTET_STRING( @@ -115,15 +129,16 @@ ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id) for (j = 0; j < test_self()->plmn_support[i].num_of_s_nssai; j++) { ogs_s_nssai_t *s_nssai = &test_self()->plmn_support[i].s_nssai[j]; + ogs_uint24_t sd; SliceSupportItem = CALLOC(1, sizeof(NGAP_SliceSupportItem_t)); ogs_asn_uint8_to_OCTET_STRING(s_nssai->sst, &SliceSupportItem->s_NSSAI.sST); - if (s_nssai->sd.v != OGS_S_NSSAI_NO_SD_VALUE) { - SliceSupportItem->s_NSSAI.sD = CALLOC(1, sizeof(ogs_uint24_t)); - ogs_asn_uint24_to_OCTET_STRING( - s_nssai->sd, SliceSupportItem->s_NSSAI.sD); - } + sd.v = s_nssai->sd.v; + if (sd.v == OGS_S_NSSAI_NO_SD_VALUE) + sd.v = 0x010000; + SliceSupportItem->s_NSSAI.sD = CALLOC(1, sizeof(ogs_uint24_t)); + ogs_asn_uint24_to_OCTET_STRING(sd, SliceSupportItem->s_NSSAI.sD); ASN_SEQUENCE_ADD(&BroadcastPLMNItem->tAISliceSupportList.list, SliceSupportItem); @@ -135,7 +150,7 @@ ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id) ASN_SEQUENCE_ADD(&SupportedTAList->list, SupportedTAItem); - *PagingDRX = NGAP_PagingDRX_v64; + *PagingDRX = NGAP_PagingDRX_v32; return nga_ngap_encode(&pdu); } @@ -237,7 +252,7 @@ ogs_pkbuf_t *testngap_build_initial_ue_message( UserLocationInformation->choice.userLocationInformationNR = userLocationInformationNR; - *RRCEstablishmentCause = NGAP_RRCEstablishmentCause_mt_Access; + *RRCEstablishmentCause = NGAP_RRCEstablishmentCause_mo_Signalling; if (test_ue->nas_guti.m_tmsi) { NGAP_AMFSetID_t *aMFSetID = NULL; @@ -345,7 +360,7 @@ ogs_pkbuf_t *testngap_build_uplink_nas_transport( ASN_SEQUENCE_ADD(&UplinkNASTransport->protocolIEs, ie); ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; - ie->criticality = NGAP_Criticality_reject; + ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_UserLocationInformation; diff --git a/tests/common/ngap-path.c b/tests/common/ngap-path.c index 3a2dc5930..52a6c3873 100644 --- a/tests/common/ngap-path.c +++ b/tests/common/ngap-path.c @@ -81,6 +81,8 @@ void testngap_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf) ogs_assert(unsuccessfulOutcome); switch (unsuccessfulOutcome->procedureCode) { + case NGAP_ProcedureCode_id_NGSetup: + break; default: ogs_error("Not implemented(choice:%d, proc:%d)", pdu->present, (int)unsuccessfulOutcome->procedureCode); diff --git a/tests/minimal/minimal-test.c b/tests/minimal/minimal-test.c index c2788503c..837fec402 100644 --- a/tests/minimal/minimal-test.c +++ b/tests/minimal/minimal-test.c @@ -217,7 +217,6 @@ static void test1_func(abts_case *tc, void *data) ABTS_PTR_NOTNULL(tc, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); - ogs_pkbuf_free(nasbuf); /* Receive Initial context setup request */ recvbuf = testgnb_ngap_read(ngap); diff --git a/tests/registration/auth-test.c b/tests/registration/auth-test.c index 321e9f6b2..1ebe8a49d 100644 --- a/tests/registration/auth-test.c +++ b/tests/registration/auth-test.c @@ -94,7 +94,7 @@ static void test1_func(abts_case *tc, void *data) test_sess.test_ue = &test_ue; test_ue.sess = &test_sess; - test_ue.nas.registration.type = 1; /* TSC[0], KSI[1] */ + test_ue.nas.registration.type = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; test_ue.nas.registration.follow_on_request = 1; test_ue.nas.registration.value = 1; /* Initial Registration */ @@ -124,7 +124,7 @@ static void test1_func(abts_case *tc, void *data) OGS_HEX(_k_string, strlen(_k_string), test_ue.k); OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc); - test_sess.psi = 1; + test_sess.psi = 5; test_sess.pti = 1; test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6; test_sess.dnn = (char *)"internet"; diff --git a/tests/registration/dereg-test.c b/tests/registration/dereg-test.c index cc2e8394b..310208240 100644 --- a/tests/registration/dereg-test.c +++ b/tests/registration/dereg-test.c @@ -26,7 +26,6 @@ static void test1_func(abts_case *tc, void *data) ogs_socknode_t *gtpu; ogs_pkbuf_t *gmmbuf; ogs_pkbuf_t *gsmbuf; - ogs_pkbuf_t *nasbuf; ogs_pkbuf_t *sendbuf; ogs_pkbuf_t *recvbuf; ogs_ngap_message_t message; @@ -124,7 +123,7 @@ static void test1_func(abts_case *tc, void *data) OGS_HEX(_k_string, strlen(_k_string), test_ue.k); OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc); - test_sess.psi = 1; + test_sess.psi = 5; test_sess.pti = 1; test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6; test_sess.dnn = (char *)"internet"; @@ -209,9 +208,7 @@ static void test1_func(abts_case *tc, void *data) testngap_recv(&test_ue, recvbuf); /* Send Security mode complete */ - nasbuf = testgmm_build_registration_request(&test_ue, false); - ABTS_PTR_NOTNULL(tc, nasbuf); - gmmbuf = testgmm_build_security_mode_complete(&test_ue, nasbuf); + gmmbuf = testgmm_build_security_mode_complete(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf); ABTS_PTR_NOTNULL(tc, sendbuf); diff --git a/tests/registration/gmm-status-test.c b/tests/registration/gmm-status-test.c index d234765cc..a26c73084 100644 --- a/tests/registration/gmm-status-test.c +++ b/tests/registration/gmm-status-test.c @@ -26,7 +26,6 @@ static void test1_func(abts_case *tc, void *data) ogs_socknode_t *gtpu; ogs_pkbuf_t *gmmbuf; ogs_pkbuf_t *gsmbuf; - ogs_pkbuf_t *nasbuf; ogs_pkbuf_t *sendbuf; ogs_pkbuf_t *recvbuf; ogs_ngap_message_t message; @@ -124,7 +123,7 @@ static void test1_func(abts_case *tc, void *data) OGS_HEX(_k_string, strlen(_k_string), test_ue.k); OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc); - test_sess.psi = 1; + test_sess.psi = 5; test_sess.pti = 1; test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6; test_sess.dnn = (char *)"internet"; @@ -209,9 +208,7 @@ static void test1_func(abts_case *tc, void *data) testngap_recv(&test_ue, recvbuf); /* Send Security mode complete */ - nasbuf = testgmm_build_registration_request(&test_ue, false); - ABTS_PTR_NOTNULL(tc, nasbuf); - gmmbuf = testgmm_build_security_mode_complete(&test_ue, nasbuf); + gmmbuf = testgmm_build_security_mode_complete(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf); ABTS_PTR_NOTNULL(tc, sendbuf); diff --git a/tests/registration/guti-test.c b/tests/registration/guti-test.c index 3e2fd3b68..fc42010c1 100644 --- a/tests/registration/guti-test.c +++ b/tests/registration/guti-test.c @@ -94,7 +94,7 @@ static void test1_func(abts_case *tc, void *data) test_sess.test_ue = &test_ue; test_ue.sess = &test_sess; - test_ue.nas.registration.type = 1; /* TSC[0], KSI[1] */ + test_ue.nas.registration.type = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; test_ue.nas.registration.follow_on_request = 1; test_ue.nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL; @@ -124,7 +124,7 @@ static void test1_func(abts_case *tc, void *data) OGS_HEX(_k_string, strlen(_k_string), test_ue.k); OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc); - test_sess.psi = 1; + test_sess.psi = 5; test_sess.pti = 1; test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6; test_sess.dnn = (char *)"internet"; @@ -209,9 +209,7 @@ static void test1_func(abts_case *tc, void *data) testngap_recv(&test_ue, recvbuf); /* Send Security mode complete */ - nasbuf = testgmm_build_registration_request(&test_ue, false); - ABTS_PTR_NOTNULL(tc, nasbuf); - gmmbuf = testgmm_build_security_mode_complete(&test_ue, nasbuf); + gmmbuf = testgmm_build_security_mode_complete(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf); ABTS_PTR_NOTNULL(tc, sendbuf); diff --git a/tests/registration/identity-test.c b/tests/registration/identity-test.c index 6faa1b92e..c6dc56c7e 100644 --- a/tests/registration/identity-test.c +++ b/tests/registration/identity-test.c @@ -26,7 +26,6 @@ static void test1_func(abts_case *tc, void *data) ogs_socknode_t *gtpu; ogs_pkbuf_t *gmmbuf; ogs_pkbuf_t *gsmbuf; - ogs_pkbuf_t *nasbuf; ogs_pkbuf_t *sendbuf; ogs_pkbuf_t *recvbuf; ogs_ngap_message_t message; @@ -124,7 +123,7 @@ static void test1_func(abts_case *tc, void *data) OGS_HEX(_k_string, strlen(_k_string), test_ue.k); OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc); - test_sess.psi = 1; + test_sess.psi = 5; test_sess.pti = 1; test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6; test_sess.dnn = (char *)"internet"; @@ -209,9 +208,7 @@ static void test1_func(abts_case *tc, void *data) testngap_recv(&test_ue, recvbuf); /* Send Security mode complete */ - nasbuf = testgmm_build_registration_request(&test_ue, false); - ABTS_PTR_NOTNULL(tc, nasbuf); - gmmbuf = testgmm_build_security_mode_complete(&test_ue, nasbuf); + gmmbuf = testgmm_build_security_mode_complete(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf); ABTS_PTR_NOTNULL(tc, sendbuf); diff --git a/tests/registration/idle-test.c b/tests/registration/idle-test.c index 8585178fa..f4a0fc141 100644 --- a/tests/registration/idle-test.c +++ b/tests/registration/idle-test.c @@ -26,7 +26,6 @@ static void test1_func(abts_case *tc, void *data) ogs_socknode_t *gtpu; ogs_pkbuf_t *gmmbuf; ogs_pkbuf_t *gsmbuf; - ogs_pkbuf_t *nasbuf; ogs_pkbuf_t *sendbuf; ogs_pkbuf_t *recvbuf; ogs_ngap_message_t message; @@ -124,7 +123,7 @@ static void test1_func(abts_case *tc, void *data) OGS_HEX(_k_string, strlen(_k_string), test_ue.k); OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc); - test_sess.psi = 1; + test_sess.psi = 5; test_sess.pti = 1; test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6; test_sess.dnn = (char *)"internet"; @@ -209,9 +208,7 @@ static void test1_func(abts_case *tc, void *data) testngap_recv(&test_ue, recvbuf); /* Send Security mode complete */ - nasbuf = testgmm_build_registration_request(&test_ue, false); - ABTS_PTR_NOTNULL(tc, nasbuf); - gmmbuf = testgmm_build_security_mode_complete(&test_ue, nasbuf); + gmmbuf = testgmm_build_security_mode_complete(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf); ABTS_PTR_NOTNULL(tc, sendbuf); diff --git a/tests/registration/ue-context-test.c b/tests/registration/ue-context-test.c index 02da1c5d2..193a91caa 100644 --- a/tests/registration/ue-context-test.c +++ b/tests/registration/ue-context-test.c @@ -123,7 +123,7 @@ static void test1_func(abts_case *tc, void *data) OGS_HEX(_k_string, strlen(_k_string), test_ue.k); OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc); - test_sess.psi = 1; + test_sess.psi = 5; test_sess.pti = 1; test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6; test_sess.dnn = (char *)"internet"; @@ -213,6 +213,7 @@ static void test1_func(abts_case *tc, void *data) sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf); ABTS_PTR_NOTNULL(tc, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Receive Initial context setup request */ recvbuf = testgnb_ngap_read(ngap);