From f71c87d895912c786114d72dfe4509c2afe17d2f Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 30 Nov 2017 17:06:56 +0000 Subject: [PATCH] Starting to add attach accept and activate default bearer request NAS messages. --- lib/include/srslte/asn1/gtpc.h | 3 -- lib/include/srslte/asn1/gtpc_ies.h | 4 +- srsepc/hdr/mme/s1ap_common.h | 2 + srsepc/hdr/mme/s1ap_nas_transport.h | 2 + srsepc/src/mme/s1ap.cc | 65 +++++++++++--------------- srsepc/src/mme/s1ap_nas_transport.cc | 69 +++++++++++++++++++++++++--- srsepc/src/spgw/spgw.cc | 2 +- 7 files changed, 95 insertions(+), 52 deletions(-) diff --git a/lib/include/srslte/asn1/gtpc.h b/lib/include/srslte/asn1/gtpc.h index 8fdbab53d..e670333bf 100644 --- a/lib/include/srslte/asn1/gtpc.h +++ b/lib/include/srslte/asn1/gtpc.h @@ -27,9 +27,6 @@ #include #include "srslte/asn1/gtpc_msg.h" -//Helpful marcos to convert TEIDs (uint64_t) to/from network byte order -#define HTONLL(x) ((1==htonl(1)) ? (x) : (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32))) -#define NTOHLL(x) ((1==ntohl(1)) ? (x) : (((uint64_t)ntohl((x) & 0xFFFFFFFFUL)) << 32) | ntohl((uint32_t)((x) >> 32))) namespace srslte{ diff --git a/lib/include/srslte/asn1/gtpc_ies.h b/lib/include/srslte/asn1/gtpc_ies.h index 8c8e5d97e..35b5e6498 100644 --- a/lib/include/srslte/asn1/gtpc_ies.h +++ b/lib/include/srslte/asn1/gtpc_ies.h @@ -310,7 +310,7 @@ struct gtpc_ambr_ie /**************************************************************************** * - * GTP-C PAA Type IE + * GTP-C PDN Type IE * Ref: 3GPP TS 29.274 v10.14.0 Figure 8.14-1 * ***************************************************************************/ @@ -327,7 +327,7 @@ struct gtpc_pdn_address_allocation_ie bool ipv4_present; bool ipv6_present; in_addr_t ipv4; - struct in6_addr; + struct in6_addr ipv6; }; //TODO diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index a3ac54dab..ad004190d 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -65,6 +65,8 @@ typedef struct{ uint32_t ul_nas_count; srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; + uint8_t k_nas_enc[32]; + uint8_t k_nas_int[32]; } security_ctxt; } ue_ctx_t; }//namespace diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index f4e207ce6..feb11379f 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -29,6 +29,7 @@ #include "srslte/asn1/liblte_s1ap.h" #include "srslte/common/buffer_pool.h" #include "mme/s1ap_common.h" +#include "srslte/asn1/gtpc.h" namespace srsepc{ @@ -45,6 +46,7 @@ public: bool unpack_authentication_response(LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *ul_xport, LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT *auth_resp); bool pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_ctx_t *ue_ctx); + bool pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt, struct srslte::gtpc_pdn_address_allocation_ie *paa, srslte::byte_buffer_t *nas_buffer); void log_unhandled_attach_request_ies(const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT *attach_req); void log_unhandled_pdn_con_request_ies(const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT *pdn_con_req); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index a3d9dbf22..0544b5311 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -585,39 +585,6 @@ s1ap::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte: in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL.BitRate=4294967295;//2^32-1 in_ctxt_req->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL.BitRate=4294967295;//FIXME Get UE-AMBR from HSS - /* - typedef struct{ - bool ext; - LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; - LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT e_RABlevelQoSParameters; - LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; - LIBLTE_S1AP_GTP_TEID_STRUCT gTP_TEID; - LIBLTE_S1AP_NAS_PDU_STRUCT nAS_PDU; - bool nAS_PDU_present; - LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; - bool iE_Extensions_present; - }LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT; - */ - /* - typedef struct{ - bool ext; - LIBLTE_S1AP_QCI_STRUCT qCI; - LIBLTE_S1AP_ALLOCATIONANDRETENTIONPRIORITY_STRUCT allocationRetentionPriority; - LIBLTE_S1AP_GBR_QOSINFORMATION_STRUCT gbrQosInformation; - bool gbrQosInformation_present; - LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; - bool iE_Extensions_present; - }LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT; - - typedef struct{ - bool ext; - LIBLTE_S1AP_PRIORITYLEVEL_STRUCT priorityLevel; - LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_ENUM pre_emptionCapability; - LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_ENUM pre_emptionVulnerability; - LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; - bool iE_Extensions_present; - }LIBLTE_S1AP_ALLOCATIONANDRETENTIONPRIORITY_STRUCT; - */ //Setup eRAB context in_ctxt_req->E_RABToBeSetupListCtxtSUReq.len = 1; erab_ctxt->e_RAB_ID.E_RAB_ID = cs_resp->eps_bearer_context_created.ebi; @@ -651,8 +618,18 @@ s1ap::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte: liblte_unpack(key_enb, 32, in_ctxt_req->SecurityKey.buffer); //Set Attach accepted and activat default bearer NAS messages - //TODO - + if(cs_resp->paa_present != true) + { + m_s1ap_log->error("PAA not present\n"); + return false; + } + if(cs_resp->paa.pdn_type != srslte::GTPC_PDN_TYPE_IPV4) + { + m_s1ap_log->error("IPv6 not supported yet\n"); + return false; + } + srslte::byte_buffer_t *nas_buffer = m_pool->allocate(); + m_s1ap_nas_transport.pack_attach_accept(ue_ctx, erab_ctxt, &cs_resp->paa, nas_buffer); LIBLTE_ERROR_ENUM err = liblte_s1ap_pack_s1ap_pdu(&pdu, (LIBLTE_BYTE_MSG_STRUCT*)reply_buffer); //reply_buffer->N_bytes = pdu->NAS_PDU.n_octets; @@ -674,13 +651,23 @@ s1ap::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte: m_s1ap_log->console("Sent Intial Context Setup Request\n"); m_pool->deallocate(reply_buffer); + m_pool->deallocate(nas_buffer); return true; } - bool - s1ap::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri) - { - uint32_t mme_ue_s1ap_id = ue_rel->MME_UE_S1AP_ID.MME_UE_S1AP_ID; + /* +bool +s1ap::handle_initial_context_setup_response(uint32_t mme_ue_s1ap_id, struct srslte::gtpc_create_session_response *cs_resp) +{ + return true; +} + */ + +bool +s1ap::handle_ue_context_release_request(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ue_rel, struct sctp_sndrcvinfo *enb_sri) +{ + + uint32_t mme_ue_s1ap_id = ue_rel->MME_UE_S1AP_ID.MME_UE_S1AP_ID; m_s1ap_log->info("Received UE Context Release Request. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); m_s1ap_log->console("Received UE Context Release Request. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 62828d9f6..a9772b4fe 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -290,17 +290,14 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, //TODO which is the RB ID? Standard says a constant, but which? uint8_t mac[4]; - uint8_t k_nas_enc[32]; - uint8_t k_nas_int[32]; - srslte::security_generate_k_nas( ue_ctx->security_ctxt.k_asme, srslte::CIPHERING_ALGORITHM_ID_EEA0, srslte::INTEGRITY_ALGORITHM_ID_128_EIA1, - k_nas_enc, - k_nas_int + ue_ctx->security_ctxt.k_nas_enc, + ue_ctx->security_ctxt.k_nas_int ); - srslte::security_128_eia1 (&k_nas_int[16], + srslte::security_128_eia1 (&ue_ctx->security_ctxt.k_nas_int[16], count, 0, SECURITY_DIRECTION_DOWNLINK, @@ -429,7 +426,7 @@ s1ap_nas_transport::log_unhandled_initial_ue_message_ies(LIBLTE_S1AP_MESSAGE_INI } if(init_ue->CellAccessMode_present){ m_s1ap_log->warning("Cell Access Mode present, but not handled."); - } + } if(init_ue->GW_TransportLayerAddress_present){ m_s1ap_log->warning("GW Transport Layer present, but not handled."); } @@ -455,6 +452,64 @@ s1ap_nas_transport::log_unhandled_initial_ue_message_ies(LIBLTE_S1AP_MESSAGE_INI } +bool +s1ap_nas_transport::pack_attach_accept(ue_ctx_t *ue_ctx, LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctxt, struct srslte::gtpc_pdn_address_allocation_ie *paa, srslte::byte_buffer_t *nas_buffer) { + LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept; + LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req; + + m_s1ap_log->info("Packing Attach Accept\n"); + bzero(&attach_accept, sizeof(LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT)); + bzero(&act_def_eps_bearer_context_req, sizeof(LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT)); + + //Attach accept + attach_accept.eps_attach_result = LIBLTE_MME_EPS_ATTACH_RESULT_EPS_ONLY; + //Mandatory + //FIXME: Set t3412.unit + //FIXME: Set tai_list + //FIXME: Set esm_msg + act_def_eps_bearer_context_req.pdn_addr.pdn_type = LIBLTE_MME_PDN_TYPE_IPV4; + memcpy(act_def_eps_bearer_context_req.pdn_addr.addr, &paa->ipv4, 4); + /* + act_def_eps_bearer_context_req.pdn_addr.addr[0] |= ip_addr << 24; + act_def_eps_bearer_context_req.pdn_addr.addr[1] |= ip_addr << 16; + act_def_eps_bearer_context_req.pdn_addr.addr[2] |= ip_addr << 8; + act_def_eps_bearer_context_req.pdn_addr.addr[3] |= ip_addr; + */ + //Activate default EPS bearer context + act_def_eps_bearer_context_req.eps_bearer_id = erab_ctxt->e_RAB_ID.E_RAB_ID; + act_def_eps_bearer_context_req.transaction_id_present = false; + liblte_mme_pack_activate_default_eps_bearer_context_request_msg(&act_def_eps_bearer_context_req, &attach_accept.esm_msg); + + //FIXME: Set the following parameters +// act_def_eps_bearer_context_req.eps_qos.qci +// act_def_eps_bearer_context_req.eps_qos.br_present +// act_def_eps_bearer_context_req.eps_qos.br_ext_present +// act_def_eps_bearer_context_req.apn.apn +// act_def_eps_bearer_context_req.negotiated_qos_present +// act_def_eps_bearer_context_req.llc_sapi_present +// act_def_eps_bearer_context_req.radio_prio_present +// act_def_eps_bearer_context_req.packet_flow_id_present +// act_def_eps_bearer_context_req.apn_ambr_present +// act_def_eps_bearer_context_req.protocol_cnfg_opts_present +// act_def_eps_bearer_context_req.connectivity_type_present + + // FIXME: Setup the default EPS bearer context + + //Integrity protect NAS message + uint8_t mac[4]; + srslte::security_128_eia1 (&ue_ctx->security_ctxt.k_nas_int[16], + ue_ctx->security_ctxt.dl_nas_count, + 0, + SECURITY_DIRECTION_DOWNLINK, + &nas_buffer->msg[5], + nas_buffer->N_bytes - 5, + mac + ); + memcpy(&nas_buffer->msg[1],mac,4); + m_s1ap_log->info("Packed Attach Complete\n"); + + return true; +} } //namespace srsepc diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index cf53686a1..19c206f6e 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -344,7 +344,7 @@ spgw::handle_create_session_request(struct srslte::gtpc_create_session_request * cs_resp->eps_bearer_context_created.cause.cause_value = srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED; cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present=true; cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.teid = spgw_uplink_user_teid; - //Fill in the PDA + //Fill in the PAA cs_resp->paa_present = true; cs_resp->paa.pdn_type = srslte::GTPC_PDN_TYPE_IPV4; cs_resp->paa.ipv4_present = true;