sgw_lite_context_manager.c 15.5 KB
Newer Older
Cedric Roux's avatar
 
Cedric Roux committed
1
/*******************************************************************************
Lionel Gauthier's avatar
GPLv3  
Lionel Gauthier committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
    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.

 *******************************************************************************/
Lionel Gauthier's avatar
Lionel Gauthier committed
29 30 31 32 33 34
/*! \file sgw_lite_context_manager.c
* \brief
* \author Lionel Gauthier
* \company Eurecom
* \email: lionel.gauthier@eurecom.fr
*/
35 36
#define SGW_LITE
#define SGW_LITE_CONTEXT_MANAGER_C
Cedric Roux's avatar
 
Cedric Roux committed
37 38 39 40 41 42 43 44 45 46

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "tree.h"
#include "hashtable.h"

#include "intertask_interface.h"
47
#include "mme_config.h"
Cedric Roux's avatar
 
Cedric Roux committed
48 49 50 51 52 53 54 55 56 57 58
#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)
//-----------------------------------------------------------------------------
{
59 60 61 62 63 64 65 66
  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");
  }
Cedric Roux's avatar
 
Cedric Roux committed
67 68 69 70 71
}
//-----------------------------------------------------------------------------
void sgw_lite_display_s11teid2mme_mappings(void)
//-----------------------------------------------------------------------------
{
72 73 74 75 76
  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");
Cedric Roux's avatar
 
Cedric Roux committed
77 78 79 80 81
}
//-----------------------------------------------------------------------------
static void sgw_lite_display_pdn_connection_sgw_eps_bearers(uint64_t keyP, void *dataP, void* unusedParameterP)
//-----------------------------------------------------------------------------
{
82 83 84 85 86 87 88 89 90 91 92 93
  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");
  }
Cedric Roux's avatar
 
Cedric Roux committed
94 95 96 97 98 99
}

//-----------------------------------------------------------------------------
static void sgw_lite_display_s11_bearer_context_information(uint64_t keyP, void *dataP, void* unusedParameterP)
//-----------------------------------------------------------------------------
{
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
  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");
Cedric Roux's avatar
 
Cedric Roux committed
127
    }
128 129 130 131 132 133

    //void                  *trxn;
    //uint32_t               peer_ip;
  } else {
    SPGW_APP_DEBUG("INVALID s_plus_p_gw_eps_bearer_context_information FOUND\n");
  }
Cedric Roux's avatar
 
Cedric Roux committed
134 135 136 137 138
}
//-----------------------------------------------------------------------------
void sgw_lite_display_s11_bearer_context_information_mapping(void)
//-----------------------------------------------------------------------------
{
139 140 141 142 143
  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");
Cedric Roux's avatar
 
Cedric Roux committed
144 145 146 147 148
}
//-----------------------------------------------------------------------------
void pgw_lite_cm_free_apn(pgw_apn_t *apnP)
//-----------------------------------------------------------------------------
{
149 150 151 152 153
  if (apnP != NULL) {
    if (apnP->pdn_connections != NULL) {
      obj_hashtable_destroy(apnP->pdn_connections);
    }
  }
Cedric Roux's avatar
 
Cedric Roux committed
154 155 156 157 158
}
//-----------------------------------------------------------------------------
Teid_t sgw_lite_get_new_S11_tunnel_id(void)
//-----------------------------------------------------------------------------
{
159 160 161 162
  // TO DO: RANDOM
  static Teid_t tunnel_id = 0;
  tunnel_id += 1;
  return tunnel_id;
Cedric Roux's avatar
 
Cedric Roux committed
163 164 165 166 167 168 169
}

//-----------------------------------------------------------------------------
mme_sgw_tunnel_t *sgw_lite_cm_create_s11_tunnel(Teid_t remote_teid, Teid_t local_teid)
//-----------------------------------------------------------------------------
{

170
  mme_sgw_tunnel_t *new_tunnel;
Cedric Roux's avatar
 
Cedric Roux committed
171

172
  new_tunnel = malloc(sizeof(mme_sgw_tunnel_t));
Cedric Roux's avatar
 
Cedric Roux committed
173

174 175 176 177 178
  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;
  }
Cedric Roux's avatar
 
Cedric Roux committed
179

180 181
  new_tunnel->remote_teid = remote_teid;
  new_tunnel->local_teid  = local_teid;
Cedric Roux's avatar
 
Cedric Roux committed
182

