From 925225dbebdf488d88ca6cae051e729e77928e07 Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Tue, 31 Mar 2020 21:50:58 +0200 Subject: [PATCH] Implement Close UE Test Loop/Complete messages This commit implements support for the CLOSE_UE_TEST_LOOP message. Currently the mode is not saved and looping the data is not implemented. Only the *_COMPLETE message is sent back as a response. --- lib/include/srslte/asn1/liblte_mme.h | 15 ++++++++++ lib/src/asn1/liblte_mme.cc | 38 +++++++++++++++++++++++++ srsue/hdr/stack/upper/nas.h | 2 ++ srsue/src/stack/upper/nas.cc | 42 ++++++++++++++++++++++++++-- 4 files changed, 95 insertions(+), 2 deletions(-) diff --git a/lib/include/srslte/asn1/liblte_mme.h b/lib/include/srslte/asn1/liblte_mme.h index 36af562b0..35af99f4c 100644 --- a/lib/include/srslte/asn1/liblte_mme.h +++ b/lib/include/srslte/asn1/liblte_mme.h @@ -4007,4 +4007,19 @@ liblte_mme_unpack_pdn_disconnect_request_msg(LIBLTE_BYTE_MSG_STRUCT* LIBLTE_ERROR_ENUM liblte_mme_pack_activate_test_mode_complete_msg(LIBLTE_BYTE_MSG_STRUCT* msg, uint8 sec_hdr_type, uint32 count); +/********************************************************************* + Message Name: CLOSE UE TEST LOOP COMPLETE + + Description: Sent by the UE to the network in response to a + CLOSE UE TEST LOOP message. + + Document Reference: 36.509 v8.7.0 Section 6.2 +*********************************************************************/ +// Defines +// Enums +// Structs +// Functions +LIBLTE_ERROR_ENUM +liblte_mme_pack_close_ue_test_loop_complete_msg(LIBLTE_BYTE_MSG_STRUCT* msg, uint8 sec_hdr_type, uint32 count); + #endif // SRSLTE_LIBLTE_MME_H diff --git a/lib/src/asn1/liblte_mme.cc b/lib/src/asn1/liblte_mme.cc index c19f3437f..46d245626 100644 --- a/lib/src/asn1/liblte_mme.cc +++ b/lib/src/asn1/liblte_mme.cc @@ -10328,6 +10328,44 @@ liblte_mme_pack_activate_test_mode_complete_msg(LIBLTE_BYTE_MSG_STRUCT* msg, uin return (err); } +LIBLTE_ERROR_ENUM +liblte_mme_pack_close_ue_test_loop_complete_msg(LIBLTE_BYTE_MSG_STRUCT* msg, uint8 sec_hdr_type, uint32 count) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + uint8* msg_ptr = msg->msg; + + if (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++; + + // MAC will be filled in later + msg_ptr += 4; + + // Sequence Number + *msg_ptr = count & 0xFF; + msg_ptr++; + } + + // Protocol Discriminator and skip indicator (always 0x0F) + *msg_ptr = + (LIBLTE_MME_MSG_TYPE_TEST_MODE_SKIP_INDICATOR << 4) | (LIBLTE_MME_MSG_TYPE_TEST_MODE_PROTOCOL_DISCRIMINATOR); + msg_ptr++; + + // Message Type + *msg_ptr = LIBLTE_MME_MSG_TYPE_CLOSE_UE_TEST_LOOP_COMPLETE; + msg_ptr++; + + // Fill in the number of bytes used + msg->N_bytes = msg_ptr - msg->msg; + + err = LIBLTE_SUCCESS; + } + + return (err); +} + /******************************************************************************* HELPER FUNCTIONS *******************************************************************************/ diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index 771a2ec1c..a640ca7d6 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -196,6 +196,7 @@ private: 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); + void parse_close_ue_test_loop(uint32_t lcid, srslte::unique_byte_buffer_t pdu); void parse_modify_eps_bearer_context_request(srslte::unique_byte_buffer_t pdu); // Packet generators @@ -219,6 +220,7 @@ private: void send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id); void send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id); void send_activate_test_mode_complete(); + void send_close_ue_test_loop_complete(); // Other internal helpers void enter_state(emm_state_t state_); diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index 45001c0e2..7df7d2cb6 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -694,10 +694,12 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) case LIBLTE_MME_MSG_TYPE_ACTIVATE_TEST_MODE: parse_activate_test_mode(lcid, std::move(pdu)); break; - // TODO: Handle deactivate test mode and ue close/open - case LIBLTE_MME_MSG_TYPE_DEACTIVATE_TEST_MODE: case LIBLTE_MME_MSG_TYPE_CLOSE_UE_TEST_LOOP: + parse_close_ue_test_loop(lcid, std::move(pdu)); + break; + // TODO: Handle deactivate test mode and ue open test loop case LIBLTE_MME_MSG_TYPE_OPEN_UE_TEST_LOOP: + case LIBLTE_MME_MSG_TYPE_DEACTIVATE_TEST_MODE: default: nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); return; @@ -1674,6 +1676,17 @@ void nas::parse_activate_test_mode(uint32_t lcid, unique_byte_buffer_t pdu) send_activate_test_mode_complete(); } +void nas::parse_close_ue_test_loop(uint32_t lcid, unique_byte_buffer_t pdu) +{ + nas_log->info("Received Close UE test loop\n"); + + ctxt.rx_count++; + + // TODO: Save the test loop mode + + send_close_ue_test_loop_complete(); +} + void nas::parse_emm_status(uint32_t lcid, unique_byte_buffer_t pdu) { LIBLTE_MME_EMM_STATUS_MSG_STRUCT emm_status; @@ -2425,6 +2438,31 @@ void nas::send_activate_test_mode_complete() ctxt.tx_count++; } +void nas::send_close_ue_test_loop_complete() +{ + unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + + if (liblte_mme_pack_close_ue_test_loop_complete_msg( + (LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), current_sec_hdr, ctxt.tx_count)) { + nas_log->error("Error packing close UE test loop complete.\n"); + return; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + if (apply_security_config(pdu, current_sec_hdr)) { + nas_log->error("Error applying NAS security.\n"); + return; + } + + nas_log->info_hex(pdu->msg, pdu->N_bytes, "Sending Close UE test loop complete\n"); + rrc->write_sdu(std::move(pdu)); + + ctxt.tx_count++; +} + /* * Handles the airplane mode simulation by triggering a UE switch off/on * in user-definable time intervals