Commit b79159f8 authored by Lionel Gauthier's avatar Lionel Gauthier

Added dynamic protocol configuration options IE in NAS ESM message

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7586 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent ec69c661
...@@ -61,7 +61,7 @@ MME : ...@@ -61,7 +61,7 @@ MME :
# TA (mcc.mnc:tracking area code) DEFAULT = 208.34:0 # TA (mcc.mnc:tracking area code) DEFAULT = 208.34:0
# max values = 999.999:65535 # max values = 999.999:65535
# maximum of 32 values, comma separated # maximum of 32 values, comma separated
PLMN = ( TAI_LIST = (
{MCC="208" ; MNC="95"; TAC = "1"; } # YOUR PLMN CONFIG HERE {MCC="208" ; MNC="95"; TAC = "1"; } # YOUR PLMN CONFIG HERE
); );
}; };
...@@ -124,8 +124,8 @@ P-GW = ...@@ -124,8 +124,8 @@ P-GW =
}; };
#WARNING DNS ARE HARDCODED IN openair-cn/NAS/EURECOM-NAS/src/esm/msg/ActivateDefaultEpsBearerContextRequest.c:305 #WARNING DNS ARE HARDCODED IN openair-cn/NAS/EURECOM-NAS/src/esm/msg/ActivateDefaultEpsBearerContextRequest.c:305
DEFAULT_DNS_1_IPV4_ADDRESS = "192.168.12.100"; # YOUR NETWORK CONFIG HERE DEFAULT_DNS_IPV4_ADDRESS = "192.168.106.12"; # YOUR NETWORK CONFIG HERE
DEFAULT_DNS_2_IPV4_ADDRESS = "192.168.106.12"; # YOUR NETWORK CONFIG HERE DEFAULT_DNS_SEC_IPV4_ADDRESS = "192.168.12.100"; # YOUR NETWORK CONFIG HERE
}; };
...@@ -61,9 +61,8 @@ MME : ...@@ -61,9 +61,8 @@ MME :
# TA (mcc.mnc:tracking area code) DEFAULT = 208.34:0 # TA (mcc.mnc:tracking area code) DEFAULT = 208.34:0
# max values = 999.999:65535 # max values = 999.999:65535
# maximum of 32 values, comma separated # maximum of 32 values, comma separated
PLMN = ( TAI_LIST = (
{MCC="208" ; MNC="95"; TAC = "1"; }, # YOUR PLMN CONFIG HERE {MCC="208" ; MNC="95"; TAC = "1"; } # YOUR PLMN CONFIG HERE
{MCC="208" ; MNC="10"; TAC = "1"; } # YOUR PLMN CONFIG HERE
); );
}; };
...@@ -125,8 +124,8 @@ P-GW = ...@@ -125,8 +124,8 @@ P-GW =
}; };
#WARNING DNS ARE HARDCODED IN openair-cn/NAS/EURECOM-NAS/src/esm/msg/ActivateDefaultEpsBearerContextRequest.c:305 #WARNING DNS ARE HARDCODED IN openair-cn/NAS/EURECOM-NAS/src/esm/msg/ActivateDefaultEpsBearerContextRequest.c:305
DEFAULT_DNS_1_IPV4_ADDRESS = "192.168.12.100"; # YOUR NETWORK CONFIG HERE DEFAULT_DNS_IPV4_ADDRESS = "192.168.106.12"; # YOUR NETWORK CONFIG HERE
DEFAULT_DNS_2_IPV4_ADDRESS = "192.168.106.12"; # YOUR NETWORK CONFIG HERE DEFAULT_DNS_SEC_IPV4_ADDRESS = "192.168.12.100"; # YOUR NETWORK CONFIG HERE
}; };
...@@ -57,6 +57,7 @@ typedef struct { ...@@ -57,6 +57,7 @@ typedef struct {
ebi_t eps_bearer_id; ///< EPS bearer identifier ebi_t eps_bearer_id; ///< EPS bearer identifier
pdn_type_t pdn_type; ///< PDN Type pdn_type_t pdn_type; ///< PDN Type
PAA_t paa; ///< PDN Address Allocation PAA_t paa; ///< PDN Address Allocation
pco_flat_t pco; ///< Protocol configuration options
} SGICreateEndpointResp; } SGICreateEndpointResp;
typedef struct { typedef struct {
......
...@@ -177,6 +177,7 @@ typedef struct nas_pdn_connectivity_req_s { ...@@ -177,6 +177,7 @@ typedef struct nas_pdn_connectivity_req_s {
char imsi[16]; char imsi[16];
uint8_t imsi_length; uint8_t imsi_length;
network_qos_t qos; network_qos_t qos;
pco_flat_t pco;
OctetString apn; OctetString apn;
OctetString pdn_addr; OctetString pdn_addr;
int pdn_type; int pdn_type;
...@@ -189,6 +190,7 @@ typedef struct nas_pdn_connectivity_rsp_s { ...@@ -189,6 +190,7 @@ typedef struct nas_pdn_connectivity_rsp_s {
int pti; // nas ref Identity of the procedure transaction executed to activate the PDN connection entry int pti; // nas ref Identity of the procedure transaction executed to activate the PDN connection entry
unsigned ue_id; // nas ref unsigned ue_id; // nas ref
network_qos_t qos; network_qos_t qos;
pco_flat_t pco;
OctetString apn; OctetString apn;
OctetString pdn_addr; OctetString pdn_addr;
int pdn_type; int pdn_type;
......
...@@ -55,6 +55,10 @@ ...@@ -55,6 +55,10 @@
/** @struct SgwCreateSessionRequest /** @struct SgwCreateSessionRequest
* @brief Create Session Request * @brief Create Session Request
* *
* Spec 3GPP TS 29.274, Universal Mobile Telecommunications System (UMTS);
* LTE; 3GPP Evolved Packet System (EPS);
* Evolved General Packet Radio Service (GPRS);
* Tunnelling Protocol for Control plane (GTPv2-C); Stage 3
* The Create Session Request will be sent on S11 interface as * The Create Session Request will be sent on S11 interface as
* part of these procedures: * part of these procedures:
* - E-UTRAN Initial Attach * - E-UTRAN Initial Attach
...@@ -250,7 +254,8 @@ typedef struct SgwCreateSessionRequest_s { ...@@ -250,7 +254,8 @@ typedef struct SgwCreateSessionRequest_s {
///< RAU/TAU/HO procedures with SGW change to identify the ///< RAU/TAU/HO procedures with SGW change to identify the
///< default bearer of the PDN Connection ///< default bearer of the PDN Connection
// PCO protocol_configuration_options ///< This IE is not applicable to TAU/RAU/Handover. If pco_flat_t pco; /// PCO protocol_configuration_options
///< This IE is not applicable to TAU/RAU/Handover. If
///< MME/SGSN receives PCO from UE (during the attach ///< MME/SGSN receives PCO from UE (during the attach
///< procedures), the MME/SGSN shall forward the PCO IE to ///< procedures), the MME/SGSN shall forward the PCO IE to
///< SGW. The SGW shall also forward it to PGW. ///< SGW. The SGW shall also forward it to PGW.
...@@ -413,7 +418,9 @@ typedef struct SgwCreateSessionResponse_s { ...@@ -413,7 +418,9 @@ typedef struct SgwCreateSessionResponse_s {
///< Gn/Gp SGSN to S4-SGSN/MME RAU/TAU procedure to ///< Gn/Gp SGSN to S4-SGSN/MME RAU/TAU procedure to
///< identify the default bearer the PGW selects for the PDN ///< identify the default bearer the PGW selects for the PDN
///< Connection. ///< Connection.
// PCO protocol_configuration_options ///< This IE is not applicable for TAU/RAU/Handover. If PGW
pco_flat_t pco;// PCO protocol_configuration_options
///< This IE is not applicable for TAU/RAU/Handover. If PGW
///< decides to return PCO to the UE, PGW shall send PCO to ///< decides to return PCO to the UE, PGW shall send PCO to
///< SGW. If SGW receives the PCO IE, SGW shall forward it ///< SGW. If SGW receives the PCO IE, SGW shall forward it
///< MME/SGSN. ///< MME/SGSN.
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "mme_app_extern.h" #include "mme_app_extern.h"
#include "mme_app_ue_context.h" #include "mme_app_ue_context.h"
#include "mme_app_defs.h" #include "mme_app_defs.h"
#include "sgw_lite_ie_defs.h"
#include "secu_defs.h" #include "secu_defs.h"
...@@ -246,6 +247,13 @@ mme_app_send_s11_create_session_req( ...@@ -246,6 +247,13 @@ mme_app_send_s11_create_session_req(
} }
} }
if ((ue_context_pP->pending_pdn_connectivity_req_pco.length >= PCO_MIN_LENGTH) && (ue_context_pP->pending_pdn_connectivity_req_pco.length <= PCO_MAX_LENGTH)) {
memcpy(&session_request_p->pco.byte[0],
&ue_context_pP->pending_pdn_connectivity_req_pco.byte[0],
ue_context_pP->pending_pdn_connectivity_req_pco.length);
session_request_p->pco.length = ue_context_pP->pending_pdn_connectivity_req_pco.length;
}
config_read_lock(&mme_config); config_read_lock(&mme_config);
session_request_p->peer_ip = mme_config.ipv4.sgw_ip_address_for_S11; session_request_p->peer_ip = mme_config.ipv4.sgw_ip_address_for_S11;
config_unlock(&mme_config); config_unlock(&mme_config);
...@@ -321,6 +329,11 @@ mme_app_handle_nas_pdn_connectivity_req( ...@@ -321,6 +329,11 @@ mme_app_handle_nas_pdn_connectivity_req(
ue_context_p->pending_pdn_connectivity_req_pti = nas_pdn_connectivity_req_pP->pti; ue_context_p->pending_pdn_connectivity_req_pti = nas_pdn_connectivity_req_pP->pti;
ue_context_p->pending_pdn_connectivity_req_ue_id = nas_pdn_connectivity_req_pP->ue_id; ue_context_p->pending_pdn_connectivity_req_ue_id = nas_pdn_connectivity_req_pP->ue_id;
memcpy(&ue_context_p->pending_pdn_connectivity_req_pco.byte[0],
&nas_pdn_connectivity_req_pP->pco.byte[0],
nas_pdn_connectivity_req_pP->pco.length);
ue_context_p->pending_pdn_connectivity_req_pco.length = nas_pdn_connectivity_req_pP->pco.length;
memcpy(&ue_context_p->pending_pdn_connectivity_req_qos, memcpy(&ue_context_p->pending_pdn_connectivity_req_qos,
&nas_pdn_connectivity_req_pP->qos, &nas_pdn_connectivity_req_pP->qos,
sizeof(network_qos_t)); sizeof(network_qos_t));
...@@ -759,6 +772,11 @@ mme_app_handle_create_sess_resp( ...@@ -759,6 +772,11 @@ mme_app_handle_create_sess_resp(
NAS_PDN_CONNECTIVITY_RSP(message_p).ambr.br_dl = ue_context_p->subscribed_ambr.br_dl; NAS_PDN_CONNECTIVITY_RSP(message_p).ambr.br_dl = ue_context_p->subscribed_ambr.br_dl;
memcpy(&NAS_PDN_CONNECTIVITY_RSP(message_p).pco.byte[0],
&create_sess_resp_pP->pco.byte[0],
create_sess_resp_pP->pco.length);
NAS_PDN_CONNECTIVITY_RSP(message_p).pco.length = create_sess_resp_pP->pco.length;
MSC_LOG_TX_MESSAGE( MSC_LOG_TX_MESSAGE(
MSC_MMEAPP_MME, MSC_MMEAPP_MME,
MSC_NAS_MME, MSC_NAS_MME,
......
...@@ -177,6 +177,7 @@ typedef struct ue_context_s { ...@@ -177,6 +177,7 @@ typedef struct ue_context_s {
int pending_pdn_connectivity_req_pti; int pending_pdn_connectivity_req_pti;
unsigned pending_pdn_connectivity_req_ue_id; unsigned pending_pdn_connectivity_req_ue_id;
network_qos_t pending_pdn_connectivity_req_qos; network_qos_t pending_pdn_connectivity_req_qos;
pco_flat_t pending_pdn_connectivity_req_pco;
void *pending_pdn_connectivity_req_proc_data; void *pending_pdn_connectivity_req_proc_data;
int pending_pdn_connectivity_req_request_type; int pending_pdn_connectivity_req_request_type;
......
...@@ -99,6 +99,8 @@ typedef struct mme_api_emm_config_s { ...@@ -99,6 +99,8 @@ typedef struct mme_api_emm_config_s {
*/ */
typedef struct mme_api_esm_config_s { typedef struct mme_api_esm_config_s {
mme_api_feature_t features; /* Supported features */ mme_api_feature_t features; /* Supported features */
uint8_t dns_prim_ipv4[4]; /* Network byte order */
uint8_t dns_sec_ipv4[4]; /* Network byte order */
} mme_api_esm_config_t; } mme_api_esm_config_t;
/****************************************************************************/ /****************************************************************************/
......
This diff is collapsed.
...@@ -399,7 +399,7 @@ typedef struct emm_data_context_s { ...@@ -399,7 +399,7 @@ typedef struct emm_data_context_s {
* Structure of the EMM data * Structure of the EMM data
* ------------------------- * -------------------------
*/ */
typedef struct { typedef struct emm_data_s {
/* /*
* MME configuration * MME configuration
* ----------------- * -----------------
......
...@@ -58,7 +58,7 @@ Description Defines the EMM primitives available at the EMMAS Service ...@@ -58,7 +58,7 @@ Description Defines the EMM primitives available at the EMMAS Service
/* /*
* EMMAS-SAP primitives * EMMAS-SAP primitives
*/ */
typedef enum { typedef enum emm_as_primitive_u {
_EMMAS_START = 200, _EMMAS_START = 200,
_EMMAS_SECURITY_REQ, /* EMM->AS: Security request */ _EMMAS_SECURITY_REQ, /* EMM->AS: Security request */
_EMMAS_SECURITY_IND, /* AS->EMM: Security indication */ _EMMAS_SECURITY_IND, /* AS->EMM: Security indication */
...@@ -80,7 +80,7 @@ typedef enum { ...@@ -80,7 +80,7 @@ typedef enum {
} emm_as_primitive_t; } emm_as_primitive_t;
/* Data used to setup EPS NAS security */ /* Data used to setup EPS NAS security */
typedef struct { typedef struct emm_as_security_data_s {
UInt8_t is_new; /* New security data indicator */ UInt8_t is_new; /* New security data indicator */
#define EMM_AS_NO_KEY_AVAILABLE 0xff #define EMM_AS_NO_KEY_AVAILABLE 0xff
UInt8_t ksi; /* NAS key set identifier */ UInt8_t ksi; /* NAS key set identifier */
...@@ -98,7 +98,7 @@ typedef struct { ...@@ -98,7 +98,7 @@ typedef struct {
* EMMAS primitive for security * EMMAS primitive for security
* ---------------------------- * ----------------------------
*/ */
typedef struct { typedef struct emm_as_security_s {
UInt32_t ueid; /* UE lower layer identifier */ UInt32_t ueid; /* UE lower layer identifier */
const GUTI_t *guti; /* GUTI temporary mobile identity */ const GUTI_t *guti; /* GUTI temporary mobile identity */
emm_as_security_data_t sctx;/* EPS NAS security context */ emm_as_security_data_t sctx;/* EPS NAS security context */
...@@ -144,7 +144,7 @@ typedef struct { ...@@ -144,7 +144,7 @@ typedef struct {
* EMMAS primitive for connection establishment * EMMAS primitive for connection establishment
* -------------------------------------------- * --------------------------------------------
*/ */
typedef struct { typedef struct emm_as_EPS_identity_s {
const GUTI_t *guti; /* The GUTI, if valid */ const GUTI_t *guti; /* The GUTI, if valid */
const tai_t *tai; /* The last visited registered Tracking const tai_t *tai; /* The last visited registered Tracking
* Area Identity, if available */ * Area Identity, if available */
...@@ -152,7 +152,7 @@ typedef struct { ...@@ -152,7 +152,7 @@ typedef struct {
const imei_t *imei; /* UE's IMEI for emergency bearer services */ const imei_t *imei; /* UE's IMEI for emergency bearer services */
} emm_as_EPS_identity_t; } emm_as_EPS_identity_t;
typedef struct { typedef struct emm_as_establish_s {
UInt32_t ueid; /* UE lower layer identifier */ UInt32_t ueid; /* UE lower layer identifier */
emm_as_EPS_identity_t UEid; /* UE's EPS mobile identity */ emm_as_EPS_identity_t UEid; /* UE's EPS mobile identity */
emm_as_security_data_t sctx;/* EPS NAS security context */ emm_as_security_data_t sctx;/* EPS NAS security context */
...@@ -184,7 +184,7 @@ typedef struct { ...@@ -184,7 +184,7 @@ typedef struct {
* EMMAS primitive for connection release * EMMAS primitive for connection release
* -------------------------------------- * --------------------------------------
*/ */
typedef struct { typedef struct emm_as_release_s {
UInt32_t ueid; /* UE lower layer identifier */ UInt32_t ueid; /* UE lower layer identifier */
const GUTI_t *guti; /* GUTI temporary mobile identity */ const GUTI_t *guti; /* GUTI temporary mobile identity */
#define EMM_AS_CAUSE_AUTHENTICATION 0x01 /* Authentication failure */ #define EMM_AS_CAUSE_AUTHENTICATION 0x01 /* Authentication failure */
...@@ -196,7 +196,7 @@ typedef struct { ...@@ -196,7 +196,7 @@ typedef struct {
* EMMAS primitive for data transfer * EMMAS primitive for data transfer
* --------------------------------- * ---------------------------------
*/ */
typedef struct { typedef struct emm_as_data_s {
UInt32_t ueid; /* UE lower layer identifier */ UInt32_t ueid; /* UE lower layer identifier */
const GUTI_t *guti; /* GUTI temporary mobile identity */ const GUTI_t *guti; /* GUTI temporary mobile identity */
emm_as_security_data_t sctx;/* EPS NAS security context */ emm_as_security_data_t sctx;/* EPS NAS security context */
...@@ -213,13 +213,13 @@ typedef struct { ...@@ -213,13 +213,13 @@ typedef struct {
* EMMAS primitive for paging * EMMAS primitive for paging
* -------------------------- * --------------------------
*/ */
typedef struct {} emm_as_page_t; typedef struct emm_as_page_s {} emm_as_page_t;
/* /*
* EMMAS primitive for status indication * EMMAS primitive for status indication
* ------------------------------------- * -------------------------------------
*/ */
typedef struct { typedef struct emm_as_status_s {
UInt32_t ueid; /* UE lower layer identifier */ UInt32_t ueid; /* UE lower layer identifier */
const GUTI_t *guti; /* GUTI temporary mobile identity */ const GUTI_t *guti; /* GUTI temporary mobile identity */
emm_as_security_data_t sctx;/* EPS NAS security context */ emm_as_security_data_t sctx;/* EPS NAS security context */
...@@ -230,7 +230,7 @@ typedef struct { ...@@ -230,7 +230,7 @@ typedef struct {
* EMMAS primitive for cell information * EMMAS primitive for cell information
* ------------------------------------ * ------------------------------------
*/ */
typedef struct { typedef struct emm_as_cell_info_s {
UInt8_t found; /* Indicates whether a suitable cell is found */ UInt8_t found; /* Indicates whether a suitable cell is found */
#define EMM_AS_PLMN_LIST_SIZE 6 #define EMM_AS_PLMN_LIST_SIZE 6
PLMN_LIST_T(EMM_AS_PLMN_LIST_SIZE) plmnIDs; PLMN_LIST_T(EMM_AS_PLMN_LIST_SIZE) plmnIDs;
...@@ -245,7 +245,7 @@ typedef struct { ...@@ -245,7 +245,7 @@ typedef struct {
* Structure of EMMAS-SAP primitive * Structure of EMMAS-SAP primitive
* -------------------------------- * --------------------------------
*/ */
typedef struct { typedef struct emm_as_s {
emm_as_primitive_t primitive; emm_as_primitive_t primitive;
union { union {
emm_as_security_t security; emm_as_security_t security;
......
...@@ -181,19 +181,26 @@ static int _emm_cn_deregister_ue(const UInt32_t ue_id) ...@@ -181,19 +181,26 @@ static int _emm_cn_deregister_ue(const UInt32_t ue_id)
static int _emm_cn_pdn_connectivity_res(const emm_cn_pdn_res_t *msg_pP) static int _emm_cn_pdn_connectivity_res(const emm_cn_pdn_res_t *msg_pP)
{ {
int rc = RETURNok; int rc = RETURNok;
struct emm_data_context_s *emm_ctx_p = NULL; struct emm_data_context_s *emm_ctx_p = NULL;
esm_proc_pdn_type_t esm_pdn_type = ESM_PDN_TYPE_IPV4; esm_proc_pdn_type_t esm_pdn_type = ESM_PDN_TYPE_IPV4;
esm_proc_data_t *esm_proc_data_p = NULL; esm_proc_data_t *esm_proc_data_p = NULL;
ESM_msg esm_msg; ESM_msg esm_msg;
EpsQualityOfService qos; EpsQualityOfService qos;
OctetString rsp = { 0, NULL}; ProtocolConfigurationOptions pco;
int is_standalone = 0; // warning hardcoded unsigned int pco_in_index = 0;
int triggered_by_ue = 1; // warning hardcoded signed int length_in_pco = 0;
attach_data_t *data_p = NULL; uint16_t pi_or_ci = 0; // protocol identifier or container identifier;
int esm_cause = ESM_CAUSE_SUCCESS; uint8_t length_pi_or_ci = 0;
int pid = 0;
unsigned int new_ebi = 0; OctetString rsp = { 0, NULL};
int is_standalone = 0; // warning hardcoded
int triggered_by_ue = 1; // warning hardcoded
attach_data_t *data_p = NULL;
int esm_cause = ESM_CAUSE_SUCCESS;
int pid = 0;
unsigned int new_ebi = 0;
LOG_FUNC_IN; LOG_FUNC_IN;
emm_ctx_p = emm_data_context_get(&_emm_data, msg_pP->ue_id); emm_ctx_p = emm_data_context_get(&_emm_data, msg_pP->ue_id);
...@@ -247,7 +254,44 @@ static int _emm_cn_pdn_connectivity_res(const emm_cn_pdn_res_t *msg_pP) ...@@ -247,7 +254,44 @@ static int _emm_cn_pdn_connectivity_res(const emm_cn_pdn_res_t *msg_pP)
qos.bitRatesExt.guarBitRateForUL = 0; qos.bitRatesExt.guarBitRateForUL = 0;
qos.bitRatesExt.guarBitRateForDL = 0; qos.bitRatesExt.guarBitRateForDL = 0;
//--------------------------------------------------------------------------
// PCO processing
//--------------------------------------------------------------------------
memset(&pco, 0, sizeof(ProtocolConfigurationOptions));
length_in_pco = msg_pP->pco.byte[1];
if ((length_in_pco+1+1) != msg_pP->pco.length) {
LOG_TRACE(WARNING, "PCO: mismatch in lengths length_pco+1+1 %u != msg_pP->pco.length %u\n",
length_in_pco+1+1, msg_pP->pco.length);
}
pco.configurationprotol = msg_pP->pco.byte[2] & 0x07;
for (int i = 0; i < msg_pP->pco.length; i++) {
LOG_TRACE(WARNING, "EMMCN_PDN_CONNECTIVITY_RES.pco.byte[%u] = 0x%x", i, msg_pP->pco.byte[i]);
}
if ((length_in_pco > 0) && (msg_pP->pco.byte[2] & 0x80)) {
pco_in_index = PCO_MIN_LENGTH;
while (length_in_pco >= 3) {
pi_or_ci = (((uint16_t)msg_pP->pco.byte[pco_in_index]) << 8) | (uint16_t)msg_pP->pco.byte[pco_in_index+1];
pco_in_index += 2;
length_pi_or_ci = msg_pP->pco.byte[pco_in_index++];
pco.protocolid[pco.num_protocol_id_or_container_id] = pi_or_ci;
pco.lengthofprotocolid[pco.num_protocol_id_or_container_id] = length_pi_or_ci;
pco.protocolidcontents[pco.num_protocol_id_or_container_id].value = malloc(length_pi_or_ci);
pco.protocolidcontents[pco.num_protocol_id_or_container_id].length = length_pi_or_ci;
memcpy(pco.protocolidcontents[pco.num_protocol_id_or_container_id].value,
&msg_pP->pco.byte[pco_in_index],
length_pi_or_ci);
LOG_TRACE(WARNING, "PCO: Found pi_or_ci 0x%x length %u content %s\n",
pi_or_ci, length_pi_or_ci, dump_octet_string(&pco.protocolidcontents[pco.num_protocol_id_or_container_id]));
pco.num_protocol_id_or_container_id++;
pco_in_index += length_pi_or_ci;
length_in_pco = length_in_pco - (length_pi_or_ci + 2 + 1);
} // while (length_in_pco >= 3) {
} // if ((length_in_pco > 0) && (msg_pP->pco.byte[2] & 0x80)) {
/*************************************************************************/ /*************************************************************************/
/* CODE THAT WAS IN esm_recv.c/esm_recv_pdn_connectivity_request() */ /* CODE THAT WAS IN esm_recv.c/esm_recv_pdn_connectivity_request() */
/*************************************************************************/ /*************************************************************************/
...@@ -294,6 +338,7 @@ static int _emm_cn_pdn_connectivity_res(const emm_cn_pdn_res_t *msg_pP) ...@@ -294,6 +338,7 @@ static int _emm_cn_pdn_connectivity_res(const emm_cn_pdn_res_t *msg_pP)
new_ebi, //msg_pP->ebi, new_ebi, //msg_pP->ebi,
&esm_msg.activate_default_eps_bearer_context_request, &esm_msg.activate_default_eps_bearer_context_request,
&msg_pP->apn, &msg_pP->apn,
&pco,
esm_pdn_type, esm_pdn_type,
&msg_pP->pdn_addr, &msg_pP->pdn_addr,
&qos, &qos,
......
...@@ -165,7 +165,7 @@ typedef enum { ...@@ -165,7 +165,7 @@ typedef enum {
/* /*
* Structure of EPS Mobility Management primitive * Structure of EPS Mobility Management primitive
*/ */
typedef struct { typedef struct emm_sap_s {
emm_primitive_t primitive; emm_primitive_t primitive;
union { union {
emm_reg_t emm_reg; /* EMMREG-SAP primitives */ emm_reg_t emm_reg; /* EMMREG-SAP primitives */
......
...@@ -96,7 +96,7 @@ typedef enum { ...@@ -96,7 +96,7 @@ typedef enum {
#ifdef NAS_MME #ifdef NAS_MME
/* ESM message timer retransmission data */ /* ESM message timer retransmission data */
typedef struct { typedef struct esm_ebr_timer_data_s {
void *ctx; void *ctx;
unsigned int ueid; /* Lower layers UE identifier */ unsigned int ueid; /* Lower layers UE identifier */
unsigned int ebi; /* EPS bearer identity */ unsigned int ebi; /* EPS bearer identity */
...@@ -110,7 +110,7 @@ typedef struct { ...@@ -110,7 +110,7 @@ typedef struct {
* EPS bearer context data * EPS bearer context data
* ----------------------- * -----------------------
*/ */
typedef struct { typedef struct esm_ebr_context_s {
unsigned char ebi; /* EPS bearer identity */ unsigned char ebi; /* EPS bearer identity */
esm_ebr_state status; /* EPS bearer context status */ esm_ebr_state status; /* EPS bearer context status */
#ifdef NAS_UE #ifdef NAS_UE
...@@ -125,7 +125,7 @@ typedef struct { ...@@ -125,7 +125,7 @@ typedef struct {
#endif #endif
} esm_ebr_context_t; } esm_ebr_context_t;
typedef struct { typedef struct esm_ebr_data_s {
unsigned char index; /* Index of the next EPS bearer context unsigned char index; /* Index of the next EPS bearer context
* identity to be used */ * identity to be used */
#define ESM_EBR_DATA_SIZE (ESM_EBI_MAX - ESM_EBI_MIN + 1) #define ESM_EBR_DATA_SIZE (ESM_EBI_MAX - ESM_EBI_MIN + 1)
...@@ -147,7 +147,7 @@ typedef struct { ...@@ -147,7 +147,7 @@ typedef struct {
* butes. An EPS bearer corresponds to one Quality of Service policy * butes. An EPS bearer corresponds to one Quality of Service policy
* applied within the EPC and E-UTRAN. * applied within the EPC and E-UTRAN.
*/ */
typedef struct { typedef struct esm_bearer_s {
int bid; /* Identifier of the EPS bearer */ int bid; /* Identifier of the EPS bearer */
unsigned int ebi; /* EPS bearer identity */ unsigned int ebi; /* EPS bearer identity */
network_qos_t qos; /* EPS bearer level QoS parameters */ network_qos_t qos; /* EPS bearer level QoS parameters */
...@@ -161,7 +161,7 @@ typedef struct { ...@@ -161,7 +161,7 @@ typedef struct {
* one IPv4 address and/or one IPv6 prefix and a PDN represented by * one IPv4 address and/or one IPv6 prefix and a PDN represented by
* an Access Point Name (APN). * an Access Point Name (APN).
*/ */
typedef struct { typedef struct esm_pdn_s {
unsigned int pti; /* Identity of the procedure transaction executed unsigned int pti; /* Identity of the procedure transaction executed
* to activate the PDN connection entry */ * to activate the PDN connection entry */
int is_emergency; /* Emergency bearer services indicator */ int is_emergency; /* Emergency bearer services indicator */
...@@ -234,7 +234,7 @@ typedef esm_data_context_t esm_data_t; ...@@ -234,7 +234,7 @@ typedef esm_data_context_t esm_data_t;
* Structure of the ESM data * Structure of the ESM data
* ------------------------- * -------------------------
*/ */
typedef struct { typedef struct esm_data_s {
/* /*
* MME configuration * MME configuration
* ----------------- * -----------------
......
...@@ -49,6 +49,7 @@ Description Defines the EPS Session Management procedures executed at ...@@ -49,6 +49,7 @@ Description Defines the EPS Session Management procedures executed at
#include "networkDef.h" #include "networkDef.h"
#include "OctetString.h" #include "OctetString.h"
#include "emmData.h" #include "emmData.h"
#include "ProtocolConfigurationOptions.h"
/****************************************************************************/ /****************************************************************************/
/********************* G L O B A L C O N S T A N T S *******************/ /********************* G L O B A L C O N S T A N T S *******************/
...@@ -103,6 +104,8 @@ typedef network_qos_t esm_proc_qos_t; ...@@ -103,6 +104,8 @@ typedef network_qos_t esm_proc_qos_t;
/* Traffic Flow Template for packet filtering */ /* Traffic Flow Template for packet filtering */
typedef network_tft_t esm_proc_tft_t; typedef network_tft_t esm_proc_tft_t;
typedef ProtocolConfigurationOptions esm_proc_pco_t;
/* PDN connection and EPS bearer context data */ /* PDN connection and EPS bearer context data */
typedef struct { typedef struct {
OctetString apn; OctetString apn;
...@@ -110,6 +113,7 @@ typedef struct { ...@@ -110,6 +113,7 @@ typedef struct {
OctetString pdn_addr; OctetString pdn_addr;
esm_proc_qos_t qos; esm_proc_qos_t qos;
esm_proc_tft_t tft; esm_proc_tft_t tft;
esm_proc_pco_t pco;
} esm_proc_data_t; } esm_proc_data_t;
/****************************************************************************/ /****************************************************************************/
......
...@@ -297,7 +297,7 @@ int encode_activate_default_eps_bearer_context_request(activate_default_eps_bear ...@@ -297,7 +297,7 @@ int encode_activate_default_eps_bearer_context_request(activate_default_eps_bear
encoded += encode_result; encoded += encode_result;
} }
#if 1 /* LW: force Protocol Configuration Options to be included in the ESM message */ #if 0 /* LW: force Protocol Configuration Options to be included in the ESM message */
{ {
#define CONFIGURATION_PROTOCOL_PPP 0 #define CONFIGURATION_PROTOCOL_PPP 0
......
...@@ -735,6 +735,7 @@ int esm_recv_pdn_connectivity_request(emm_data_context_t *ctx, int pti, int ebi, ...@@ -735,6 +735,7 @@ int esm_recv_pdn_connectivity_request(emm_data_context_t *ctx, int pti, int ebi,
unsigned int *new_ebi, void *data) unsigned int *new_ebi, void *data)
{ {
int esm_cause = ESM_CAUSE_SUCCESS; int esm_cause = ESM_CAUSE_SUCCESS;
uint8_t i;
LOG_FUNC_IN; LOG_FUNC_IN;
...@@ -823,6 +824,13 @@ int esm_recv_pdn_connectivity_request(emm_data_context_t *ctx, int pti, int ebi, ...@@ -823,6 +824,13 @@ int esm_recv_pdn_connectivity_request(emm_data_context_t *ctx, int pti, int ebi,
*/ */
//TODO: rc = esm_proc_information_request(); //TODO: rc = esm_proc_information_request();
} }
esm_data->pco = msg->protocolconfigurationoptions;
for (i = 0; i < msg->protocolconfigurationoptions.num_protocol_id_or_container_id; i++) {
DUP_OCTET_STRING(msg->protocolconfigurationoptions.protocolidcontents[i], esm_data->pco.protocolidcontents[i]);
esm_data->pco.protocolid[i] = msg->protocolconfigurationoptions.protocolid[i];
esm_data->pco.lengthofprotocolid[i] = msg->protocolconfigurationoptions.lengthofprotocolid[i];
}
#if defined(ORIGINAL_CODE) #if defined(ORIGINAL_CODE)
/* Execute the PDN connectivity procedure requested by the UE */ /* Execute the PDN connectivity procedure requested by the UE */
......
...@@ -59,7 +59,7 @@ Description Defines the ESM Service Access Point that provides EPS ...@@ -59,7 +59,7 @@ Description Defines the ESM Service Access Point that provides EPS
* EPS Session Management primitives * EPS Session Management primitives
* --------------------------------- * ---------------------------------
*/ */
typedef enum { typedef enum esm_primitive_s {
ESM_START = 0, ESM_START = 0,
/* Procedures related to EPS bearer contexts (initiated by the network) */ /* Procedures related to EPS bearer contexts (initiated by the network) */
ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ, ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ,
...@@ -107,14 +107,14 @@ typedef enum { ...@@ -107,14 +107,14 @@ typedef enum {
* ESM primitive for activate EPS default bearer context procedure * ESM primitive for activate EPS default bearer context procedure
* --------------------------------------------------------------- * ---------------------------------------------------------------
*/ */
typedef struct { typedef struct esm_activate_eps_default_bearer_context_s {
} esm_activate_eps_default_bearer_context_t; } esm_activate_eps_default_bearer_context_t;
/* /*
* ESM primitive for PDN connectivity procedure * ESM primitive for PDN connectivity procedure
* -------------------------------------------- * --------------------------------------------
*/ */
typedef struct { typedef struct esm_pdn_connectivity_s {
int cid; /* PDN connection local identifier */ int cid; /* PDN connection local identifier */
int is_defined; /* Indicates whether a PDN context has been defined int is_defined; /* Indicates whether a PDN context has been defined
* for the specified APN */ * for the specified APN */
...@@ -129,7 +129,7 @@ typedef struct { ...@@ -129,7 +129,7 @@ typedef struct {
* ESM primitive for PDN disconnect procedure * ESM primitive for PDN disconnect procedure
* ------------------------------------------ * ------------------------------------------
*/ */
typedef struct { typedef struct esm_pdn_disconnect_s {
int cid; /* PDN connection local identifier */ int cid; /* PDN connection local identifier */
} esm_pdn_disconnect_t; } esm_pdn_disconnect_t;
...@@ -137,7 +137,7 @@ typedef struct { ...@@ -137,7 +137,7 @@ typedef struct {
* ESM primitive for deactivate EPS bearer context procedure * ESM primitive for deactivate EPS bearer context procedure
* --------------------------------------------------------- * ---------------------------------------------------------
*/ */
typedef struct { typedef struct esm_eps_bearer_context_deactivate_s {
#define ESM_SAP_ALL_EBI 0xff #define ESM_SAP_ALL_EBI 0xff
unsigned int ebi; /* EPS bearer identity of the EPS bearer context unsigned int ebi; /* EPS bearer identity of the EPS bearer context
* to be deactivated */ * to be deactivated */
...@@ -154,20 +154,20 @@ typedef union { ...@@ -154,20 +154,20 @@ typedef union {
esm_eps_bearer_context_deactivate_t eps_bearer_context_deactivate; esm_eps_bearer_context_deactivate_t eps_bearer_context_deactivate;
} esm_sap_data_t; } esm_sap_data_t;
typedef struct { typedef struct esm_sap_s {
esm_primitive_t primitive; /* ESM-SAP primitive to process */ esm_primitive_t primitive; /* ESM-SAP primitive to process */
int is_standalone; /* Indicates whether the ESM message handled int is_standalone; /* Indicates whether the ESM message handled
* within this primitive has to be sent/received * within this primitive has to be sent/received
* standalone or together within an EMM related * standalone or together within an EMM related
* message */ * message */
#if defined(NAS_MME) #if defined(NAS_MME)
emm_data_context_t *ctx; /* UE context */ emm_data_context_t *ctx; /* UE context */
#endif #endif
unsigned int ueid; /* Local UE identifier */ unsigned int ueid; /* Local UE identifier */
esm_sap_error_t err; /* ESM-SAP error code */ esm_sap_error_t err; /* ESM-SAP error code */
const OctetString *recv; /* Encoded ESM message received */ const OctetString *recv; /* Encoded ESM message received */
OctetString send; /* Encoded ESM message to be sent */ OctetString send; /* Encoded ESM message to be sent */
esm_sap_data_t data; /* ESM message data parameters */ esm_sap_data_t data; /* ESM message data parameters */
} esm_sap_t; } esm_sap_t;
/****************************************************************************/ /****************************************************************************/
......
...@@ -555,6 +555,7 @@ int esm_send_activate_default_eps_bearer_context_request(int pti, ...@@ -555,6 +555,7 @@ int esm_send_activate_default_eps_bearer_context_request(int pti,
int ebi, int ebi,
activate_default_eps_bearer_context_request_msg *msg, activate_default_eps_bearer_context_request_msg *msg,
const OctetString *apn, const OctetString *apn,
const ProtocolConfigurationOptions *pco,
int pdn_type, int pdn_type,
const OctetString *pdn_addr, const OctetString *pdn_addr,
const EpsQualityOfService *qos, const EpsQualityOfService *qos,
...@@ -615,6 +616,12 @@ int esm_send_activate_default_eps_bearer_context_request(int pti, ...@@ -615,6 +616,12 @@ int esm_send_activate_default_eps_bearer_context_request(int pti,
msg->esmcause = esm_cause; msg->esmcause = esm_cause;
} }
if (pco != NULL) {
msg->presencemask |=
ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
msg->protocolconfigurationoptions = *pco;
}
#warning "TEST LG FORCE APN-AMBR" #warning "TEST LG FORCE APN-AMBR"
LOG_TRACE(INFO, "ESM-SAP - FORCE APN-AMBR"); LOG_TRACE(INFO, "ESM-SAP - FORCE APN-AMBR");
msg->presencemask |= msg->presencemask |=
......
...@@ -159,8 +159,8 @@ int esm_send_pdn_disconnect_reject(int pti, pdn_disconnect_reject_msg *msg, ...@@ -159,8 +159,8 @@ int esm_send_pdn_disconnect_reject(int pti, pdn_disconnect_reject_msg *msg,
*/ */
int esm_send_activate_default_eps_bearer_context_request(int pti, int ebi, int esm_send_activate_default_eps_bearer_context_request(int pti, int ebi,
activate_default_eps_bearer_context_request_msg *msg, const OctetString *apn, activate_default_eps_bearer_context_request_msg *msg, const OctetString *apn,
int pdn_type, const OctetString *pdn_addr, const EpsQualityOfService *qos, const ProtocolConfigurationOptions *pco, int pdn_type, const OctetString *pdn_addr,
int esm_cause); const EpsQualityOfService *qos, int esm_cause);
int esm_send_activate_dedicated_eps_bearer_context_request(int pti, int ebi, int esm_send_activate_dedicated_eps_bearer_context_request(int pti, int ebi,
activate_dedicated_eps_bearer_context_request_msg *msg, int linked_ebi, activate_dedicated_eps_bearer_context_request_msg *msg, int linked_ebi,
......
...@@ -54,6 +54,7 @@ int decode_esm_message_container(EsmMessageContainer *esmmessagecontainer, uint8 ...@@ -54,6 +54,7 @@ int decode_esm_message_container(EsmMessageContainer *esmmessagecontainer, uint8
CHECK_LENGTH_DECODER(len - decoded, ielen); CHECK_LENGTH_DECODER(len - decoded, ielen);
if ((decode_result = decode_octet_string(&esmmessagecontainer->esmmessagecontainercontents, ielen, buffer + decoded, len - decoded)) < 0) { if ((decode_result = decode_octet_string(&esmmessagecontainer->esmmessagecontainercontents, ielen, buffer + decoded, len - decoded)) < 0) {
LOG_FUNC_RETURN(decode_result); LOG_FUNC_RETURN(decode_result);
} else { } else {
......
...@@ -64,16 +64,23 @@ int decode_protocol_configuration_options(ProtocolConfigurationOptions *protocol ...@@ -64,16 +64,23 @@ int decode_protocol_configuration_options(ProtocolConfigurationOptions *protocol
decoded++; decoded++;
//IES_DECODE_U16(protocolconfigurationoptions->protocolid, *(buffer + decoded)); //IES_DECODE_U16(protocolconfigurationoptions->protocolid, *(buffer + decoded));
protocolconfigurationoptions->num_protocol_id_or_container_id = 0;
while ((len - decoded) > 0) { while ((len - decoded) > 0) {
IES_DECODE_U16(buffer, decoded, protocolconfigurationoptions->protocolid); IES_DECODE_U16(buffer, decoded, protocolconfigurationoptions->protocolid[protocolconfigurationoptions->num_protocol_id_or_container_id]);
DECODE_U8(buffer + decoded, protocolconfigurationoptions->lengthofprotocolid, decoded); DECODE_U8(buffer + decoded, protocolconfigurationoptions->lengthofprotocolid[protocolconfigurationoptions->num_protocol_id_or_container_id], decoded);
if ((decode_result = decode_octet_string(&protocolconfigurationoptions->protocolidcontents, if (protocolconfigurationoptions->lengthofprotocolid[protocolconfigurationoptions->num_protocol_id_or_container_id] > 0) {
protocolconfigurationoptions->lengthofprotocolid, buffer + decoded, len - decoded)) < 0) { if ((decode_result = decode_octet_string(&protocolconfigurationoptions->protocolidcontents[protocolconfigurationoptions->num_protocol_id_or_container_id],
return decode_result; protocolconfigurationoptions->lengthofprotocolid[protocolconfigurationoptions->num_protocol_id_or_container_id], buffer + decoded, len - decoded)) < 0) {
return decode_result;
} else {
decoded += decode_result;
}
} else { } else {
decoded += decode_result; protocolconfigurationoptions->protocolidcontents[protocolconfigurationoptions->num_protocol_id_or_container_id].length = 0;
protocolconfigurationoptions->protocolidcontents[protocolconfigurationoptions->num_protocol_id_or_container_id].value = NULL;
} }
protocolconfigurationoptions->num_protocol_id_or_container_id += 1;
} }
#if defined (NAS_DEBUG) #if defined (NAS_DEBUG)
...@@ -84,6 +91,7 @@ int decode_protocol_configuration_options(ProtocolConfigurationOptions *protocol ...@@ -84,6 +91,7 @@ int decode_protocol_configuration_options(ProtocolConfigurationOptions *protocol
int encode_protocol_configuration_options(ProtocolConfigurationOptions *protocolconfigurationoptions, uint8_t iei, uint8_t *buffer, uint32_t len) int encode_protocol_configuration_options(ProtocolConfigurationOptions *protocolconfigurationoptions, uint8_t iei, uint8_t *buffer, uint32_t len)
{ {
uint8_t *lenPtr; uint8_t *lenPtr;
uint8_t num_protocol_id_or_container_id = 0;
uint32_t encoded = 0; uint32_t encoded = 0;
int encode_result; int encode_result;
/* Checking IEI and pointer */ /* Checking IEI and pointer */
...@@ -102,21 +110,29 @@ int encode_protocol_configuration_options(ProtocolConfigurationOptions *protocol ...@@ -102,21 +110,29 @@ int encode_protocol_configuration_options(ProtocolConfigurationOptions *protocol
*(buffer + encoded) = 0x00 | (1 << 7) | *(buffer + encoded) = 0x00 | (1 << 7) |
(protocolconfigurationoptions->configurationprotol & 0x7); (protocolconfigurationoptions->configurationprotol & 0x7);
encoded++; encoded++;
IES_ENCODE_U16(buffer, encoded, protocolconfigurationoptions->protocolid);
*(buffer + encoded) = protocolconfigurationoptions->lengthofprotocolid;
encoded++;
if ((encode_result = encode_octet_string(&protocolconfigurationoptions->protocolidcontents, buffer + encoded, len - encoded)) < 0) while (num_protocol_id_or_container_id < protocolconfigurationoptions->num_protocol_id_or_container_id) {
return encode_result;
else IES_ENCODE_U16(buffer, encoded, protocolconfigurationoptions->protocolid[num_protocol_id_or_container_id]);
encoded += encode_result; *(buffer + encoded) = protocolconfigurationoptions->lengthofprotocolid[num_protocol_id_or_container_id];
encoded++;
if ((encode_result = encode_octet_string(&protocolconfigurationoptions->protocolidcontents[num_protocol_id_or_container_id],
buffer + encoded,
len - encoded)) < 0)
return encode_result;
else
encoded += encode_result;
num_protocol_id_or_container_id += 1;
}
*lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0); *lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0);
return encoded; return encoded;
} }
void dump_protocol_configuration_options_xml(ProtocolConfigurationOptions *protocolconfigurationoptions, uint8_t iei) void dump_protocol_configuration_options_xml(ProtocolConfigurationOptions *protocolconfigurationoptions, uint8_t iei)
{ {
int i;
printf("<Protocol Configuration Options>\n"); printf("<Protocol Configuration Options>\n");
if (iei > 0) if (iei > 0)
...@@ -124,9 +140,13 @@ void dump_protocol_configuration_options_xml(ProtocolConfigurationOptions *proto ...@@ -124,9 +140,13 @@ void dump_protocol_configuration_options_xml(ProtocolConfigurationOptions *proto
printf(" <IEI>0x%X</IEI>\n", iei); printf(" <IEI>0x%X</IEI>\n", iei);
printf(" <Configuration protol>%u</Configuration protol>\n", protocolconfigurationoptions->configurationprotol); printf(" <Configuration protol>%u</Configuration protol>\n", protocolconfigurationoptions->configurationprotol);
printf(" <Protocol ID>%u</Protocol ID>\n", protocolconfigurationoptions->protocolid); i = 0;
printf(" <Length of protocol ID>%u</Length of protocol ID>\n", protocolconfigurationoptions->lengthofprotocolid); while (i < protocolconfigurationoptions->num_protocol_id_or_container_id) {
printf("%s",dump_octet_string_xml(&protocolconfigurationoptions->protocolidcontents)); printf(" <Protocol ID>%u</Protocol ID>\n", protocolconfigurationoptions->protocolid[i]);
printf(" <Length of protocol ID>%u</Length of protocol ID>\n", protocolconfigurationoptions->lengthofprotocolid[i]);
printf(" %s",dump_octet_string_xml(&protocolconfigurationoptions->protocolidcontents[i]));
i++;
}
printf("</Protocol Configuration Options>\n"); printf("</Protocol Configuration Options>\n");
} }
...@@ -38,6 +38,10 @@ ...@@ -38,6 +38,10 @@
#define PROTOCOL_CONFIGURATION_OPTIONS_MINIMUM_LENGTH 3 #define PROTOCOL_CONFIGURATION_OPTIONS_MINIMUM_LENGTH 3
#define PROTOCOL_CONFIGURATION_OPTIONS_MAXIMUM_LENGTH 253 #define PROTOCOL_CONFIGURATION_OPTIONS_MAXIMUM_LENGTH 253
// arbitrary value, theoricaly can be greater than defined (250/3)
#define PROTOCOL_CONFIGURATION_OPTIONS_MAXIMUM_PROTOCOL_ID_OR_CONTAINER_ID 16
/* 3GPP TS 24.008 Table 10.5.154 /* 3GPP TS 24.008 Table 10.5.154
* MS to network table * MS to network table
*/ */
...@@ -58,10 +62,11 @@ typedef enum ProtocolConfigurationOptionsList_ids_tag { ...@@ -58,10 +62,11 @@ typedef enum ProtocolConfigurationOptionsList_ids_tag {
*/ */
typedef struct ProtocolConfigurationOptions_tag { typedef struct ProtocolConfigurationOptions_tag {
uint8_t configurationprotol:3; uint8_t configurationprotol:3;
uint16_t protocolid; uint8_t num_protocol_id_or_container_id;
uint8_t lengthofprotocolid; uint16_t protocolid[PROTOCOL_CONFIGURATION_OPTIONS_MAXIMUM_PROTOCOL_ID_OR_CONTAINER_ID];
OctetString protocolidcontents; uint8_t lengthofprotocolid[PROTOCOL_CONFIGURATION_OPTIONS_MAXIMUM_PROTOCOL_ID_OR_CONTAINER_ID];
OctetString protocolidcontents[PROTOCOL_CONFIGURATION_OPTIONS_MAXIMUM_PROTOCOL_ID_OR_CONTAINER_ID];
} ProtocolConfigurationOptions; } ProtocolConfigurationOptions;
int encode_protocol_configuration_options(ProtocolConfigurationOptions *protocolconfigurationoptions, uint8_t iei, uint8_t *buffer, uint32_t len); int encode_protocol_configuration_options(ProtocolConfigurationOptions *protocolconfigurationoptions, uint8_t iei, uint8_t *buffer, uint32_t len);
......
...@@ -48,7 +48,6 @@ OctetString* dup_octet_string(OctetString *octetstring) ...@@ -48,7 +48,6 @@ OctetString* dup_octet_string(OctetString *octetstring)
memcpy(os_p->value, octetstring->value, octetstring->length); memcpy(os_p->value, octetstring->value, octetstring->length);
os_p->value[octetstring->length] = '\0'; os_p->value[octetstring->length] = '\0';
} }
return os_p; return os_p;
} }
...@@ -57,7 +56,6 @@ void free_octet_string(OctetString *octetstring) ...@@ -57,7 +56,6 @@ void free_octet_string(OctetString *octetstring)
{ {
if (octetstring) { if (octetstring) {
if (octetstring->value) free(octetstring->value); if (octetstring->value) free(octetstring->value);
octetstring->value = NULL; octetstring->value = NULL;
octetstring->length = 0; octetstring->length = 0;
free(octetstring); free(octetstring);
...@@ -67,9 +65,17 @@ void free_octet_string(OctetString *octetstring) ...@@ -67,9 +65,17 @@ void free_octet_string(OctetString *octetstring)
int encode_octet_string(OctetString *octetstring, uint8_t *buffer, uint32_t buflen) int encode_octet_string(OctetString *octetstring, uint8_t *buffer, uint32_t buflen)
{ {
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, octetstring->length, buflen); if (octetstring != NULL) {
memcpy((void*)buffer, (void*)octetstring->value, octetstring->length); if ((octetstring->value != NULL) && (octetstring->length > 0)) {
return octetstring->length; CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, octetstring->length, buflen);
memcpy((void*)buffer, (void*)octetstring->value, octetstring->length);
return octetstring->length;
} else {
return 0;
}
} else {
return 0;
}
} }
int decode_octet_string(OctetString *octetstring, uint16_t pdulen, uint8_t *buffer, uint32_t buflen) int decode_octet_string(OctetString *octetstring, uint16_t pdulen, uint8_t *buffer, uint32_t buflen)
...@@ -77,11 +83,15 @@ int decode_octet_string(OctetString *octetstring, uint16_t pdulen, uint8_t *buff ...@@ -77,11 +83,15 @@ int decode_octet_string(OctetString *octetstring, uint16_t pdulen, uint8_t *buff
if (buflen < pdulen) if (buflen < pdulen)
return -1; return -1;
octetstring->length = pdulen; if ((octetstring != NULL) && (buffer!= NULL)) {
octetstring->value = malloc(sizeof(uint8_t) * (pdulen+1)); octetstring->length = pdulen;
memcpy((void*)octetstring->value, (void*)buffer, pdulen); octetstring->value = malloc(sizeof(uint8_t) * (pdulen+1));
octetstring->value[pdulen] = '\0'; memcpy((void*)octetstring->value, (void*)buffer, pdulen);
return octetstring->length; octetstring->value[pdulen] = '\0';
return octetstring->length;
} else {
return -1;
}
} }
char* dump_octet_string_xml( const OctetString * const octetstring) char* dump_octet_string_xml( const OctetString * const octetstring)
...@@ -89,15 +99,19 @@ char* dump_octet_string_xml( const OctetString * const octetstring) ...@@ -89,15 +99,19 @@ char* dump_octet_string_xml( const OctetString * const octetstring)
int i; int i;
int remaining_size = DUMP_OUTPUT_SIZE; int remaining_size = DUMP_OUTPUT_SIZE;
int size = 0; int size = 0;
size = snprintf(_dump_output, remaining_size, "<Length>%u</Length>\n\t<values>", octetstring->length); int size_print = 0;
remaining_size -= size;
size_print = snprintf(_dump_output, remaining_size, "<Length>%u</Length>\n\t<values>", octetstring->length);
size += size_print;
remaining_size -= size_print;
for (i = 0; i < octetstring->length; i++) { for (i = 0; i < octetstring->length; i++) {
size +=snprintf(&_dump_output[size], remaining_size, "0x%x ", octetstring->value[i]); size_print = snprintf(&_dump_output[size], remaining_size, "0x%x ", octetstring->value[i]);
remaining_size -= size; size += size_print;
remaining_size -= size_print;
} }
size +=snprintf(&_dump_output[size], remaining_size, "</values>\n"); size_print = snprintf(&_dump_output[size], remaining_size, "</values>\n");
return _dump_output; return _dump_output;
} }
...@@ -106,10 +120,12 @@ char* dump_octet_string( const OctetString * const octetstring) ...@@ -106,10 +120,12 @@ char* dump_octet_string( const OctetString * const octetstring)
int i; int i;
int remaining_size = DUMP_OUTPUT_SIZE; int remaining_size = DUMP_OUTPUT_SIZE;
int size = 0; int size = 0;
int size_print = 0;
for (i = 0; i < octetstring->length; i++) { for (i = 0; i < octetstring->length; i++) {
size +=snprintf(&_dump_output[size], remaining_size, "0x%x ", octetstring->value[i]); size_print = snprintf(&_dump_output[size], remaining_size, "0x%x ", octetstring->value[i]);
remaining_size -= size; size += size_print;
remaining_size -= size_print;
} }
return _dump_output; return _dump_output;
......
...@@ -46,19 +46,19 @@ typedef struct OctetString_tag { ...@@ -46,19 +46,19 @@ typedef struct OctetString_tag {
} while (0); } while (0);
#define DUP_OCTET_STRING(oCTETsTRINGoRIG,oCTETsTRINGcOPY) \ #define DUP_OCTET_STRING(oCTETsTRINGoRIG,oCTETsTRINGcOPY) \
do { \ do { \
if ((oCTETsTRINGoRIG).value == NULL) { \ if ((oCTETsTRINGoRIG).value == NULL) { \
(oCTETsTRINGcOPY).length = 0; \ (oCTETsTRINGcOPY).length = 0; \
(oCTETsTRINGcOPY).value = NULL; \ (oCTETsTRINGcOPY).value = NULL; \
break; \ break; \
} \ } \
(oCTETsTRINGcOPY).length = strlen((const char*)(oCTETsTRINGoRIG).value);\ (oCTETsTRINGcOPY).length = (oCTETsTRINGoRIG).length; \
assert((oCTETsTRINGoRIG).length == (oCTETsTRINGcOPY).length); \ (oCTETsTRINGcOPY).value = malloc((oCTETsTRINGoRIG).length+1); \
(oCTETsTRINGcOPY).value = malloc((oCTETsTRINGoRIG).length); \ (oCTETsTRINGcOPY).value[(oCTETsTRINGoRIG).length] = '\0'; \
memcpy((oCTETsTRINGcOPY).value, \ memcpy((oCTETsTRINGcOPY).value, \
(oCTETsTRINGoRIG).value, \ (oCTETsTRINGoRIG).value, \
(oCTETsTRINGoRIG).length); \ (oCTETsTRINGoRIG).length); \
} while (0); } while (0);
OctetString* dup_octet_string(OctetString*octetstring); OctetString* dup_octet_string(OctetString*octetstring);
......
...@@ -68,6 +68,8 @@ static inline void nas_itti_pdn_connectivity_req( ...@@ -68,6 +68,8 @@ static inline void nas_itti_pdn_connectivity_req(
esm_proc_pdn_request_t request_typeP) esm_proc_pdn_request_t request_typeP)
{ {
MessageDef *message_p = NULL; MessageDef *message_p = NULL;
uint8_t i;
uint8_t index;
AssertFatal(imsi_pP != NULL, "imsi_pP param is NULL"); AssertFatal(imsi_pP != NULL, "imsi_pP param is NULL");
AssertFatal(proc_data_pP != NULL, "proc_data_pP param is NULL"); AssertFatal(proc_data_pP != NULL, "proc_data_pP param is NULL");
...@@ -125,6 +127,30 @@ static inline void nas_itti_pdn_connectivity_req( ...@@ -125,6 +127,30 @@ static inline void nas_itti_pdn_connectivity_req(
NAS_PDN_CONNECTIVITY_REQ(message_p).request_type = request_typeP; NAS_PDN_CONNECTIVITY_REQ(message_p).request_type = request_typeP;
if (proc_data_pP->pco.num_protocol_id_or_container_id <= PROTOCOL_CONFIGURATION_OPTIONS_MAXIMUM_PROTOCOL_ID_OR_CONTAINER_ID) {
NAS_PDN_CONNECTIVITY_REQ(message_p).pco.byte[0] = ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT_PROTOCOL_CONFIGURATION_OPTIONS_IEI;
NAS_PDN_CONNECTIVITY_REQ(message_p).pco.byte[1] = 1 + 3 * proc_data_pP->pco.num_protocol_id_or_container_id;
NAS_PDN_CONNECTIVITY_REQ(message_p).pco.byte[2] = 0x80; // do it fast
i = 0;
index = 3;
while (( i < proc_data_pP->pco.num_protocol_id_or_container_id) &&
((index + proc_data_pP->pco.protocolidcontents[i].length) <= PROTOCOL_CONFIGURATION_OPTIONS_MAXIMUM_LENGTH)){
NAS_PDN_CONNECTIVITY_REQ(message_p).pco.byte[1] += proc_data_pP->pco.lengthofprotocolid[i];
NAS_PDN_CONNECTIVITY_REQ(message_p).pco.byte[index++] = (proc_data_pP->pco.protocolid[i] >> 8);
NAS_PDN_CONNECTIVITY_REQ(message_p).pco.byte[index++] = (proc_data_pP->pco.protocolid[i] & 0x00FF);
NAS_PDN_CONNECTIVITY_REQ(message_p).pco.byte[index++] = proc_data_pP->pco.lengthofprotocolid[i];
if (proc_data_pP->pco.lengthofprotocolid[i] > 0) {
memcpy( &NAS_PDN_CONNECTIVITY_REQ(message_p).pco.byte[index],
proc_data_pP->pco.protocolidcontents[i].value,
proc_data_pP->pco.lengthofprotocolid[i]);
index += proc_data_pP->pco.lengthofprotocolid[i];
}
i++;
}
NAS_PDN_CONNECTIVITY_REQ(message_p).pco.length = index;
}
MSC_LOG_TX_MESSAGE( MSC_LOG_TX_MESSAGE(
MSC_NAS_MME, MSC_NAS_MME,
MSC_MMEAPP_MME, MSC_MMEAPP_MME,
......
This diff is collapsed.
...@@ -99,6 +99,66 @@ typedef struct { ...@@ -99,6 +99,66 @@ typedef struct {
uint8_t ipv6_prefix_length; uint8_t ipv6_prefix_length;
} PAA_t; } PAA_t;
/* Protocol configuration options from ts124008*/
#define PCO_MIN_LENGTH 3
#define PCO_MAX_LENGTH 253
#define PCO_CONFIGURATION_PROTOCOL_PPP_FOR_USE_WITH_IP_PDP_TYPE_OR_IP_PDN_TYPE 000b
#define PCO_PI_LCP (0xC021)
#define PCO_PI_PAP (0xC023)
#define PCO_PI_CHAP (0xC223)
#define PCO_PI_IPCP (0x8021)
#define IPCP_CODE_CONFIGURE_REQUEST (0x01)
#define IPCP_CODE_CONFIGURE_ACK (0x02)
#define IPCP_CODE_CONFIGURE_NACK (0x03)
#define IPCP_CODE_CONFIGURE_REJECT (0x04)
#define IPCP_CODE_TERMINATE_REQUEST (0x05)
#define IPCP_CODE_TERMINATE_ACK (0x06)
#define IPCP_CODE_REJECT (0x07)
#define IPCP_OPTION_PRIMARY_DNS_SERVER_IP_ADDRESS (0x81)
#define IPCP_OPTION_SECONDARY_DNS_SERVER_IP_ADDRESS (0x83)
/* CONTAINER IDENTIFIER MS to network direction:*/
#define PCO_CI_P_CSCF_IPV6_ADDRESS_REQUEST (0x0001)
#define PCO_CI_DNS_SERVER_IPV6_ADDRESS_REQUEST (0x0003)
#define PCO_CI_MS_SUPPORT_OF_NETWORK_REQUESTED_BEARER_CONTROL_INDICATOR (0x0005)
#define PCO_CI_DSMIPV6_HOME_AGENT_ADDRESS_REQUEST (0x0007)
#define PCO_CI_DSMIPV6_HOME_NETWORK_PREFIX_REQUEST (0x0008)
#define PCO_CI_DSMIPV6_IPV4_HOME_AGENT_ADDRESS_REQUEST (0x0009)
#define PCO_CI_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING (0x000A)
#define PCO_CI_IPV4_ADDRESS_ALLOCATION_VIA_DHCPV4 (0x000B)
#define PCO_CI_P_CSCF_IPV4_ADDRESS_REQUEST (0x000C)
#define PCO_CI_DNS_SERVER_IPV4_ADDRESS_REQUEST (0x000D)
#define PCO_CI_MSISDN_REQUEST (0x000E)
#define PCO_CI_IFOM_SUPPORT_REQUEST (0x000F)
#define PCO_CI_IPV4_LINK_MTU_REQUEST (0x0010)
/* CONTAINER IDENTIFIER Network to MS direction:*/
#define PCO_CI_P_CSCF_IPV6_ADDRESS (0x0001)
#define PCO_CI_IM_CN_SUBSYSTEM_SIGNALING_FLAG (0x0002)
#define PCO_CI_DNS_SERVER_IPV6_ADDRESS (0x0003)
#define PCO_CI_POLICY_CONTROL_REJECTION_CODE (0x0004)
#define PCO_CI_SELECTED_BEARER_CONTROL_MODE (0x0005)
#define PCO_CI_DSMIPV6_HOME_AGENT_ADDRESS (0x0007)
#define PCO_CI_DSMIPV6_HOME_NETWORK_PREFIX (0x0008)
#define PCO_CI_DSMIPV6_IPV4_HOME_AGENT_ADDRESS (0x0009)
#define PCO_CI_P_CSCF_IPV4_ADDRESS (0x000C)
#define PCO_CI_DNS_SERVER_IPV4_ADDRESS (0x000D)
#define PCO_CI_MSISDN (0x000E)
#define PCO_CI_IFOM_SUPPORT (0x000F)
#define PCO_CI_IPV4_LINK_MTU (0x0010)
/* Both directions:*/
#define PCO_CI_IM_CN_SUBSYSTEM_SIGNALING_FLAG (0x0002)
typedef struct pco_flat_s{
uint8_t byte[PCO_MAX_LENGTH];
uint8_t length;
} pco_flat_t;
#define IMSI(imsi) \ #define IMSI(imsi) \
(imsi)->digit[0], \ (imsi)->digit[0], \
(imsi)->digit[1], \ (imsi)->digit[1], \
......
...@@ -576,15 +576,19 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) ...@@ -576,15 +576,19 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP)
} }
if( if(
config_setting_lookup_string(subsetting, config_setting_lookup_string(setting_pgw,
PGW_CONFIG_STRING_DEFAULT_DNS_IPV4_ADDRESS, PGW_CONFIG_STRING_DEFAULT_DNS_IPV4_ADDRESS,
(const char **)&pgw_default_dns_ipv4_address) (const char **)&pgw_default_dns_ipv4_address)
&& config_setting_lookup_string(subsetting, && config_setting_lookup_string(setting_pgw,
PGW_CONFIG_STRING_DEFAULT_DNS_SEC_IPV4_ADDRESS, PGW_CONFIG_STRING_DEFAULT_DNS_SEC_IPV4_ADDRESS,
(const char **)&pgw_default_dns_sec_ipv4_address)) { (const char **)&pgw_default_dns_sec_ipv4_address)) {
config_pP->pgw_config.ipv4.pgw_interface_name_for_S5_S8 = strdup(pgw_interface_name_for_S5_S8); config_pP->pgw_config.ipv4.pgw_interface_name_for_S5_S8 = strdup(pgw_interface_name_for_S5_S8);
IPV4_STR_ADDR_TO_INT_NWBO ( pgw_default_dns_ipv4_address, config_pP->pgw_config.ipv4.default_dns_v4, "BAD IPv4 ADDRESS FORMAT FOR DEFAULT DNS !\n" ) IPV4_STR_ADDR_TO_INT_NWBO ( pgw_default_dns_ipv4_address, config_pP->pgw_config.ipv4.default_dns_v4, "BAD IPv4 ADDRESS FORMAT FOR DEFAULT DNS !\n" )
IPV4_STR_ADDR_TO_INT_NWBO ( pgw_default_dns_sec_ipv4_address, config_pP->pgw_config.ipv4.default_dns_sec_v4, "BAD IPv4 ADDRESS FORMAT FOR DEFAULT DNS SEC!\n" ) IPV4_STR_ADDR_TO_INT_NWBO ( pgw_default_dns_sec_ipv4_address, config_pP->pgw_config.ipv4.default_dns_sec_v4, "BAD IPv4 ADDRESS FORMAT FOR DEFAULT DNS SEC!\n" )
SPGW_APP_INFO("Parsing configuration file default primary DNS IPv4 address: %x\n",
config_pP->pgw_config.ipv4.default_dns_v4);
SPGW_APP_INFO("Parsing configuration file default secondary DNS IPv4 address: %x\n",
config_pP->pgw_config.ipv4.default_dns_sec_v4);
} else { } else {
SPGW_APP_WARN("NO DNS CONFIGURATION FOUND\n"); SPGW_APP_WARN("NO DNS CONFIGURATION FOUND\n");
} }
......
...@@ -367,7 +367,7 @@ static int config_parse_file(mme_config_t *mme_config_p) ...@@ -367,7 +367,7 @@ static int config_parse_file(mme_config_t *mme_config_p)
} }
} }
subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_PLMN); subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_TAI_LIST);
if (subsetting != NULL) { if (subsetting != NULL) {
num = config_setting_length(subsetting); num = config_setting_length(subsetting);
......
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
#define MME_CONFIG_STRING_GUMMEI_CONFIG "GUMMEI" #define MME_CONFIG_STRING_GUMMEI_CONFIG "GUMMEI"
#define MME_CONFIG_STRING_MME_CODE "MME_CODE" #define MME_CONFIG_STRING_MME_CODE "MME_CODE"
#define MME_CONFIG_STRING_MME_GID "MME_GID" #define MME_CONFIG_STRING_MME_GID "MME_GID"
#define MME_CONFIG_STRING_PLMN "PLMN" #define MME_CONFIG_STRING_TAI_LIST "TAI_LIST"
#define MME_CONFIG_STRING_MCC "MCC" #define MME_CONFIG_STRING_MCC "MCC"
#define MME_CONFIG_STRING_MNC "MNC" #define MME_CONFIG_STRING_MNC "MNC"
#define MME_CONFIG_STRING_TAC "TAC" #define MME_CONFIG_STRING_TAC "TAC"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment