From 41262d50fa0a1d684b6d42db82207a26b208b72f Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Tue, 5 Sep 2017 00:04:05 +0900 Subject: [PATCH] dedicated bearer(MME->UE) --- lib/nas/nas_types.c | 40 ++++++++++++ lib/nas/nas_types.h | 8 ++- lib/s1ap/s1ap_encoder.c | 129 +++++++++++++++++++++++++------------- lib/s1ap/s1ap_free.c | 5 ++ src/mme/esm_build.c | 52 ++++++++++++--- src/mme/esm_build.h | 4 +- src/mme/esm_handler.c | 26 ++++++++ src/mme/esm_handler.h | 2 + src/mme/esm_sm.c | 12 ++++ src/mme/mme_context.c | 11 ++++ src/mme/mme_context.h | 1 + src/mme/mme_s11_handler.c | 4 ++ src/mme/s1ap_build.c | 96 ++++++++++++++++++++++++---- src/mme/s1ap_build.h | 2 + test/volte_test.c | 6 ++ 15 files changed, 331 insertions(+), 67 deletions(-) diff --git a/lib/nas/nas_types.c b/lib/nas/nas_types.c index a157f029d..a091e72a6 100644 --- a/lib/nas/nas_types.c +++ b/lib/nas/nas_types.c @@ -176,3 +176,43 @@ void apn_ambr_build( apn_aggregate_maximum_bit_rate->length = length*2; } +void eps_qos_build(nas_eps_quality_of_service_t *eps_qos, c_uint8_t qci, + c_uint64_t dl_mbr, c_uint64_t ul_mbr, c_uint64_t dl_gbr, c_uint64_t ul_gbr) +{ + c_uint8_t length = 0; + + dl_mbr = dl_mbr / 1024; /* Kbps */ + ul_mbr = ul_mbr / 1024; /* Kbps */ + dl_gbr = dl_gbr / 1024; /* Kbps */ + ul_gbr = ul_gbr / 1024; /* Kbps */ + + memset(eps_qos, 0, sizeof(nas_eps_quality_of_service_t)); + + eps_qos->qci = qci; + + length = c_max(length, br_calculate( + &eps_qos->dl_mbr, + &eps_qos->dl_mbr_extended, + &eps_qos->dl_mbr_extended2, + dl_mbr)); + + length = c_max(length, br_calculate( + &eps_qos->ul_mbr, + &eps_qos->ul_mbr_extended, + &eps_qos->ul_mbr_extended2, + ul_mbr)); + + length = c_max(length, br_calculate( + &eps_qos->dl_gbr, + &eps_qos->dl_gbr_extended, + &eps_qos->dl_gbr_extended2, + dl_gbr)); + + length = c_max(length, br_calculate( + &eps_qos->ul_gbr, + &eps_qos->ul_gbr_extended, + &eps_qos->ul_gbr_extended2, + ul_gbr)); + + eps_qos->length = length*4+1; +} diff --git a/lib/nas/nas_types.h b/lib/nas/nas_types.h index f9bb3574f..936645759 100644 --- a/lib/nas/nas_types.h +++ b/lib/nas/nas_types.h @@ -1044,6 +1044,10 @@ typedef struct _nas_eps_quality_of_service_t { c_uint8_t dl_gbr_extended2; } nas_eps_quality_of_service_t; +CORE_DECLARE(void) eps_qos_build(nas_eps_quality_of_service_t *eps_qos, + c_uint8_t qci, + c_uint64_t dl_mbr, c_uint64_t ul_mbr, c_uint64_t dl_gbr, c_uint64_t ul_gbr); + /* 9.9.4.4 ESM cause * M V 1 * Annex B (informative):
Cause values for EPS session management @@ -1108,8 +1112,8 @@ ED3(c_uint8_t type:4;, /* 9.9.4.6 Linked EPS bearer identity * M V 1/2 */ typedef struct _nas_linked_eps_bearer_identity_t { -ED2(c_uint8_t eps_bearer_identity:4;, - c_uint8_t spare:4;) +ED2(c_uint8_t spare:4;, + c_uint8_t eps_bearer_identity:4;) } __attribute__ ((packed)) nas_linked_eps_bearer_identity_t; /* 9.9.4.7 LLC service access point identifier diff --git a/lib/s1ap/s1ap_encoder.c b/lib/s1ap/s1ap_encoder.c index a4725b68d..aab9154c8 100644 --- a/lib/s1ap/s1ap_encoder.c +++ b/lib/s1ap/s1ap_encoder.c @@ -13,8 +13,6 @@ static inline int s1ap_encode_successfull_outcome( static inline int s1ap_encode_unsuccessfull_outcome( s1ap_message_t *message_p, pkbuf_t *pkbuf); -static inline int s1ap_encode_initial_context_setup_request( - s1ap_message_t *message_p, pkbuf_t *pkbuf); static inline int s1ap_encode_s1setup_request( s1ap_message_t *message_p, pkbuf_t *pkbuf); static inline int s1ap_encode_s1setup_response( @@ -23,6 +21,10 @@ static inline int s1ap_encode_s1setup_failure( s1ap_message_t *message_p, pkbuf_t *pkbuf); static inline int s1ap_encode_downlink_nas_transport( s1ap_message_t *message_p, pkbuf_t *pkbuf); +static inline int s1ap_encode_initial_context_setup_request( + s1ap_message_t *message_p, pkbuf_t *pkbuf); +static inline int s1ap_encode_e_rab_setup_request( + s1ap_message_t *message_p, pkbuf_t *pkbuf); static inline int s1ap_encode_ue_context_release_command( s1ap_message_t *message_p, pkbuf_t *pkbuf); static inline int s1ap_encode_paging( @@ -99,6 +101,12 @@ static inline int s1ap_encode_initiating_message( s1ap_xer__print2sp, message_p); ret = s1ap_encode_initial_context_setup_request(message_p, pkbuf); break; + case S1ap_ProcedureCode_id_E_RABSetup: + s1ap_encode_xer_print_message( + s1ap_xer_print_s1ap_e_rabsetuprequest, + s1ap_xer__print2sp, message_p); + ret = s1ap_encode_e_rab_setup_request(message_p, pkbuf); + break; case S1ap_ProcedureCode_id_UEContextRelease: s1ap_encode_xer_print_message( s1ap_xer_print_s1ap_uecontextreleasecommand, @@ -162,46 +170,6 @@ static inline int s1ap_encode_unsuccessfull_outcome( return ret; } -static inline int s1ap_encode_initial_context_setup_request( - s1ap_message_t *message_p, pkbuf_t *pkbuf) -{ - asn_enc_rval_t enc_ret = {0}; - - S1AP_PDU_t pdu; - S1ap_InitialContextSetupRequest_t initialContextSetupRequest; - asn_TYPE_descriptor_t *td = &asn_DEF_S1ap_InitialContextSetupRequest; - - memset(&initialContextSetupRequest, 0, - sizeof(S1ap_InitialContextSetupRequest_t)); - if (s1ap_encode_s1ap_initialcontextsetuprequesties( - &initialContextSetupRequest, - &message_p->s1ap_InitialContextSetupRequestIEs) < 0) - { - d_error("Encoding of %s failed", td->name); - return -1; - } - - memset(&pdu, 0, sizeof (S1AP_PDU_t)); - pdu.present = S1AP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage.procedureCode = message_p->procedureCode; - pdu.choice.initiatingMessage.criticality = S1ap_Criticality_reject; - ANY_fromType_aper(&pdu.choice.initiatingMessage.value, - td, &initialContextSetupRequest); - - enc_ret = aper_encode_to_buffer(&asn_DEF_S1AP_PDU, - &pdu, pkbuf->payload, MAX_SDU_LEN); - - ASN_STRUCT_FREE_CONTENTS_ONLY(*td, &initialContextSetupRequest); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_S1AP_PDU, &pdu); - - if (enc_ret.encoded < 0) - { - d_error("Encoding of %s failed", td->name); - } - - return enc_ret.encoded; -} - static inline int s1ap_encode_s1setup_request( s1ap_message_t *message_p, pkbuf_t *pkbuf) { @@ -353,6 +321,83 @@ static inline int s1ap_encode_downlink_nas_transport( return enc_ret.encoded; } +static inline int s1ap_encode_initial_context_setup_request( + s1ap_message_t *message_p, pkbuf_t *pkbuf) +{ + asn_enc_rval_t enc_ret = {0}; + + S1AP_PDU_t pdu; + S1ap_InitialContextSetupRequest_t initialContextSetupRequest; + asn_TYPE_descriptor_t *td = &asn_DEF_S1ap_InitialContextSetupRequest; + + memset(&initialContextSetupRequest, 0, + sizeof(S1ap_InitialContextSetupRequest_t)); + if (s1ap_encode_s1ap_initialcontextsetuprequesties( + &initialContextSetupRequest, + &message_p->s1ap_InitialContextSetupRequestIEs) < 0) + { + d_error("Encoding of %s failed", td->name); + return -1; + } + + memset(&pdu, 0, sizeof (S1AP_PDU_t)); + pdu.present = S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = message_p->procedureCode; + pdu.choice.initiatingMessage.criticality = S1ap_Criticality_reject; + ANY_fromType_aper(&pdu.choice.initiatingMessage.value, + td, &initialContextSetupRequest); + + enc_ret = aper_encode_to_buffer(&asn_DEF_S1AP_PDU, + &pdu, pkbuf->payload, MAX_SDU_LEN); + + ASN_STRUCT_FREE_CONTENTS_ONLY(*td, &initialContextSetupRequest); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_S1AP_PDU, &pdu); + + if (enc_ret.encoded < 0) + { + d_error("Encoding of %s failed", td->name); + } + + return enc_ret.encoded; +} + +static inline int s1ap_encode_e_rab_setup_request( + s1ap_message_t *message_p, pkbuf_t *pkbuf) +{ + asn_enc_rval_t enc_ret = {0}; + + S1AP_PDU_t pdu; + S1ap_E_RABSetupRequest_t req; + asn_TYPE_descriptor_t *td = &asn_DEF_S1ap_E_RABSetupRequest; + + memset(&req, 0, sizeof(S1ap_E_RABSetupRequest_t)); + if (s1ap_encode_s1ap_e_rabsetuprequesties( + &req, &message_p->s1ap_E_RABSetupRequestIEs) < 0) + { + d_error("Encoding of %s failed", td->name); + return -1; + } + + memset(&pdu, 0, sizeof (S1AP_PDU_t)); + pdu.present = S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = message_p->procedureCode; + pdu.choice.initiatingMessage.criticality = S1ap_Criticality_reject; + ANY_fromType_aper(&pdu.choice.initiatingMessage.value, td, &req); + + enc_ret = aper_encode_to_buffer(&asn_DEF_S1AP_PDU, + &pdu, pkbuf->payload, MAX_SDU_LEN); + + ASN_STRUCT_FREE_CONTENTS_ONLY(*td, &req); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_S1AP_PDU, &pdu); + + if (enc_ret.encoded < 0) + { + d_error("Encoding of %s failed", td->name); + } + + return enc_ret.encoded; +} + static inline int s1ap_encode_ue_context_release_command( s1ap_message_t *message_p, pkbuf_t *pkbuf) { diff --git a/lib/s1ap/s1ap_free.c b/lib/s1ap/s1ap_free.c index 1d8124f62..92abed83c 100644 --- a/lib/s1ap/s1ap_free.c +++ b/lib/s1ap/s1ap_free.c @@ -55,6 +55,11 @@ static inline int s1ap_free_initiating_message(s1ap_message_t *message) &message->s1ap_InitialContextSetupRequestIEs); break; + case S1ap_ProcedureCode_id_E_RABSetup: + s1ap_free_s1ap_e_rabsetuprequesties( + &message->s1ap_E_RABSetupRequestIEs); + break; + case S1ap_ProcedureCode_id_downlinkNASTransport: s1ap_free_s1ap_downlinknastransport_ies( &message->s1ap_DownlinkNASTransport_IEs); diff --git a/src/mme/esm_build.c b/src/mme/esm_build.c index 1c83ae0d4..c727b60b6 100644 --- a/src/mme/esm_build.c +++ b/src/mme/esm_build.c @@ -90,17 +90,8 @@ status_t esm_build_activate_default_bearer_context( message.esm.h.message_type = NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST; -#if 0 /* default bearer is not needed */ - eps_qos->length = 5; - eps_qos->qci = pdn->qos.qci; - eps_qos->ul_mbr = 0xff; - eps_qos->dl_mbr = 0xff; - eps_qos->ul_gbr = 0xff; - eps_qos->dl_gbr = 0xff; -#else eps_qos->length = 1; eps_qos->qci = pdn->qos.qci; -#endif access_point_name->length = strlen(pdn->apn); core_cpystrn(access_point_name->apn, pdn->apn, @@ -129,3 +120,46 @@ status_t esm_build_activate_default_bearer_context( return CORE_OK; } + +status_t esm_build_activate_dedicated_bearer_context( + pkbuf_t **pkbuf, mme_bearer_t *bearer) +{ + mme_ue_t *mme_ue = NULL; + mme_bearer_t *linked_bearer = NULL; + + nas_message_t message; + nas_activate_dedicated_eps_bearer_context_request_t + *activate_dedicated_eps_bearer_context_request = + &message.esm.activate_dedicated_eps_bearer_context_request; + nas_linked_eps_bearer_identity_t *linked_ebi = + &activate_dedicated_eps_bearer_context_request-> + linked_eps_bearer_identity; + nas_eps_quality_of_service_t *eps_qos = + &activate_dedicated_eps_bearer_context_request->eps_qos; + + d_assert(bearer, return CORE_ERROR, "Null param"); + mme_ue = bearer->mme_ue; + d_assert(mme_ue, return CORE_ERROR, "Null param"); + linked_bearer = mme_linked_bearer(bearer); + d_assert(linked_bearer, return CORE_ERROR, "Null param"); + + memset(&message, 0, sizeof(message)); + message.h.security_header_type = + NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED; + message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; + message.esm.h.eps_bearer_identity = bearer->ebi; + message.esm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_ESM; + message.esm.h.procedure_transaction_identity = 0; + message.esm.h.message_type = + NAS_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST; + + linked_ebi->eps_bearer_identity = linked_bearer->ebi; + eps_qos_build(eps_qos, bearer->qos.qci, + bearer->qos.mbr.downlink, bearer->qos.mbr.uplink, + bearer->qos.gbr.downlink, bearer->qos.gbr.uplink); + + d_assert(nas_security_encode(pkbuf, mme_ue, &message) == CORE_OK && + *pkbuf,,); + + return CORE_OK; +} diff --git a/src/mme/esm_build.h b/src/mme/esm_build.h index 7da78df19..7a035f7fb 100644 --- a/src/mme/esm_build.h +++ b/src/mme/esm_build.h @@ -9,12 +9,12 @@ extern "C" { CORE_DECLARE(status_t) esm_build_pdn_connectivity_reject(pkbuf_t **pkbuf, c_uint8_t pti, nas_esm_cause_t esm_cause); - CORE_DECLARE(status_t) esm_build_information_request(pkbuf_t **pkbuf, mme_bearer_t *bearer); - CORE_DECLARE(status_t) esm_build_activate_default_bearer_context( pkbuf_t **pkbuf, mme_sess_t *sess); +CORE_DECLARE(status_t) esm_build_activate_dedicated_bearer_context( + pkbuf_t **pkbuf, mme_bearer_t *bearer); #ifdef __cplusplus } diff --git a/src/mme/esm_handler.c b/src/mme/esm_handler.c index 5514eae31..6135d89a4 100644 --- a/src/mme/esm_handler.c +++ b/src/mme/esm_handler.c @@ -59,3 +59,29 @@ void esm_handle_information_response(mme_sess_t *sess, sess->ue_pco_len); } } + +void esm_handle_activate_dedicated_bearer_request(mme_bearer_t *bearer) +{ + status_t rv; + mme_ue_t *mme_ue = NULL; + enb_ue_t *enb_ue = NULL; + pkbuf_t *esmbuf = NULL, *s1apbuf = NULL; + + d_assert(bearer, return, "Null param"); + mme_ue = bearer->mme_ue; + d_assert(mme_ue, return, "Null param"); + enb_ue = mme_ue->enb_ue; + d_assert(enb_ue, return, "Null param"); + + rv = esm_build_activate_dedicated_bearer_context(&esmbuf, bearer); + d_assert(rv == CORE_OK && esmbuf, return, "esm build error"); + + d_trace(3, "[NAS] Activate dedicated bearer context request : " + "EMM <-- ESM\n"); + + rv = s1ap_build_e_rab_setup_request(&s1apbuf, bearer, esmbuf); + d_assert(rv == CORE_OK && s1apbuf, + pkbuf_free(esmbuf); return, "s1ap build error"); + + d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,); +} diff --git a/src/mme/esm_handler.h b/src/mme/esm_handler.h index 49b08d18b..38edee4a2 100644 --- a/src/mme/esm_handler.h +++ b/src/mme/esm_handler.h @@ -13,6 +13,8 @@ CORE_DECLARE(void) esm_handle_pdn_connectivity_request(mme_sess_t *sess, nas_pdn_connectivity_request_t *pdn_connectivity_request); CORE_DECLARE(void) esm_handle_information_response(mme_sess_t *sess, nas_esm_information_response_t *bearer_information_response); +CORE_DECLARE(void) esm_handle_activate_dedicated_bearer_request( + mme_bearer_t *bearer); #ifdef __cplusplus } diff --git a/src/mme/esm_sm.c b/src/mme/esm_sm.c index 9bb7dac2b..0404f0a18 100644 --- a/src/mme/esm_sm.c +++ b/src/mme/esm_sm.c @@ -113,9 +113,21 @@ void esm_state_operational(fsm_t *s, event_t *e) } case NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT: { + mme_bearer_t *dedicated_bearer = NULL; + d_trace(3, "[NAS] Activate default eps bearer " "context accept : UE[%s] --> ESM[%d]\n", mme_ue->imsi_bcd, bearer->pti); + dedicated_bearer = mme_bearer_next(bearer); + while(dedicated_bearer) + { + if (MME_BEARER_IS_VALID(dedicated_bearer)) + continue; + + esm_handle_activate_dedicated_bearer_request( + dedicated_bearer); + dedicated_bearer = mme_bearer_next(dedicated_bearer); + } break; } default: diff --git a/src/mme/mme_context.c b/src/mme/mme_context.c index dfa7fcda9..e85c28653 100644 --- a/src/mme/mme_context.c +++ b/src/mme/mme_context.c @@ -1709,6 +1709,17 @@ mme_bearer_t* mme_default_bearer_in_sess(mme_sess_t *sess) return mme_bearer_first(sess); } +mme_bearer_t* mme_linked_bearer(mme_bearer_t *bearer) +{ + mme_sess_t *sess = NULL; + + d_assert(bearer, return NULL, "Null param"); + sess = bearer->sess; + d_assert(sess, return NULL, "Null param"); + + return mme_default_bearer_in_sess(sess); +} + mme_bearer_t* mme_bearer_first(mme_sess_t *sess) { d_assert(sess, return NULL, "Null param"); diff --git a/src/mme/mme_context.h b/src/mme/mme_context.h index e340d2e39..2343dbc1b 100644 --- a/src/mme/mme_context.h +++ b/src/mme/mme_context.h @@ -373,6 +373,7 @@ CORE_DECLARE(mme_bearer_t*) mme_bearer_find_by_sess_ebi( CORE_DECLARE(mme_bearer_t*) mme_bearer_find_by_ue_ebi( mme_ue_t *mme_ue, c_uint8_t ebi); CORE_DECLARE(mme_bearer_t*) mme_default_bearer_in_sess(mme_sess_t *sess); +CORE_DECLARE(mme_bearer_t*) mme_linked_bearer(mme_bearer_t *bearer); CORE_DECLARE(mme_bearer_t*) mme_bearer_first(mme_sess_t *sess); CORE_DECLARE(mme_bearer_t*) mme_bearer_next(mme_bearer_t *bearer); diff --git a/src/mme/mme_s11_handler.c b/src/mme/mme_s11_handler.c index cb85bb0ce..282a4264e 100644 --- a/src/mme/mme_s11_handler.c +++ b/src/mme/mme_s11_handler.c @@ -267,6 +267,10 @@ void mme_s11_handle_create_bearer_request( bearer_qos.pre_emption_capability; bearer->qos.arp.pre_emption_vulnerability = bearer_qos.pre_emption_vulnerability; + bearer->qos.mbr.downlink = bearer_qos.dl_mbr; + bearer->qos.mbr.uplink = bearer_qos.ul_mbr; + bearer->qos.gbr.downlink = bearer_qos.dl_gbr; + bearer->qos.gbr.uplink = bearer_qos.ul_gbr; /* Save Transaction */ bearer->xact = xact; diff --git a/src/mme/s1ap_build.c b/src/mme/s1ap_build.c index 38b03ca71..a9c867a5b 100644 --- a/src/mme/s1ap_build.c +++ b/src/mme/s1ap_build.c @@ -157,9 +157,6 @@ status_t s1ap_build_initial_context_setup_request( S1ap_InitialContextSetupRequestIEs_t *ies = &message.s1ap_InitialContextSetupRequestIEs; S1ap_E_RABToBeSetupItemCtxtSUReq_t *e_rab = NULL; -#if 0 /* Not needed in default bearer */ - struct S1ap_GBR_QosInformation *gbrQosInformation = NULL; /* OPTIONAL */ -#endif S1ap_NAS_PDU_t *nasPdu = NULL; mme_ue_t *mme_ue = NULL; enb_ue_t *enb_ue = NULL; @@ -203,15 +200,6 @@ status_t s1ap_build_initial_context_setup_request( e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. pre_emptionVulnerability = !(pdn->qos.arp.pre_emption_vulnerability); -#if 0 /* Not needed in default bearer */ - gbrQosInformation = core_calloc(1, sizeof(struct S1ap_GBR_QosInformation)); - asn_uint642INTEGER(&gbrQosInformation->e_RAB_MaximumBitrateDL, 0); - asn_uint642INTEGER(&gbrQosInformation->e_RAB_MaximumBitrateUL, 0); - asn_uint642INTEGER(&gbrQosInformation->e_RAB_GuaranteedBitrateDL, 0); - asn_uint642INTEGER(&gbrQosInformation->e_RAB_GuaranteedBitrateUL, 0); - e_rab->e_RABlevelQoSParameters.gbrQosInformation = gbrQosInformation; -#endif - e_rab->transportLayerAddress.size = 4; e_rab->transportLayerAddress.buf = core_calloc(e_rab->transportLayerAddress.size, sizeof(c_uint8_t)); @@ -290,6 +278,90 @@ status_t s1ap_build_initial_context_setup_request( return CORE_OK; } +status_t s1ap_build_e_rab_setup_request( + pkbuf_t **s1apbuf, mme_bearer_t *bearer, pkbuf_t *esmbuf) +{ + char buf[INET_ADDRSTRLEN]; + + int encoded; + s1ap_message_t message; + S1ap_E_RABSetupRequestIEs_t *ies = &message.s1ap_E_RABSetupRequestIEs; + S1ap_E_RABToBeSetupItemBearerSUReq_t *e_rab = NULL; + struct S1ap_GBR_QosInformation *gbrQosInformation = NULL; /* OPTIONAL */ + S1ap_NAS_PDU_t *nasPdu = NULL; + mme_ue_t *mme_ue = NULL; + enb_ue_t *enb_ue = NULL; + + d_assert(esmbuf, return CORE_ERROR, "Null param"); + d_assert(bearer, return CORE_ERROR, "Null param"); + + mme_ue = bearer->mme_ue; + d_assert(mme_ue, return CORE_ERROR, "Null param"); + enb_ue = mme_ue->enb_ue; + d_assert(enb_ue, return CORE_ERROR, "Null param"); + + memset(&message, 0, sizeof(s1ap_message_t)); + + ies->mme_ue_s1ap_id = enb_ue->mme_ue_s1ap_id; + ies->eNB_UE_S1AP_ID = enb_ue->enb_ue_s1ap_id; + + e_rab = (S1ap_E_RABToBeSetupItemBearerSUReq_t *) + core_calloc(1, sizeof(S1ap_E_RABToBeSetupItemBearerSUReq_t)); + e_rab->e_RAB_ID = bearer->ebi; + e_rab->e_RABlevelQoSParameters.qCI = bearer->qos.qci; + + e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. + priorityLevel = bearer->qos.arp.priority_level; + e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. + pre_emptionCapability = !(bearer->qos.arp.pre_emption_capability); + e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. + pre_emptionVulnerability = !(bearer->qos.arp.pre_emption_vulnerability); + + gbrQosInformation = core_calloc(1, sizeof(struct S1ap_GBR_QosInformation)); + asn_uint642INTEGER(&gbrQosInformation->e_RAB_MaximumBitrateDL, + bearer->qos.mbr.downlink); + asn_uint642INTEGER(&gbrQosInformation->e_RAB_MaximumBitrateUL, + bearer->qos.mbr.uplink); + asn_uint642INTEGER(&gbrQosInformation->e_RAB_GuaranteedBitrateDL, + bearer->qos.gbr.downlink); + asn_uint642INTEGER(&gbrQosInformation->e_RAB_GuaranteedBitrateUL, + bearer->qos.gbr.uplink); + e_rab->e_RABlevelQoSParameters.gbrQosInformation = gbrQosInformation; + + e_rab->transportLayerAddress.size = 4; + e_rab->transportLayerAddress.buf = + core_calloc(e_rab->transportLayerAddress.size, sizeof(c_uint8_t)); + memcpy(e_rab->transportLayerAddress.buf, &bearer->sgw_s1u_addr, + e_rab->transportLayerAddress.size); + + s1ap_uint32_to_OCTET_STRING(bearer->sgw_s1u_teid, &e_rab->gTP_TEID); + + nasPdu = &e_rab->nAS_PDU; + nasPdu->size = esmbuf->len; + nasPdu->buf = core_calloc(nasPdu->size, sizeof(c_uint8_t)); + memcpy(nasPdu->buf, esmbuf->payload, nasPdu->size); + + ASN_SEQUENCE_ADD(&ies->e_RABToBeSetupListBearerSUReq, e_rab); + + message.procedureCode = S1ap_ProcedureCode_id_E_RABSetup; + message.direction = S1AP_PDU_PR_initiatingMessage; + + encoded = s1ap_encode_pdu(s1apbuf, &message); + s1ap_free_pdu(&message); + + d_assert(s1apbuf && encoded >= 0,return CORE_ERROR,); + + d_trace(3, "[S1AP] E-RAB Setup Request : " + "UE[eNB-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n", + enb_ue->enb_ue_s1ap_id, + INET_NTOP(&enb_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf), + enb_ue->enb->enb_id); + + pkbuf_free(esmbuf); + + return CORE_OK; +} + status_t s1ap_build_ue_context_release_commmand( pkbuf_t **s1apbuf, enb_ue_t *enb_ue, S1ap_Cause_t *cause) { diff --git a/src/mme/s1ap_build.h b/src/mme/s1ap_build.h index 0ad19820f..29d0f0bb2 100644 --- a/src/mme/s1ap_build.h +++ b/src/mme/s1ap_build.h @@ -15,6 +15,8 @@ CORE_DECLARE(status_t) s1ap_build_downlink_nas_transport( pkbuf_t **s1apbuf, enb_ue_t *enb_ue, pkbuf_t *emmbuf); CORE_DECLARE(status_t) s1ap_build_initial_context_setup_request( pkbuf_t **s1apbuf, mme_sess_t *sess, pkbuf_t *emmbuf); +CORE_DECLARE(status_t) s1ap_build_e_rab_setup_request( + pkbuf_t **s1apbuf, mme_bearer_t *bearer, pkbuf_t *esmbuf); CORE_DECLARE(status_t) s1ap_build_ue_context_release_commmand( pkbuf_t **s1apbuf, enb_ue_t *enb_ue, S1ap_Cause_t *cause); CORE_DECLARE(status_t) s1ap_build_paging(pkbuf_t **s1apbuf, mme_ue_t *mme_ue); diff --git a/test/volte_test.c b/test/volte_test.c index 01ef9cc8b..e53948b6d 100644 --- a/test/volte_test.c +++ b/test/volte_test.c @@ -218,6 +218,12 @@ static void volte_test1(abts_case *tc, void *data) ABTS_INT_NEQUAL(tc, 0, rc); pkbuf_free(recvbuf); + /* Receive E-RAB Setup */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + pkbuf_free(recvbuf); + /********** Remove Subscriber in Database */ doc = BCON_NEW("imsi", BCON_UTF8("001010123456819")); ABTS_PTR_NOTNULL(tc, doc);