From 1c749ad559c81a340b1b0152fa0aef4613a402ff Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 23 May 2019 21:57:43 +0200 Subject: [PATCH] add basic handling for deactivating eps bearer --- lib/include/srslte/asn1/liblte_mme.h | 7 ++- lib/src/asn1/liblte_mme.cc | 73 ++++++++++++++++------------ srsue/hdr/stack/upper/nas.h | 2 + srsue/src/stack/upper/nas.cc | 61 +++++++++++++++++++++++ 4 files changed, 111 insertions(+), 32 deletions(-) diff --git a/lib/include/srslte/asn1/liblte_mme.h b/lib/include/srslte/asn1/liblte_mme.h index 485a5f077..975d238e7 100644 --- a/lib/include/srslte/asn1/liblte_mme.h +++ b/lib/include/srslte/asn1/liblte_mme.h @@ -3733,8 +3733,11 @@ typedef struct{ bool protocol_cnfg_opts_present; }LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT; // Functions -LIBLTE_ERROR_ENUM liblte_mme_pack_deactivate_eps_bearer_context_accept_msg(LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT *deact_eps_bearer_context_accept, - LIBLTE_BYTE_MSG_STRUCT *msg); +LIBLTE_ERROR_ENUM liblte_mme_pack_deactivate_eps_bearer_context_accept_msg( + LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT* deact_eps_bearer_context_accept, + uint8 sec_hdr_type, + uint32 count, + LIBLTE_BYTE_MSG_STRUCT* msg); LIBLTE_ERROR_ENUM liblte_mme_unpack_deactivate_eps_bearer_context_accept_msg(LIBLTE_BYTE_MSG_STRUCT *msg, LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT *deact_eps_bearer_context_accept); diff --git a/lib/src/asn1/liblte_mme.cc b/lib/src/asn1/liblte_mme.cc index 4d81cb56b..becc6def1 100644 --- a/lib/src/asn1/liblte_mme.cc +++ b/lib/src/asn1/liblte_mme.cc @@ -9810,42 +9810,55 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_bearer_resource_modification_request_msg(LIB Document Reference: 24.301 v10.2.0 Section 8.3.11 *********************************************************************/ -LIBLTE_ERROR_ENUM liblte_mme_pack_deactivate_eps_bearer_context_accept_msg(LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT *deact_eps_bearer_context_accept, - LIBLTE_BYTE_MSG_STRUCT *msg) +LIBLTE_ERROR_ENUM liblte_mme_pack_deactivate_eps_bearer_context_accept_msg( + LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT* deact_eps_bearer_context_accept, + uint8 sec_hdr_type, + uint32 count, + LIBLTE_BYTE_MSG_STRUCT* msg) { - LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; - uint8 *msg_ptr = msg->msg; + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + uint8* msg_ptr = msg->msg; - if(deact_eps_bearer_context_accept != NULL && - msg != NULL) - { - // Protocol Discriminator and EPS Bearer ID - *msg_ptr = (deact_eps_bearer_context_accept->eps_bearer_id << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT); - msg_ptr++; + if (deact_eps_bearer_context_accept != 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_MOBILITY_MANAGEMENT); + msg_ptr++; - // Procedure Transaction ID - *msg_ptr = deact_eps_bearer_context_accept->proc_transaction_id; - msg_ptr++; + // MAC will be filled in later + msg_ptr += 4; - // Message Type - *msg_ptr = LIBLTE_MME_MSG_TYPE_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT; - msg_ptr++; - - // Protocol Configuration Options - if(deact_eps_bearer_context_accept->protocol_cnfg_opts_present) - { - *msg_ptr = LIBLTE_MME_PROTOCOL_CONFIGURATION_OPTIONS_IEI; - msg_ptr++; - liblte_mme_pack_protocol_config_options_ie(&deact_eps_bearer_context_accept->protocol_cnfg_opts, &msg_ptr); - } - - // Fill in the number of bytes used - msg->N_bytes = msg_ptr - msg->msg; - - err = LIBLTE_SUCCESS; + // Sequence Number + *msg_ptr = count & 0xFF; + msg_ptr++; } - return(err); + // Protocol Discriminator and EPS Bearer ID + *msg_ptr = (deact_eps_bearer_context_accept->eps_bearer_id << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT); + msg_ptr++; + + // Procedure Transaction ID + *msg_ptr = deact_eps_bearer_context_accept->proc_transaction_id; + msg_ptr++; + + // Message Type + *msg_ptr = LIBLTE_MME_MSG_TYPE_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT; + msg_ptr++; + + // Protocol Configuration Options + if (deact_eps_bearer_context_accept->protocol_cnfg_opts_present) { + *msg_ptr = LIBLTE_MME_PROTOCOL_CONFIGURATION_OPTIONS_IEI; + msg_ptr++; + liblte_mme_pack_protocol_config_options_ie(&deact_eps_bearer_context_accept->protocol_cnfg_opts, &msg_ptr); + } + + // Fill in the number of bytes used + msg->N_bytes = msg_ptr - msg->msg; + + err = LIBLTE_SUCCESS; + } + + return (err); } LIBLTE_ERROR_ENUM liblte_mme_unpack_deactivate_eps_bearer_context_accept_msg(LIBLTE_BYTE_MSG_STRUCT *msg, LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT *deact_eps_bearer_context_accept) diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index 3c8b94846..cf80bd49f 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -183,6 +183,7 @@ private: void parse_detach_request(uint32_t lcid, srslte::unique_byte_buffer_t pdu); void parse_emm_status(uint32_t lcid, srslte::unique_byte_buffer_t pdu); void parse_activate_dedicated_eps_bearer_context_request(uint32_t lcid, srslte::unique_byte_buffer_t pdu); + void parse_deactivate_eps_bearer_context_request(srslte::unique_byte_buffer_t pdu); void parse_activate_test_mode(uint32_t lcid, srslte::unique_byte_buffer_t pdu, const uint8_t sec_hdr_type); // Packet generators @@ -202,6 +203,7 @@ private: void send_detach_accept(); void send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id); + void send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id); void send_activate_test_mode_complete(const uint8_t sec_hdr_type); // security context persistence file diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index f469f2c8f..01eb4676a 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -419,6 +419,9 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) case LIBLTE_MME_MSG_TYPE_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST: parse_activate_dedicated_eps_bearer_context_request(lcid, std::move(pdu)); break; + case LIBLTE_MME_MSG_TYPE_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST: + parse_deactivate_eps_bearer_context_request(std::move(pdu)); + break; case LIBLTE_MME_MSG_TYPE_ACTIVATE_TEST_MODE: parse_activate_test_mode(lcid, std::move(pdu), sec_hdr_type); break; @@ -1115,6 +1118,24 @@ void nas::parse_activate_dedicated_eps_bearer_context_request(uint32_t lcid, uni send_activate_dedicated_eps_bearer_context_accept(request.proc_transaction_id, request.eps_bearer_id); } +void nas::parse_deactivate_eps_bearer_context_request(unique_byte_buffer_t pdu) +{ + LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT request; + + liblte_mme_unpack_deactivate_eps_bearer_context_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &request); + + nas_log->info("Received Deactivate EPS bearer context request (eps_bearer_id=%d, proc_id=%d)\n", + request.eps_bearer_id, + request.proc_transaction_id); + + ctxt.rx_count++; + + // fixme: add proper checks before sending accepts + + send_deactivate_eps_bearer_context_accept(request.proc_transaction_id, request.eps_bearer_id); +} + + void nas::parse_activate_test_mode(uint32_t lcid, unique_byte_buffer_t pdu, const uint8_t sec_hdr_type) { nas_log->info("Received Activate test mode\n"); @@ -1785,6 +1806,46 @@ void nas::send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_ ctxt.tx_count++; } +void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id) +{ + unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + + LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT accept = {}; + + accept.eps_bearer_id = eps_bearer_id; + accept.proc_transaction_id = proc_transaction_id; + + if (liblte_mme_pack_deactivate_eps_bearer_context_accept_msg(&accept, + LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, + ctxt.tx_count, + (LIBLTE_BYTE_MSG_STRUCT*)pdu.get())) { + nas_log->error("Error packing Aeactivate EPS Bearer context accept.\n"); + return; + } + + if (pcap != NULL) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + cipher_encrypt(pdu.get()); + if (pdu->N_bytes > 5) { + integrity_generate( + &k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, &pdu->msg[5], pdu->N_bytes - 5, &pdu->msg[1]); + } else { + nas_log->error("Invalid PDU size %d\n", pdu->N_bytes); + return; + } + + nas_log->info_hex(pdu->msg, + pdu->N_bytes, + "Sending Deactivate EPS Bearer context accept (eps_bearer_id=%d, proc_id=%d)\n", + accept.eps_bearer_id, + accept.proc_transaction_id); + rrc->write_sdu(std::move(pdu)); + + ctxt.tx_count++; +} + void nas::send_activate_test_mode_complete(const uint8_t sec_hdr_type) { unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true);