From 06c9a3f07fa9814999c55db563cf1de670a8a9bf Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 7 Aug 2018 15:18:07 +0200 Subject: [PATCH] add network initiated detach --- srsue/hdr/upper/nas.h | 2 ++ srsue/src/upper/nas.cc | 55 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 150f97b0a..70ccbea35 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -173,6 +173,7 @@ private: void parse_service_reject(uint32_t lcid, byte_buffer_t *pdu); void parse_esm_information_request(uint32_t lcid, byte_buffer_t *pdu); void parse_emm_information(uint32_t lcid, byte_buffer_t *pdu); + void parse_detach_request(uint32_t lcid, byte_buffer_t *pdu); // Packet generators void gen_attach_request(byte_buffer_t *msg); @@ -187,6 +188,7 @@ private: void gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg); void send_security_mode_reject(uint8_t cause); void send_detach_request(bool switch_off); + void send_detach_accept(); // security context persistence file bool read_ctxt_file(nas_sec_ctxt *ctxt); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 30bd50f50..1438f005a 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -371,6 +371,9 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { case LIBLTE_MME_MSG_TYPE_EMM_INFORMATION: parse_emm_information(lcid, pdu); break; + case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: + parse_detach_request(lcid, pdu); + break; default: nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); pool->deallocate(pdu); @@ -975,6 +978,23 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) { pool->deallocate(pdu); } +void nas::parse_detach_request(uint32_t lcid, byte_buffer_t *pdu) +{ + LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_request; + liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &detach_request); + ctxt.rx_count++; + pool->deallocate(pdu); + + if (state == EMM_STATE_REGISTERED) { + nas_log->info("Received Detach request (type=%d)\n", detach_request.detach_type.type_of_detach); + state = EMM_STATE_DEREGISTERED; + // send accept + send_detach_accept(); + } else { + nas_log->warning("Received detach request in invalid state (state=%d)\n", state); + } +} + /******************************************************************************* * Senders ******************************************************************************/ @@ -1205,6 +1225,41 @@ void nas::send_detach_request(bool switch_off) rrc->write_sdu(cfg.lcid, pdu); } +void nas::send_detach_accept() +{ + byte_buffer_t *pdu = pool_allocate_blocking; + if (!pdu) { + nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__); + return; + } + + LIBLTE_MME_DETACH_ACCEPT_MSG_STRUCT detach_accept; + bzero(&detach_accept, sizeof(detach_accept)); + liblte_mme_pack_detach_accept_msg(&detach_accept, + LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, + ctxt.tx_count, + (LIBLTE_BYTE_MSG_STRUCT *) pdu); + + // Add MAC + 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); + } + + if(pcap != NULL) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + nas_log->info("Sending detach accept\n"); + rrc->write_sdu(cfg.lcid, pdu); +} + void nas::send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type) { byte_buffer_t *pdu = pool_allocate_blocking;