Changing Handling of initial UE NAS messages to use static methods. Handling of unknown GUTI attach request should be ok.

This commit is contained in:
Pedro Alvarez 2018-08-27 16:06:18 +01:00
parent 9e808ff968
commit 860e1b5491
6 changed files with 51 additions and 223 deletions

View File

@ -53,6 +53,8 @@ public:
virtual bool add_nas_ctx_to_mme_ue_s1ap_id_map(nas *nas_ctx) = 0;
virtual bool add_ue_to_enb_set(int32_t enb_assoc, uint32_t mme_ue_s1ap_id) = 0;
virtual bool release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) = 0;
virtual uint64_t find_imsi_from_m_tmsi(uint32_t m_tmsi) = 0;
virtual nas* find_nas_ctx_from_imsi(uint64_t imsi) = 0;
virtual bool send_initial_context_setup_request(uint64_t imsi, uint16_t erab_to_setup) = 0;
virtual bool send_ue_context_release_command(uint32_t mme_ue_s1ap_id) = 0;
virtual bool send_downlink_nas_transport(uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *nas_msg, struct sctp_sndrcvinfo enb_sri) = 0;

View File

@ -160,7 +160,7 @@ public:
//Attach request messages
static bool handle_attach_request( uint32_t enb_ue_s1ap_id,
struct sctp_sndrcvinfo *enb_sri,
srslte::byte_buffer_t *nas_msg,
srslte::byte_buffer_t *nas_rx,
nas_init_t args,
s1ap_interface_nas *s1ap,
gtpc_interface_nas *gtpc,
@ -196,7 +196,8 @@ public:
bool handle_guti_attach_request_known_ue( uint32_t enb_ue_s1ap_id,
struct sctp_sndrcvinfo *enb_sri,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req,
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req);
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req,
srslte::byte_buffer_t *nas_rx);
//Service request Messages
//Dettach request Messages

View File

@ -89,7 +89,7 @@ public:
bool add_nas_ctx_to_mme_ue_s1ap_id_map(nas *nas_ctx);
bool add_ue_to_enb_set(int32_t enb_assoc, uint32_t mme_ue_s1ap_id);
nas* find_nas_ctx_from_imsi(uint64_t imsi);
virtual nas* find_nas_ctx_from_imsi(uint64_t imsi);
nas* find_nas_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id);
bool release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id);
@ -97,7 +97,7 @@ public:
bool delete_ue_ctx(uint64_t imsi);
uint32_t allocate_m_tmsi(uint64_t imsi);
uint64_t find_imsi_from_m_tmsi(uint32_t m_tmsi);
virtual uint64_t find_imsi_from_m_tmsi(uint32_t m_tmsi);
s1ap_args_t m_s1ap_args;
srslte::log_filter *m_s1ap_log;

View File

@ -48,27 +48,6 @@ public:
bool handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *ul_xport, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag);
bool send_downlink_nas_transport(uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *nas_msg, struct sctp_sndrcvinfo enb_sri);
bool handle_nas_attach_request(uint32_t enb_ue_s1ap_id,
srslte::byte_buffer_t *nas_msg,
srslte::byte_buffer_t *reply_buffer,
bool* reply_flag,
struct sctp_sndrcvinfo *enb_sri);
bool handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req,
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req,
srslte::byte_buffer_t *reply_buffer,
bool* reply_flag,
struct sctp_sndrcvinfo *enb_sri);
bool handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req,
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req,
srslte::byte_buffer_t *nas_msg,
srslte::byte_buffer_t *reply_buffer,
bool* reply_flag,
struct sctp_sndrcvinfo *enb_sri);
bool handle_nas_detach_request( uint32_t m_tmsi,
uint32_t enb_ue_s1ap_id,
srslte::byte_buffer_t *nas_msg,

View File

@ -65,10 +65,10 @@ nas::init(nas_init_t args,
* Handle UE Initiating Messages
*
********************************/
static bool
bool
nas::handle_attach_request( uint32_t enb_ue_s1ap_id,
struct sctp_sndrcvinfo *enb_sri,
srslte::byte_buffer_t *nas_msg,
srslte::byte_buffer_t *nas_rx,
nas_init_t args,
s1ap_interface_nas *s1ap,
gtpc_interface_nas *gtpc,
@ -81,7 +81,7 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id,
LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req;
//Get NAS Attach Request and PDN connectivity request messages
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_req);
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_rx, &attach_req);
if(err != LIBLTE_SUCCESS){
nas_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]);
return false;
@ -165,7 +165,7 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id,
} else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) {
nas_log->console("Attach Request -- GUTI-style attach request\n");
nas_log->info("Attach Request -- GUTI-style attach request\n");
nas_ctx->handle_guti_attach_request_known_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req);
nas_ctx->handle_guti_attach_request_known_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, nas_rx);
} else {
nas_log->error("Unhandled Mobile Id type in attach request\n");
return false;
@ -176,7 +176,7 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id,
return true;
}
static bool
bool
nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
struct sctp_sndrcvinfo *enb_sri,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req,
@ -190,6 +190,7 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
{
return true;
}
bool
nas::handle_imsi_attach_request_known_ue( uint32_t enb_ue_s1ap_id,
struct sctp_sndrcvinfo *enb_sri,
@ -272,7 +273,8 @@ bool
nas::handle_guti_attach_request_known_ue( uint32_t enb_ue_s1ap_id,
struct sctp_sndrcvinfo *enb_sri,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req,
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req)
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req,
srslte::byte_buffer_t *nas_rx)
{
m_nas_log->console("Found UE context. IMSI: %015lu, old eNB UE S1ap Id %d, old MME UE S1AP Id %d\n",m_emm_ctx.imsi, m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id);
@ -407,7 +409,7 @@ nas::handle_guti_attach_request_known_ue( uint32_t enb_ue_s1ap_id,
}
}
static bool
bool
nas::handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
struct sctp_sndrcvinfo *enb_sri,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req,
@ -419,63 +421,70 @@ nas::handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
srslte::log *nas_log)
{
nas *nas_ctx;
srslte::byte_buffer_pool *pool = srslte::byte_buffer_pool::get_instance();
srslte::byte_buffer_t *nas_tx;
//Create new NAS context.
nas_ctx = new nas;
nas_ctx->init(args, s1ap, gtpc, hss, nas_log);
//Could not find IMSI from M-TMSI, send Id request
//The IMSI will be set when the identity response is received
//Set EMM ctx
m_emm_ctx.imsi = 0;
m_emm_ctx.state = EMM_STATE_DEREGISTERED;
nas_ctx->m_emm_ctx.imsi = 0;
nas_ctx->m_emm_ctx.state = EMM_STATE_DEREGISTERED;
//Save UE network capabilities
memcpy(&m_sec_ctx.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT));
m_sec_ctx.ms_network_cap_present = attach_req.ms_network_cap_present;
memcpy(&nas_ctx->m_sec_ctx.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT));
nas_ctx->m_sec_ctx.ms_network_cap_present = attach_req.ms_network_cap_present;
if (attach_req.ms_network_cap_present) {
memcpy(&m_sec_ctx.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT));
memcpy(&nas_ctx->m_sec_ctx.ms_network_cap, &attach_req.ms_network_cap, sizeof(LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT));
}
//Initialize NAS count
m_sec_ctx.ul_nas_count = 0;
m_sec_ctx.dl_nas_count = 0;
m_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id;
nas_ctx->m_sec_ctx.ul_nas_count = 0;
nas_ctx->m_sec_ctx.dl_nas_count = 0;
nas_ctx->m_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id;
//Set ECM context
m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id;
m_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id();
nas_ctx->m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id;
nas_ctx->m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id();
uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id;
//Save attach request type
m_emm_ctx.attach_type = attach_req.eps_attach_type;
nas_ctx->m_emm_ctx.attach_type = attach_req.eps_attach_type;
//Save whether ESM information transfer is necessary
m_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present;
nas_ctx->m_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present;
//Add eNB info to UE ctxt
memcpy(&m_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo));
memcpy(&nas_ctx->m_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo));
//Initialize E-RABs
for (uint i = 0 ; i< MAX_ERABS_PER_UE; i++) {
m_esm_ctx[i].state = ERAB_DEACTIVATED;
m_esm_ctx[i].erab_id = i;
nas_ctx->m_esm_ctx[i].state = ERAB_DEACTIVATED;
nas_ctx->m_esm_ctx[i].erab_id = i;
}
//Store temporary ue context
m_s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(this);
m_s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,m_ecm_ctx.mme_ue_s1ap_id);
s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx);
s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,nas_ctx->m_ecm_ctx.mme_ue_s1ap_id);
//Send Identity Request
nas_tx = m_pool->allocate();
pack_identity_request(nas_tx);
m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri);
m_pool->deallocate(nas_tx);
nas_tx = pool->allocate();
nas_ctx->pack_identity_request(nas_tx);
s1ap->send_downlink_nas_transport(nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx, nas_ctx->m_ecm_ctx.enb_sri);
pool->deallocate(nas_tx);
return true;
}
/*
/***************************************
*
* Handle Uplink NAS Transport message
* Handle Uplink NAS Transport messages
*
*/
***************************************/
bool
nas::handle_authentication_response(srslte::byte_buffer_t *nas_rx)
{

View File

@ -102,16 +102,16 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA
nas_init.mme_code = m_s1ap->m_s1ap_args.mme_code;
nas_init.mme_group = m_s1ap->m_s1ap_args.mme_group;
nas_init.tac = m_s1ap->m_s1ap_args.tac;
nas_init.mme_apn = m_s1ap->m_s1ap_args.mme_apn;
nas_init.dns_addr = m_s1ap->m_s1ap_args.dns_addr;
nas_init.apn = m_s1ap->m_s1ap_args.mme_apn;
nas_init.dns = m_s1ap->m_s1ap_args.dns_addr;
switch (msg_type)
{
case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST:
m_s1ap_log->console("Received Initial UE message -- Attach Request\n");
m_s1ap_log->info("Received Initial UE message -- Attach Request\n");
err = nas::handle_nas_attach_request(enb_ue_s1ap_id, nas_init, enb_sri, nas_msg,
m_s1ap, m_gtpc, m_hss, m_s1ap->m_nas_log);
err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg, nas_init,
m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log);
break;
case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST:
m_s1ap_log->console("Received Initial UE message -- Service Request\n");
@ -301,169 +301,6 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA
return true;
}
bool
s1ap_nas_transport::handle_nas_attach_request(uint32_t enb_ue_s1ap_id,
srslte::byte_buffer_t *nas_msg,
srslte::byte_buffer_t *reply_buffer,
bool* reply_flag,
struct sctp_sndrcvinfo *enb_sri)
{
LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req;
LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req;
//Get NAS Attach Request and PDN connectivity request messages
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_req);
if(err != LIBLTE_SUCCESS){
m_s1ap_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]);
m_pool->deallocate(nas_msg);
return false;
}
/*Get PDN Connectivity Request*/
err = liblte_mme_unpack_pdn_connectivity_request_msg(&attach_req.esm_msg, &pdn_con_req);
if(err != LIBLTE_SUCCESS){
m_s1ap_log->error("Error unpacking NAS PDN Connectivity Request. Error: %s\n", liblte_error_text[err]);
m_pool->deallocate(nas_msg);
return false;
}
//Get attach type from attach request
if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) {
m_s1ap_log->console("Attach Request -- IMSI-style attach request\n");
m_s1ap_log->info("Attach Request -- IMSI-style attach request\n");
handle_nas_imsi_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, reply_buffer, reply_flag, enb_sri);
} else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) {
m_s1ap_log->console("Attach Request -- GUTI-style attach request\n");
m_s1ap_log->info("Attach Request -- GUTI-style attach request\n");
handle_nas_guti_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, nas_msg, reply_buffer, reply_flag, enb_sri);
} else {
m_s1ap_log->error("Unhandled Mobile Id type in attach request\n");
return false;
}
return true;
}
bool
s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req,
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req,
srslte::byte_buffer_t *reply_buffer,
bool* reply_flag,
struct sctp_sndrcvinfo *enb_sri)
{
//Get UE's IMSI
uint64_t imsi = 0;
for(int i=0;i<=14;i++){
imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i);
}
//Check if UE is already attached
nas *old_ctx = m_s1ap->find_nas_ctx_from_imsi(imsi);
if (old_ctx!=NULL) {
m_s1ap_log->console("Attach Request -- UE is already attached.");
m_s1ap_log->info("Attach Request -- UE is already attached.");
//Detaching previoulsy attached UE.
m_mme_gtpc->send_delete_session_request(imsi);
if (old_ctx->m_ecm_ctx.mme_ue_s1ap_id!=0) {
m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(old_ctx);
}
m_s1ap->delete_ue_ctx(imsi);
}
//Set UE's EMM context
nas *nas_ctx = new nas;
nas_ctx->init(m_s1ap->m_s1ap_args.mcc,
m_s1ap->m_s1ap_args.mnc,
m_s1ap->m_s1ap_args.mme_code,
m_s1ap->m_s1ap_args.mme_group,
m_s1ap->m_s1ap_args.tac,
m_s1ap->m_s1ap_args.mme_apn,
m_s1ap->m_s1ap_args.dns_addr,
m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log);
bool err = nas_ctx->handle_imsi_attach_request( enb_ue_s1ap_id,
attach_req,
pdn_con_req,
enb_sri);
if (err == false){
delete nas_ctx;
}
return err;
}
bool
s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req,
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req,
srslte::byte_buffer_t *nas_msg,
srslte::byte_buffer_t *reply_buffer,
bool* reply_flag,
struct sctp_sndrcvinfo *enb_sri)
{
//Parse the message security header
uint8 pd = 0;
uint8 sec_hdr_type = 0;
liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type);
bool integrity_valid = false;
if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) {
m_s1ap_log->info("Attach request -- GUTI-stlye attach request is not integrity protected\n");
m_s1ap_log->console("Attach request -- GUTI-stlye attach request is not integrity protected\n");
} else {
m_s1ap_log->info("Attach request -- GUTI-stlye attach request is integrity protected\n");
m_s1ap_log->console("Attach request -- GUTI-stlye attach request is integrity protected\n");
}
//GUTI style attach
uint32_t m_tmsi = attach_req.eps_mobile_id.guti.m_tmsi;
std::map<uint32_t,uint64_t>::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi);
if (it == m_s1ap->m_tmsi_to_imsi.end()) {
//Could not find IMSI from M-TMSI, send Id request
m_s1ap_log->console("Attach Request -- Could not find M-TMSI 0x%x\n", m_tmsi);
m_s1ap_log->info("Attach Request -- Could not find M-TMSI 0x%x\n", m_tmsi);
nas *nas_ctx = new nas;
nas_ctx->init(m_s1ap->m_s1ap_args.mcc,
m_s1ap->m_s1ap_args.mnc,
m_s1ap->m_s1ap_args.mme_code,
m_s1ap->m_s1ap_args.mme_group,
m_s1ap->m_s1ap_args.tac,
m_s1ap->m_s1ap_args.mme_apn,
m_s1ap->m_s1ap_args.dns_addr,
m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log);
bool err = nas_ctx->handle_guti_attach_request_unknown_ue( enb_ue_s1ap_id,
attach_req,
pdn_con_req,
nas_msg,
reply_buffer,
reply_flag,
enb_sri);
if (err == false) {
delete nas_ctx;
}
return err;
} else {
//Found UE context from M-TMSI
m_s1ap_log->console("Attach Request -- Found M-TMSI: %d\n",m_tmsi);
m_s1ap_log->console("Attach Request -- IMSI: %015lu\n",it->second);
//Get UE EMM context
nas *nas_ctx = m_s1ap->find_nas_ctx_from_imsi(it->second);
if (nas_ctx!=NULL) {
nas_ctx->handle_guti_attach_request_known_ue( enb_ue_s1ap_id,
attach_req,
pdn_con_req,
nas_msg,
enb_sri);
} else {
m_s1ap_log->error("Found M-TMSI but could not find UE context\n");
m_s1ap_log->console("Error: Found M-TMSI but could not find UE context\n");
return false;
}
}
return true;
}
bool
s1ap_nas_transport::handle_nas_service_request( uint32_t m_tmsi,
uint32_t enb_ue_s1ap_id,