From 8c9704ef3cc95913229569026822e09654407007 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 21 Dec 2017 18:48:31 +0000 Subject: [PATCH] Adding delete session request. --- lib/include/srslte/asn1/gtpc.h | 2 ++ lib/include/srslte/asn1/gtpc_msg.h | 33 +++++++++++++++++++++++ srsepc/hdr/mme/mme_gtpc.h | 1 + srsepc/hdr/spgw/spgw.h | 1 + srsepc/src/mme/mme_gtpc.cc | 34 ++++++++++++++++++++++++ srsepc/src/mme/s1ap.cc | 17 ++++++++++-- srsepc/src/spgw/spgw.cc | 42 ++++++++++++++++++++++++------ 7 files changed, 120 insertions(+), 10 deletions(-) diff --git a/lib/include/srslte/asn1/gtpc.h b/lib/include/srslte/asn1/gtpc.h index 23a4d7118..aca57a4bf 100644 --- a/lib/include/srslte/asn1/gtpc.h +++ b/lib/include/srslte/asn1/gtpc.h @@ -76,6 +76,8 @@ typedef union gtpc_msg_choice struct gtpc_create_session_response create_session_response; struct gtpc_modify_bearer_request modify_bearer_request; struct gtpc_modify_bearer_response modify_bearer_response; + struct gtpc_delete_session_request delete_session_request; + struct gtpc_delete_session_response delete_session_response; } gtpc_msg_choice_t; /**************************************************************************** diff --git a/lib/include/srslte/asn1/gtpc_msg.h b/lib/include/srslte/asn1/gtpc_msg.h index efd2a2290..4271b064d 100644 --- a/lib/include/srslte/asn1/gtpc_msg.h +++ b/lib/include/srslte/asn1/gtpc_msg.h @@ -377,5 +377,38 @@ struct gtpc_modify_bearer_response //ext }; +/**************************************************************************** + * + * GTP-C v2 Delete Session Resquest + * Ref: 3GPP TS 29.274 v10.14.0 Table 7.2.9.1-1 + * + ***************************************************************************/ + +struct gtpc_delete_session_request +{ + struct gtpc_cause_ie cause; + //Linked EPS Bearer ID + //User Location Information + //Indication Flags + //Protocol Configuration Options + //Originating Node + //Private extension +}; + +/**************************************************************************** + * + * GTP-C v2 Delete Session Response + * Ref: 3GPP TS 29.274 v10.14.0 Table 7.2.10.1-1 + * + ***************************************************************************/ + +struct gtpc_delete_session_response +{ + struct gtpc_cause_ie cause; + //Recovery + //Protocol Configuration Options + //Private extension +}; + } //namespace #endif //GTPC_V2_MSG_H diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 2c4cb10c9..f2804e22b 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -52,6 +52,7 @@ public: void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu); void send_modify_bearer_request(erab_ctx_t *bearer_ctx); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); + void send_delete_session_request(ue_ctx_t *ue_ctx); private: diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index 047a5db9a..095b4d9b0 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -75,6 +75,7 @@ public: void handle_create_session_request(struct srslte::gtpc_create_session_request *cs_req, struct srslte::gtpc_pdu *cs_resp_pdu); void handle_modify_bearer_request(struct srslte::gtpc_pdu *mb_req_pdu, struct srslte::gtpc_pdu *mb_resp_pdu); + void handle_delete_session_request(struct srslte::gtpc_pdu *del_req_pdu, struct srslte::gtpc_pdu *del_resp_pdu); void handle_sgi_pdu(srslte::byte_buffer_t *msg); void handle_s1u_pdu(srslte::byte_buffer_t *msg); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 4d7a0aee9..ade0a0687 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -212,4 +212,38 @@ mme_gtpc::handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu) return; } +void +mme_gtpc::send_delete_session_request(ue_ctx_t *ue_ctx) +{ + m_mme_gtpc_log->info("Sending GTP-C Delete Session Request request\n"); + srslte::gtpc_pdu del_req_pdu; + srslte::gtpc_f_teid_ie *sgw_ctrl_fteid; + + //FIXME the UE control TEID sould be stored in the UE ctxt, not in the E-RAB ctxt + //Maybe a mme_s1ap_id to ctrl teid map as well? + + for(int i = 0; ierabs_ctx[i].state != ERAB_DEACTIVATED) + { + sgw_ctrl_fteid = &ue_ctx->erabs_ctx[i].sgw_ctrl_fteid; + break; + } + } + + srslte::gtpc_header *header = &del_req_pdu.header; + header->teid_present = true; + header->teid = sgw_ctrl_fteid->teid; + header->type = srslte::GTPC_MSG_TYPE_DELETE_SESSION_REQUEST; + + srslte::gtpc_delete_session_request *del_req = &del_req_pdu.choice.delete_session_request; + del_req->cause.cause_value = srslte::GTPC_CAUSE_VALUE_ISR_DEACTIVATION; + m_mme_gtpc_log->info("GTP-C Delete Session Request -- S-GW Control TEID %d\n", sgw_ctrl_fteid->teid ); + + srslte::gtpc_pdu del_resp_pdu; + m_spgw->handle_delete_session_request(&del_req_pdu, &del_resp_pdu); + + //TODO Handle delete session response + return; +} } //namespace srsepc diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 322ae165b..e7650e871 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -506,7 +506,7 @@ s1ap::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQU { m_s1ap_log->error("Could not find eNB for this request.\n"); return false; - } + } uint16_t enb_id = it->second; std::map >::iterator ue_set = m_enb_id_to_ue_ids.find(enb_id); if(ue_set == m_enb_id_to_ue_ids.end()) @@ -517,7 +517,20 @@ s1ap::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQU ue_set->second.erase(mme_ue_s1ap_id); //Delete any context at the SPGW - //m_spgw->delete_session_request(ue_ctx->imsi); + bool active = false; + for(int i=0;isecond->erabs_ctx[i].state != ERAB_DEACTIVATED) + { + active = true; + break; + } + } + if(active == true) + { + //There are active E-RABs, send delete session request + m_mme_gtpc->send_delete_session_request(ue_ctx->second); + } //Delete UE context delete ue_ctx->second; diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index 01592286f..c4064d695 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -375,7 +375,7 @@ spgw::handle_sgi_pdu(srslte::byte_buffer_t *msg) int n = sendto(m_s1u,msg->msg,msg->N_bytes,0,(struct sockaddr*) &enb_addr,sizeof(enb_addr)); if(n<0) { - m_spgw_log->console("Error sending packet to eNB\n"); + m_spgw_log->error("Error sending packet to eNB\n"); return; } //m_spgw_log->console("Sent packet to %s:%d. Bytes=%d\n",inet_ntoa(enb_addr.sin_addr), GTPU_RX_PORT,n); @@ -437,7 +437,8 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request * in_addr_t ue_ip = get_new_ue_ipv4(); uint8_t default_bearer_id = 5; - //Save the UE IP to User TEID map //TODO!!! + + //Save the UE IP to User TEID map spgw_tunnel_ctx_t *tunnel_ctx = new spgw_tunnel_ctx_t; tunnel_ctx->imsi = cs_req->imsi; tunnel_ctx->ebi = default_bearer_id; @@ -449,6 +450,7 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request * tunnel_ctx->up_ctrl_fteid.teid = spgw_uplink_ctrl_teid; tunnel_ctx->ue_ipv4 = ue_ip; m_teid_to_tunnel_ctx.insert(std::pair(spgw_uplink_ctrl_teid,tunnel_ctx)); + //Create session response message //Setup GTP-C header header->piggyback = false; @@ -479,13 +481,9 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request * return; } - /* -void -spgw::delete_session_request(uint64_t imsi) -{ -} - */ + + void spgw::handle_modify_bearer_request(struct srslte::gtpc_pdu *mb_req_pdu, struct srslte::gtpc_pdu *mb_resp_pdu) { @@ -541,4 +539,32 @@ spgw::handle_modify_bearer_request(struct srslte::gtpc_pdu *mb_req_pdu, struct s printf("%d %d\n",mb_resp->eps_bearer_context_modified.ebi, tunnel_ctx->ebi); mb_resp->eps_bearer_context_modified.cause.cause_value = srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED; } + +void +spgw::handle_delete_session_request(struct srslte::gtpc_pdu *del_req_pdu, struct srslte::gtpc_pdu *del_resp_pdu) +{ + //Find tunel ctxt + uint32_t ctrl_teid = del_req_pdu->header.teid; + std::map::iterator tunnel_it = m_teid_to_tunnel_ctx.find(ctrl_teid); + if(tunnel_it == m_teid_to_tunnel_ctx.end()) + { + m_spgw_log->warning("Could not find TEID %d to delete\n",ctrl_teid); + return; + } + spgw_tunnel_ctx_t *tunnel_ctx = tunnel_it->second; + in_addr_t ue_ipv4 = tunnel_ctx->ue_ipv4; + + //Delete data tunnel + pthread_mutex_lock(&m_mutex); + std::map::iterator data_it = m_ip_to_teid.find(tunnel_ctx->ue_ipv4); + if(data_it != m_ip_to_teid.end()) + { + m_ip_to_teid.erase(data_it); + } + pthread_mutex_unlock(&m_mutex); + + delete tunnel_ctx; + return; +} + } //namespace srsepc