diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 9979b6594..3e4136141 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -47,7 +47,9 @@ public: void init(void); - bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); + //bool send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid); + bool send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, ue_ecm_ctx_t *ecm_ctx, uint16_t erab_id, + struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid, struct srslte::gtpc_f_teid_ie sgw_s1u_fteid, struct srslte::gtpc_pdn_address_allocation_ie pdn_addr_aloc); bool handle_initial_context_setup_response(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *in_ctxt_resp); bool handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool send_ue_context_release_command(ue_ecm_ctx_t *ecm_ctx, srslte::byte_buffer_t *reply_buffer); diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index ba9d38577..6d645c095 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -77,7 +77,12 @@ s1ap_ctx_mngmt_proc::init(void) } bool -s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp, struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid) +s1ap_ctx_mngmt_proc::send_initial_context_setup_request(ue_emm_ctx_t *emm_ctx, + ue_ecm_ctx_t *ecm_ctx, + uint16_t erab_id, + struct srslte::gtpc_f_teid_ie sgw_ctrl_fteid, + struct srslte::gtpc_f_teid_ie sgw_s1u_fteid, + struct srslte::gtpc_pdn_address_allocation_ie pdn_addr_alloc) { int s1mme = m_s1ap->get_s1_mme(); @@ -97,23 +102,9 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, m_s1ap_log->info("Preparing to send Initial Context Setup request\n"); - //Find UE Context - ue_ecm_ctx_t *ue_ecm_ctx = m_s1ap->find_ue_ecm_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); - if(ue_ecm_ctx == NULL) - { - m_s1ap_log->error("Could not find UE to send Setup Context Request. MME S1AP Id: %d", mme_ue_s1ap_id); - return false; - } - ue_emm_ctx_t *ue_emm_ctx = m_s1ap->find_ue_emm_ctx_from_imsi(ue_ecm_ctx->imsi); - if(ue_emm_ctx == NULL) - { - m_s1ap_log->error("Could not find UE to send Setup Context Request. MME S1AP Id: %d", mme_ue_s1ap_id); - return false; - } - //Add MME and eNB S1AP Ids - in_ctxt_req->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id; - in_ctxt_req->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id; + in_ctxt_req->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ecm_ctx->mme_ue_s1ap_id; + in_ctxt_req->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ecm_ctx->enb_ue_s1ap_id; //Set UE-AMBR in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL.BitRate=1000000000; @@ -121,7 +112,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, //Setup eRAB context in_ctxt_req->E_RABToBeSetupListCtxtSUReq.len = 1; - erab_ctxt->e_RAB_ID.E_RAB_ID = cs_resp->eps_bearer_context_created.ebi; + erab_ctxt->e_RAB_ID.E_RAB_ID = erab_id; //Setup E-RAB QoS parameters erab_ctxt->e_RABlevelQoSParameters.qCI.QCI = 9; erab_ctxt->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel.PriorityLevel = 15 ;//Lowest @@ -131,25 +122,25 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, erab_ctxt->e_RABlevelQoSParameters.gbrQosInformation_present=false; //Set E-RAB S-GW F-TEID - 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; - } + //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.n_bits = 32; //IPv4 - uint32_t sgw_s1u_ip = htonl(cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4); + uint32_t sgw_s1u_ip = htonl(sgw_s1u_fteid.ipv4); //uint32_t sgw_s1u_ip = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4; uint8_t *tmp_ptr = erab_ctxt->transportLayerAddress.buffer; liblte_value_2_bits(sgw_s1u_ip, &tmp_ptr, 32);//FIXME consider ipv6 - uint32_t tmp_teid = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.teid; - memcpy(erab_ctxt->gTP_TEID.buffer, &tmp_teid, sizeof(uint32_t)); + uint32_t sgw_s1u_teid = sgw_s1u_fteid.teid; + memcpy(erab_ctxt->gTP_TEID.buffer, &sgw_s1u_teid, sizeof(uint32_t)); //Set UE security capabilities and k_enb bzero(in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer,sizeof(uint8_t)*16); bzero(in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer,sizeof(uint8_t)*16); for(int i = 0; i<3; i++) { - if(ue_emm_ctx->security_ctxt.ue_network_cap.eea[i+1] == true) + if(emm_ctx->security_ctxt.ue_network_cap.eea[i+1] == true) { in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 1; //EEA supported } @@ -157,7 +148,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, { in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 0; //EEA not supported } - if(ue_emm_ctx->security_ctxt.ue_network_cap.eia[i+1] == true) + if(emm_ctx->security_ctxt.ue_network_cap.eia[i+1] == true) { in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[i] = 1; //EEA supported } @@ -168,21 +159,22 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, // in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[0] = 1; //EIA1 } //Get K eNB - liblte_unpack(ue_emm_ctx->security_ctxt.k_enb, 32, in_ctxt_req->SecurityKey.buffer); - m_s1ap_log->info_hex(ue_emm_ctx->security_ctxt.k_enb, 32, "Initial Context Setup Request -- Key eNB\n"); + liblte_unpack(emm_ctx->security_ctxt.k_enb, 32, in_ctxt_req->SecurityKey.buffer); + m_s1ap_log->info_hex(emm_ctx->security_ctxt.k_enb, 32, "Initial Context Setup Request -- Key eNB\n"); + //Set Attach accepted and activat default bearer NAS messages - if(cs_resp->paa_present != true) - { - m_s1ap_log->error("PAA not present\n"); - return false; - } - if(cs_resp->paa.pdn_type != srslte::GTPC_PDN_TYPE_IPV4) - { - m_s1ap_log->error("IPv6 not supported yet\n"); - return false; - } + //if(cs_resp->paa_present != true) + //{ + // m_s1ap_log->error("PDN Adress Allocation not present\n"); + // return false; + //} + //if(cs_resp->paa.pdn_type != srslte::GTPC_PDN_TYPE_IPV4) + //{ + // m_s1ap_log->error("IPv6 not supported yet\n"); + // return false; + //} srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); - m_s1ap_nas_transport->pack_attach_accept(ue_emm_ctx, ue_ecm_ctx, erab_ctxt, &cs_resp->paa, nas_buffer); + m_s1ap_nas_transport->pack_attach_accept(emm_ctx, ecm_ctx, erab_ctxt, &pdn_addr_alloc, nas_buffer); LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); @@ -192,7 +184,7 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, return false; } //Send Reply to eNB - ssize_t n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ue_ecm_ctx->enb_sri, 0); + ssize_t n_sent = sctp_send(s1mme,reply_buffer->msg, reply_buffer->N_bytes, &ecm_ctx->enb_sri, 0); if(n_sent == -1) { m_s1ap_log->error("Failed to send Initial Context Setup Request\n"); @@ -200,16 +192,16 @@ s1ap_ctx_mngmt_proc::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, } //Change E-RAB state to Context Setup Requested and save S-GW control F-TEID - ue_ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].state = ERAB_CTX_REQUESTED; - ue_ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; - ue_ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; + ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].state = ERAB_CTX_REQUESTED; + ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.teid = sgw_ctrl_fteid.teid; + ecm_ctx->erabs_ctx[erab_ctxt->e_RAB_ID.E_RAB_ID].sgw_ctrl_fteid.ipv4 = sgw_ctrl_fteid.ipv4; struct in_addr addr; addr.s_addr = htonl(sgw_s1u_ip); m_s1ap_log->info("Sent Intial Context Setup Request. E-RAB id %d \n",erab_ctxt->e_RAB_ID.E_RAB_ID); - m_s1ap_log->info("Initial Context -- S1-U TEID 0x%x. IP %s \n", tmp_teid,inet_ntoa(addr)); + m_s1ap_log->info("Initial Context -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); m_s1ap_log->console("Sent Intial Context Setup Request, E-RAB id %d\n",erab_ctxt->e_RAB_ID.E_RAB_ID); - m_s1ap_log->console("Initial Context -- S1-U TEID 0x%x. IP %s \n", tmp_teid,inet_ntoa(addr)); + m_s1ap_log->console("Initial Context -- S1-U TEID 0x%x. IP %s \n", sgw_s1u_teid,inet_ntoa(addr)); m_pool->deallocate(reply_buffer); m_pool->deallocate(nas_buffer); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 9c445878f..99cbc52f5 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -378,7 +378,6 @@ s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, //Save whether secure ESM information transfer is necessary ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; - //Add eNB info to UE ctxt //Initialize E-RABs for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { @@ -543,6 +542,28 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, msg_valid = integrity_check(ue_emm_ctx,nas_msg); if(msg_valid == true) { + //Create new MME UE S1AP Identity + ue_emm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + + //Create UE ECM context + ue_ecm_ctx_t ue_ecm_ctx; + + //Set UE ECM context + ue_ecm_ctx.imsi = ue_emm_ctx->imsi; + ue_ecm_ctx.mme_ue_s1ap_id = ue_emm_ctx->mme_ue_s1ap_id; + //Set eNB information + ue_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ue_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + //Save whether secure ESM information transfer is necessary + ue_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; + + //Initialize E-RABs + for(uint i = 0 ; i< MAX_ERABS_PER_UE; i++) + { + ue_ecm_ctx.erabs_ctx[i].state = ERAB_DEACTIVATED; + ue_ecm_ctx.erabs_ctx[i].erab_id = i; + } + 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); @@ -608,9 +629,10 @@ s1ap_nas_transport::handle_nas_service_request(uint32_t m_tmsi, if(ecm_ctx !=NULL) { //Service request to Connected UE. - //Delete ECM context and connect. - m_mme_gtpc->send_delete_session_request(ecm_ctx); - //m_s1ap send_context_release_request(ecm_ctx, reply_buffer); + //Delete eNB context and connect. + + m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(ecm_ctx,reply_buffer); + m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(ecm_ctx); } else {