Fixed bug in packing ESM information request.

master
Pedro Alvarez 7 years ago
parent 39e34a7bf9
commit a4e1707835

@ -3752,6 +3752,10 @@ typedef struct{
uint8 proc_transaction_id;
}LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT;
// Functions
LIBLTE_ERROR_ENUM srslte_mme_pack_esm_information_request_msg(LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT *esm_info_req,
uint8 sec_hdr_type,
uint32 count,
LIBLTE_BYTE_MSG_STRUCT *msg);
LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_request_msg(LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT *esm_info_req,
LIBLTE_BYTE_MSG_STRUCT *msg);
LIBLTE_ERROR_ENUM liblte_mme_unpack_esm_information_request_msg(LIBLTE_BYTE_MSG_STRUCT *msg,
@ -3782,6 +3786,8 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_response_msg(LIBLTE_MME_ESM_IN
LIBLTE_BYTE_MSG_STRUCT *msg);
LIBLTE_ERROR_ENUM liblte_mme_unpack_esm_information_response_msg(LIBLTE_BYTE_MSG_STRUCT *msg,
LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT *esm_info_resp);
LIBLTE_ERROR_ENUM srslte_mme_unpack_esm_information_response_msg(LIBLTE_BYTE_MSG_STRUCT *msg,
LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT *esm_info_resp);
/*********************************************************************
Message Name: ESM Status

@ -7063,7 +7063,6 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_identity_request_msg(LIBLTE_BYTE_MSG_STRUCT
return(err);
}
/*********************************************************************
Message Name: Identity Response
@ -7101,6 +7100,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_identity_response_msg(LIBLTE_MME_ID_RESPONSE_M
return(err);
}
LIBLTE_ERROR_ENUM liblte_mme_unpack_identity_response_msg(LIBLTE_BYTE_MSG_STRUCT *msg,
LIBLTE_MME_ID_RESPONSE_MSG_STRUCT *id_resp)
{
@ -9845,6 +9845,64 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_deactivate_eps_bearer_context_request_msg(LI
return(err);
}
/*********************************************************************
Message Name: ESM Information Request
Description: Sent by the network to the UE to request the UE to
provide ESM information, i.e. protocol configuration
options or APN or both. This function is being added
to support encryption and integrety protection on
ESM information transfer.
Document Reference: 24.301 v10.2.0 Section 8.3.13
*********************************************************************/
LIBLTE_ERROR_ENUM srslte_mme_pack_esm_information_request_msg(LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT *esm_info_req,
uint8 sec_hdr_type,
uint32 count,
LIBLTE_BYTE_MSG_STRUCT *msg)
{
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
uint8 *msg_ptr = msg->msg;
if(esm_info_req != NULL &&
msg != NULL)
{
if(LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS != sec_hdr_type)
{
// Protocol Discriminator and Security Header Type
*msg_ptr = (sec_hdr_type << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT);
msg_ptr++;
// MAC will be filled in later
msg_ptr += 4;
// Sequence Number
*msg_ptr = count & 0xFF;
msg_ptr++;
}
// Protocol Discriminator and EPS Bearer ID
*msg_ptr = (esm_info_req->eps_bearer_id << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT);
msg_ptr++;
// Procedure Transaction ID
*msg_ptr = esm_info_req->proc_transaction_id;
msg_ptr++;
// Message Type
*msg_ptr = LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_REQUEST;
msg_ptr++;
// Fill in the number of bytes used
msg->N_bytes = msg_ptr - msg->msg;
err = LIBLTE_SUCCESS;
}
return(err);
}
/*********************************************************************
Message Name: ESM Information Request
@ -9863,6 +9921,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_request_msg(LIBLTE_MME_ESM_INF
if(esm_info_req != NULL &&
msg != NULL)
{
// Protocol Discriminator and EPS Bearer ID
*msg_ptr = (esm_info_req->eps_bearer_id << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT);
msg_ptr++;
@ -9883,6 +9942,9 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_request_msg(LIBLTE_MME_ESM_INF
return(err);
}
LIBLTE_ERROR_ENUM liblte_mme_unpack_esm_information_request_msg(LIBLTE_BYTE_MSG_STRUCT *msg,
LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT *esm_info_req)
{
@ -9963,6 +10025,62 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_response_msg(LIBLTE_MME_ESM_IN
return(err);
}
LIBLTE_ERROR_ENUM srslte_mme_unpack_esm_information_response_msg(LIBLTE_BYTE_MSG_STRUCT *msg,
LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT *esm_info_resp)
{
LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
uint8 *msg_ptr = msg->msg;
uint8 sec_hdr_type;
if(msg != NULL &&
esm_info_resp != NULL)
{
// Security Header Type
sec_hdr_type = (msg->msg[0] & 0xF0) >> 4;
if(LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS == sec_hdr_type)
{
msg_ptr++;
}else{
msg_ptr += 7;
}
// EPS Bearer ID
esm_info_resp->eps_bearer_id = (*msg_ptr >> 4);
msg_ptr++;
// Procedure Transaction ID
esm_info_resp->proc_transaction_id = *msg_ptr;
msg_ptr++;
// Skip Message Type
msg_ptr++;
// Access Point Name
if(LIBLTE_MME_ACCESS_POINT_NAME_IEI == *msg_ptr)
{
msg_ptr++;
liblte_mme_unpack_access_point_name_ie(&msg_ptr, &esm_info_resp->apn);
esm_info_resp->apn_present = true;
}else{
esm_info_resp->apn_present = false;
}
// Protocol Configuration Options
if(LIBLTE_MME_PROTOCOL_CONFIGURATION_OPTIONS_IEI == *msg_ptr)
{
msg_ptr++;
liblte_mme_unpack_protocol_config_options_ie(&msg_ptr, &esm_info_resp->protocol_cnfg_opts);
esm_info_resp->protocol_cnfg_opts_present = true;
}else{
esm_info_resp->protocol_cnfg_opts_present = false;
}
err = LIBLTE_SUCCESS;
}
return(err);
}
LIBLTE_ERROR_ENUM liblte_mme_unpack_esm_information_response_msg(LIBLTE_BYTE_MSG_STRUCT *msg,
LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT *esm_info_resp)
{

@ -89,6 +89,7 @@ public:
void activate_eps_bearer(uint32_t mme_s1ap_id, uint8_t ebi);
bool pack_esm_information_request(srslte::byte_buffer_t* reply_msg, srsepc::ue_ctx_t* ue_ctx);
bool handle_esm_information_response(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_msg, ue_ctx_t* ue_ctx);
void print_enb_ctx_info(const enb_ctx_t &enb_ctx);

@ -95,6 +95,7 @@ typedef struct{
bool ms_network_cap_present;
LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ms_network_cap;
bool eit;
uint8_t procedure_transaction_id;
} ue_ctx_t;
}//namespace
#endif

@ -378,7 +378,7 @@ s1ap::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT *ini
}
//FIXME use this info
uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //TODO: Unused
uint8_t proc_transaction_id = pdn_con_req.proc_transaction_id; //TODO: Transaction ID unused
ue_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id;
//Save whether ESM information transfer is necessary
ue_ctx.eit = pdn_con_req.esm_info_transfer_flag_present;
@ -473,12 +473,17 @@ s1ap::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT
return true; //no need for reply. FIXME this should be better structured...
break;
case LIBLTE_MME_MSG_TYPE_ATTACH_COMPLETE:
m_s1ap_log->info("UL NAS: Received Attach Complete\n");
handle_nas_attach_complete(nas_msg, reply_msg, ue_ctx);
return true; //no need for reply. FIXME this should be better structured...
m_s1ap_log->info("UL NAS: Received Attach Complete\n");
handle_nas_attach_complete(nas_msg, reply_msg, ue_ctx);
return true; //no need for reply. FIXME this should be better structured...
break;
case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_RESPONSE:
m_s1ap_log->info("UL NAS: Received ESM Information Response\n");
handle_esm_information_response(nas_msg,reply_msg,ue_ctx);
return true;
default:
m_s1ap_log->info("Unhandled NAS message 0x%x\n", msg_type );
m_s1ap_log->warning("Unhandled NAS message 0x%x\n", msg_type );
m_s1ap_log->console("Unhandled NAS message 0x%x\n", msg_type );
return false; //FIXME (nas_msg deallocate needs to be called)
}
@ -611,15 +616,17 @@ s1ap::pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_ctx_t *u
uint8 eps_bearer_id;
uint8 proc_transaction_id;
}LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT;*/
uint8_t sec_hdr_type=3;
esm_info_req.eps_bearer_id=0;
esm_info_req.proc_transaction_id = ue_ctx->procedure_transaction_id;
uint8_t sec_hdr_type=2;
ue_ctx->security_ctxt.dl_nas_count++;
LIBLTE_ERROR_ENUM err = liblte_mme_pack_esm_information_request_msg(&esm_info_req, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
LIBLTE_ERROR_ENUM err = srslte_mme_pack_esm_information_request_msg(&esm_info_req, sec_hdr_type,ue_ctx->security_ctxt.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
if(err != LIBLTE_SUCCESS)
{
m_s1ap_log->error("Error packing Athentication Reject\n");
m_s1ap_log->console("Error packing Athentication Reject\n");
m_s1ap_log->error("Error packing ESM information request\n");
m_s1ap_log->console("Error packing ESM information request\n");
return false;
}
@ -657,6 +664,47 @@ s1ap::pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_ctx_t *u
return true;
}
bool
s1ap::handle_esm_information_response(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_msg, ue_ctx_t* ue_ctx)
{
LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT esm_info_resp;
/*
typedef struct{
LIBLTE_MME_ACCESS_POINT_NAME_STRUCT apn;
LIBLTE_MME_PROTOCOL_CONFIG_OPTIONS_STRUCT protocol_cnfg_opts;
uint8 eps_bearer_id;
uint8 proc_transaction_id;
bool apn_present;
bool protocol_cnfg_opts_present;
}LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT;*/
//Get NAS authentication response
LIBLTE_ERROR_ENUM err = srslte_mme_unpack_esm_information_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &esm_info_resp);
if(err != LIBLTE_SUCCESS){
m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]);
return false;
}
m_s1ap_log->info("ESM Info: EPS bearer id %d\n",esm_info_resp.eps_bearer_id);
if(esm_info_resp.apn_present)
{
m_s1ap_log->info("ESM Info: APN %s\n",esm_info_resp.eps_bearer_id);
m_s1ap_log->console("ESM Info: APN %s\n",esm_info_resp.eps_bearer_id);
}
/*
m_pool->deallocate(nas_buffer);
ssize_t n_sent = sctp_send(m_s1mme,reply_msg->msg, reply_msg->N_bytes, &ue_ctx->enb_sri, 0);
if(n_sent == -1)
{
m_s1ap_log->error("Failed to send NAS Attach Request");
return false;
}
*/
//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_ctx->imsi, ue_ctx->mme_ue_s1ap_id);
return true;
}
bool
s1ap::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)
{
@ -692,8 +740,8 @@ s1ap::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte:
in_ctxt_req->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctx->enb_ue_s1ap_id;
//Set UE-AMBR
in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL.BitRate=4294967295;//2^32-1
in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL.BitRate=4294967295;//FIXME Get UE-AMBR from HSS
in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL.BitRate=1000000000;//2^32-1
in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL.BitRate=1000000000;//FIXME Get UE-AMBR from HSS
//Setup eRAB context
in_ctxt_req->E_RABToBeSetupListCtxtSUReq.len = 1;
@ -721,9 +769,26 @@ s1ap::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte:
memcpy(erab_ctxt->gTP_TEID.buffer, &tmp_teid, sizeof(uint32_t));
//Set UE security capabilities and k_enb
in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[0] = 0; //EEA0
in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[0] = 1; //EIA1
for(int i = 0; i<16; i++)
{
if(ue_ctx->ue_network_cap.eea[i] == true)
{
in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 1; //EEA supported
}
else
{
in_ctxt_req->UESecurityCapabilities.encryptionAlgorithms.buffer[i] = 0; //EEA not supported
}
if(ue_ctx->ue_network_cap.eia[i] == true)
{
in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[i] = 1; //EEA supported
}
else
{
in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[i] = 0; //EEA not supported
}
// in_ctxt_req->UESecurityCapabilities.integrityProtectionAlgorithms.buffer[0] = 1; //EIA1
}
uint8_t key_enb[32];
liblte_security_generate_k_enb(ue_ctx->security_ctxt.k_asme, ue_ctx->security_ctxt.dl_nas_count, key_enb);
liblte_unpack(key_enb, 32, in_ctxt_req->SecurityKey.buffer);

@ -476,7 +476,7 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE
attach_accept.tai_list.N_tais = 1;
attach_accept.tai_list.tai[0].mcc = 1;
attach_accept.tai_list.tai[0].mnc = 1;
attach_accept.tai_list.tai[0].tac = 1;
attach_accept.tai_list.tai[0].tac = 7;
//Make sure all unused options are set to false
attach_accept.guti_present=false;
@ -507,10 +507,10 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE
act_def_eps_bearer_context_req.eps_qos.mbr_dl_ext = 250; //FIXME check
//set apn
//act_def_eps_bearer_context_req.apn
std::string apn("internet");
std::string apn("test123");
act_def_eps_bearer_context_req.apn.apn = apn; //FIXME
act_def_eps_bearer_context_req.proc_transaction_id = 1; //FIXME
act_def_eps_bearer_context_req.proc_transaction_id = ue_ctx->procedure_transaction_id; //FIXME
//Make sure unused options are set to false
@ -536,7 +536,7 @@ s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESE
bool br_ext_present;
}LIBLTE_MME_EPS_QUALITY_OF_SERVICE_STRUCT;
*/
uint8_t sec_hdr_type =3;
uint8_t sec_hdr_type =2;
ue_ctx->security_ctxt.dl_nas_count++;
liblte_mme_pack_activate_default_eps_bearer_context_request_msg(&act_def_eps_bearer_context_req, &attach_accept.esm_msg);
liblte_mme_pack_attach_accept_msg(&attach_accept, sec_hdr_type, ue_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);

Loading…
Cancel
Save