diff --git a/lib/include/srslte/asn1/gtpc_ies.h b/lib/include/srslte/asn1/gtpc_ies.h index 35b5e6498..657fc7c16 100644 --- a/lib/include/srslte/asn1/gtpc_ies.h +++ b/lib/include/srslte/asn1/gtpc_ies.h @@ -400,7 +400,8 @@ enum gtpc_interface_type S2B_U_PGW_GTP_U_INTERFACE }; -struct gtpc_f_teid_ie + +typedef struct gtpc_f_teid_ie { bool ipv4_present; bool ipv6_present; @@ -408,7 +409,7 @@ struct gtpc_f_teid_ie uint32_t teid; in_addr_t ipv4; struct in6_addr ipv6; //FIXME -}; +} gtp_fteid_t; //TODO //TODO IEs between 8.22 and 8.28 missing diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index c1656afaf..992ccdae7 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -42,13 +42,17 @@ class mme_gtpc { public: + struct gtpc_ctx{ + srslte::gtp_fteid_t mme_ctr_fteid; + srslte::gtp_fteid_t sgw_ctr_fteid; + }; static mme_gtpc* get_instance(void); static void cleanup(void); bool init(srslte::log_filter *mme_gtpc_log); uint32_t get_new_ctrl_teid(); - void send_create_session_request(uint64_t imsi, uint32_t mme_s1ap_id, bool pack_attach); + void send_create_session_request(uint64_t imsi, bool pack_attach); void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach); void send_modify_bearer_request(erab_ctx_t *bearer_ctx); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 19bb0f96d..3e35844b2 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -88,7 +88,7 @@ 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, uint32_t mme_ue_s1ap_id, bool pack_attach) +mme_gtpc::send_create_session_request(uint64_t imsi, bool pack_attach) { m_mme_gtpc_log->info("Sending Create Session Request.\n"); m_mme_gtpc_log->console("Sending Create Session Request.\n"); @@ -96,7 +96,6 @@ mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id, bo 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)); @@ -113,19 +112,39 @@ mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id, bo cs_req->sender_f_teid.teid = get_new_ctrl_teid(); cs_req->sender_f_teid.ipv4 = m_mme_gtpc_ip; - m_mme_gtpc_log->info("Next control TEID: %lu \n", m_next_ctrl_teid); - m_mme_gtpc_log->info("Allocated control TEID: %lu \n", cs_req->sender_f_teid.teid); + m_mme_gtpc_log->info("Next MME control TEID: %lu \n", m_next_ctrl_teid); + m_mme_gtpc_log->info("Allocated MME control TEID: %lu \n", cs_req->sender_f_teid.teid); m_mme_gtpc_log->console("Creating Session Response -- IMSI: %015lu \n", imsi); m_mme_gtpc_log->console("Creating Session Response -- MME control TEID: %lu \n", cs_req->sender_f_teid.teid); + // APN strncpy(cs_req->apn, m_s1ap->m_s1ap_args.mme_apn.c_str(), sizeof(cs_req->apn)-1); cs_req->apn[sizeof(cs_req->apn)-1] = 0; // RAT Type //cs_req->rat_type = srslte::GTPC_RAT_TYPE::EUTRAN; - //Save RX Control TEID - m_teid_to_mme_s1ap_id.insert(std::pair(cs_req->sender_f_teid.teid, mme_ue_s1ap_id)); + //Check whether this UE is already registed + std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); + if(it == m_imsi_to_ctr_fteid.end()) + { + m_mme_gtpc_log->warning("Create Session Request being called for an UE with an active GTP-C connection.\n"); + m_mme_gtpc_log->warning("Deleting previous GTP-C connection.\n"); + std::map::iterator jt = m_mme_ctr_teid_to_imsi.find(it->second.mme_ctr_fteid.teid); + if(jt == m_ctr_teid_to_imsi.end()) + { + m_mme_gtpc_log->error("Could not find IMSI from MME Ctrl TEID.\n") + } + else + { + m_ctr_teid_to_imsi.erease(jt); + } + m_imsi_to_ctr_fteid.erease(it); + //No need to send delete session request to the SPGW. + //The create session request will be interpreted as a new request and SPGW will delete locally in existing context. + } + //Save RX Control TEID + m_mme_ctr_teid_to_imsi.insert(std::pair(cs_req->sender_f_teid.teid, imsi)); m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu, pack_attach); } @@ -190,14 +209,12 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pac //Save create session response info to E-RAB context ue_ecm_ctx_t *ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_s1ap_id); - if(ecm_ctx ==NULL) - { + if(ecm_ctx ==NULL){ m_mme_gtpc_log->error("Could not find UE ECM context\n"); return; } ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ecm_ctx->imsi); - if(emm_ctx ==NULL) - { + if(emm_ctx ==NULL){ m_mme_gtpc_log->error("Could not find UE EMM context\n"); return; } @@ -304,9 +321,9 @@ mme_gtpc::send_release_access_bearers_request(ue_ecm_ctx_t *ecm_ctx) { m_mme_gtpc_log->info("Sending GTP-C Delete Access Bearers Request\n"); srslte::gtpc_pdu rel_req_pdu; - if(ecm_ctx->state != ECM_ ) + if(ecm_ctx->state != ECM_STATE_CONNECTED ) { - + m_mme_gtpc_log->error("ECM State is not connected. No valid SGW Ctr TEID present\n"); } srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = NULL; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 97f6149f6..d897d3b2e 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -592,7 +592,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx); //Create session request m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); - m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi, ue_emm_ctx->mme_ue_s1ap_id,true); + m_mme_gtpc->send_create_session_request(ue_emm_ctx->imsi,true); *reply_flag = false; //No reply needed return true; } @@ -706,7 +706,7 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, liblte_security_generate_k_enb(ue_emm_ctx->security_ctxt.k_asme, ue_emm_ctx->security_ctxt.ul_nas_count, ue_emm_ctx->security_ctxt.k_enb); m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n",ue_emm_ctx->security_ctxt.ul_nas_count); //FIXME Send Modify context request OR send ctx release command and wait for the reply. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi, ue_ecm_ctx.mme_ue_s1ap_id,false); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx.imsi,false); m_s1ap_log->console("UE ESM Ctr TEID %d\n", ue_ecm_ctx.sgw_ctrl_fteid.teid); // m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ue_); } @@ -823,7 +823,7 @@ s1ap_nas_transport::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas { //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. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id,true); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi,true); *reply_flag = false; //No reply needed } return true; @@ -897,7 +897,7 @@ s1ap_nas_transport::handle_esm_information_response(srslte::byte_buffer_t *nas_m //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. - m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi, ue_ecm_ctx->mme_ue_s1ap_id,true); + m_mme_gtpc->send_create_session_request(ue_ecm_ctx->imsi,true); return true; }