From 6cd055e80e1609752d579696028eaa9039520b4d Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 27 Nov 2017 19:13:34 +0000 Subject: [PATCH] Continuing to work on initial context setup request. --- lib/include/srslte/asn1/gtpc.h | 4 +++ lib/include/srslte/asn1/gtpc_msg.h | 2 +- srsepc/hdr/mme/mme_gtpc.h | 2 +- srsepc/hdr/mme/s1ap.h | 2 +- srsepc/src/mme/mme_gtpc.cc | 36 +++++++++++++++---- srsepc/src/mme/s1ap.cc | 57 +++++++++++++++++++----------- 6 files changed, 72 insertions(+), 31 deletions(-) diff --git a/lib/include/srslte/asn1/gtpc.h b/lib/include/srslte/asn1/gtpc.h index ce46ab9e2..8fdbab53d 100644 --- a/lib/include/srslte/asn1/gtpc.h +++ b/lib/include/srslte/asn1/gtpc.h @@ -27,6 +27,10 @@ #include #include "srslte/asn1/gtpc_msg.h" +//Helpful marcos to convert TEIDs (uint64_t) to/from network byte order +#define HTONLL(x) ((1==htonl(1)) ? (x) : (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32))) +#define NTOHLL(x) ((1==ntohl(1)) ? (x) : (((uint64_t)ntohl((x) & 0xFFFFFFFFUL)) << 32) | ntohl((uint32_t)((x) >> 32))) + namespace srslte{ /*GTP-C Version*/ diff --git a/lib/include/srslte/asn1/gtpc_msg.h b/lib/include/srslte/asn1/gtpc_msg.h index 4db2e9c6f..a72e51ac9 100644 --- a/lib/include/srslte/asn1/gtpc_msg.h +++ b/lib/include/srslte/asn1/gtpc_msg.h @@ -202,7 +202,7 @@ struct gtpc_create_session_request struct gtpc_f_teid_ie s12_rnc_f_teid; bool s2b_u_epdg_f_teid_present; struct gtpc_f_teid_ie s2b_u_epdg_f_teid; - } bearer_context_created; // M + } eps_bearer_context_created; // M //bool bearer_context_deleted_present; //struct bearer_context_ bearer_context_deleted; // C //bool trace_information_present; diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index d003e9cc6..db886f137 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -46,7 +46,7 @@ public: void init(); uint64_t get_new_ctrl_teid(); - void send_create_session_request(uint64_t imsi, struct srslte::gtpc_pdu *cs_resp_pdu); + void send_create_session_request(uint64_t imsi, uint32_t mme_s1ap_id); void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu); private: diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 3fdfda9bc..ebf4ae60d 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -81,7 +81,7 @@ public: bool handle_nas_authentication_response(srslte::byte_buffer_t *nas_buffer, srslte::byte_buffer_t *reply_buffer, ue_ctx_t *ue_ctx); bool handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_msg, ue_ctx_t *ue_ctx); - bool send_initial_context_setup_request(struct srslte::gtpc_create_session_response *cs_resp); + bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp); void print_enb_ctx_info(const enb_ctx_t &enb_ctx); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 9a65d78fa..58c1d3ef2 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -79,11 +79,14 @@ mme_gtpc::get_new_ctrl_teid() return m_next_ctrl_teid++; //FIXME Use a Id pool? } void -mme_gtpc::send_create_session_request(uint64_t imsi, struct srslte::gtpc_pdu *cs_resp_pdu) +mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id) { struct srslte::gtpc_pdu cs_req_pdu; struct srslte::gtpc_create_session_request *cs_req = &cs_req_pdu.choice.create_session_request; + struct srslte::gtpc_pdu cs_resp_pdu; + + //Initialize GTP-C message to zero bzero(&cs_req_pdu, sizeof(struct srslte::gtpc_pdu)); @@ -95,7 +98,7 @@ mme_gtpc::send_create_session_request(uint64_t imsi, struct srslte::gtpc_pdu *cs //Setup GTP-C Create Session Request IEs // Control TEID allocated \\ - cs_req->sender_f_teid.tied = get_new_ctrl_teid(); + cs_req->sender_f_teid.teid = get_new_ctrl_teid(); cs_req->sender_f_teid.ipv4 = m_mme_gtpc_ip; // APN \\ memcpy(cs_req->apn, "internet", sizeof("internet")); @@ -103,20 +106,39 @@ mme_gtpc::send_create_session_request(uint64_t imsi, struct srslte::gtpc_pdu *cs cs_req->rat_type = GTPC_RAT_TYPE::EUTRAN; //Save RX Control TEID - //create_rx_control_teid(cs_req->sender_f_teid); + m_teid_to_mme_s1ap_id.insert(std::pair(cs_req->sender_f_teid.teid, mme_ue_s1ap_id)); - m_spgw->handle_create_session_request(cs_req, cs_resp_pdu); - return; + m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu); + handle_create_session_response(&cs_resp_pdu); + } void mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) { + struct srslte::gtpc_create_session_response *cs_resp = & cs_resp_pdu->choice.create_session_response; + + if (cs_resp_pdu->header.type != srslte::GTPC_MSG_TYPE_CREATE_SESSION_RESPONSE) + { + //m_mme_gtpc_log->warning("Could not create GTPC session.\n"); + //TODO Handle err + return; + } + if (cs_resp->cause.cause_value != srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED){ + //m_mme_gtpc_log->warning("Could not create GTPC session.\n"); + //TODO Handle error + return; + } + //Get MME_UE_S1AP_ID from the Ctrl TEID std::map::iterator id_it = m_teid_to_mme_s1ap_id.find(cs_resp_pdu->header.teid); + if(id_it == m_teid_to_mme_s1ap_id.end()) + { + //Could not find MME UE S1AP TEID + return; + } uint32_t mme_s1ap_id = id_it->second; - - m_s1ap->send_intial_context_setup_request(mme_s1ap_id, &cs_resp_pdu->choice.create_session_request); + m_s1ap->send_initial_context_setup_request(mme_s1ap_id, cs_resp); } } //namespace srsepc diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index e0f74b710..3ceed89bb 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -50,7 +50,7 @@ s1ap::get_instance(void) { boost::mutex::scoped_lock lock(s1ap_instance_mutex); if(NULL == m_instance) { - m_instance = new mme(); + m_instance = new s1ap(); } return(m_instance); } @@ -538,37 +538,41 @@ s1ap::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, srslte:: //FIXME The packging of GTP-C messages is not ready. //This means that GTP-U tunnels are created with function calls, as opposed to GTP-C. - struct srslte::gtpc_pdu cs_resp_pdu; - struct srslte::gtpc_create_session_response *cs_resp = & cs_resp_pdu.choice.create_session_response; + m_mme_gtpc->send_create_session_request(ue_ctx->imsi, ue_ctx->mme_ue_s1ap_id); - m_mme_gtpc->send_create_session_request(ue_ctx->imsi, &cs_resp_pdu); - if (cs_resp->cause.cause_value != srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED){ - m_s1ap_log->warning("Could not create GTPC session.\n"); - //TODO Handle error - } - else{ - send_initial_context_setup_request(cs_resp); - } return true; } bool -s1ap::send_initial_context_setup_request(struct srslte::gtpc_create_session_response *cs_resp) +s1ap::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp) { + //Find UE Context + ue_ctx_t *ue_ctx; + std::map::iterator ue_ctx_it = m_active_ues.find(mme_ue_s1ap_id); + if(ue_ctx_it == m_active_ues.end()) + { + m_s1ap_log->error("Could not find UE to send Setup Context Request. MME S1AP Id: %d", mme_ue_s1ap_id); + return false; + } + ue_ctx = ue_ctx_it->second; + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT in_ctxt_req; - uint64_t imsi = m_mme_gtpc->ctrl_teid_to_imsi(); bzero(&in_ctxt_req, sizeof(in_ctxt_req)); - in_ctxt_req.MME_UE_S1AP_ID = ; - in_ctxt_req.eNB_UE_S1AP_ID =; - in_ctxt_req.uEaggregateMaximumBitrate =; - + in_ctxt_req.MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctx->mme_ue_s1ap_id; + in_ctxt_req.eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctx->enb_ue_s1ap_id; + in_ctxt_req.uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL.BitRate=4294967295;//2^32-1 + in_ctxt_req.uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL.BitRate=4294967295;//FIXME Get UE-AMBR from HSS //eRAB context to setup - LIBLTE_S1AP_E_RABSETUPITEMCTXTSURES_STRUCT *erab_ctxt = &in_ctxt_req.E_RABToBeSetupListCtxtSUReq.buffer[0]; //FIXME? - erab_ctxt->e_RAB_ID = cs_resp->bearer_context_created.ebi; - erab_ctxt->transportLayerAddress = cs_resp->bearer_context_created.sender_f_teid.ipv4; - erab_ctxt->gTP_TEID = cs_resp->bearer_context_created.sender_f_teid.teid; + LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt = &in_ctxt_req.E_RABToBeSetupListCtxtSUReq.buffer[0]; //FIXME? + erab_ctxt->e_RAB_ID.E_RAB_ID = cs_resp->eps_bearer_context_created.ebi; + if (cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present == false){ + m_s1ap_log->error("Did not receive S1-U TEID in create session response\n"); + return false; + } + erab_ctxt->transportLayerAddress = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4; + memcpy(erab_ctxt->gTP_TEID.buffer, cs_resp->eps_bearer_context_created.sender_f_teid.teid, sizeof(uint64_t)); in_ctxt_req->UESecurityCapabilities =; in_ctxt_req->SecurityKey = ; @@ -589,6 +593,17 @@ s1ap::send_initial_context_setup_request(struct srslte::gtpc_create_session_resp bool iE_Extensions_present; }LIBLTE_S1AP_E_RABSETUPITEMCTXTSURES_STRUCT; */ + /*typedef struct{ + bool ext; + uint32_t n_bits; + uint8_t buffer[160]; + }LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT; + */ + /* + typedef struct{ + uint8_t buffer[4]; + }LIBLTE_S1AP_GTP_TEID_STRUCT; + */ /*typedef struct{ bool ext; LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID;