Starting to save GTP-C context in a map, to keep the GTP-C connection even when the NAS connection is released.

master
Pedro Alvarez 7 years ago
parent e9213f807d
commit e499fffe01

@ -400,7 +400,8 @@ enum gtpc_interface_type
S2B_U_PGW_GTP_U_INTERFACE S2B_U_PGW_GTP_U_INTERFACE
}; };
struct gtpc_f_teid_ie
typedef struct gtpc_f_teid_ie
{ {
bool ipv4_present; bool ipv4_present;
bool ipv6_present; bool ipv6_present;
@ -408,7 +409,7 @@ struct gtpc_f_teid_ie
uint32_t teid; uint32_t teid;
in_addr_t ipv4; in_addr_t ipv4;
struct in6_addr ipv6; //FIXME struct in6_addr ipv6; //FIXME
}; } gtp_fteid_t;
//TODO //TODO
//TODO IEs between 8.22 and 8.28 missing //TODO IEs between 8.22 and 8.28 missing

@ -42,13 +42,17 @@ class mme_gtpc
{ {
public: 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 mme_gtpc* get_instance(void);
static void cleanup(void); static void cleanup(void);
bool init(srslte::log_filter *mme_gtpc_log); bool init(srslte::log_filter *mme_gtpc_log);
uint32_t get_new_ctrl_teid(); 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 handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu, bool pack_attach);
void send_modify_bearer_request(erab_ctx_t *bearer_ctx); void send_modify_bearer_request(erab_ctx_t *bearer_ctx);
void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu);

@ -88,7 +88,7 @@ mme_gtpc::get_new_ctrl_teid()
return m_next_ctrl_teid++; //FIXME Use a Id pool? return m_next_ctrl_teid++; //FIXME Use a Id pool?
} }
void 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->info("Sending Create Session Request.\n");
m_mme_gtpc_log->console("Sending Create Session Request.\n"); m_mme_gtpc_log->console("Sending Create Session Request.\n");
@ -97,7 +97,6 @@ mme_gtpc::send_create_session_request(uint64_t imsi, uint32_t mme_ue_s1ap_id, bo
struct srslte::gtpc_pdu cs_resp_pdu; struct srslte::gtpc_pdu cs_resp_pdu;
//Initialize GTP-C message to zero //Initialize GTP-C message to zero
bzero(&cs_req_pdu, sizeof(struct srslte::gtpc_pdu)); 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.teid = get_new_ctrl_teid();
cs_req->sender_f_teid.ipv4 = m_mme_gtpc_ip; 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("Next MME 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("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 -- IMSI: %015lu \n", imsi);
m_mme_gtpc_log->console("Creating Session Response -- MME control TEID: %lu \n", cs_req->sender_f_teid.teid); m_mme_gtpc_log->console("Creating Session Response -- MME control TEID: %lu \n", cs_req->sender_f_teid.teid);
// APN // APN
strncpy(cs_req->apn, m_s1ap->m_s1ap_args.mme_apn.c_str(), sizeof(cs_req->apn)-1); 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; cs_req->apn[sizeof(cs_req->apn)-1] = 0;
// RAT Type // RAT Type
//cs_req->rat_type = srslte::GTPC_RAT_TYPE::EUTRAN; //cs_req->rat_type = srslte::GTPC_RAT_TYPE::EUTRAN;
//Save RX Control TEID //Check whether this UE is already registed
m_teid_to_mme_s1ap_id.insert(std::pair<uint32_t,uint32_t>(cs_req->sender_f_teid.teid, mme_ue_s1ap_id)); std::map<uint64_t, srslte::gtcp_f_teid>::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<uint32_t, uint64_t>::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<uint32_t,uint64_t>(cs_req->sender_f_teid.teid, imsi));
m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu, pack_attach); 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 //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); 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"); m_mme_gtpc_log->error("Could not find UE ECM context\n");
return; return;
} }
ue_emm_ctx_t *emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ecm_ctx->imsi); 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"); m_mme_gtpc_log->error("Could not find UE EMM context\n");
return; 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"); m_mme_gtpc_log->info("Sending GTP-C Delete Access Bearers Request\n");
srslte::gtpc_pdu rel_req_pdu; 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; srslte::gtpc_f_teid_ie *sgw_ctrl_fteid = NULL;

@ -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); m_s1ap->add_new_ue_ecm_ctx(ue_ecm_ctx);
//Create session request //Create session request
m_s1ap_log->console("GUTI Attach -- NAS Integrity OK."); 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 *reply_flag = false; //No reply needed
return true; 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); 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); 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. //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_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_); // 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. //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. //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 *reply_flag = false; //No reply needed
} }
return true; 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. //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. //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; return true;
} }

Loading…
Cancel
Save