183 184 185 186
  /* 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);
Cedric Roux's avatar
 
Cedric Roux committed
187

188
  return new_tunnel;
Cedric Roux's avatar
 
Cedric Roux committed
189 190 191 192 193 194
}

//-----------------------------------------------------------------------------
int sgw_lite_cm_remove_s11_tunnel(Teid_t local_teid)
//-----------------------------------------------------------------------------
{
195
  int  temp;
Cedric Roux's avatar
 
Cedric Roux committed
196

197
  temp = hashtable_remove(sgw_app.s11teid2mme_hashtable, local_teid);
Cedric Roux's avatar
 
Cedric Roux committed
198

199
  return temp;
Cedric Roux's avatar
 
Cedric Roux committed
200 201 202 203 204 205
}

//-----------------------------------------------------------------------------
sgw_eps_bearer_entry_t * sgw_lite_cm_create_eps_bearer_entry(void)
//-----------------------------------------------------------------------------
{
206
  sgw_eps_bearer_entry_t *eps_bearer_entry;
Cedric Roux's avatar
 
Cedric Roux committed
207

208
  eps_bearer_entry = malloc(sizeof(sgw_eps_bearer_entry_t));
Cedric Roux's avatar
 
Cedric Roux committed
209

210 211 212 213 214 215 216
  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;
Cedric Roux's avatar
 
Cedric Roux committed
217 218 219 220 221 222 223
}


//-----------------------------------------------------------------------------
sgw_pdn_connection_t * sgw_lite_cm_create_pdn_connection(void)
//-----------------------------------------------------------------------------
{
224
  sgw_pdn_connection_t *pdn_connection;
Cedric Roux's avatar
 
Cedric Roux committed
225

226
  pdn_connection = malloc(sizeof(sgw_pdn_connection_t));
Cedric Roux's avatar
 
Cedric Roux committed
227

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
  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;
  }
Cedric Roux's avatar
 
Cedric Roux committed
244

245
  return pdn_connection;
Cedric Roux's avatar
 
Cedric Roux committed
246 247 248 249 250
}
//-----------------------------------------------------------------------------
void sgw_lite_cm_free_pdn_connection(sgw_pdn_connection_t *pdn_connectionP)
//-----------------------------------------------------------------------------
{
251 252 253 254 255
  if (pdn_connectionP != NULL) {
    if (pdn_connectionP->sgw_eps_bearers != NULL) {
      hashtable_destroy(pdn_connectionP->sgw_eps_bearers);
    }
  }
Cedric Roux's avatar
 
Cedric Roux committed
256 257 258 259 260
}
//-----------------------------------------------------------------------------
void sgw_lite_cm_free_s_plus_p_gw_eps_bearer_context_information(s_plus_p_gw_eps_bearer_context_information_t *contextP)
//-----------------------------------------------------------------------------
{
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
  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);
Cedric Roux's avatar
 
Cedric Roux committed
277 278 279 280 281 282
}

//-----------------------------------------------------------------------------
s_plus_p_gw_eps_bearer_context_information_t * sgw_lite_cm_create_bearer_context_information_in_collection(Teid_t teid)
//-----------------------------------------------------------------------------
{
283
  s_plus_p_gw_eps_bearer_context_information_t *new_bearer_context_information;
Cedric Roux's avatar
 
Cedric Roux committed
284

285
  new_bearer_context_information = malloc(sizeof(s_plus_p_gw_eps_bearer_context_information_t));
Cedric Roux's avatar
 
Cedric Roux committed
286

287 288 289 290 291
  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;
  }
Cedric Roux's avatar
 
Cedric Roux committed
292

293 294
  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);
Cedric Roux's avatar
 
Cedric Roux committed
295

296
  /*new_bearer_context_information->sgw_eps_bearer_context_information.pdn_connections = obj_hashtable_create(32, NULL, NULL, sgw_lite_cm_free_pdn_connection);
Cedric Roux's avatar
 
Cedric Roux committed
297

298 299 300 301 302
  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;
  }*/
Cedric Roux's avatar
 
Cedric Roux committed
303

304 305 306 307 308 309 310
  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;
  }
Cedric Roux's avatar
 
Cedric Roux committed
311

312 313 314 315 316
  /* 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);
Cedric Roux's avatar
 
Cedric Roux committed
317

318
  return new_bearer_context_information;
Cedric Roux's avatar
 
Cedric Roux committed
319 320
}

321 322 323
int sgw_lite_cm_remove_bearer_context_information(Teid_t teid)
{
  int temp;
324
  temp = hashtable_remove(sgw_app.s11_bearer_context_information_hashtable, teid);
325
  return temp;
Cedric Roux's avatar
 
Cedric Roux committed
326 327 328 329 330 331 332 333
}

//--- 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)
//-----------------------------------------------------------------------------
{
334 335
  sgw_eps_bearer_entry_t *new_eps_bearer_entry;
  hashtable_rc_t            hash_rc = HASH_TABLE_OK;
Cedric Roux's avatar
 
Cedric Roux committed
336

337 338 339 340
  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;
  }
Cedric Roux's avatar
 
Cedric Roux committed
341

342
  new_eps_bearer_entry = malloc(sizeof(sgw_eps_bearer_entry_t));
Cedric Roux's avatar
 
Cedric Roux committed
343

344 345 346 347 348
  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;
  }
Cedric Roux's avatar
 
Cedric Roux committed
349

350
  memset(new_eps_bearer_entry, 0, sizeof(sgw_eps_bearer_entry_t));
Cedric Roux's avatar
 
Cedric Roux committed
351

352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
  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;
Cedric Roux's avatar
 
Cedric Roux committed
371 372 373 374 375
}
//-----------------------------------------------------------------------------
int sgw_lite_cm_remove_eps_bearer_entry(hash_table_t *eps_bearersP, ebi_t eps_bearer_idP)
//-----------------------------------------------------------------------------
{
376
  int temp;
Cedric Roux's avatar
 
Cedric Roux committed
377

378 379 380 381
  if (eps_bearersP == NULL) {
    return -1;
  }

382
  temp = hashtable_remove(eps_bearersP, eps_bearer_idP);
Cedric Roux's avatar
 
Cedric Roux committed
383

384
  return temp;
Cedric Roux's avatar
 
Cedric Roux committed
385 386
}