From f31a7d1d02c23e9bc7d1d80fdca311e0c694118a Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 26 Nov 2021 10:25:34 +0100 Subject: [PATCH] epc,nas: add handler for PDN connectivity request COTS phones seem to send standalone PDN connectivity request messages even after the initial attach was complete. We don't fully support them in the EPC but instead of logging a warning we can just send a reject at least to keep the logs clean. --- srsepc/hdr/mme/nas.h | 1 + srsepc/src/mme/nas.cc | 45 ++++++++++++++++++++++++++-- srsepc/src/mme/s1ap_nas_transport.cc | 5 ++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index 10179c95c..208f2ae3a 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -216,6 +216,7 @@ public: /* Uplink NAS messages handling */ bool handle_attach_request(srsran::byte_buffer_t* nas_rx); + bool handle_pdn_connectivity_request(srsran::byte_buffer_t* nas_rx); bool handle_authentication_response(srsran::byte_buffer_t* nas_rx); bool handle_security_mode_complete(srsran::byte_buffer_t* nas_rx); bool handle_attach_complete(srsran::byte_buffer_t* nas_rx); diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index 56d8f6da7..3c81aca41 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -956,8 +956,8 @@ bool nas::handle_attach_request(srsran::byte_buffer_t* nas_rx) m_s1ap->send_downlink_nas_transport( m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); - m_logger.info("Downlink NAS: Sending Authentication Request"); - srsran::console("Downlink NAS: Sending Authentication Request\n"); + m_logger.info("DL NAS: Sending Authentication Request"); + srsran::console("DL NAS: Sending Authentication Request\n"); return true; } else { m_logger.error("Attach request from known UE"); @@ -965,6 +965,47 @@ bool nas::handle_attach_request(srsran::byte_buffer_t* nas_rx) return true; } +bool nas::handle_pdn_connectivity_request(srsran::byte_buffer_t* nas_rx) +{ + LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req = {}; + + // Get PDN connectivity request messages + LIBLTE_ERROR_ENUM err = + liblte_mme_unpack_pdn_connectivity_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx->msg, &pdn_con_req); + if (err != LIBLTE_SUCCESS) { + m_logger.error("Error unpacking NAS PDN Connectivity Request. Error: %s", liblte_error_text[err]); + return false; + } + + // Send PDN connectivity reject + srsran::unique_byte_buffer_t nas_tx = srsran::make_byte_buffer(); + if (nas_tx == nullptr) { + m_logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return false; + } + + LIBLTE_MME_PDN_CONNECTIVITY_REJECT_MSG_STRUCT pdn_con_reject = {}; + pdn_con_reject.eps_bearer_id = pdn_con_req.eps_bearer_id; + pdn_con_reject.proc_transaction_id = pdn_con_req.proc_transaction_id; + pdn_con_reject.esm_cause = LIBLTE_MME_ESM_CAUSE_SERVICE_OPTION_NOT_SUPPORTED; + + err = liblte_mme_pack_pdn_connectivity_reject_msg(&pdn_con_reject, (LIBLTE_BYTE_MSG_STRUCT*)nas_tx.get()); + if (err != LIBLTE_SUCCESS) { + m_logger.error("Error packing PDN connectivity reject"); + srsran::console("Error packing PDN connectivity reject\n"); + return false; + } + + // Send reply to eNB + m_s1ap->send_downlink_nas_transport( + m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); + + m_logger.info("DL NAS: Sending PDN Connectivity Reject"); + srsran::console("DL NAS: Sending PDN Connectivity Reject\n"); + + return true; +} + bool nas::handle_authentication_response(srsran::byte_buffer_t* nas_rx) { LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp = {}; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 6e7633c16..758caeb86 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -308,6 +308,11 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr srsran::console("UL NAS: Tracking Area Update Request\n"); nas_ctx->handle_tracking_area_update_request(nas_msg.get()); break; + case LIBLTE_MME_MSG_TYPE_PDN_CONNECTIVITY_REQUEST: + m_logger.info("UL NAS: PDN Connectivity Request"); + srsran::console("UL NAS: PDN Connectivity Request\n"); + nas_ctx->handle_pdn_connectivity_request(nas_msg.get()); + break; default: m_logger.warning("Unhandled NAS integrity protected message %s", liblte_nas_msg_type_to_string(msg_type)); srsran::console("Unhandled NAS integrity protected message %s\n", liblte_nas_msg_type_to_string(msg_type));