Commit 117f955d authored by Cedric Roux's avatar Cedric Roux
Browse files

- Fixed initial tac/mcc/mnc

- Trigger a dummy initial ue message when receiving s1 setup response
- Added new S1AP <-> RRC messages
- Fixed almost all S1AP messages to integrate ITTI

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4347 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 7535f20c
......@@ -421,12 +421,6 @@ struct s1ap_message_s;
/** \brief Function callback prototype.
**/
// typedef int (*s1ap_message_decoded_callback)(
// eNB_mme_desc_t *eNB_desc_p,
// sctp_queue_item_t *packet_p,
// struct s1ap_message_s *message_p
// );
typedef int (*s1ap_message_decoded_callback)(
uint32_t assoc_id,
uint32_t stream,
......
......@@ -55,69 +55,12 @@
#include "s1ap_eNB_itti_messaging.h"
#include "sctp_primitives_client.h"
#include "assertions.h"
#include "conversions.h"
s1ap_eNB_internal_data_t s1ap_eNB_internal_data;
static int s1ap_eNB_generate_s1_setup_request(
s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p);
RB_GENERATE(s1ap_mme_map, s1ap_eNB_mme_data_s, entry, s1ap_eNB_compare_assoc_id);
inline int s1ap_eNB_compare_assoc_id(
struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2)
{
if (p1->assoc_id == -1) {
if (p1->cnx_id < p2->cnx_id) {
return -1;
}
if (p1->cnx_id > p2->cnx_id) {
return 1;
}
} else {
if (p1->assoc_id < p2->assoc_id) {
return -1;
}
if (p1->assoc_id > p2->assoc_id) {
return 1;
}
}
/* Matching reference */
return 0;
}
inline struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
s1ap_eNB_instance_t *instance_p,
int32_t assoc_id, uint16_t cnx_id)
{
struct s1ap_eNB_mme_data_s temp;
struct s1ap_eNB_mme_data_s *found;
memset(&temp, 0, sizeof(struct s1ap_eNB_mme_data_s));
temp.assoc_id = assoc_id;
temp.cnx_id = cnx_id;
if (instance_p == NULL) {
STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
s1ap_eNB_entries)
{
found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
if (found != NULL) {
return found;
}
}
} else {
return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
}
return NULL;
}
uint32_t s1ap_generate_eNB_id(void)
{
char *out;
......@@ -137,55 +80,6 @@ uint32_t s1ap_generate_eNB_id(void)
return eNB_id;
}
// int s1ap_run(eNB_mme_desc_t *eNB_desc_p)
// {
// int ret = 0;
// struct s1ap_eNB_mme_data_s *mme_p;
//
// DevAssert(eNB_desc_p != NULL);
//
// RB_FOREACH(mme_p, s1ap_mme_map, &eNB_desc_p->s1ap_mme_head) {
// struct sctp_queue_item_s *item_p;
//
// /* Run the SCTP part for each MME */
// sctp_run(&mme_p->sctp_data);
//
// S1AP_DEBUG("Entering s1ap_run for eNB %d: %d packet(s) to handle\n",
// eNB_desc_p->eNB_id, mme_p->sctp_data.queue_length);
//
// /* Handle every message in the queue */
// TAILQ_FOREACH(item_p, &mme_p->sctp_data.sctp_queue, entry) {
// /* Handle the message in S1AP */
// s1ap_eNB_handle_message(eNB_desc_p, item_p);
// /* Remove the packet from the list and update data */
// TAILQ_REMOVE(&mme_p->sctp_data.sctp_queue, item_p, entry);
// ret += item_p->length;
// mme_p->sctp_data.queue_size -= item_p->length;
// mme_p->sctp_data.queue_length--;
// /* Deallocate memory as the message has been handled */
// free(item_p->buffer);
// free(item_p);
// }
// }
// return ret;
// }
static s1ap_eNB_instance_t *s1ap_eNB_get_instance(uint8_t mod_id)
{
s1ap_eNB_instance_t *temp = NULL;
STAILQ_FOREACH(temp, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
s1ap_eNB_entries)
{
if (temp->mod_id == mod_id) {
/* Matching occurence */
return temp;
}
}
return NULL;
}
static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
net_ip_address_t *mme_ip_address,
net_ip_address_t *local_ip_addr)
......@@ -211,9 +105,8 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p));
DevAssert(s1ap_mme_data_p != NULL);
s1ap_mme_data_p->cnx_id = s1ap_eNB_internal_data.global_cnx_id;
s1ap_mme_data_p->cnx_id = s1ap_eNB_fetch_add_global_cnx_id();
sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
s1ap_eNB_internal_data.global_cnx_id++;
s1ap_mme_data_p->assoc_id = -1;
s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
......@@ -257,8 +150,8 @@ void s1ap_eNB_handle_register_eNB(s1ap_register_eNB_t *s1ap_register_eNB)
new_instance->mnc = s1ap_register_eNB->mnc;
new_instance->default_drx = s1ap_register_eNB->default_drx;
STAILQ_INSERT_TAIL(&s1ap_eNB_internal_data.s1ap_eNB_instances_head,
new_instance, s1ap_eNB_entries);
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
s1ap_eNB_insert_new_instance(new_instance);
S1AP_DEBUG("Registered new eNB with mod_id %u and %s eNB id %u\n",
s1ap_register_eNB->mod_id,
......@@ -322,8 +215,7 @@ void *s1ap_eNB_task(void *arg)
S1AP_DEBUG("Starting S1AP layer\n");
memset(&s1ap_eNB_internal_data, 0, sizeof(s1ap_eNB_internal_data));
STAILQ_INIT(&s1ap_eNB_internal_data.s1ap_eNB_instances_head);
s1ap_eNB_prepare_internal_data();
itti_mark_task_ready(TASK_S1AP);
......@@ -348,6 +240,9 @@ void *s1ap_eNB_task(void *arg)
case SCTP_DATA_IND: {
s1ap_eNB_handle_sctp_data_ind(&received_msg->msg.sctp_data_ind);
} break;
case S1AP_NAS_FIRST_REQ: {
s1ap_eNB_handle_nas_first_req(&received_msg->msg.s1ap_nas_first_req);
} break;
default:
S1AP_ERROR("Received unhandled message with id %d\n",
received_msg->header.messageId);
......@@ -418,123 +313,3 @@ static int s1ap_eNB_generate_s1_setup_request(
return ret;
}
// int s1ap_eNB_generate_initial_UE_message(eNB_mme_desc_t *eNB_desc_p,
// s1ap_nas_first_req_t nas_req_p)
// {
// s1ap_message message;
// struct s1ap_eNB_mme_data_s *mme_desc_p;
// struct s1ap_eNB_ue_context_s *ue_desc_p;
// InitialUEMessageIEs_t *initial_ue_message_p;
//
// uint8_t *buffer;
// uint32_t length;
//
// DevAssert(eNB_desc_p != NULL);
//
// memset(&message, 0, sizeof(s1ap_message));
//
// message.direction = S1AP_PDU_PR_initiatingMessage;
// message.procedureCode = ProcedureCode_id_initialUEMessage;
//
// initial_ue_message_p = &message.msg.initialUEMessageIEs;
//
// /* Select the MME corresponding to the provided GUMMEI.
// * If no MME corresponds to the GUMMEI, the function selects the MME with the
// * highest capacity.
// * In case eNB has no MME associated, the eNB should inform RRC and discard
// * this request.
// */
// if (nas_req_p.ue_identity.present == GUMMEI_PROVIDED) {
// mme_desc_p = s1ap_eNB_nnsf_select_mme_by_gummei(
// eNB_desc_p,
// nas_req_p.establishment_cause, nas_req_p.ue_identity.identity.gummei);
// } else {
// mme_desc_p = s1ap_eNB_nnsf_select_mme_by_mme_code(
// eNB_desc_p,
// nas_req_p.establishment_cause, nas_req_p.ue_identity.identity.s_tmsi.mme_code);
// }
// if (mme_desc_p == NULL) {
// S1AP_WARN("No MME is associated to the eNB\n");
// // TODO: Inform RRC
// return -1;
// }
//
// /* The eNB should allocate a unique eNB UE S1AP ID for this UE. The value
// * will be used for the duration of the connectivity.
// */
// if ((ue_desc_p = s1ap_eNB_allocate_new_UE_context()) == NULL) {
// return -1;
// }
//
// /* Keep a reference to the selected MME */
// ue_desc_p->mme_ref = mme_desc_p;
// ue_desc_p->rnti = nas_req_p.rnti;
//
// do {
// struct s1ap_eNB_ue_context_s *collision_p;
//
// /* Peek a random value for the eNB_ue_s1ap_id */
// ue_desc_p->eNB_ue_s1ap_id = (random() + random()) & 0x00ffffff;
// if ((collision_p = RB_INSERT(s1ap_ue_map, &eNB_desc_p->s1ap_ue_head, ue_desc_p))
// == NULL) {
// /* Break the loop as the id is not already used by another UE */
// break;
// }
// } while(1);
//
// initial_ue_message_p->eNB_UE_S1AP_ID = ue_desc_p->eNB_ue_s1ap_id;
// /* Prepare the NAS PDU */
// initial_ue_message_p->nas_pdu.buf = nas_req_p.nas_pdu.buffer;
// initial_ue_message_p->nas_pdu.size = nas_req_p.nas_pdu.length;
//
// /* Set the establishment cause according to those provided by RRC */
// DevCheck(nas_req_p.establishment_cause <= RRC_CAUSE_MAX,
// nas_req_p.establishment_cause, 0, 0);
// initial_ue_message_p->rrC_Establishment_Cause = nas_req_p.establishment_cause;
//
// if (nas_req_p.ue_identity.present == S_TMSI_PROVIDED) {
// initial_ue_message_p->presenceMask |= INITIALUEMESSAGEIES_S_TMSI_PRESENT;
//
// MME_CODE_TO_OCTET_STRING(nas_req_p.ue_identity.identity.s_tmsi.mme_code,
// &initial_ue_message_p->s_tmsi.mMEC);
// M_TMSI_TO_OCTET_STRING(nas_req_p.ue_identity.identity.s_tmsi.m_tmsi,
// &initial_ue_message_p->s_tmsi.m_TMSI);
// } else {
// initial_ue_message_p->presenceMask |= INITIALUEMESSAGEIES_GUMMEI_ID_PRESENT;
//
// MCC_MNC_TO_PLMNID(nas_req_p.ue_identity.identity.gummei.mcc,
// nas_req_p.ue_identity.identity.gummei.mnc,
// &initial_ue_message_p->gummei_id.pLMN_Identity);
// MME_GID_TO_OCTET_STRING(nas_req_p.ue_identity.identity.gummei.mme_group_id,
// &initial_ue_message_p->gummei_id.mME_Group_ID);
// MME_CODE_TO_OCTET_STRING(nas_req_p.ue_identity.identity.gummei.mme_code,
// &initial_ue_message_p->gummei_id.mME_Code);
// }
//
// /* Assuming TAI is the TAI from the cell */
// INT16_TO_OCTET_STRING(eNB_desc_p->tac, &initial_ue_message_p->tai.tAC);
// MCC_MNC_TO_PLMNID(eNB_desc_p->mcc, eNB_desc_p->mnc,
// &initial_ue_message_p->tai.pLMNidentity);
//
// /* Set the EUTRAN CGI
// * The cell identity is defined on 28 bits but as we use macro enb id,
// * we have to pad.
// */
// MACRO_ENB_ID_TO_CELL_IDENTITY(eNB_desc_p->eNB_id,
// &initial_ue_message_p->eutran_cgi.cell_ID);
// MCC_MNC_TO_TBCD(eNB_desc_p->mcc, eNB_desc_p->mnc,
// &initial_ue_message_p->eutran_cgi.pLMNidentity);
//
// if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
// /* Failed to encode message */
// return -1;
// }
//
// /* Update the current S1AP UE state */
// ue_desc_p->ue_state = S1AP_UE_WAITING_CSR;
//
// /* Send encoded message over sctp */
// return sctp_send_msg(&mme_desc_p->sctp_data, S1AP_SCTP_PPID, 1, buffer, length);
// }
......@@ -82,46 +82,6 @@ typedef enum {
S1AP_OVERLOAD_MAX,
} s1ap_overload_state_t;
// typedef enum {
// PAGING_DRX_32 = 0x0,
// PAGING_DRX_64 = 0x1,
// PAGING_DRX_128 = 0x2,
// PAGING_DRX_256 = 0x3,
// } paging_drx_t;
typedef struct {
/* Octet string data */
uint8_t *buffer;
/* Length of the octet string */
uint32_t length;
} nas_pdu_t, ue_radio_cap_t;
typedef struct {
uint16_t mcc;
uint16_t mnc;
uint8_t mme_code;
uint16_t mme_group_id;
} gummei_t;
typedef struct {
uint8_t mme_code;
uint32_t m_tmsi;
} s_tmsi_t;
/* Provides the establishment cause for the RRC connection request as provided
* by the upper layers. W.r.t. the cause value names: highPriorityAccess
* concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for
* 'Mobile Originating'. Defined in TS 36.331.
*/
typedef enum {
RRC_CAUSE_EMERGENCY = 0x0,
RRC_CAUSE_HIGH_PRIO_ACCESS = 0x1,
RRC_CAUSE_MT_ACCESS = 0x2,
RRC_CAUSE_MO_SIGNALLING = 0x3,
RRC_CAUSE_MO_DATA = 0x4,
RRC_CAUSE_MAX = RRC_CAUSE_MO_DATA,
} rrc_establishment_cause_t;
typedef struct {
uint8_t qci;
......@@ -166,16 +126,6 @@ typedef struct {
// cause_t cause;
} e_rab_failed_t;
typedef struct {
#define S_TMSI_PROVIDED 0x0
#define GUMMEI_PROVIDED 0x1
unsigned present:1;
union {
gummei_t gummei;
s_tmsi_t s_tmsi;
} identity;
} ue_identity_t;
/* Served PLMN identity element */
struct plmn_identity_s {
uint16_t mcc;
......
......@@ -58,6 +58,7 @@ static
int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
uint32_t stream,
struct s1ap_message_s *message_p);
static
int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
uint32_t stream,
struct s1ap_message_s *message_p);
......@@ -164,6 +165,7 @@ int s1ap_eNB_handle_message(uint32_t assoc_id, int32_t stream,
(assoc_id, stream, &message);
}
static
int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
uint32_t stream,
struct s1ap_message_s *message_p)
......@@ -173,14 +175,11 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_WARN("[SCTP %d] Received s1 setup failure on stream != 0 (%d)\n",
assoc_id, stream);
}
S1AP_DEBUG("Received s1 setup failure for MME... please check your parameters\n");
S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
return 0;
}
// int s1ap_eNB_handle_s1_setup_response(eNB_mme_desc_t *eNB_desc_p,
// sctp_queue_item_t *packet_p,
// struct s1ap_message_s *message_p)
static
int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
uint32_t stream,
......@@ -277,71 +276,62 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
*/
mme_desc_p->state = S1AP_ENB_STATE_CONNECTED;
// /* We call back our self
// * -> generate a dummy initial UE message
// */
// {
// extern int s1ap_eNB_handle_api_req(eNB_mme_desc_t *eNB_desc_p,
// s1ap_rrc_api_req_t *api_req_p);
// s1ap_rrc_api_req_t api_req;
// s1ap_nas_first_req_t *nas_req_p;
//
// memset(&api_req, 0, sizeof(s1ap_rrc_api_req_t));
//
// nas_req_p = &api_req.msg.first_nas_req;
// api_req.api_req = S1AP_API_NAS_FIRST_REQ;
//
// nas_req_p->rnti = 0xC03A;
// nas_req_p->establishment_cause = RRC_CAUSE_MO_DATA;
// nas_req_p->ue_identity.present = GUMMEI_PROVIDED;
//
// nas_req_p->ue_identity.identity.gummei.mcc = 208;
// nas_req_p->ue_identity.identity.gummei.mnc = 34;
// nas_req_p->ue_identity.identity.gummei.mme_code = 0;
// nas_req_p->ue_identity.identity.gummei.mme_group_id = 0;
//
// /* NAS Attach request with IMSI */
// uint8_t nas_attach_req_imsi[] =
// {
// 0x07, 0x41,
// /* EPS Mobile identity = IMSI */
// 0x71, 0x08, 0x29, 0x80, 0x43, 0x21, 0x43, 0x65, 0x87,
// 0xF9,
// /* End of EPS Mobile Identity */
// 0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03,
// 0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
// 0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2,
// 0x01, 0x27, 0x11,
// };
//
// /* NAS Attach request with GUTI */
// uint8_t nas_attach_req_guti[] =
// {
// 0x07, 0x41,
// /* EPS Mobile identity = IMSI */
// 0x71, 0x0B, 0xF6, 0x12, 0xF2, 0x01, 0x80, 0x00, 0x01, 0xE0, 0x00,
// 0xDA, 0x1F,
// /* End of EPS Mobile Identity */
// 0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03,
// 0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
// 0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2,
// 0x01, 0x27, 0x11,
// };
//
// nas_req_p->nas_pdu.buffer = nas_attach_req_guti;
// nas_req_p->nas_pdu.length = sizeof(nas_attach_req_guti);
//
// s1ap_eNB_handle_api_req(eNB_desc_p, &api_req);
// }
/* We call back our self
* -> generate a dummy initial UE message
*/
{
s1ap_nas_first_req_t s1ap_nas_first_req;
memset(&s1ap_nas_first_req, 0, sizeof(s1ap_nas_first_req_t));
s1ap_nas_first_req.rnti = 0xC03A;
s1ap_nas_first_req.establishment_cause = RRC_CAUSE_MO_DATA;
s1ap_nas_first_req.ue_identity.present = GUMMEI_PROVIDED;
s1ap_nas_first_req.ue_identity.identity.gummei.mcc = 208;
s1ap_nas_first_req.ue_identity.identity.gummei.mnc = 34;
s1ap_nas_first_req.ue_identity.identity.gummei.mme_code = 0;
s1ap_nas_first_req.ue_identity.identity.gummei.mme_group_id = 0;
/* NAS Attach request with IMSI */
uint8_t nas_attach_req_imsi[] =
{
0x07, 0x41,
/* EPS Mobile identity = IMSI */
0x71, 0x08, 0x29, 0x80, 0x43, 0x21, 0x43, 0x65, 0x87,
0xF9,
/* End of EPS Mobile Identity */
0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03,
0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2,
0x01, 0x27, 0x11,
};
/* NAS Attach request with GUTI */
uint8_t nas_attach_req_guti[] =
{
0x07, 0x41,
/* EPS Mobile identity = IMSI */
0x71, 0x0B, 0xF6, 0x12, 0xF2, 0x01, 0x80, 0x00, 0x01, 0xE0, 0x00,
0xDA, 0x1F,
/* End of EPS Mobile Identity */
0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03,
0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2,
0x01, 0x27, 0x11,
};
s1ap_nas_first_req.nas_pdu.buffer = nas_attach_req_guti;
s1ap_nas_first_req.nas_pdu.length = sizeof(nas_attach_req_guti);
s1ap_eNB_handle_nas_first_req(&s1ap_nas_first_req);
}
return 0;
}
// int s1ap_eNB_handle_initial_context_request(eNB_mme_desc_t *eNB_desc_p,
// sctp_queue_item_t *packet_p,
// struct s1ap_message_s *message_p)
static
int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
uint32_t stream,
......@@ -351,30 +341,28 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
s1ap_eNB_ue_context_t *ue_desc_p;
InitialContextSetupRequestIEs_t *initialContextSetupRequest_p;
// DevAssert(eNB_desc_p != NULL);
DevAssert(message_p != NULL);
initialContextSetupRequest_p = &message_p->msg.initialContextSetupRequestIEs;
/* Initial context request = UE-related procedure -> stream != 0 */
if (stream == 0) {
S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream = 0 (%d)\n",
assoc_id, stream);
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
"existing MME context\n", assoc_id);
return -1;
}
if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
initialContextSetupRequest_p->eNB_UE_S1AP_ID)) == NULL) {
S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
"existing UE context\n", assoc_id);
return -1;
}
// if ((mme_desc_p = s1ap_eNB_get_MME(eNB_desc_p, assoc_id)) == NULL) {
// S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
// "existing MME context\n", packet_p->assoc_id);
// return -1;
// }
// if ((ue_desc_p = s1ap_eNB_get_ue_context(eNB_desc_p,
// initialContextSetupRequest_p->eNB_UE_S1AP_ID)) == NULL) {
// S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
// "existing UE context\n", packet_p->assoc_id);
// return -1;
// }
/* Initial context request = UE-related procedure -> stream != 0 */
if (stream != ue_desc_p->stream) {
S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d) whereas expecting (%d)\n",
assoc_id, stream, ue_desc_p->stream);
return -1;
}
ue_desc_p->mme_ue_s1ap_id = initialContextSetupRequest_p->mme_ue_s1ap_id;
......
......@@ -19,3 +19,20 @@ void s1ap_eNB_itti_send_sctp_data_req(int32_t assoc_id, uint8_t *buffer,
itti_send_msg_to_task(TASK_SCTP, INSTANCE_DEFAULT, message_p);
}
void s1ap_eNB_itti_send_nas_downlink_ind(uint8_t mod_id, uint8_t *nas_pdu,
uint32_t nas_pdu_length)
{
MessageDef *message_p;
s1ap_downlink_nas_t *s1ap_downlink_nas;
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DOWNLINK_NAS);
s1ap_downlink_nas = &message_p->msg.s1ap_downlink_nas;
s1ap_downlink_nas->mod_id = mod_id;
s1ap_downlink_nas->nas_pdu.buffer = nas_pdu;
s1ap_downlink_nas->nas_pdu.length = nas_pdu_length;
itti_send_msg_to_task(TASK_RRC_ENB, INSTANCE_DEFAULT, message_p);
}
......@@ -4,4 +4,7 @@
void s1ap_eNB_itti_send_sctp_data_req(int32_t assoc_id, uint8_t *buffer,
uint32_t buffer_length, uint16_t stream);
void s1ap_eNB_itti_send_nas_downlink_ind(uint8_t mod_id, uint8_t *nas_pdu,
uint32_t nas_pdu_length);
#endif /* S1AP_ENB_ITTI_MESSAGING_H_ */
......@@ -35,17 +35,104 @@
#include "intertask_interface.h"
#include "assertions.h"
// #include "conversions.h"
#include "conversions.h"
#include "s1ap_common.h"
#include "s1ap_ies_defs.h"
#include "s1ap_eNB_defs.h"
#include "s1ap_eNB.h"
#include "s1ap_eNB_encoder.h"
#include "s1ap_eNB_management_procedures.h"
s1ap_eNB_internal_data_t s1ap_eNB_internal_data;
#include "sctp_primitives_client.h"
static int s1ap_eNB_generate_s1_setup_request(
s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p);
RB_GENERATE(s1ap_mme_map, s1ap_eNB_mme_data_s, entry, s1ap_eNB_compare_assoc_id);
inline int s1ap_eNB_compare_assoc_id(
struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2)
{
if (p1->assoc_id == -1) {
if (p1->cnx_id < p2->cnx_id) {
return -1;
}