Files
openairinterface5g/openair-cn/MME_APP/mme_app_context.c
T
Lionel Gauthier 059a0a3fdc astyle --recursive --indent=spaces=2 --style=kr --indent-col1-comments --break-blocks --convert-tabs --max-code-length=200
This is done for better merging branch/LG_PRE_RELEASE_0.3 into trunk (same process is applied on this branch)

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7073 818b1a75-f10b-46b9-bf7c-635c3b92a50f
2015-04-09 09:29:12 +00:00

420 lines
15 KiB
C

/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include "intertask_interface.h"
#include "mme_config.h"
#include "assertions.h"
#include "conversions.h"
#include "tree.h"
#include "enum_string.h"
#include "common_types.h"
#include "mme_app_extern.h"
#include "mme_app_ue_context.h"
#include "mme_app_defs.h"
static inline int ue_context_compare_identifiers(struct ue_context_s *p1,
struct ue_context_s *p2);
RB_PROTOTYPE(ue_context_map, ue_context_s, rb_entry,
ue_context_compare_identifiers);
RB_GENERATE(ue_context_map, ue_context_s, rb_entry,
ue_context_compare_identifiers);
static inline int ue_context_compare_identifiers(
struct ue_context_s *p1, struct ue_context_s *p2)
{
MME_APP_DEBUG(" ue_context_compare_identifiers IMSI %"SCNu64"\n", p1->imsi);
MME_APP_DEBUG(" ue_context_compare_identifiers mme_s11_teid %08x\n" , p1->mme_s11_teid);
MME_APP_DEBUG(" ue_context_compare_identifiers mme_ue_s1ap_id %08x\n" , p1->mme_ue_s1ap_id);
MME_APP_DEBUG(" ue_context_compare_identifiers ue_id %08x\n" , p1->ue_id);
if (p1->imsi > 0) {
/* if IMSI provided */
if (p1->imsi > p2->imsi) {
return 1;
}
if (p1->imsi < p2->imsi) {
return -1;
}
} else if (p1->mme_s11_teid > 0) {
/* if s11 teid provided */
if (p1->mme_s11_teid > p2->mme_s11_teid) {
return 1;
}
if (p1->mme_s11_teid < p2->mme_s11_teid) {
return -1;
}
} else if (p1->mme_ue_s1ap_id > 0) {
MME_APP_DEBUG(" with mme_ue_s1ap_id %d\n" , p2->mme_ue_s1ap_id);
/* if s1ap ue id provided */
if (p1->mme_ue_s1ap_id > p2->mme_ue_s1ap_id) {
return 1;
}
if (p1->mme_ue_s1ap_id < p2->mme_ue_s1ap_id) {
return -1;
}
} else if (p1->ue_id > 0) {
/* if nas ue_id provided */
if (p1->ue_id > p2->ue_id) {
return 1;
}
if (p1->ue_id < p2->ue_id) {
return -1;
}
} else {
uint16_t mcc1;
uint16_t mnc1;
uint16_t mnc1_len;
uint16_t mcc2;
uint16_t mnc2;
uint16_t mnc2_len;
PLMN_T_TO_MCC_MNC(p1->guti.gummei.plmn, mcc1, mnc1, mnc1_len);
PLMN_T_TO_MCC_MNC(p1->guti.gummei.plmn, mcc2, mnc2, mnc2_len);
/* else compare by GUTI */
if ((p1->guti.m_tmsi < p2->guti.m_tmsi) &&
(p1->guti.gummei.MMEcode < p2->guti.gummei.MMEcode) &&
(p1->guti.gummei.MMEgid < p2->guti.gummei.MMEgid) &&
(mcc1 < mcc2) &&
(mnc1 < mnc2) &&
(mnc1_len < mnc2_len))
return 1;
if ((p1->guti.m_tmsi > p2->guti.m_tmsi) &&
(p1->guti.gummei.MMEcode > p2->guti.gummei.MMEcode) &&
(p1->guti.gummei.MMEgid > p2->guti.gummei.MMEgid) &&
(mcc1 > mcc2) &&
(mnc1 > mnc2) &&
(mnc1_len > mnc2_len))
return -1;
}
/* Match -> return 0 */
return 0;
}
ue_context_t *mme_create_new_ue_context(void)
{
ue_context_t *new_p;
new_p = malloc(sizeof(ue_context_t));
if (new_p == NULL) {
return NULL;
}
memset(new_p, 0, sizeof(ue_context_t));
return new_p;
}
inline
struct ue_context_s *mme_ue_context_exists_imsi(mme_ue_context_t *mme_ue_context,
mme_app_imsi_t imsi)
{
struct ue_context_s reference;
DevAssert(mme_ue_context != NULL);
memset(&reference, 0, sizeof(struct ue_context_s));
reference.imsi = imsi;
return RB_FIND(ue_context_map, &mme_ue_context->ue_context_tree,
&reference);
}
inline
struct ue_context_s *mme_ue_context_exists_s11_teid(mme_ue_context_t *mme_ue_context,
uint32_t teid)
{
struct ue_context_s reference;
DevAssert(mme_ue_context != NULL);
memset(&reference, 0, sizeof(struct ue_context_s));
reference.mme_s11_teid = teid;
return RB_FIND(ue_context_map, &mme_ue_context->ue_context_tree,
&reference);
}
inline
ue_context_t *mme_ue_context_exists_mme_ue_s1ap_id(
mme_ue_context_t *mme_ue_context,
uint32_t mme_ue_s1ap_id)
{
struct ue_context_s reference;
DevAssert(mme_ue_context != NULL);
memset(&reference, 0, sizeof(struct ue_context_s));
reference.mme_ue_s1ap_id = mme_ue_s1ap_id;
return RB_FIND(ue_context_map, &mme_ue_context->ue_context_tree,
&reference);
}
inline
ue_context_t *mme_ue_context_exists_nas_ue_id(
mme_ue_context_t *mme_ue_context,
uint32_t nas_ue_id)
{
struct ue_context_s reference;
DevAssert(mme_ue_context != NULL);
memset(&reference, 0, sizeof(struct ue_context_s));
reference.ue_id = nas_ue_id;
return RB_FIND(ue_context_map, &mme_ue_context->ue_context_tree,
&reference);
}
inline
ue_context_t *mme_ue_context_exists_guti(mme_ue_context_t *mme_ue_context,
GUTI_t guti)
{
struct ue_context_s reference;
DevAssert(mme_ue_context != NULL);
memset(&reference, 0, sizeof(struct ue_context_s));
memcpy(&reference.guti, &guti, sizeof(GUTI_t));
return RB_FIND(ue_context_map, &mme_ue_context->ue_context_tree,
&reference);
}
int mme_insert_ue_context(mme_ue_context_t *mme_ue_context, struct ue_context_s *ue_context_p)
{
struct ue_context_s *collision_p = NULL;
DevAssert(mme_ue_context != NULL);
DevAssert(ue_context_p != NULL);
/* Updating statistics */
mme_ue_context->nb_ue_managed++;
mme_ue_context->nb_ue_since_last_stat++;
collision_p = RB_INSERT(ue_context_map, &mme_ue_context->ue_context_tree,
ue_context_p);
if (collision_p != NULL) {
fprintf(stderr, "This ue context already exists...\n");
return -1;
}
return 0;
}
void mme_app_dump_ue_contexts(mme_ue_context_t *mme_ue_context)
{
struct ue_context_s *context_p;
MME_APP_DEBUG("-----------------------UE contexts-----------------------\n");
RB_FOREACH(context_p, ue_context_map, &mme_ue_context->ue_context_tree) {
uint8_t j;
MME_APP_DEBUG(" - IMSI ...........: %"SCNu64"\n", context_p->imsi);
MME_APP_DEBUG(" | m_tmsi | mmec | mmegid | mcc | mnc |\n");
MME_APP_DEBUG(" - GUTI............: | %08x | %02x | %04x | %03u | %03u |\n",
context_p->guti.m_tmsi, context_p->guti.gummei.MMEcode,
context_p->guti.gummei.MMEgid,
/* TODO check if two or three digits MNC... */
context_p->guti.gummei.plmn.MCCdigit3 * 100 +
context_p->guti.gummei.plmn.MCCdigit2 * 10 +
context_p->guti.gummei.plmn.MCCdigit1,
context_p->guti.gummei.plmn.MNCdigit3 * 100 +
context_p->guti.gummei.plmn.MNCdigit2 * 10 +
context_p->guti.gummei.plmn.MNCdigit1);
MME_APP_DEBUG(" - Authenticated ..: %s\n",
(context_p->imsi_auth == IMSI_UNAUTHENTICATED) ? "FALSE": "TRUE");
MME_APP_DEBUG(" - eNB UE s1ap ID .: %08x\n", context_p->eNB_ue_s1ap_id);
MME_APP_DEBUG(" - MME UE s1ap ID .: %08x\n", context_p->mme_ue_s1ap_id);
MME_APP_DEBUG(" - MME S11 TEID ...: %08x\n", context_p->mme_s11_teid);
MME_APP_DEBUG(" - SGW S11 TEID ...: %08x\n", context_p->sgw_s11_teid);
MME_APP_DEBUG(" | mcc | mnc | cell id |\n");
MME_APP_DEBUG(" - E-UTRAN CGI ....: | %03u | %03u | %08x |\n",
context_p->e_utran_cgi.plmn.MCCdigit3 * 100 +
context_p->e_utran_cgi.plmn.MCCdigit2 * 10 +
context_p->e_utran_cgi.plmn.MCCdigit1,
context_p->e_utran_cgi.plmn.MNCdigit3 * 100 +
context_p->e_utran_cgi.plmn.MNCdigit2 * 10 +
context_p->e_utran_cgi.plmn.MNCdigit1,
context_p->e_utran_cgi.cell_identity);
/* Ctime return a \n in the string */
MME_APP_DEBUG(" - Last acquired ..: %s", ctime(&context_p->cell_age));
/* Display UE info only if we know them */
if (context_p->subscription_known == SUBSCRIPTION_KNOWN) {
MME_APP_DEBUG(" - Status .........: %s\n",
(context_p->sub_status == SS_SERVICE_GRANTED) ? "Granted" : "Barred");
#define DISPLAY_BIT_MASK_PRESENT(mASK) \
((context_p->access_restriction_data & mASK) ? 'X' : 'O')
MME_APP_DEBUG(" (O = allowed, X = !O) |UTRAN|GERAN|GAN|HSDPA EVO|E_UTRAN|HO TO NO 3GPP|\n");
MME_APP_DEBUG(" - Access restriction | %c | %c | %c | %c | %c | %c |\n",
DISPLAY_BIT_MASK_PRESENT(ARD_UTRAN_NOT_ALLOWED),
DISPLAY_BIT_MASK_PRESENT(ARD_GERAN_NOT_ALLOWED),
DISPLAY_BIT_MASK_PRESENT(ARD_GAN_NOT_ALLOWED),
DISPLAY_BIT_MASK_PRESENT(ARD_I_HSDPA_EVO_NOT_ALLOWED),
DISPLAY_BIT_MASK_PRESENT(ARD_E_UTRAN_NOT_ALLOWED),
DISPLAY_BIT_MASK_PRESENT(ARD_HO_TO_NON_3GPP_NOT_ALLOWED));
MME_APP_DEBUG(" - Access Mode ....: %s\n",
ACCESS_MODE_TO_STRING(context_p->access_mode));
MME_APP_DEBUG(" - MSISDN .........: %-*s\n",
MSISDN_LENGTH, context_p->msisdn);
MME_APP_DEBUG(" - RAU/TAU timer ..: %u\n", context_p->rau_tau_timer);
MME_APP_DEBUG(" - IMEISV .........: %*s\n", 15,
context_p->me_identity.imeisv);
MME_APP_DEBUG(" - AMBR (bits/s) ( Downlink | Uplink )\n");
MME_APP_DEBUG(" Subscribed ...: (%010"PRIu64"|%010"PRIu64")\n",
context_p->subscribed_ambr.br_dl,
context_p->subscribed_ambr.br_ul);
MME_APP_DEBUG(" Allocated ....: (%010"PRIu64"|%010"PRIu64")\n",
context_p->used_ambr.br_dl, context_p->used_ambr.br_ul);
MME_APP_DEBUG(" - Known vectors ..: %u\n", context_p->nb_of_vectors);
for (j = 0; j < context_p->nb_of_vectors; j++) {
int k;
char xres_string[3 * XRES_LENGTH_MAX + 1];
eutran_vector_t *vector_p;
vector_p = &context_p->vector_list[j];
MME_APP_DEBUG(" - RAND ..: "RAND_FORMAT"\n",
RAND_DISPLAY(vector_p->rand));
MME_APP_DEBUG(" - AUTN ..: "AUTN_FORMAT"\n",
AUTN_DISPLAY(vector_p->autn));
MME_APP_DEBUG(" - KASME .: "KASME_FORMAT"\n",
KASME_DISPLAY_1(vector_p->kasme));
MME_APP_DEBUG(" "KASME_FORMAT"\n",
KASME_DISPLAY_2(vector_p->kasme));
for (k = 0; k < vector_p->xres.size; k++) {
sprintf(&xres_string[k * 3], "%02x,", vector_p->xres.data[k]);
}
xres_string[k * 3 - 1] = '\0';
MME_APP_DEBUG(" - XRES ..: %s\n", xres_string);
}
MME_APP_DEBUG(" - PDN List:\n");
for (j = 0; j < context_p->apn_profile.nb_apns; j++) {
struct apn_configuration_s *apn_config_p;
apn_config_p = &context_p->apn_profile.apn_configuration[j];
/* Default APN ? */
MME_APP_DEBUG(" - Default APN ...: %s\n",
(apn_config_p->context_identifier == context_p->apn_profile.context_identifier)
? "TRUE" : "FALSE");
MME_APP_DEBUG(" - APN ...........: %s\n", apn_config_p->service_selection);
MME_APP_DEBUG(" - AMBR (bits/s) ( Downlink | Uplink )\n");
MME_APP_DEBUG(" (%010"PRIu64"|%010"PRIu64")\n",
apn_config_p->ambr.br_dl, apn_config_p->ambr.br_ul);
MME_APP_DEBUG(" - PDN type ......: %s\n",
PDN_TYPE_TO_STRING(apn_config_p->pdn_type));
MME_APP_DEBUG(" - QOS\n");
MME_APP_DEBUG(" QCI .........: %u\n",
apn_config_p->subscribed_qos.qci);
MME_APP_DEBUG(" Prio level ..: %u\n",
apn_config_p->subscribed_qos.allocation_retention_priority.priority_level);
MME_APP_DEBUG(" Pre-emp vul .: %s\n",
(apn_config_p->subscribed_qos.allocation_retention_priority.pre_emp_vulnerability
== PRE_EMPTION_VULNERABILITY_ENABLED) ? "ENABLED" : "DISABLED");
MME_APP_DEBUG(" Pre-emp cap .: %s\n",
(apn_config_p->subscribed_qos.allocation_retention_priority.pre_emp_capability
== PRE_EMPTION_CAPABILITY_ENABLED) ? "ENABLED" : "DISABLED");
if (apn_config_p->nb_ip_address == 0) {
MME_APP_DEBUG(" IP addr .....: Dynamic allocation\n");
} else {
int i;
MME_APP_DEBUG(" IP addresses :\n");
for (i = 0; i < apn_config_p->nb_ip_address; i++) {
if (apn_config_p->ip_address[i].pdn_type == IPv4) {
MME_APP_DEBUG(" ["IPV4_ADDR"]\n",
IPV4_ADDR_DISPLAY_8(apn_config_p->ip_address[i].address.ipv4_address));
} else {
char ipv6[40];
inet_ntop(AF_INET6, apn_config_p->ip_address[i].address.ipv6_address,ipv6, 40);
MME_APP_DEBUG(" [%s]\n", ipv6);
}
}
}
MME_APP_DEBUG("\n");
}
MME_APP_DEBUG(" - Bearer List:\n");
for (j = 0; j < BEARERS_PER_UE; j++) {
bearer_context_t *bearer_context_p;
bearer_context_p = &context_p->eps_bearers[j];
if (bearer_context_p->s_gw_teid != 0) {
MME_APP_DEBUG(" Bearer id .......: %02u\n", j);
MME_APP_DEBUG(" S-GW TEID (UP)...: %08x\n", bearer_context_p->s_gw_teid);
MME_APP_DEBUG(" P-GW TEID (UP)...: %08x\n", bearer_context_p->p_gw_teid);
MME_APP_DEBUG(" QCI .............: %u\n",
bearer_context_p->qci);
MME_APP_DEBUG(" Priority level ..: %u\n",
bearer_context_p->prio_level);
MME_APP_DEBUG(" Pre-emp vul .....: %s\n",
(bearer_context_p->pre_emp_vulnerability
== PRE_EMPTION_VULNERABILITY_ENABLED) ? "ENABLED" : "DISABLED");
MME_APP_DEBUG(" Pre-emp cap .....: %s\n",
(bearer_context_p->pre_emp_capability
== PRE_EMPTION_CAPABILITY_ENABLED) ? "ENABLED" : "DISABLED");
}
}
}
}
MME_APP_DEBUG("---------------------------------------------------------\n");
}