git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7886 818b1a75-f10b-46b9-bf7c-635c3b92a50f
392 lines
17 KiB
C
Executable File
392 lines
17 KiB
C
Executable File
/*******************************************************************************
|
|
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@lists.eurecom.fr
|
|
|
|
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
|
|
|
|
*******************************************************************************/
|
|
/*****************************************************************************
|
|
Source esm_main.c
|
|
|
|
Version 0.1
|
|
|
|
Date 2012/12/04
|
|
|
|
Product NAS stack
|
|
|
|
Subsystem EPS Session Management
|
|
|
|
Author Frederic Maurel
|
|
|
|
Description Defines the EPS Session Management procedure call manager,
|
|
the main entry point for elementary ESM processing.
|
|
|
|
*****************************************************************************/
|
|
|
|
#include "esm_main.h"
|
|
#include "commonDef.h"
|
|
#include "nas_log.h"
|
|
|
|
#include "emmData.h"
|
|
#include "esmData.h"
|
|
#include "esm_pt.h"
|
|
#include "esm_ebr.h"
|
|
|
|
/****************************************************************************/
|
|
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
|
/****************************************************************************/
|
|
|
|
/****************************************************************************/
|
|
/******************* L O C A L D E F I N I T I O N S *******************/
|
|
/****************************************************************************/
|
|
|
|
/****************************************************************************/
|
|
/****************** E X P O R T E D F U N C T I O N S ******************/
|
|
/****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: esm_main_initialize() **
|
|
** **
|
|
** Description: Initializes ESM internal data **
|
|
** **
|
|
** Inputs: cb: The user notification callback **
|
|
** Others: None **
|
|
** **
|
|
** Outputs: None **
|
|
** Return: None **
|
|
** Others: _esm_data **
|
|
** **
|
|
***************************************************************************/
|
|
void esm_main_initialize(esm_indication_callback_t cb)
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
int i;
|
|
|
|
/* Total number of active EPS bearer contexts */
|
|
_esm_data.n_ebrs = 0;
|
|
/* List of active PDN connections */
|
|
_esm_data.n_pdns = 0;
|
|
|
|
for (i = 0; i < ESM_DATA_PDN_MAX + 1; i++) {
|
|
_esm_data.pdn[i].pid = -1;
|
|
_esm_data.pdn[i].is_active = FALSE;
|
|
_esm_data.pdn[i].data = NULL;
|
|
}
|
|
|
|
/* Emergency bearer services indicator */
|
|
_esm_data.emergency = FALSE;
|
|
|
|
/* Initialize the procedure transaction identity manager */
|
|
esm_pt_initialize();
|
|
|
|
/* Initialize the EPS bearer context manager */
|
|
esm_ebr_initialize(cb);
|
|
|
|
LOG_FUNC_OUT;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: esm_main_cleanup() **
|
|
** **
|
|
** Description: Performs the EPS Session Management clean up procedure **
|
|
** **
|
|
** Inputs: None **
|
|
** Others: None **
|
|
** **
|
|
** Outputs: None **
|
|
** Return: None **
|
|
** Others: None **
|
|
** **
|
|
***************************************************************************/
|
|
void esm_main_cleanup(void)
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
{
|
|
int i;
|
|
int pid;
|
|
int bid;
|
|
|
|
/* De-activate EPS bearers and clean up PDN connections */
|
|
for (pid = 0; pid < ESM_DATA_PDN_MAX; pid++) {
|
|
if (_esm_data.pdn[pid].data) {
|
|
esm_pdn_t *pdn = _esm_data.pdn[pid].data;
|
|
|
|
if (pdn->apn.length > 0) {
|
|
free(pdn->apn.value);
|
|
}
|
|
|
|
/* Release EPS bearer contexts */
|
|
for (bid = 0; bid < pdn->n_bearers; bid++) {
|
|
if (pdn->bearer[bid]) {
|
|
LOG_TRACE(WARNING, "ESM-MAIN - Release EPS bearer "
|
|
"context (ebi=%d)", pdn->bearer[bid]->ebi);
|
|
|
|
/* Delete the TFT */
|
|
for (i = 0; i < pdn->bearer[bid]->tft.n_pkfs; i++) {
|
|
if (pdn->bearer[bid]->tft.pkf[i]) {
|
|
free(pdn->bearer[bid]->tft.pkf[i]);
|
|
}
|
|
}
|
|
|
|
free(pdn->bearer[bid]);
|
|
}
|
|
}
|
|
|
|
/* Release the PDN connection */
|
|
free(_esm_data.pdn[pid].data);
|
|
}
|
|
}
|
|
}
|
|
|
|
LOG_FUNC_OUT;
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: esm_main_get_nb_pdn_max() **
|
|
** **
|
|
** Description: Get the maximum number of PDN connections that may be in **
|
|
** a defined state at the same time **
|
|
** **
|
|
** Inputs: None **
|
|
** Others: _esm_data **
|
|
** **
|
|
** Outputs: None **
|
|
** Return: The maximum number of PDN connections that **
|
|
** may be defined **
|
|
** Others: None **
|
|
** **
|
|
***************************************************************************/
|
|
int esm_main_get_nb_pdns_max(void)
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
LOG_FUNC_RETURN (ESM_DATA_PDN_MAX);
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: esm_main_get_nb_pdns() **
|
|
** **
|
|
** Description: Get the number of active PDN connections **
|
|
** **
|
|
** Inputs: None **
|
|
** Others: _esm_data **
|
|
** **
|
|
** Outputs: None **
|
|
** Return: The number of active PDN connections **
|
|
** Others: None **
|
|
** **
|
|
***************************************************************************/
|
|
int esm_main_get_nb_pdns(void)
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
LOG_FUNC_RETURN (_esm_data.n_pdns);
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: esm_main_has_emergency() **
|
|
** **
|
|
** Description: Check whether a PDN connection for emergency bearer ser- **
|
|
** vices is established **
|
|
** **
|
|
** Inputs: None **
|
|
** Others: _esm_data **
|
|
** **
|
|
** Outputs: None **
|
|
** Return: TRUE if a PDN connection for emergency **
|
|
** bearer services is established **
|
|
** Others: None **
|
|
** **
|
|
***************************************************************************/
|
|
int esm_main_has_emergency(void)
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
LOG_FUNC_RETURN (_esm_data.emergency);
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: esm_main_get_pdn_status() **
|
|
** **
|
|
** Description: Get the status of the specified PDN connection **
|
|
** **
|
|
** Inputs: cid: PDN connection identifier **
|
|
** Others: _esm_data **
|
|
** **
|
|
** Outputs: state: TRUE if the current state of the PDN con- **
|
|
** nection is ACTIVE; FALSE otherwise. **
|
|
** Return: TRUE if the specified PDN connection has a **
|
|
** PDN context defined; FALSE if no any PDN **
|
|
** context has been defined for the specified **
|
|
** connection. **
|
|
** Others: None **
|
|
** **
|
|
***************************************************************************/
|
|
int esm_main_get_pdn_status(int cid, int *state)
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
unsigned int pid = cid - 1;
|
|
|
|
if (pid >= ESM_DATA_PDN_MAX) {
|
|
return (FALSE);
|
|
} else if (pid != _esm_data.pdn[pid].pid) {
|
|
LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid);
|
|
return (FALSE);
|
|
} else if (_esm_data.pdn[pid].data == NULL) {
|
|
LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated",
|
|
cid);
|
|
return (FALSE);
|
|
}
|
|
|
|
if (_esm_data.pdn[pid].data->bearer[0] != NULL) {
|
|
/* The status of a PDN connection is the status of the default EPS bearer
|
|
* that has been assigned to this PDN connection at activation time */
|
|
int ebi = _esm_data.pdn[pid].data->bearer[0]->ebi;
|
|
*state = (esm_ebr_get_status(ebi) == ESM_EBR_ACTIVE);
|
|
}
|
|
|
|
/* The PDN connection has not been activated yet */
|
|
LOG_FUNC_RETURN (TRUE);
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: esm_main_get_pdn() **
|
|
** **
|
|
** Description: Get parameters defined for the specified PDN connection **
|
|
** **
|
|
** Inputs: cid: PDN connection identifier **
|
|
** Others: _esm_data **
|
|
** **
|
|
** Outputs: type: PDN connection type (IPv4, IPv6, IPv4v6) **
|
|
** apn: Access Point logical Name in used **
|
|
** is_emergency: Emergency bearer services indicator **
|
|
** is_active: Active PDN connection indicator **
|
|
** Return: RETURNok, RETURNerror **
|
|
** Others: None **
|
|
** **
|
|
***************************************************************************/
|
|
int esm_main_get_pdn(int cid, int *type, const char **apn,
|
|
int *is_emergency, int *is_active)
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
unsigned int pid = cid - 1;
|
|
|
|
if (pid >= ESM_DATA_PDN_MAX) {
|
|
return (RETURNerror);
|
|
} else if (pid != _esm_data.pdn[pid].pid) {
|
|
LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid);
|
|
return (RETURNerror);
|
|
} else if (_esm_data.pdn[pid].data == NULL) {
|
|
LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated",
|
|
cid);
|
|
return (RETURNerror);
|
|
}
|
|
|
|
/* Get the PDN type */
|
|
*type = _esm_data.pdn[pid].data->type;
|
|
|
|
/* Get the Access Point Name */
|
|
if (_esm_data.pdn[pid].data->apn.length > 0) {
|
|
*apn = (char *)(_esm_data.pdn[pid].data->apn.value);
|
|
} else {
|
|
*apn = NULL;
|
|
}
|
|
|
|
/* Get the emergency bearer services indicator */
|
|
*is_emergency = _esm_data.pdn[pid].data->is_emergency;
|
|
/* Get the active PDN connection indicator */
|
|
*is_active = _esm_data.pdn[pid].is_active;
|
|
|
|
LOG_FUNC_RETURN (RETURNok);
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: esm_main_get_pdn_addr() **
|
|
** **
|
|
** Description: Get IP address(es) assigned to the specified PDN connec- **
|
|
** tion **
|
|
** **
|
|
** Inputs: cid: PDN connection identifier **
|
|
** Others: _esm_data **
|
|
** **
|
|
** Outputs: ipv4adddr: IPv4 address **
|
|
** ipv6adddr: IPv6 address **
|
|
** Return: RETURNok, RETURNerror **
|
|
** Others: None **
|
|
** **
|
|
***************************************************************************/
|
|
int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr)
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
unsigned int pid = cid - 1;
|
|
|
|
if (pid >= ESM_DATA_PDN_MAX) {
|
|
return (RETURNerror);
|
|
} else if (pid != _esm_data.pdn[pid].pid) {
|
|
LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid);
|
|
return (RETURNerror);
|
|
} else if (_esm_data.pdn[pid].data == NULL) {
|
|
LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated",
|
|
cid);
|
|
return (RETURNerror);
|
|
} else if (!_esm_data.pdn[pid].is_active) {
|
|
/* No any IP address has been assigned to this PDN connection */
|
|
return (RETURNok);
|
|
}
|
|
|
|
if (_esm_data.pdn[pid].data->type == NET_PDN_TYPE_IPV4) {
|
|
/* Get IPv4 address */
|
|
*ipv4addr = _esm_data.pdn[pid].data->ip_addr;
|
|
} else if (_esm_data.pdn[pid].data->type == NET_PDN_TYPE_IPV6) {
|
|
/* Get IPv6 address */
|
|
*ipv6addr = _esm_data.pdn[pid].data->ip_addr;
|
|
} else {
|
|
/* IPv4v6 dual-stack terminal */
|
|
*ipv4addr = _esm_data.pdn[pid].data->ip_addr;
|
|
*ipv6addr = _esm_data.pdn[pid].data->ip_addr+ESM_DATA_IPV4_ADDRESS_SIZE;
|
|
}
|
|
|
|
LOG_FUNC_RETURN (RETURNok);
|
|
}
|
|
|
|
|
|
/****************************************************************************/
|
|
/********************* L O C A L F U N C T I O N S *********************/
|
|
/****************************************************************************/
|
|
|