From 6a9c7f16c16f3fd9158921bc7a684ba7e9687dcc Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Thu, 21 Dec 2023 14:57:34 +0100 Subject: [PATCH] Revert "[MME] Gn: Introduce initial support for 4G->2G cell reselection" This reverts commit 5a31af36e00c3878ca3f910294e8975dc841459e. --- lib/crypt/ogs-kdf.c | 53 ------- lib/crypt/ogs-kdf.h | 12 -- lib/gtp/v1/conv.c | 28 ---- lib/gtp/v1/conv.h | 3 - lib/gtp/v1/types.c | 315 --------------------------------------- lib/gtp/v1/types.h | 108 -------------- lib/gtp/xact.c | 1 - src/mme/mme-context.h | 5 - src/mme/mme-gn-build.c | 258 +------------------------------- src/mme/mme-gn-build.h | 3 - src/mme/mme-gn-handler.c | 111 -------------- src/mme/mme-gn-handler.h | 6 - src/mme/mme-gtp-path.c | 30 ---- src/mme/mme-gtp-path.h | 3 - src/mme/mme-sm.c | 6 - 15 files changed, 1 insertion(+), 941 deletions(-) diff --git a/lib/crypt/ogs-kdf.c b/lib/crypt/ogs-kdf.c index a1290a26f..7d125c95c 100644 --- a/lib/crypt/ogs-kdf.c +++ b/lib/crypt/ogs-kdf.c @@ -34,9 +34,6 @@ #define FC_FOR_KENB_DERIVATION 0x11 #define FC_FOR_NH_ENB_DERIVATION 0x12 #define FC_FOR_EPS_ALGORITHM_KEY_DERIVATION 0x15 -#define FC_FOR_CK_IK_DERIVATION_HANDOVER 0x16 -#define FC_FOR_NAS_TOKEN_DERIVATION 0x17 -#define FC_FOR_CK_IK_DERIVATION_IDLE_MOBILITY 0x1B typedef struct kdf_param_s { const uint8_t *buf; @@ -382,56 +379,6 @@ void ogs_kdf_nas_eps(uint8_t algorithm_type_distinguishers, memcpy(knas, output+16, 16); } -/* TS33.401 Annex A.8: KASME to CK', IK' derivation at handover */ -void ogs_kdf_ck_ik_handover( - uint32_t dl_count, const uint8_t *kasme, uint8_t *ck, uint8_t *ik) -{ - kdf_param_t param; - uint8_t output[OGS_SHA256_DIGEST_SIZE]; - - memset(param, 0, sizeof(param)); - param[0].buf = (uint8_t *)&dl_count; - param[0].len = 4; - - ogs_kdf_common(kasme, OGS_SHA256_DIGEST_SIZE, - FC_FOR_CK_IK_DERIVATION_HANDOVER, param, output); - memcpy(ck, output, 16); - memcpy(ik, output+16, 16); -} - -/* TS33.401 Annex A.9: NAS token derivation for inter-RAT mobility */ -void ogs_kdf_nas_token( - uint32_t ul_count, const uint8_t *kasme, uint8_t *nas_token) -{ - kdf_param_t param; - uint8_t output[OGS_SHA256_DIGEST_SIZE]; - - memset(param, 0, sizeof(param)); - param[0].buf = (uint8_t *)&ul_count; - param[0].len = 4; - - ogs_kdf_common(kasme, OGS_SHA256_DIGEST_SIZE, - FC_FOR_NAS_TOKEN_DERIVATION, param, output); - memcpy(nas_token, output, 2); -} - -/* TS33.401 Annex A.13: KASME to CK', IK' derivation at idle mobility */ -void ogs_kdf_ck_ik_idle_mobility( - uint32_t ul_count, const uint8_t *kasme, uint8_t *ck, uint8_t *ik) -{ - kdf_param_t param; - uint8_t output[OGS_SHA256_DIGEST_SIZE]; - - memset(param, 0, sizeof(param)); - param[0].buf = (uint8_t *)&ul_count; - param[0].len = 4; - - ogs_kdf_common(kasme, OGS_SHA256_DIGEST_SIZE, - FC_FOR_CK_IK_DERIVATION_IDLE_MOBILITY, param, output); - memcpy(ck, output, 16); - memcpy(ik, output+16, 16); -} - /* * TS33.401 Annex I Hash Functions * Use the KDF given in TS33.220 diff --git a/lib/crypt/ogs-kdf.h b/lib/crypt/ogs-kdf.h index 139283436..c83993e2a 100644 --- a/lib/crypt/ogs-kdf.h +++ b/lib/crypt/ogs-kdf.h @@ -101,18 +101,6 @@ void ogs_kdf_nh_enb(const uint8_t *kasme, const uint8_t *sync_input, uint8_t *ke void ogs_kdf_nas_eps(uint8_t algorithm_type_distinguishers, uint8_t algorithm_identity, const uint8_t *kasme, uint8_t *knas); -/* TS33.401 Annex A.8: KASME to CK', IK' derivation at handover */ -void ogs_kdf_ck_ik_handover( - uint32_t dl_count, const uint8_t *kasme, uint8_t *ck, uint8_t *ik); - -/* TS33.401 Annex A.9: NAS token derivation for inter-RAT mobility */ -void ogs_kdf_nas_token( - uint32_t ul_count, const uint8_t *kasme, uint8_t *nas_token); - -/* TS33.401 Annex A.13: KASME to CK', IK' derivation at idle mobility */ -void ogs_kdf_ck_ik_idle_mobility( - uint32_t ul_count, const uint8_t *kasme, uint8_t *ck, uint8_t *ik); - /* * TS33.401 Annex I Hash Functions * Use the KDF given in TS33.220 diff --git a/lib/gtp/v1/conv.c b/lib/gtp/v1/conv.c index c4e7b78a5..9951f702f 100644 --- a/lib/gtp/v1/conv.c +++ b/lib/gtp/v1/conv.c @@ -104,34 +104,6 @@ int ogs_gtp1_gsn_addr_to_ip(const ogs_gtp1_gsn_addr_t *gsnaddr, uint16_t gsnaddr return OGS_OK; } -int ogs_gtp1_pdu_session_type_to_eua_ietf_type(uint8_t session_type) -{ - switch (session_type) { - case OGS_PDU_SESSION_TYPE_IPV4: - return OGS_PDP_EUA_IETF_IPV4; - case OGS_PDU_SESSION_TYPE_IPV6: - return OGS_PDP_EUA_IETF_IPV6; - case OGS_PDU_SESSION_TYPE_IPV4V6: - return OGS_PDP_EUA_IETF_IPV4V6; - default: - return OGS_ERROR; - } -} - -int ogs_gtp1_eua_ietf_type_to_pdu_session_type(uint8_t eua_ietf_type) -{ - switch (eua_ietf_type) { - case OGS_PDP_EUA_IETF_IPV4: - return OGS_PDU_SESSION_TYPE_IPV4; - case OGS_PDP_EUA_IETF_IPV6: - return OGS_PDU_SESSION_TYPE_IPV6; - case OGS_PDP_EUA_IETF_IPV4V6: - return OGS_PDU_SESSION_TYPE_IPV4V6; - default: - return OGS_ERROR; - } -} - int ogs_gtp1_eua_to_ip(const ogs_eua_t *eua, uint16_t eua_len, ogs_ip_t *ip, uint8_t *pdu_session_type) { diff --git a/lib/gtp/v1/conv.h b/lib/gtp/v1/conv.h index ee95b6b37..1b0e14a1d 100644 --- a/lib/gtp/v1/conv.h +++ b/lib/gtp/v1/conv.h @@ -35,9 +35,6 @@ int ogs_gtp1_sockaddr_to_gsn_addr(const ogs_sockaddr_t *addr, int ogs_gtp1_gsn_addr_to_ip(const ogs_gtp1_gsn_addr_t *gsnaddr, uint16_t gsnaddr_len, ogs_ip_t *ip); -int ogs_gtp1_pdu_session_type_to_eua_ietf_type(uint8_t session_type); -int ogs_gtp1_eua_ietf_type_to_pdu_session_type(uint8_t eua_ietf_type); - int ogs_gtp1_eua_to_ip(const ogs_eua_t *eua, uint16_t eua_len, ogs_ip_t *ip, uint8_t *pdu_session_type); diff --git a/lib/gtp/v1/types.c b/lib/gtp/v1/types.c index 17667d391..aabfb25e4 100644 --- a/lib/gtp/v1/types.c +++ b/lib/gtp/v1/types.c @@ -398,318 +398,3 @@ int16_t ogs_gtp1_build_qos_profile(ogs_tlv_octet_t *octet, octet->len = 6; return octet->len; } - -/* 7.7.28 MM Context */ -/* TODO: UMTS support, see Figure 41 and Figure 42. */ -int ogs_gtp1_build_mm_context(ogs_gtp1_tlv_mm_context_t *octet, - const ogs_gtp1_mm_context_decoded_t *decoded, uint8_t *data, int data_len) -{ - uint8_t *ptr = data; - unsigned int i; - uint16_t *len_ptr; - uint16_t val16; - - ogs_assert(octet); - ogs_assert(data); - ogs_assert((size_t)data_len >= 1); - - octet->data = data; - -#define CHECK_SPACE_ERR(bytes) \ - if ((ptr - data) + (bytes) > data_len) \ - return OGS_ERROR - CHECK_SPACE_ERR(1); - *ptr++ = (decoded->gupii & 0x01) << 7 | - (decoded->ugipai & 0x01) << 6 | - (decoded->used_gprs_protection_algo & 0x07) << 3 | - (decoded->ksi & 0x07); - - CHECK_SPACE_ERR(1); - *ptr++ = (decoded->sec_mode & 0x03) << 6 | - (decoded->num_vectors & 0x07) << 3 | - (decoded->sec_mode == OGS_GTP1_SEC_MODE_USED_CIPHER_VALUE_UMTS_KEY_AND_QUINTUPLETS ? - decoded->used_cipher & 0x07 : 0x07); - - CHECK_SPACE_ERR(sizeof(decoded->ck)); - memcpy(ptr, &decoded->ck[0], sizeof(decoded->ck)); - ptr += sizeof(decoded->ck); - - CHECK_SPACE_ERR(sizeof(decoded->ik)); - memcpy(ptr, &decoded->ik[0], sizeof(decoded->ik)); - ptr += sizeof(decoded->ik); - - /* Quintuplet Length */ - CHECK_SPACE_ERR(2); - len_ptr = (uint16_t *)ptr; /* will be filled later */ - ptr += 2; - - for (i = 0; i < decoded->num_vectors; i++) { - CHECK_SPACE_ERR(sizeof(decoded->auth_quintuplets[0])); - - memcpy(ptr, &decoded->auth_quintuplets[i].rand, sizeof(decoded->auth_quintuplets[i].rand)); - ptr += sizeof(decoded->auth_quintuplets[i].rand); - - *ptr++ = decoded->auth_quintuplets[i].xres_len; - memcpy(ptr, &decoded->auth_quintuplets[i].xres[0], decoded->auth_quintuplets[i].xres_len); - ptr += decoded->auth_quintuplets[i].xres_len; - - memcpy(ptr, &decoded->auth_quintuplets[i].ck, sizeof(decoded->auth_quintuplets[i].ck)); - ptr += sizeof(decoded->auth_quintuplets[i].ck); - memcpy(ptr, &decoded->auth_quintuplets[i].ik, sizeof(decoded->auth_quintuplets[i].ik)); - ptr += sizeof(decoded->auth_quintuplets[i].ik); - - *ptr++ = decoded->auth_quintuplets[i].autn_len; - memcpy(ptr, &decoded->auth_quintuplets[i].autn[0], decoded->auth_quintuplets[i].autn_len); - ptr += decoded->auth_quintuplets[i].autn_len; - } - - *len_ptr = htobe16(ptr - (((uint8_t *)len_ptr) + 2)); - - CHECK_SPACE_ERR(sizeof(decoded->drx_param)); - memcpy(ptr, &decoded->drx_param, sizeof(decoded->drx_param)); - ptr += sizeof(decoded->drx_param); - - if (decoded->ms_network_capability_len != 0) { - /* MS Network Capability Length */ - CHECK_SPACE_ERR(1 + decoded->ms_network_capability_len); - *ptr++ = decoded->ms_network_capability_len; - memcpy(ptr, &decoded->ms_network_capability, decoded->ms_network_capability_len); - ptr += decoded->ms_network_capability_len; - } else { - CHECK_SPACE_ERR(1); - *ptr++ = 0; - } - - if (decoded->imeisv_len != 0) { - /* Container Len */ - CHECK_SPACE_ERR(2); - val16 = htobe16(2 + decoded->imeisv_len); - memcpy(ptr, &val16, 2); - ptr += 2; - - /* Container (Mobile Identity IMEISV), TS 29.060 Table 47A */ - CHECK_SPACE_ERR(2 + decoded->imeisv_len); - *ptr++ = 0x23; - *ptr++ = decoded->imeisv_len; /* Length of mobile identity contents */ - memcpy(ptr, &decoded->imeisv[0], decoded->imeisv_len); - ptr += decoded->imeisv_len; - } else { - /* Container Len */ - CHECK_SPACE_ERR(2); - *ptr++ = 0; - *ptr++ = 0; - } - - if (decoded->nrsrna) { - CHECK_SPACE_ERR(2); - *ptr++ = 1; - *ptr++ = 0x01; - } - - octet->len = (ptr - data); - return OGS_OK; -#undef CHECK_SPACE_ERR -} - -/* The format of EUA in PDP Context is not exactly the same for the entire EUA, - * hence a separate function is required to encode the value part of the address, - * instead of using regular ogs_gtp1_ip_to_eua(). */ -static int enc_pdp_ctx_as_eua(uint8_t pdu_session_type, const ogs_ip_t *ip, - uint8_t *data, int data_len) -{ - switch (pdu_session_type) - { - case OGS_PDU_SESSION_TYPE_IPV4: - if (!ip->ipv4) { - ogs_error("EUA type IPv4 but no IPv4 address available"); - return OGS_ERROR; - } - if (data_len < OGS_IPV4_LEN) - return OGS_ERROR; - memcpy(data, &ip->addr, OGS_IPV4_LEN); - return OGS_IPV4_LEN; - case OGS_PDU_SESSION_TYPE_IPV6: - if (!ip->ipv6) { - ogs_error("EUA type IPv4 but no IPv6 address available"); - return OGS_ERROR; - } - if (data_len < OGS_IPV6_LEN) - return OGS_ERROR; - memcpy(data, ip->addr6, OGS_IPV6_LEN); - return OGS_IPV6_LEN; - case OGS_PDU_SESSION_TYPE_IPV4V6: - if (ip->ipv4 && ip->ipv6) { - if (data_len < OGS_IPV4_LEN + OGS_IPV6_LEN) - return OGS_ERROR; - memcpy(data, &ip->addr, OGS_IPV4_LEN); - memcpy(data + OGS_IPV4_LEN, ip->addr6, OGS_IPV6_LEN); - return OGS_IPV4_LEN + OGS_IPV6_LEN; - } else if (ip->ipv4) { - if (data_len < OGS_IPV4_LEN) - return OGS_ERROR; - memcpy(data, &ip->addr, OGS_IPV4_LEN); - return OGS_IPV4_LEN; - } else if (ip->ipv6) { - if (data_len < OGS_IPV6_LEN) - return OGS_ERROR; - memcpy(data, ip->addr6, OGS_IPV6_LEN); - return OGS_IPV6_LEN; - } else { - ogs_error("EUA type IPv4 but no IPv4 nor IPv6 address available"); - return OGS_ERROR; - } - break; - default: - ogs_error("Unexpected session type"); - return OGS_ERROR; - } - return OGS_OK; -} - -/* TS 29.060 7.7.29 PDP Context */ -int ogs_gtp1_build_pdp_context(ogs_tlv_octet_t *octet, - const ogs_gtp1_pdp_context_decoded_t *decoded, uint8_t *data, int data_len) -{ - uint8_t *ptr = data; - uint16_t val16; - uint32_t val32; - int rv; - ogs_tlv_octet_t qos_sub_tlv_unused; - - ogs_assert(octet); - ogs_assert(data); - ogs_assert((size_t)data_len >= 1); - - octet->data = data; - -#define CHECK_SPACE_ERR(bytes) \ - if ((ptr - data) + (bytes) > data_len) \ - return OGS_ERROR - - CHECK_SPACE_ERR(1); - *ptr++ = (decoded->ea << 7) | (decoded->vaa << 6) | - (decoded->asi << 5)| (decoded->order << 4) | - (decoded->nsapi & 0x0f); - - CHECK_SPACE_ERR(1); - *ptr++ = (decoded->sapi & 0x0f); - - /* Quality of Service Subscribed */ - CHECK_SPACE_ERR(1 + OGS_GTP1_QOS_PROFILE_MAX_LEN); - rv = ogs_gtp1_build_qos_profile(&qos_sub_tlv_unused, &decoded->qos_sub, - ptr, (data + data_len) - (ptr + 1)); - if (rv < 0) - return rv; - *ptr = rv; - ptr += 1 + rv; - - /* Quality of Service Requested */ - CHECK_SPACE_ERR(1 + OGS_GTP1_QOS_PROFILE_MAX_LEN); - rv = ogs_gtp1_build_qos_profile(&qos_sub_tlv_unused, &decoded->qos_req, - ptr, (data + data_len) - (ptr + 1)); - if (rv < 0) - return rv; - *ptr = rv; - ptr += 1 + rv; - - /* Quality of Service Negotiated */ - CHECK_SPACE_ERR(1 + OGS_GTP1_QOS_PROFILE_MAX_LEN); - rv = ogs_gtp1_build_qos_profile(&qos_sub_tlv_unused, &decoded->qos_neg, - ptr, (data + data_len) - (ptr + 1)); - if (rv < 0) - return rv; - *ptr = rv; - ptr += 1 + rv; - - CHECK_SPACE_ERR(2); - val16 = htobe16(decoded->snd); - memcpy(ptr, &val16, 2); - ptr += 2; - - CHECK_SPACE_ERR(2); - val16 = htobe16(decoded->snu); - memcpy(ptr, &val16, 2); - ptr += 2; - - CHECK_SPACE_ERR(1); - *ptr++ = decoded->send_npdu_nr; - - CHECK_SPACE_ERR(1); - *ptr++ = decoded->receive_npdu_nr; - - CHECK_SPACE_ERR(4); - val32 = htobe32(decoded->ul_teic); - memcpy(ptr, &val32, 4); - ptr += 4; - - CHECK_SPACE_ERR(4); - val32 = htobe32(decoded->ul_teid); - memcpy(ptr, &val32, 4); - ptr += 4; - - CHECK_SPACE_ERR(1); - *ptr++ = decoded->pdp_ctx_id; - - CHECK_SPACE_ERR(1); - *ptr++ = 0xf0 | decoded->pdp_type_org; - CHECK_SPACE_ERR(1); - *ptr++ = ogs_gtp1_pdu_session_type_to_eua_ietf_type(decoded->pdp_type_num[0]); - /* PDP Address Length filled after PDP Address */ - CHECK_SPACE_ERR(1); - rv = enc_pdp_ctx_as_eua(decoded->pdp_type_num[0], &decoded->pdp_address[0], - ptr + 1, (data + data_len) - (ptr + 1)); - if (rv < 0) - return rv; - *ptr = rv; - ptr += 1 + rv; - - /* GGSN Address for control plane Length */ - CHECK_SPACE_ERR(1); - *ptr = decoded->ggsn_address_c.ipv6 ? OGS_GTP_GSN_ADDRESS_IPV6_LEN : OGS_GTP_GSN_ADDRESS_IPV4_LEN; - CHECK_SPACE_ERR(1 + (*ptr)); - memcpy(ptr + 1, - decoded->ggsn_address_c.ipv6 ? - (uint8_t *)decoded->ggsn_address_c.addr6 : - (uint8_t *)&decoded->ggsn_address_c.addr, - *ptr); - ptr += 1 + *ptr; - - /* GGSN Address for User Traffic Length */ - CHECK_SPACE_ERR(1); - *ptr = decoded->ggsn_address_u.ipv6 ? OGS_GTP_GSN_ADDRESS_IPV6_LEN : OGS_GTP_GSN_ADDRESS_IPV4_LEN; - CHECK_SPACE_ERR(1 + (*ptr)); - memcpy(ptr + 1, - decoded->ggsn_address_u.ipv6 ? - (uint8_t *)decoded->ggsn_address_u.addr6 : - (uint8_t *)&decoded->ggsn_address_u.addr, - *ptr); - ptr += 1 + *ptr; - - /* APN */ - rv = strlen(decoded->apn); - CHECK_SPACE_ERR(1 + rv + 1); - *ptr = ogs_fqdn_build( - (char *)ptr + 1, decoded->apn, rv); - ptr += 1 + *ptr; - - CHECK_SPACE_ERR(2); - *ptr++ = (decoded->trans_id >> 8) & 0x0f; - *ptr++ = decoded->trans_id & 0xff; - - if (decoded->ea == OGS_GTP1_PDPCTX_EXT_EUA_YES) { - CHECK_SPACE_ERR(1); - *ptr++ = decoded->pdp_type_num[1]; - /* PDP Address Length filled after PDP Address */ - CHECK_SPACE_ERR(1); - rv = enc_pdp_ctx_as_eua(decoded->pdp_type_num[1], &decoded->pdp_address[1], - ptr + 1, (data + data_len) - (ptr + 1)); - if (rv < 0) - return rv; - *ptr = rv; - ptr += 1 + rv; - } - - octet->len = (ptr - data); - return OGS_OK; -#undef CHECK_SPACE_ERR -} diff --git a/lib/gtp/v1/types.h b/lib/gtp/v1/types.h index 843d6c19a..b3a4c8af5 100644 --- a/lib/gtp/v1/types.h +++ b/lib/gtp/v1/types.h @@ -300,112 +300,4 @@ int16_t ogs_gtp1_parse_qos_profile( int16_t ogs_gtp1_build_qos_profile(ogs_tlv_octet_t *octet, const ogs_gtp1_qos_profile_decoded_t *decoded, void *data, int data_len); -/* 7.7.7 Authentication Triplet. FIXME: Not used in MME Gn scenario? */ -# if 0 -struct ogs_gtp1_auth_triplet_s { - uint8_t rand[16]; - uint8_t sres[4]; - uint8_t kc[8]; -} __attribute__ ((packed)) ogs_gtp1_auth_triplet_t; -#endif - -/* 7.7.35 Authentication Quintuplet */ -typedef struct ogs_gtp1_auth_quintuplet_s { - uint8_t rand[OGS_RAND_LEN]; - uint8_t xres_len; - uint8_t xres[OGS_MAX_RES_LEN]; - uint8_t ck[128/8]; - uint8_t ik[128/8]; - uint8_t autn_len; - uint8_t autn[OGS_AUTN_LEN]; -} ogs_gtp1_auth_quintuplet_t; - -/* TS 24.008 10.5.5.6 DRX parameter (value part only) */ -typedef struct ogs_gtp1_drx_param_val_s { - uint8_t split_pg_cycle_code; /* 0 = equivalent to no DRX */ - ED3(uint8_t cn_drx_cycle_len_coeff:4;, - uint8_t split_on_ccch:1;, - uint8_t non_drx_timer:3;) -} __attribute__ ((packed)) ogs_gtp1_drx_param_val_t; - - - -/* 7.7.28 MM Context (Figure 41) */ -/* Table 47: Security Mode Values */ -#define OGS_GTP1_SEC_MODE_GSM_KEY_AND_TRIPLETS 1 -#define OGS_GTP1_SEC_MODE_GSM_KEY_AND_QUINTUPLETS 3 -#define OGS_GTP1_SEC_MODE_UMTS_KEY_AND_QUINTUPLETS 2 -#define OGS_GTP1_SEC_MODE_USED_CIPHER_VALUE_UMTS_KEY_AND_QUINTUPLETS 0 -/* Table 47B: Used GPRS integrity protection algorithm Values */ -#define OGS_GTP1_USED_GPRS_IP_NO_IP 0 -#define OGS_GTP1_USED_GPRS_IP_GIA4 4 -#define OGS_GTP1_USED_GPRS_IP_GIA5 5 -typedef struct ogs_gtp1_mm_context_decoded_s { - uint8_t gupii:1; - uint8_t ugipai:1; - uint8_t used_gprs_protection_algo:3; /* OGS_GTP1_USED_GPRS_IP */ - uint8_t ksi:3; - uint8_t sec_mode:2; /* OGS_GTP1_SEC_MODE_* */ - uint8_t num_vectors:3; - uint8_t used_cipher:3; /* 0..7 -> GEA/... */ - uint8_t ck[OGS_SHA256_DIGEST_SIZE/2]; - uint8_t ik[OGS_SHA256_DIGEST_SIZE/2]; - ogs_gtp1_auth_quintuplet_t auth_quintuplets[5]; - ogs_gtp1_drx_param_val_t drx_param; - uint8_t ms_network_capability_len; - uint8_t ms_network_capability[6]; /* ogs_nas_ms_network_capability_t */ - uint8_t imeisv_len; - uint8_t imeisv[10]; /* ogs_nas_mobile_identity_imeisv_t */ - uint8_t nrsrna; -} ogs_gtp1_mm_context_decoded_t; - -int ogs_gtp1_build_mm_context(ogs_gtp1_tlv_mm_context_t *octet, - const ogs_gtp1_mm_context_decoded_t *decoded, uint8_t *data, int data_len); - -/* Extended End User Address. Not explicitly defined in a table: */ -#define OGS_GTP1_PDPCTX_EXT_EUA_NO 0 -#define OGS_GTP1_PDPCTX_EXT_EUA_YES 1 - -/* 7.7.29 Table 48 Reordering Required Values */ -#define OGS_GTP1_PDPCTX_REORDERING_REQUIRED_NO 0 -#define OGS_GTP1_PDPCTX_REORDERING_REQUIRED_YES 1 - -/* 7.7.29 Table 49 VPLMN Address Allowed Values */ -#define OGS_GTP1_PDPCTX_VLPMN_ADDR_ALLOWED_NO 0 -#define OGS_GTP1_PDPCTX_VLPMN_ADDR_ALLOWED_YES 1 - -/* 7.7.29 Table 49A Activity Status Indicator Value */ -#define OGS_GTP1_PDPCTX_ACTIVITY_STATUS_IND_YES 0 -#define OGS_GTP1_PDPCTX_ACTIVITY_STATUS_IND_NO 1 - -/* 7.7.29 PDP Context */ -typedef struct ogs_gtp1_pdp_context_decoded_s { - uint8_t ea:1; /* OGS_GTP1_PDPCTX_EXT_EUA_* */ - uint8_t vaa:1; /* OGS_GTP1_PDPCTX_VLPMN_ADDR_ALLOWED_* */ - uint8_t asi:1; /* OGS_GTP1_PDPCTX_ACTIVITY_STATUS_IND_* */ - uint8_t order:1; /* OGS_GTP1_PDPCTX_REORDERING_REQUIRED_* */ - uint8_t nsapi:4; - uint8_t sapi:4; - ogs_gtp1_qos_profile_decoded_t qos_sub; - ogs_gtp1_qos_profile_decoded_t qos_req; - ogs_gtp1_qos_profile_decoded_t qos_neg; - uint16_t snd; - uint16_t snu; - uint8_t send_npdu_nr; - uint8_t receive_npdu_nr; - uint32_t ul_teic; - uint32_t ul_teid; - uint8_t pdp_ctx_id; - uint8_t pdp_type_org; - uint8_t pdp_type_num[2]; - ogs_ip_t pdp_address[2]; - ogs_ip_t ggsn_address_c; - ogs_ip_t ggsn_address_u; - char apn[OGS_MAX_APN_LEN+1]; - uint16_t trans_id:12; -} ogs_gtp1_pdp_context_decoded_t; - -int ogs_gtp1_build_pdp_context(ogs_gtp1_tlv_pdp_context_t *octet, - const ogs_gtp1_pdp_context_decoded_t *decoded, uint8_t *data, int data_len); - #endif /* OGS_GTP1_TYPES_H */ diff --git a/lib/gtp/xact.c b/lib/gtp/xact.c index 0030de27b..6731047a4 100644 --- a/lib/gtp/xact.c +++ b/lib/gtp/xact.c @@ -1012,7 +1012,6 @@ static ogs_gtp_xact_stage_t ogs_gtp1_xact_get_stage(uint8_t type, uint32_t xid) case OGS_GTP1_NOTE_MS_GPRS_PRESENT_RESPONSE_TYPE: case OGS_GTP1_IDENTIFICATION_RESPONSE_TYPE: case OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE: - case OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE: case OGS_GTP1_FORWARD_RELOCATION_RESPONSE_TYPE: case OGS_GTP1_RELOCATION_CANCEL_RESPONSE_TYPE: case OGS_GTP1_UE_REGISTRATION_QUERY_RESPONSE_TYPE: diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index 2bf14268e..749a48c5e 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -421,11 +421,6 @@ struct mme_ue_s { char a_msisdn_bcd[OGS_MAX_MSISDN_BCD_LEN+1]; mme_p_tmsi_t p_tmsi; - struct { - uint32_t sgsn_gn_teid; - ogs_ip_t sgsn_gn_ip; - ogs_ip_t sgsn_gn_ip_alt; - } gn; struct { mme_m_tmsi_t *m_tmsi; diff --git a/src/mme/mme-gn-build.c b/src/mme/mme-gn-build.c index 83f000b15..dc88063dd 100644 --- a/src/mme/mme-gn-build.c +++ b/src/mme/mme-gn-build.c @@ -21,262 +21,6 @@ #include "mme-gn-build.h" -static int sess_fill_mm_context_decoded(mme_sess_t *sess, ogs_gtp1_mm_context_decoded_t *mmctx_dec) -{ - mme_ue_t *mme_ue = sess->mme_ue; - mme_bearer_t *bearer = NULL; - *mmctx_dec = (ogs_gtp1_mm_context_decoded_t) { - .gupii = 1, /* Integrity Protection not required */ - .ugipai = 1, /* Ignore "Used GPRS integrity protection algorithm" field" */ - .ksi = mme_ue->nas_eps.ksi, - .sec_mode = OGS_GTP1_SEC_MODE_UMTS_KEY_AND_QUINTUPLETS, - .num_vectors = 0, /* TODO: figure out how to fill the quintuplets */ - .drx_param = { - .split_pg_cycle_code = 0, /* equivalent to no DRX */ - .cn_drx_cycle_len_coeff = 0, - .split_on_ccch = 0, - .non_drx_timer = 0, - }, - .nrsrna = 0, - }; - - //TODO: derive cK Ki from mme_ue->kasme - ogs_kdf_ck_ik_idle_mobility(mme_ue->ul_count.i32, mme_ue->kasme, &mmctx_dec->ck[0], &mmctx_dec->ik[0]); - - mmctx_dec->imeisv_len = sizeof(mme_ue->nas_mobile_identity_imeisv); - memcpy(&mmctx_dec->imeisv[0], &mme_ue->nas_mobile_identity_imeisv, sizeof(mme_ue->nas_mobile_identity_imeisv)); - - mmctx_dec->ms_network_capability_len = mme_ue->ms_network_capability.length; - memcpy(&mmctx_dec->ms_network_capability[0], ((uint8_t*)&mme_ue->ms_network_capability)+1, sizeof(mme_ue->ms_network_capability) - 1); - - ogs_list_for_each(&sess->bearer_list, bearer) { - - /* FIXME: only 1 PDP Context supported in the message so far. */ - break; - } - - return OGS_OK; -} - -/* 3GPP TS 23.401 Annex E */ -static void build_qos_profile_from_session(ogs_gtp1_qos_profile_decoded_t *qos_pdec, - const mme_sess_t *sess, const mme_bearer_t *bearer) -{ - const mme_ue_t *mme_ue = sess->mme_ue; - const ogs_session_t *session = sess->session; - /* FIXME: Initialize with defaults: */ - memset(qos_pdec, 0, sizeof(*qos_pdec)); - - qos_pdec->qos_profile.arp = session->qos.arp.priority_level; - - /* 3GPP TS 23.401 Annex E table Table E.3 */ - /* Also take into account table 7 in 3GPP TS 23.107 9.1.2.2 */ - switch (session->qos.index) { /* QCI */ - case 1: - qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_CONVERSATIONAL; - qos_pdec->qos_profile.data.source_statistics_descriptor = OGS_GTP1_QOS_SRC_STATS_DESC_SPEECH; - qos_pdec->dec_transfer_delay = 150; - qos_pdec->qos_profile.data.delay_class = 1; - break; - case 2: - qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_CONVERSATIONAL; - qos_pdec->qos_profile.data.source_statistics_descriptor = OGS_GTP1_QOS_SRC_STATS_DESC_UNKNOWN; - qos_pdec->dec_transfer_delay = 150; - qos_pdec->qos_profile.data.delay_class = 1; - break; - case 3: - qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_CONVERSATIONAL; - qos_pdec->qos_profile.data.source_statistics_descriptor = OGS_GTP1_QOS_SRC_STATS_DESC_UNKNOWN; - qos_pdec->dec_transfer_delay = 80; - qos_pdec->qos_profile.data.delay_class = 1; - break; - case 4: - qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_STREAMING; - qos_pdec->qos_profile.data.source_statistics_descriptor = OGS_GTP1_QOS_SRC_STATS_DESC_UNKNOWN; - qos_pdec->qos_profile.data.sdu_error_ratio = 5; /* 10^-5*/ - qos_pdec->qos_profile.data.delay_class = 1; - break; - case 5: - qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_INTERACTIVE; - qos_pdec->qos_profile.data.traffic_handling_priority = 1; - qos_pdec->qos_profile.data.signalling_indication = 1; - qos_pdec->qos_profile.data.delay_class = qos_pdec->qos_profile.data.traffic_handling_priority; - break; - case 6: - qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_INTERACTIVE; - qos_pdec->qos_profile.data.traffic_handling_priority = 1; - qos_pdec->qos_profile.data.delay_class = qos_pdec->qos_profile.data.traffic_handling_priority; - break; - case 7: - qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_INTERACTIVE; - qos_pdec->qos_profile.data.traffic_handling_priority = 2; - qos_pdec->qos_profile.data.delay_class = qos_pdec->qos_profile.data.traffic_handling_priority; - break; - case 8: - qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_INTERACTIVE; - qos_pdec->qos_profile.data.traffic_handling_priority = 3; - qos_pdec->qos_profile.data.delay_class = qos_pdec->qos_profile.data.traffic_handling_priority; - break; - case 9: - default: - qos_pdec->qos_profile.data.traffic_class = OGS_GTP1_QOS_TRAFFIC_CLASS_BACKGROUND; - qos_pdec->qos_profile.data.delay_class = 4; - break; - } - - qos_pdec->data_octet6_to_13_present = true; - qos_pdec->data_octet14_present = true; - qos_pdec->dec_mbr_kbps_dl = mme_ue->ambr.downlink / 1000; - qos_pdec->dec_mbr_kbps_ul = mme_ue->ambr.uplink / 1000; - qos_pdec->dec_gbr_kbps_dl = bearer->qos.gbr.downlink / 1000; - qos_pdec->dec_gbr_kbps_ul = bearer->qos.gbr.uplink / 1000; -} - -static int sess_fill_pdp_context_decoded(mme_sess_t *sess, ogs_gtp1_pdp_context_decoded_t *pdpctx_dec) -{ - mme_bearer_t *bearer = NULL; - - *pdpctx_dec = (ogs_gtp1_pdp_context_decoded_t){ - .ea = OGS_GTP1_PDPCTX_EXT_EUA_NO, - .vaa = OGS_GTP1_PDPCTX_VLPMN_ADDR_ALLOWED_YES, - .asi = OGS_GTP1_PDPCTX_ACTIVITY_STATUS_IND_NO, - .order = OGS_GTP1_PDPCTX_REORDERING_REQUIRED_NO, - .ul_teic = sess->pgw_s5c_teid, - }; - - pdpctx_dec->ggsn_address_c = sess->pgw_s5c_ip; - pdpctx_dec->pdp_type_org = OGS_PDP_EUA_ORG_IETF; - pdpctx_dec->pdp_type_num[0] = sess->session->session_type; - pdpctx_dec->pdp_address[0] = sess->session->ue_ip; - ogs_cpystrn(pdpctx_dec->apn, sess->session->name, sizeof(pdpctx_dec->apn)); - pdpctx_dec->trans_id = sess->pti; - - ogs_list_for_each(&sess->bearer_list, bearer) { - pdpctx_dec->nsapi = bearer->ebi; - pdpctx_dec->sapi = 3; /* FIXME. Using 3 = default for now. Maybe use 0 = UNASSIGNED ?*/ - build_qos_profile_from_session(&pdpctx_dec->qos_sub, sess, bearer); - //FIXME: sort out where to get each one: - memcpy(&pdpctx_dec->qos_req, &pdpctx_dec->qos_sub, sizeof(pdpctx_dec->qos_sub)); - memcpy(&pdpctx_dec->qos_neg, &pdpctx_dec->qos_sub, sizeof(pdpctx_dec->qos_sub)); - pdpctx_dec->snd = 0; /* FIXME. */ - pdpctx_dec->snu = 0; /* FIXME. */ - pdpctx_dec->send_npdu_nr = 0; /* FIXME. */ - pdpctx_dec->receive_npdu_nr = 0; /* FIXME. */ - pdpctx_dec->ul_teid = bearer->pgw_s5u_teid; - pdpctx_dec->pdp_ctx_id = 0; /* FIXME. */ - pdpctx_dec->ggsn_address_u = bearer->pgw_s5u_ip; - /* TODO: session->qos and bearer->qos to fill something in pdpctx_dec. */ - - /* FIXME: only 1 PDP Context supported in the message so far. */ - break; - } - - return OGS_OK; -} - -/* 3GPP TS 29.060 7.5.4 SGSN Context Response */ -ogs_pkbuf_t *mme_gn_build_sgsn_context_response( - mme_ue_t *mme_ue, uint8_t cause) -{ - ogs_gtp1_message_t gtp1_message; - ogs_gtp1_sgsn_context_response_t *rsp = NULL; - mme_sess_t *sess = NULL; - ogs_gtp1_gsn_addr_t mme_gnc_gsnaddr; - int gsn_len; - int rv; - ogs_gtp1_mm_context_decoded_t mmctx_dec; - uint8_t mmctx_dec_buf[512]; - ogs_gtp1_pdp_context_decoded_t pdpctx_dec; - uint8_t pdpctx_dec_buf[1024]; - - ogs_debug("[Gn] build SGSN Context Response"); - - rsp = >p1_message.sgsn_context_response; - memset(>p1_message, 0, sizeof(ogs_gtp1_message_t)); - gtp1_message.h.type = OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE; - - /* 3GPP TS 29.060 7.7.1 Cause, Mandatory */ - rsp->cause.presence = 1; - rsp->cause.u8 = cause; - - /* 3GPP TS 29.060 7.7.2 IMSI, Conditional */ - rsp->imsi.presence = !!mme_ue; - if (rsp->imsi.presence) { - rsp->imsi.data = mme_ue->imsi; - rsp->imsi.len = mme_ue->imsi_len; - } - - if (cause != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) - goto build_ret; - - ogs_assert(mme_ue); - - /* FIXME: Reuse S11 TEID as local Gn interface for now */ - rsp->tunnel_endpoint_identifier_control_plane.presence = 1; - rsp->tunnel_endpoint_identifier_control_plane.u32 = mme_ue->mme_s11_teid; - - ogs_list_for_each(&mme_ue->sess_list, sess) { - if (!MME_HAVE_SGW_S1U_PATH(sess)) - continue; - - /* 7.7.28 MM Context */ - rv = sess_fill_mm_context_decoded(sess, &mmctx_dec); - if (rv != OGS_OK) { - ogs_error("sess_fill_mm_context_decoded() failed"); - return NULL; - } - rsp->mm_context.presence = 1; - rv = ogs_gtp1_build_mm_context(&rsp->mm_context, &mmctx_dec, - &mmctx_dec_buf[0], sizeof(mmctx_dec_buf)); - if (rv != OGS_OK) { - ogs_error("ogs_gtp1_build_mm_context() failed"); - return NULL; - } - - /* 7.7.29 PDP Context */ - rv = sess_fill_pdp_context_decoded(sess, &pdpctx_dec); - if (rv != OGS_OK) { - ogs_error("sess_fill_pdp_context_decoded() failed"); - return NULL; - } - rsp->pdp_context.presence = 1; - rv = ogs_gtp1_build_pdp_context(&rsp->pdp_context, &pdpctx_dec, - &pdpctx_dec_buf[0], sizeof(pdpctx_dec_buf)); - if (rv != OGS_OK) { - ogs_error("ogs_gtp1_build_pdp_context() failed"); - return NULL; - } - - /* FIXME: right now we only support encoding 1 context in the message. */ - break; - } - - /* SGSN Address for Control Plane */ - if (ogs_gtp_self()->gtpc_addr6 && - (mme_ue->gn.sgsn_gn_ip.ipv6 || mme_ue->gn.sgsn_gn_ip_alt.ipv6)) { - rv = ogs_gtp1_sockaddr_to_gsn_addr(NULL, ogs_gtp_self()->gtpc_addr6, - &mme_gnc_gsnaddr, &gsn_len); - if (rv != OGS_OK) { - ogs_error("ogs_gtp1_sockaddr_to_gsn_addr() failed"); - return NULL; - } - } else { - rv = ogs_gtp1_sockaddr_to_gsn_addr(ogs_gtp_self()->gtpc_addr, NULL, - &mme_gnc_gsnaddr, &gsn_len); - if (rv != OGS_OK) { - ogs_error("ogs_gtp1_sockaddr_to_gsn_addr() failed"); - return NULL; - } - } - rsp->sgsn_address_for_control_plane.presence = 1; - rsp->sgsn_address_for_control_plane.data = &mme_gnc_gsnaddr; - rsp->sgsn_address_for_control_plane.len = gsn_len; - - -build_ret: - return ogs_gtp1_build_msg(>p1_message); -} - /* 3GPP TS 29.060 7.5.14.1 RAN Information Relay */ ogs_pkbuf_t *mme_gn_build_ran_information_relay( uint8_t type, const uint8_t *buf, size_t len, @@ -315,4 +59,4 @@ ogs_pkbuf_t *mme_gn_build_ran_information_relay( gtp1_message.h.type = type; return ogs_gtp1_build_msg(>p1_message); -} +} \ No newline at end of file diff --git a/src/mme/mme-gn-build.h b/src/mme/mme-gn-build.h index 6a7af32b5..fc66282c6 100644 --- a/src/mme/mme-gn-build.h +++ b/src/mme/mme-gn-build.h @@ -30,9 +30,6 @@ extern "C" { } #endif -ogs_pkbuf_t *mme_gn_build_sgsn_context_response( - mme_ue_t *mme_ue, uint8_t cause); - ogs_pkbuf_t *mme_gn_build_ran_information_relay( uint8_t type, const uint8_t *buf, size_t len, const ogs_nas_rai_t *rai, uint16_t cell_id); diff --git a/src/mme/mme-gn-handler.c b/src/mme/mme-gn-handler.c index cca5dba04..b661d0de9 100644 --- a/src/mme/mme-gn-handler.c +++ b/src/mme/mme-gn-handler.c @@ -68,117 +68,6 @@ static int decode_global_enb_id(S1AP_Global_ENB_ID_t *glob_enb_id, const uint8_t return OGS_OK; } -/* 3GPP TS 23.003 2.8.2.2 Mapping from RAI and P-TMSI to GUT */ -static void rai_ptmsi_to_guti(const ogs_nas_rai_t *rai, mme_p_tmsi_t ptmsi, uint32_t ptmsi_sig, ogs_nas_eps_guti_t *nas_guti) -{ - uint16_t lac = be16toh(rai->lai.lac);; - nas_guti->nas_plmn_id =rai->lai.nas_plmn_id; - nas_guti->mme_gid = lac; - nas_guti->mme_code = rai->rac; - nas_guti->m_tmsi = 0xC0000000 | (ptmsi & 0x3f000000) | (ptmsi_sig & 0x00ff0000) | (ptmsi & 0x0000ffff); -} - -/* TS 29.060 7.5.3 SGSN Context Request */ -void mme_gn_handle_sgsn_context_request( - ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_request_t *req) -{ - ogs_nas_eps_guti_t nas_guti; - ogs_nas_rai_t *rai; - mme_ue_t *mme_ue = NULL; - int rv; - - ogs_debug("[Gn] Rx SGSN Context Request"); - - if (!req->routeing_area_identity.presence) { - ogs_warn("[Gn] Rx SGSN Context Request with no RAI!"); - mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact); - return; - } - if (req->routeing_area_identity.len != sizeof(*rai)) { - ogs_warn("[Gn] Rx SGSN Context Request RAI wrong size %u vs exp %zu!", - req->routeing_area_identity.len, sizeof(*rai)); - mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT, xact); - return; - } - if (!req->tunnel_endpoint_identifier_control_plane.presence) { - ogs_warn("[Gn] Rx SGSN Context Request with no Tunnel Endpoint Identifier Control Plane!"); - mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact); - return; - } - if (!req->sgsn_address_for_control_plane.presence) { - ogs_warn("[Gn] Rx SGSN Context Request with no SGSN Address for Control Plane!"); - mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact); - return; - } - if (!req->imsi.presence && - !req->temporary_logical_link_identifier.presence && - !req->packet_tmsi.presence) { - ogs_warn("[Gn] Rx SGSN Context Request with no IMSI/TLLI/P-TMSI!"); - mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact); - return; - } - - if (req->ms_validated.presence && - (req->ms_validated.u8 & 0x01) /* 1=> "Yes" */ - && !req->imsi.presence) { - ogs_warn("[Gn] Rx SGSN Context Request with 'MS Validated' but no IMSI!"); - mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_MANDATORY_IE_MISSING, xact); - return; - } - - rai = req->routeing_area_identity.data; - - if (req->imsi.presence) { - mme_ue = mme_ue_find_by_imsi(req->imsi.data, req->imsi.len); - } else if (req->packet_tmsi.presence) { /* P-TMSI */ - if (!req->p_tmsi_signature.presence) { - ogs_warn("[Gn] Rx SGSN Context Request with 'P-TMSI' but no P-TMSI Signature! Assuming value 0."); - req->p_tmsi_signature.u24 = 0; - } - rai_ptmsi_to_guti(rai, req->packet_tmsi.u32, req->p_tmsi_signature.u24, &nas_guti); - mme_ue = mme_ue_find_by_guti(&nas_guti); - } else if (req->temporary_logical_link_identifier.presence) { - if (!req->p_tmsi_signature.presence) { - ogs_warn("[Gn] Rx SGSN Context Request with 'TLLI' but no P-TMSI Signature! Assuming value 0."); - req->p_tmsi_signature.u24 = 0; - } - /* TS 29.060 7.5.3 "The TLLI/P-TMSI and RAI is a foreign TLLI/P-TMSI and an RAI in the old SGSN." - * A foregin TLLI is "tlli = (p_tmsi & 0x3fffffff) | 0x80000000", and since we only use 0x3fffffff - * bits of P-TMSI to derive the GUTI, it's totally fine passing the TLLI as P-TMSI. */ - rai_ptmsi_to_guti(rai, req->temporary_logical_link_identifier.u32, req->p_tmsi_signature.u24, &nas_guti); - mme_ue = mme_ue_find_by_guti(&nas_guti); - } - - if (!mme_ue) { - mme_gtp1_send_sgsn_context_response(NULL, OGS_GTP1_CAUSE_IMSI_IMEI_NOT_KNOWN, xact); - return; - } - - mme_ue->gn.sgsn_gn_teid = req->tunnel_endpoint_identifier_control_plane.u32; - - rv = ogs_gtp1_gsn_addr_to_ip(req->sgsn_address_for_control_plane.data, - req->sgsn_address_for_control_plane.len, - &mme_ue->gn.sgsn_gn_ip); - ogs_assert(rv == OGS_OK); - - if (req->alternative_sgsn_address_for_control_plane.presence) { - rv = ogs_gtp1_gsn_addr_to_ip(req->alternative_sgsn_address_for_control_plane.data, - req->alternative_sgsn_address_for_control_plane.len, - &mme_ue->gn.sgsn_gn_ip_alt); - ogs_assert(rv == OGS_OK); - } - - mme_gtp1_send_sgsn_context_response(mme_ue, OGS_GTP1_CAUSE_REQUEST_ACCEPTED, xact); -} - -/* TS 29.060 7.5.5 SGSN Context Acknowledge */ -void mme_gn_handle_sgsn_context_acknowledge( - ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_acknowledge_t *req) -{ - /* FIXME: find out what to do here, 3GPP TS 23.401 D.3.5 - * Probably release the Session on the SGW (without releasing in the PGW) */ -} - /* TS 29.060 7.5.14.1 */ void mme_gn_handle_ran_information_relay( ogs_gtp_xact_t *xact, ogs_gtp1_ran_information_relay_t *req) diff --git a/src/mme/mme-gn-handler.h b/src/mme/mme-gn-handler.h index 192650b55..3cf2e661b 100644 --- a/src/mme/mme-gn-handler.h +++ b/src/mme/mme-gn-handler.h @@ -32,12 +32,6 @@ void mme_gn_handle_echo_request( void mme_gn_handle_echo_response( ogs_gtp_xact_t *xact, ogs_gtp1_echo_response_t *req); -void mme_gn_handle_sgsn_context_request( - ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_request_t *req); - -void mme_gn_handle_sgsn_context_acknowledge( - ogs_gtp_xact_t *xact, ogs_gtp1_sgsn_context_acknowledge_t *req); - void mme_gn_handle_ran_information_relay( ogs_gtp_xact_t *xact, ogs_gtp1_ran_information_relay_t *req); diff --git a/src/mme/mme-gtp-path.c b/src/mme/mme-gtp-path.c index 92ed42b6c..cce8a714e 100644 --- a/src/mme/mme-gtp-path.c +++ b/src/mme/mme-gtp-path.c @@ -758,36 +758,6 @@ int mme_gtp_send_bearer_resource_command( return rv; } -int mme_gtp1_send_sgsn_context_response( - mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact) -{ - int rv; - ogs_gtp1_header_t h; - ogs_pkbuf_t *pkbuf = NULL; - - memset(&h, 0, sizeof(ogs_gtp1_header_t)); - h.type = OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE; - h.teid = mme_ue ? mme_ue->gn.sgsn_gn_teid : 0; - - pkbuf = mme_gn_build_sgsn_context_response(mme_ue, cause); - if (!pkbuf) { - ogs_error("mme_gn_build_sgsn_context_response() failed"); - return OGS_ERROR; - } - /* FIXME: Reuse S11 TEID as local Gn interface for now */ - xact->local_teid = mme_ue ? mme_ue->mme_s11_teid : 0; - - rv = ogs_gtp1_xact_update_tx(xact, &h, pkbuf); - if (rv != OGS_OK) { - ogs_error("ogs_gtp1_xact_update_tx() failed"); - return OGS_ERROR; - } - - rv = ogs_gtp_xact_commit(xact); - ogs_expect(rv == OGS_OK); - - return rv; -} int mme_gtp1_send_ran_information_relay( mme_sgsn_t *sgsn, const uint8_t *buf, size_t len, diff --git a/src/mme/mme-gtp-path.h b/src/mme/mme-gtp-path.h index 1e41d34ff..37773e115 100644 --- a/src/mme/mme-gtp-path.h +++ b/src/mme/mme-gtp-path.h @@ -55,9 +55,6 @@ int mme_gtp_send_delete_indirect_data_forwarding_tunnel_request( int mme_gtp_send_bearer_resource_command( mme_bearer_t *bearer, ogs_nas_eps_message_t *nas_message); -int mme_gtp1_send_sgsn_context_response( - mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact); - int mme_gtp1_send_ran_information_relay( mme_sgsn_t *sgsn, const uint8_t *buf, size_t len, const ogs_nas_rai_t *rai, uint16_t cell_id); diff --git a/src/mme/mme-sm.c b/src/mme/mme-sm.c index 3c2a2678b..1a437a5d5 100644 --- a/src/mme/mme-sm.c +++ b/src/mme/mme-sm.c @@ -662,12 +662,6 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) case OGS_GTP1_ECHO_RESPONSE_TYPE: mme_gn_handle_echo_response(xact, >p1_message.echo_response); break; - case OGS_GTP1_SGSN_CONTEXT_REQUEST_TYPE: - mme_gn_handle_sgsn_context_request(xact, >p1_message.sgsn_context_request); - break; - case OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE: - mme_gn_handle_sgsn_context_acknowledge(xact, >p1_message.sgsn_context_acknowledge); - break; case OGS_GTP1_RAN_INFORMATION_RELAY_TYPE: mme_gn_handle_ran_information_relay(xact, >p1_message.ran_information_relay); break;