Files
openairinterface5g/openair-cn/SGW-LITE/sgw_lite_context_manager.c
T
Lionel Gauthier 26495e6a0a GPLv3
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5552 818b1a75-f10b-46b9-bf7c-635c3b92a50f
2014-07-17 13:40:57 +00:00

374 lines
16 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.
*******************************************************************************/
/*! \file sgw_lite_context_manager.c
* \brief
* \author Lionel Gauthier
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
#define SGW_LITE
#define SGW_LITE_CONTEXT_MANAGER_C
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "tree.h"
#include "hashtable.h"
#include "intertask_interface.h"
#include "mme_config.h"
#include "sgw_lite_defs.h"
#include "sgw_lite_context_manager.h"
#include "sgw_lite.h"
extern sgw_app_t sgw_app;
//-----------------------------------------------------------------------------
static void sgw_lite_display_s11teid2mme_mapping(uint64_t keyP, void *dataP, void* unusedParameterP)
//-----------------------------------------------------------------------------
{
mme_sgw_tunnel_t * mme_sgw_tunnel= NULL;
if (dataP != NULL) {
mme_sgw_tunnel = (mme_sgw_tunnel_t *)dataP;
SPGW_APP_DEBUG("| %u\t<------------->\t%u\n", mme_sgw_tunnel->remote_teid, mme_sgw_tunnel->local_teid);
} else {
SPGW_APP_DEBUG("INVALID S11 TEID MAPPING FOUND\n");
}
}
//-----------------------------------------------------------------------------
void sgw_lite_display_s11teid2mme_mappings(void)
//-----------------------------------------------------------------------------
{
SPGW_APP_DEBUG("+--------------------------------------+\n");
SPGW_APP_DEBUG("| MME <--- S11 TE ID MAPPINGS ---> SGW |\n");
SPGW_APP_DEBUG("+--------------------------------------+\n");
hashtable_apply_funct_on_elements(sgw_app.s11teid2mme_hashtable, sgw_lite_display_s11teid2mme_mapping, NULL);
SPGW_APP_DEBUG("+--------------------------------------+\n");
}
//-----------------------------------------------------------------------------
static void sgw_lite_display_pdn_connection_sgw_eps_bearers(uint64_t keyP, void *dataP, void* unusedParameterP)
//-----------------------------------------------------------------------------
{
sgw_eps_bearer_entry_t *eps_bearer_entry = NULL;
if (dataP != NULL) {
eps_bearer_entry = (sgw_eps_bearer_entry_t *)dataP;
SPGW_APP_DEBUG("|\t\t\t\t%"PRId64"\t<-> ebi: %u, enb_teid_for_S1u: %u, s_gw_teid_for_S1u_S12_S4_up: %u (tbc)\n",
keyP,
eps_bearer_entry->eps_bearer_id,
eps_bearer_entry->enb_teid_for_S1u,
eps_bearer_entry->s_gw_teid_for_S1u_S12_S4_up);
} else {
SPGW_APP_DEBUG("\t\t\t\tINVALID eps_bearer_entry FOUND\n");
}
}
//-----------------------------------------------------------------------------
static void sgw_lite_display_s11_bearer_context_information(uint64_t keyP, void *dataP, void* unusedParameterP)
//-----------------------------------------------------------------------------
{
s_plus_p_gw_eps_bearer_context_information_t * sp_context_information= NULL;
hashtable_rc_t hash_rc;
if (dataP != NULL) {
sp_context_information = (s_plus_p_gw_eps_bearer_context_information_t *)dataP;
SPGW_APP_DEBUG("| KEY %"PRId64": \n", keyP);
SPGW_APP_DEBUG("|\tsgw_eps_bearer_context_information: |\n");
//Imsi_t imsi; ///< IMSI (International Mobile Subscriber Identity) is the subscriber permanent identity.
SPGW_APP_DEBUG("|\t\timsi_unauthenticated_indicator:\t%u\n", sp_context_information->sgw_eps_bearer_context_information.imsi_unauthenticated_indicator);
//char msisdn[MSISDN_LENGTH]; ///< The basic MSISDN of the UE. The presence is dictated by its storage in the HSS.
SPGW_APP_DEBUG("|\t\tmme_teid_for_S11: \t%u\n", sp_context_information->sgw_eps_bearer_context_information.mme_teid_for_S11);
//ip_address_t mme_ip_address_for_S11; ///< MME IP address the S11 interface.
SPGW_APP_DEBUG("|\t\ts_gw_teid_for_S11_S4: \t%u\n", sp_context_information->sgw_eps_bearer_context_information.s_gw_teid_for_S11_S4);
//ip_address_t s_gw_ip_address_for_S11_S4; ///< S-GW IP address for the S11 interface and the S4 Interface (control plane).
//cgi_t last_known_cell_Id; ///< This is the last location of the UE known by the network
SPGW_APP_DEBUG("|\t\tpdn_connection:\n");
SPGW_APP_DEBUG("|\t\t\tapn_in_use: %s\n", sp_context_information->sgw_eps_bearer_context_information.pdn_connection.apn_in_use);
SPGW_APP_DEBUG("|\t\t\tdefault_bearer: %u\n", sp_context_information->sgw_eps_bearer_context_information.pdn_connection.default_bearer);
SPGW_APP_DEBUG("|\t\t\teps_bearers:\n");
hash_rc = hashtable_apply_funct_on_elements(sp_context_information->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers,
sgw_lite_display_pdn_connection_sgw_eps_bearers,
NULL);
if (hash_rc != HASH_TABLE_OK) {
SPGW_APP_DEBUG("Invalid sgw_eps_bearers hashtable for display\n");
}
//void *trxn;
//uint32_t peer_ip;
} else {
SPGW_APP_DEBUG("INVALID s_plus_p_gw_eps_bearer_context_information FOUND\n");
}
}
//-----------------------------------------------------------------------------
void sgw_lite_display_s11_bearer_context_information_mapping(void)
//-----------------------------------------------------------------------------
{
SPGW_APP_DEBUG("+-----------------------------------------+\n");
SPGW_APP_DEBUG("| S11 BEARER CONTEXT INFORMATION MAPPINGS |\n");
SPGW_APP_DEBUG("+-----------------------------------------+\n");
hashtable_apply_funct_on_elements(sgw_app.s11_bearer_context_information_hashtable, sgw_lite_display_s11_bearer_context_information, NULL);
SPGW_APP_DEBUG("+--------------------------------------+\n");
}
//-----------------------------------------------------------------------------
void pgw_lite_cm_free_apn(pgw_apn_t *apnP)
//-----------------------------------------------------------------------------
{
if (apnP != NULL) {
if (apnP->pdn_connections != NULL) {
obj_hashtable_destroy(apnP->pdn_connections);
}
}
}
//-----------------------------------------------------------------------------
Teid_t sgw_lite_get_new_S11_tunnel_id(void)
//-----------------------------------------------------------------------------
{
// TO DO: RANDOM
static Teid_t tunnel_id = 0;
tunnel_id += 1;
return tunnel_id;
}
//-----------------------------------------------------------------------------
mme_sgw_tunnel_t *sgw_lite_cm_create_s11_tunnel(Teid_t remote_teid, Teid_t local_teid)
//-----------------------------------------------------------------------------
{
mme_sgw_tunnel_t *new_tunnel;
new_tunnel = malloc(sizeof(mme_sgw_tunnel_t));
if (new_tunnel == NULL) {
/* Malloc failed, may be ENOMEM error */
SPGW_APP_ERROR("Failed to create tunnel for remote_teid %u\n", remote_teid);
return NULL;
}
new_tunnel->remote_teid = remote_teid;
new_tunnel->local_teid = local_teid;
/* Trying to insert the new tunnel into the tree.
* If collision_p is not NULL (0), it means tunnel is already present.
*/
hashtable_insert(sgw_app.s11teid2mme_hashtable, local_teid, new_tunnel);
return new_tunnel;
}
//-----------------------------------------------------------------------------
int sgw_lite_cm_remove_s11_tunnel(Teid_t local_teid)
//-----------------------------------------------------------------------------
{
int temp;
temp = hashtable_remove(sgw_app.s11teid2mme_hashtable, local_teid);
return temp;
}
//-----------------------------------------------------------------------------
sgw_eps_bearer_entry_t * sgw_lite_cm_create_eps_bearer_entry(void)
//-----------------------------------------------------------------------------
{
sgw_eps_bearer_entry_t *eps_bearer_entry;
eps_bearer_entry = malloc(sizeof(sgw_eps_bearer_entry_t));
if (eps_bearer_entry == NULL) {
/* Malloc failed, may be ENOMEM error */
SPGW_APP_ERROR("Failed to create new EPS bearer object\n");
return NULL;
}
return eps_bearer_entry;
}
//-----------------------------------------------------------------------------
sgw_pdn_connection_t * sgw_lite_cm_create_pdn_connection(void)
//-----------------------------------------------------------------------------
{
sgw_pdn_connection_t *pdn_connection;
pdn_connection = malloc(sizeof(sgw_pdn_connection_t));
if (pdn_connection == NULL) {
/* Malloc failed, may be ENOMEM error */
SPGW_APP_ERROR("Failed to create new PDN connection object\n");
return NULL;
}
memset(pdn_connection, 0, sizeof(sgw_pdn_connection_t));
pdn_connection->sgw_eps_bearers = hashtable_create(12, NULL, NULL);
if ( pdn_connection->sgw_eps_bearers == NULL) {
SPGW_APP_ERROR("Failed to create eps bearers collection object\n");
free(pdn_connection);
pdn_connection = NULL;
return NULL;
}
return pdn_connection;
}
//-----------------------------------------------------------------------------
void sgw_lite_cm_free_pdn_connection(sgw_pdn_connection_t *pdn_connectionP)
//-----------------------------------------------------------------------------
{
if (pdn_connectionP != NULL) {
if (pdn_connectionP->sgw_eps_bearers != NULL) {
hashtable_destroy(pdn_connectionP->sgw_eps_bearers);
}
}
}
//-----------------------------------------------------------------------------
void sgw_lite_cm_free_s_plus_p_gw_eps_bearer_context_information(s_plus_p_gw_eps_bearer_context_information_t *contextP)
//-----------------------------------------------------------------------------
{
if (contextP == NULL) {
return;
}
/*if (contextP->sgw_eps_bearer_context_information.pdn_connections != NULL) {
obj_hashtable_destroy(contextP->sgw_eps_bearer_context_information.pdn_connections);
}*/
if (contextP->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers != NULL) {
hashtable_destroy(contextP->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers);
}
if (contextP->pgw_eps_bearer_context_information.apns != NULL) {
obj_hashtable_destroy(contextP->pgw_eps_bearer_context_information.apns);
}
free(contextP);
}
//-----------------------------------------------------------------------------
s_plus_p_gw_eps_bearer_context_information_t * sgw_lite_cm_create_bearer_context_information_in_collection(Teid_t teid)
//-----------------------------------------------------------------------------
{
s_plus_p_gw_eps_bearer_context_information_t *new_bearer_context_information;
new_bearer_context_information = malloc(sizeof(s_plus_p_gw_eps_bearer_context_information_t));
if (new_bearer_context_information == NULL) {
/* Malloc failed, may be ENOMEM error */
SPGW_APP_ERROR("Failed to create new bearer context information object for S11 remote_teid %u\n", teid);
return NULL;
}
memset(new_bearer_context_information, 0, sizeof(s_plus_p_gw_eps_bearer_context_information_t));
SPGW_APP_DEBUG("sgw_lite_cm_create_bearer_context_information_in_collection %d\n", teid);
/*new_bearer_context_information->sgw_eps_bearer_context_information.pdn_connections = obj_hashtable_create(32, NULL, NULL, sgw_lite_cm_free_pdn_connection);
if ( new_bearer_context_information->sgw_eps_bearer_context_information.pdn_connections == NULL) {
SPGW_APP_ERROR("Failed to create PDN connections collection object entry for EPS bearer teid %u \n", teid);
sgw_lite_cm_free_s_plus_p_gw_eps_bearer_context_information(new_bearer_context_information);
return NULL;
}*/
new_bearer_context_information->pgw_eps_bearer_context_information.apns = obj_hashtable_create(32, NULL, NULL, pgw_lite_cm_free_apn);
if ( new_bearer_context_information->pgw_eps_bearer_context_information.apns == NULL) {
SPGW_APP_ERROR("Failed to create APN collection object entry for EPS bearer S11 teid %u \n", teid);
sgw_lite_cm_free_s_plus_p_gw_eps_bearer_context_information(new_bearer_context_information);
return NULL;
}
/* Trying to insert the new tunnel into the tree.
* If collision_p is not NULL (0), it means tunnel is already present.
*/
hashtable_insert(sgw_app.s11_bearer_context_information_hashtable, teid, new_bearer_context_information);
SPGW_APP_DEBUG("Added new s_plus_p_gw_eps_bearer_context_information_t in s11_bearer_context_information_hashtable key teid %u\n", teid);
return new_bearer_context_information;
}
int sgw_lite_cm_remove_bearer_context_information(Teid_t teid) {
int temp;
temp = hashtable_remove(sgw_app.s11_bearer_context_information_hashtable, teid);
return temp;
}
//--- EPS Bearer Entry
//-----------------------------------------------------------------------------
sgw_eps_bearer_entry_t * sgw_lite_cm_create_eps_bearer_entry_in_collection(hash_table_t *eps_bearersP, ebi_t eps_bearer_idP)
//-----------------------------------------------------------------------------
{
sgw_eps_bearer_entry_t *new_eps_bearer_entry;
hashtable_rc_t hash_rc = HASH_TABLE_OK;
if (eps_bearersP == NULL) {
SPGW_APP_ERROR("Failed to create EPS bearer entry for EPS bearer id %u. reason eps bearer hashtable is NULL \n", eps_bearer_idP);
return NULL;
}
new_eps_bearer_entry = malloc(sizeof(sgw_eps_bearer_entry_t));
if (new_eps_bearer_entry == NULL) {
/* Malloc failed, may be ENOMEM error */
SPGW_APP_ERROR("Failed to create EPS bearer entry for EPS bearer id %u \n", eps_bearer_idP);
return NULL;
}
memset(new_eps_bearer_entry, 0, sizeof(sgw_eps_bearer_entry_t));
new_eps_bearer_entry->eps_bearer_id = eps_bearer_idP;
hash_rc = hashtable_insert(eps_bearersP, eps_bearer_idP, new_eps_bearer_entry);
SPGW_APP_DEBUG("Inserted new EPS bearer entry for EPS bearer id %u status %s\n", eps_bearer_idP, hashtable_rc_code2string(hash_rc));
hash_rc = hashtable_apply_funct_on_elements(eps_bearersP,
sgw_lite_display_pdn_connection_sgw_eps_bearers,
NULL);
if (hash_rc != HASH_TABLE_OK) {
SPGW_APP_DEBUG("Invalid sgw_eps_bearers hashtable for display\n");
}
/* CHECK DUPLICATES IN HASH TABLES ? if (temp == 1) {
SPGW_APP_WARN("This EPS bearer entry already exists: %u\n", eps_bearer_idP);
free(new_eps_bearer_entry);
new_eps_bearer_entry = collision_p;
}*/
return new_eps_bearer_entry;
}
//-----------------------------------------------------------------------------
int sgw_lite_cm_remove_eps_bearer_entry(hash_table_t *eps_bearersP, ebi_t eps_bearer_idP)
//-----------------------------------------------------------------------------
{
int temp;
if (eps_bearersP == NULL) {
return -1;
}
temp = hashtable_remove(eps_bearersP, eps_bearer_idP);
return temp;
}