Added a mechanism to wait for eNB MME link to be establish for all eNB before starting L2L1 task.
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4577 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
+42
-28
@@ -66,7 +66,7 @@ static int s1ap_eNB_generate_s1_setup_request(
|
|||||||
s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p);
|
s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p);
|
||||||
|
|
||||||
static
|
static
|
||||||
void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_eNB_t *s1ap_register_eNB);
|
void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB);
|
||||||
static
|
static
|
||||||
void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
|
void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
|
||||||
|
|
||||||
@@ -126,47 +126,56 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
|||||||
* but not yet associated.
|
* but not yet associated.
|
||||||
*/
|
*/
|
||||||
RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p);
|
RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p);
|
||||||
|
s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING;
|
||||||
|
instance_p->s1ap_mme_nb ++;
|
||||||
|
instance_p->s1ap_mme_pending_nb ++;
|
||||||
|
|
||||||
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
|
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_eNB_t *s1ap_register_eNB)
|
void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB)
|
||||||
{
|
{
|
||||||
s1ap_eNB_instance_t *new_instance;
|
s1ap_eNB_instance_t *new_instance;
|
||||||
uint8_t index;
|
uint8_t index;
|
||||||
|
|
||||||
DevAssert(s1ap_register_eNB != NULL);
|
DevAssert(s1ap_register_eNB != NULL);
|
||||||
|
|
||||||
/* Look if the provided instance already exists
|
/* Look if the provided instance already exists */
|
||||||
* If so notify user...
|
|
||||||
*/
|
|
||||||
new_instance = s1ap_eNB_get_instance(instance);
|
new_instance = s1ap_eNB_get_instance(instance);
|
||||||
DevAssert(new_instance == NULL);
|
if (new_instance != NULL) {
|
||||||
|
/* Checks if it is a retry on the same eNB */
|
||||||
|
DevCheck(new_instance->eNB_id == s1ap_register_eNB->eNB_id, new_instance->eNB_id, s1ap_register_eNB->eNB_id, 0);
|
||||||
|
DevCheck(new_instance->cell_type == s1ap_register_eNB->cell_type, new_instance->cell_type, s1ap_register_eNB->cell_type, 0);
|
||||||
|
DevCheck(new_instance->tac == s1ap_register_eNB->tac, new_instance->tac, s1ap_register_eNB->tac, 0);
|
||||||
|
DevCheck(new_instance->mcc == s1ap_register_eNB->mcc, new_instance->mcc, s1ap_register_eNB->mcc, 0);
|
||||||
|
DevCheck(new_instance->mnc == s1ap_register_eNB->mnc, new_instance->mnc, s1ap_register_eNB->mnc, 0);
|
||||||
|
DevCheck(new_instance->default_drx == s1ap_register_eNB->default_drx, new_instance->default_drx, s1ap_register_eNB->default_drx, 0);
|
||||||
|
} else {
|
||||||
|
new_instance = calloc(1, sizeof(s1ap_eNB_instance_t));
|
||||||
|
DevAssert(new_instance != NULL);
|
||||||
|
|
||||||
new_instance = calloc(1, sizeof(s1ap_eNB_instance_t));
|
RB_INIT(&new_instance->s1ap_ue_head);
|
||||||
DevAssert(new_instance != NULL);
|
RB_INIT(&new_instance->s1ap_mme_head);
|
||||||
|
|
||||||
RB_INIT(&new_instance->s1ap_ue_head);
|
/* Copy usefull parameters */
|
||||||
RB_INIT(&new_instance->s1ap_mme_head);
|
new_instance->instance = instance;
|
||||||
|
new_instance->eNB_name = s1ap_register_eNB->eNB_name;
|
||||||
|
new_instance->eNB_id = s1ap_register_eNB->eNB_id;
|
||||||
|
new_instance->cell_type = s1ap_register_eNB->cell_type;
|
||||||
|
new_instance->tac = s1ap_register_eNB->tac;
|
||||||
|
new_instance->mcc = s1ap_register_eNB->mcc;
|
||||||
|
new_instance->mnc = s1ap_register_eNB->mnc;
|
||||||
|
new_instance->default_drx = s1ap_register_eNB->default_drx;
|
||||||
|
|
||||||
/* Copy usefull parameters */
|
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
|
||||||
new_instance->instance = instance;
|
s1ap_eNB_insert_new_instance(new_instance);
|
||||||
new_instance->eNB_name = s1ap_register_eNB->eNB_name;
|
|
||||||
new_instance->eNB_id = s1ap_register_eNB->eNB_id;
|
|
||||||
new_instance->cell_type = s1ap_register_eNB->cell_type;
|
|
||||||
new_instance->tac = s1ap_register_eNB->tac;
|
|
||||||
new_instance->mcc = s1ap_register_eNB->mcc;
|
|
||||||
new_instance->mnc = s1ap_register_eNB->mnc;
|
|
||||||
new_instance->default_drx = s1ap_register_eNB->default_drx;
|
|
||||||
|
|
||||||
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
|
S1AP_DEBUG("Registered new eNB[%d] and %s eNB id %u\n",
|
||||||
s1ap_eNB_insert_new_instance(new_instance);
|
instance,
|
||||||
|
s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
|
||||||
S1AP_DEBUG("Registered new eNB[%d] and %s eNB id %u\n",
|
s1ap_register_eNB->eNB_id);
|
||||||
instance,
|
}
|
||||||
s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
|
|
||||||
s1ap_register_eNB->eNB_id);
|
|
||||||
|
|
||||||
DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS,
|
DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS,
|
||||||
S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0);
|
S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0);
|
||||||
@@ -198,6 +207,9 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
|
|||||||
sctp_new_association_resp->sctp_state,
|
sctp_new_association_resp->sctp_state,
|
||||||
instance,
|
instance,
|
||||||
sctp_new_association_resp->ulp_cnx_id);
|
sctp_new_association_resp->ulp_cnx_id);
|
||||||
|
|
||||||
|
s1ap_handle_s1_setup_message(s1ap_mme_data_p);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,14 +250,14 @@ void *s1ap_eNB_task(void *arg)
|
|||||||
case TERMINATE_MESSAGE:
|
case TERMINATE_MESSAGE:
|
||||||
itti_exit_task();
|
itti_exit_task();
|
||||||
break;
|
break;
|
||||||
case S1AP_REGISTER_ENB: {
|
case S1AP_REGISTER_ENB_REQ: {
|
||||||
/* Register a new eNB.
|
/* Register a new eNB.
|
||||||
* in Virtual mode eNBs will be distinguished using the mod_id/
|
* in Virtual mode eNBs will be distinguished using the mod_id/
|
||||||
* Each eNB has to send an S1AP_REGISTER_ENB message with its
|
* Each eNB has to send an S1AP_REGISTER_ENB message with its
|
||||||
* own parameters.
|
* own parameters.
|
||||||
*/
|
*/
|
||||||
s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||||
&received_msg->ittiMsg.s1ap_register_eNB);
|
&S1AP_REGISTER_ENB_REQ(received_msg));
|
||||||
} break;
|
} break;
|
||||||
case SCTP_NEW_ASSOCIATION_RESP: {
|
case SCTP_NEW_ASSOCIATION_RESP: {
|
||||||
s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||||
@@ -318,6 +330,8 @@ static int s1ap_eNB_generate_s1_setup_request(
|
|||||||
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc,
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc,
|
||||||
&s1SetupRequest_p->global_ENB_ID.pLMNidentity);
|
&s1SetupRequest_p->global_ENB_ID.pLMNidentity);
|
||||||
|
|
||||||
|
S1AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[0], s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[1], s1SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[2]);
|
||||||
|
|
||||||
INT16_TO_OCTET_STRING(instance_p->tac, &ta.tAC);
|
INT16_TO_OCTET_STRING(instance_p->tac, &ta.tAC);
|
||||||
MCC_MNC_TO_TBCD(instance_p->mcc, instance_p->mnc, &plmnIdentity);
|
MCC_MNC_TO_TBCD(instance_p->mcc, instance_p->mnc, &plmnIdentity);
|
||||||
|
|
||||||
|
|||||||
@@ -172,6 +172,12 @@ typedef struct s1ap_eNB_instance_s {
|
|||||||
*/
|
*/
|
||||||
STAILQ_ENTRY(s1ap_eNB_instance_s) s1ap_eNB_entries;
|
STAILQ_ENTRY(s1ap_eNB_instance_s) s1ap_eNB_entries;
|
||||||
|
|
||||||
|
/* Number of MME requested by eNB (tree size) */
|
||||||
|
uint32_t s1ap_mme_nb;
|
||||||
|
/* Number of MME for which association is pending */
|
||||||
|
uint32_t s1ap_mme_pending_nb;
|
||||||
|
/* Number of MME successfully associated to eNB */
|
||||||
|
uint32_t s1ap_mme_associated_nb;
|
||||||
/* Tree of S1AP MME associations ordered by association ID */
|
/* Tree of S1AP MME associations ordered by association ID */
|
||||||
RB_HEAD(s1ap_mme_map, s1ap_eNB_mme_data_s) s1ap_mme_head;
|
RB_HEAD(s1ap_mme_map, s1ap_eNB_mme_data_s) s1ap_mme_head;
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
|
|
||||||
#include "s1ap_eNB_default_values.h"
|
#include "s1ap_eNB_default_values.h"
|
||||||
|
|
||||||
|
#include "assertions.h"
|
||||||
#include "conversions.h"
|
#include "conversions.h"
|
||||||
|
|
||||||
static
|
static
|
||||||
@@ -132,6 +133,24 @@ static const char *direction2String[] = {
|
|||||||
"UnSuccessfull outcome", /* successfull outcome */
|
"UnSuccessfull outcome", /* successfull outcome */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p) {
|
||||||
|
/* Check that at least one setup message is pending */
|
||||||
|
DevCheck(mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0, mme_desc_p->s1ap_eNB_instance->instance,
|
||||||
|
mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb, 0);
|
||||||
|
/* Decrease pending messages number */
|
||||||
|
mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb --;
|
||||||
|
|
||||||
|
/* If there are no more pending messages, inform eNB app */
|
||||||
|
if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0)
|
||||||
|
{
|
||||||
|
MessageDef *message_p;
|
||||||
|
|
||||||
|
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_REGISTER_ENB_CNF);
|
||||||
|
S1AP_REGISTER_ENB_CNF(message_p).nb_mme = mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb;
|
||||||
|
itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int s1ap_eNB_handle_message(uint32_t assoc_id, int32_t stream,
|
int s1ap_eNB_handle_message(uint32_t assoc_id, int32_t stream,
|
||||||
const uint8_t * const data, const uint32_t data_length)
|
const uint8_t * const data, const uint32_t data_length)
|
||||||
{
|
{
|
||||||
@@ -173,13 +192,25 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
|
|||||||
uint32_t stream,
|
uint32_t stream,
|
||||||
struct s1ap_message_s *message_p)
|
struct s1ap_message_s *message_p)
|
||||||
{
|
{
|
||||||
|
s1ap_eNB_mme_data_t *mme_desc_p;
|
||||||
|
|
||||||
/* S1 Setup Failure == Non UE-related procedure -> stream 0 */
|
/* S1 Setup Failure == Non UE-related procedure -> stream 0 */
|
||||||
if (stream != 0) {
|
if (stream != 0) {
|
||||||
S1AP_WARN("[SCTP %d] Received s1 setup failure on stream != 0 (%d)\n",
|
S1AP_WARN("[SCTP %d] Received s1 setup failure on stream != 0 (%d)\n",
|
||||||
assoc_id, stream);
|
assoc_id, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||||
|
S1AP_ERROR("[SCTP %d] Received S1 setup response for non existing "
|
||||||
|
"MME context\n", assoc_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
|
S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
|
||||||
|
|
||||||
|
mme_desc_p->state = S1AP_ENB_STATE_WAITING;
|
||||||
|
s1ap_handle_s1_setup_message(mme_desc_p);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,6 +309,8 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
|
|||||||
* Mark the association as UP to enable UE contexts creation.
|
* Mark the association as UP to enable UE contexts creation.
|
||||||
*/
|
*/
|
||||||
mme_desc_p->state = S1AP_ENB_STATE_CONNECTED;
|
mme_desc_p->state = S1AP_ENB_STATE_CONNECTED;
|
||||||
|
mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++;
|
||||||
|
s1ap_handle_s1_setup_message(mme_desc_p);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* We call back our self
|
/* We call back our self
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
#ifndef S1AP_ENB_HANDLERS_H_
|
#ifndef S1AP_ENB_HANDLERS_H_
|
||||||
#define S1AP_ENB_HANDLERS_H_
|
#define S1AP_ENB_HANDLERS_H_
|
||||||
|
|
||||||
|
void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p);
|
||||||
|
|
||||||
int s1ap_eNB_handle_message(uint32_t assoc_id, int32_t stream,
|
int s1ap_eNB_handle_message(uint32_t assoc_id, int32_t stream,
|
||||||
const uint8_t * const data, const uint32_t data_length);
|
const uint8_t * const data, const uint32_t data_length);
|
||||||
|
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ void sctp_handle_new_association_req(
|
|||||||
close(sd);
|
close(sd);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
SCTP_DEBUG("connectx in progress...\n");
|
SCTP_DEBUG("connectx %d in progress...\n", assoc_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -270,6 +270,7 @@ void sctp_handle_new_association_req(
|
|||||||
sctp_cnx->cnx_id = sctp_new_association_req_p->ulp_cnx_id;
|
sctp_cnx->cnx_id = sctp_new_association_req_p->ulp_cnx_id;
|
||||||
sctp_cnx->ppid = sctp_new_association_req_p->ppid;
|
sctp_cnx->ppid = sctp_new_association_req_p->ppid;
|
||||||
sctp_cnx->instance = instance;
|
sctp_cnx->instance = instance;
|
||||||
|
sctp_cnx->assoc_id = assoc_id;
|
||||||
|
|
||||||
/* Insert new element at end of list */
|
/* Insert new element at end of list */
|
||||||
STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries);
|
STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries);
|
||||||
@@ -412,6 +413,7 @@ inline void sctp_eNB_read_from_socket(struct sctp_cnx_list_elm_s *sctp_cnx)
|
|||||||
sctp_cnx->cnx_id, SCTP_STATE_UNREACHABLE, 0, 0);
|
sctp_cnx->cnx_id, SCTP_STATE_UNREACHABLE, 0, 0);
|
||||||
|
|
||||||
close(sctp_cnx->sd);
|
close(sctp_cnx->sd);
|
||||||
|
STAILQ_REMOVE(&sctp_cnx_list, sctp_cnx, sctp_cnx_list_elm_s, entries);
|
||||||
sctp_nb_cnx--;
|
sctp_nb_cnx--;
|
||||||
free(sctp_cnx);
|
free(sctp_cnx);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
/* eNB application layer -> S1AP messages */
|
/* eNB application layer -> S1AP messages */
|
||||||
MESSAGE_DEF(S1AP_REGISTER_ENB , MESSAGE_PRIORITY_MED, s1ap_register_eNB_t , s1ap_register_eNB )
|
MESSAGE_DEF(S1AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, s1ap_register_enb_req_t , s1ap_register_enb_req)
|
||||||
|
|
||||||
|
/* S1AP -> eNB application layer messages */
|
||||||
|
MESSAGE_DEF(S1AP_REGISTER_ENB_CNF , MESSAGE_PRIORITY_MED, s1ap_register_enb_cnf_t , s1ap_register_enb_cnf)
|
||||||
|
|
||||||
/* RRC -> S1AP messages */
|
/* RRC -> S1AP messages */
|
||||||
MESSAGE_DEF(S1AP_NAS_FIRST_REQ , MESSAGE_PRIORITY_MED, s1ap_nas_first_req_t , s1ap_nas_first_req)
|
MESSAGE_DEF(S1AP_NAS_FIRST_REQ , MESSAGE_PRIORITY_MED, s1ap_nas_first_req_t , s1ap_nas_first_req)
|
||||||
MESSAGE_DEF(S1AP_UPLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_uplink_nas_t , s1ap_uplink_nas )
|
MESSAGE_DEF(S1AP_UPLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_uplink_nas_t , s1ap_uplink_nas)
|
||||||
MESSAGE_DEF(S1AP_UE_CAPABILITIES_IND , MESSAGE_PRIORITY_MED, s1ap_ue_cap_info_ind_t , s1ap_ue_cap_info_ind)
|
MESSAGE_DEF(S1AP_UE_CAPABILITIES_IND , MESSAGE_PRIORITY_MED, s1ap_ue_cap_info_ind_t , s1ap_ue_cap_info_ind)
|
||||||
MESSAGE_DEF(S1AP_INITIAL_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, s1ap_initial_context_setup_resp_t, s1ap_initial_context_setup_resp)
|
MESSAGE_DEF(S1AP_INITIAL_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, s1ap_initial_context_setup_resp_t, s1ap_initial_context_setup_resp)
|
||||||
MESSAGE_DEF(S1AP_INITIAL_CONTEXT_SETUP_FAIL, MESSAGE_PRIORITY_MED, s1ap_initial_context_setup_fail_t, s1ap_initial_context_setup_fail)
|
MESSAGE_DEF(S1AP_INITIAL_CONTEXT_SETUP_FAIL, MESSAGE_PRIORITY_MED, s1ap_initial_context_setup_fail_t, s1ap_initial_context_setup_fail)
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
//-------------------------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------------------------//
|
||||||
// Defines to access message fields.
|
// Defines to access message fields.
|
||||||
|
|
||||||
|
#define S1AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_register_enb_req
|
||||||
|
|
||||||
|
#define S1AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.s1ap_register_enb_cnf
|
||||||
|
|
||||||
#define S1AP_NAS_FIRST_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_nas_first_req
|
#define S1AP_NAS_FIRST_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_nas_first_req
|
||||||
#define S1AP_UPLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_uplink_nas
|
#define S1AP_UPLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_uplink_nas
|
||||||
#define S1AP_UE_CAPABILITIES_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_cap_info_ind
|
#define S1AP_UE_CAPABILITIES_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_cap_info_ind
|
||||||
@@ -22,6 +26,24 @@
|
|||||||
#define S1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_req
|
#define S1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_req
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------------------------//
|
||||||
|
/* Maximum number of e-rabs to be setup/deleted in a single message.
|
||||||
|
* Even if only one bearer will be modified by message.
|
||||||
|
*/
|
||||||
|
#define S1AP_MAX_E_RAB 11
|
||||||
|
|
||||||
|
/* Length of the transport layer address string
|
||||||
|
* 160 bits / 8 bits by char.
|
||||||
|
*/
|
||||||
|
#define S1AP_TRANSPORT_LAYER_ADDRESS_SIZE (160 / 8)
|
||||||
|
|
||||||
|
#define S1AP_MAX_NB_MME_IP_ADDRESS 10
|
||||||
|
#define S1AP_IMSI_LENGTH 16
|
||||||
|
|
||||||
|
/* Security key length used within eNB
|
||||||
|
* Even if only 16 bytes will be effectively used,
|
||||||
|
* the key length is 32 bytes (256 bits)
|
||||||
|
*/
|
||||||
|
#define SECURITY_KEY_LENGTH 32
|
||||||
|
|
||||||
typedef enum cell_type_e {
|
typedef enum cell_type_e {
|
||||||
CELL_MACRO_ENB,
|
CELL_MACRO_ENB,
|
||||||
@@ -63,7 +85,7 @@ typedef struct net_ip_address_s {
|
|||||||
|
|
||||||
typedef uint64_t bitrate_t;
|
typedef uint64_t bitrate_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct ambr_s {
|
||||||
bitrate_t br_ul;
|
bitrate_t br_ul;
|
||||||
bitrate_t br_dl;
|
bitrate_t br_dl;
|
||||||
} ambr_t;
|
} ambr_t;
|
||||||
@@ -75,19 +97,19 @@ typedef enum priority_level_s {
|
|||||||
PRIORITY_LEVEL_NO_PRIORITY = 15
|
PRIORITY_LEVEL_NO_PRIORITY = 15
|
||||||
} priority_level_t;
|
} priority_level_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum pre_emp_capability_e {
|
||||||
PRE_EMPTION_CAPABILITY_ENABLED = 0,
|
PRE_EMPTION_CAPABILITY_ENABLED = 0,
|
||||||
PRE_EMPTION_CAPABILITY_DISABLED = 1,
|
PRE_EMPTION_CAPABILITY_DISABLED = 1,
|
||||||
PRE_EMPTION_CAPABILITY_MAX,
|
PRE_EMPTION_CAPABILITY_MAX,
|
||||||
} pre_emp_capability_t;
|
} pre_emp_capability_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum pre_emp_vulnerability_e {
|
||||||
PRE_EMPTION_VULNERABILITY_ENABLED = 0,
|
PRE_EMPTION_VULNERABILITY_ENABLED = 0,
|
||||||
PRE_EMPTION_VULNERABILITY_DISABLED = 1,
|
PRE_EMPTION_VULNERABILITY_DISABLED = 1,
|
||||||
PRE_EMPTION_VULNERABILITY_MAX,
|
PRE_EMPTION_VULNERABILITY_MAX,
|
||||||
} pre_emp_vulnerability_t;
|
} pre_emp_vulnerability_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct allocation_retention_priority_s {
|
||||||
priority_level_t priority_level;
|
priority_level_t priority_level;
|
||||||
pre_emp_capability_t pre_emp_capability;
|
pre_emp_capability_t pre_emp_capability;
|
||||||
pre_emp_vulnerability_t pre_emp_vulnerability;
|
pre_emp_vulnerability_t pre_emp_vulnerability;
|
||||||
@@ -98,25 +120,6 @@ typedef struct security_capabilities_s {
|
|||||||
uint16_t integrity_algorithms;
|
uint16_t integrity_algorithms;
|
||||||
} security_capabilities_t;
|
} security_capabilities_t;
|
||||||
|
|
||||||
/* Maximum number of e-rabs to be setup/deleted in a single message.
|
|
||||||
* Even if only one bearer will be modified by message.
|
|
||||||
*/
|
|
||||||
#define S1AP_MAX_E_RAB 11
|
|
||||||
|
|
||||||
/* Length of the transport layer address string
|
|
||||||
* 160 bits / 8 bits by char.
|
|
||||||
*/
|
|
||||||
#define S1AP_TRANSPORT_LAYER_ADDRESS_SIZE (160 / 8)
|
|
||||||
|
|
||||||
#define S1AP_MAX_NB_MME_IP_ADDRESS 10
|
|
||||||
#define S1AP_IMSI_LENGTH 16
|
|
||||||
|
|
||||||
/* Security key length used within eNB
|
|
||||||
* Even if only 16 bytes will be effectively used,
|
|
||||||
* the key length is 32 bytes (256 bits)
|
|
||||||
*/
|
|
||||||
#define SECURITY_KEY_LENGTH 32
|
|
||||||
|
|
||||||
/* Provides the establishment cause for the RRC connection request as provided
|
/* Provides the establishment cause for the RRC connection request as provided
|
||||||
* by the upper layers. W.r.t. the cause value names: highPriorityAccess
|
* by the upper layers. W.r.t. the cause value names: highPriorityAccess
|
||||||
* concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for
|
* concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for
|
||||||
@@ -226,7 +229,20 @@ typedef struct e_rab_failed_s {
|
|||||||
// cause_t cause;
|
// cause_t cause;
|
||||||
} e_rab_failed_t;
|
} e_rab_failed_t;
|
||||||
|
|
||||||
typedef struct s1ap_register_eNB_s {
|
typedef enum s1ap_ue_ctxt_modification_present_s {
|
||||||
|
S1AP_UE_CONTEXT_MODIFICATION_SECURITY_KEY = (1 << 0),
|
||||||
|
S1AP_UE_CONTEXT_MODIFICATION_UE_AMBR = (1 << 1),
|
||||||
|
S1AP_UE_CONTEXT_MODIFICATION_UE_SECU_CAP = (1 << 2),
|
||||||
|
} s1ap_ue_ctxt_modification_present_t;
|
||||||
|
|
||||||
|
typedef enum s1ap_paging_ind_present_s {
|
||||||
|
S1AP_PAGING_IND_PAGING_DRX = (1 << 0),
|
||||||
|
S1AP_PAGING_IND_PAGING_PRIORITY = (1 << 1),
|
||||||
|
} s1ap_paging_ind_present_t;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------//
|
||||||
|
// eNB application layer -> S1AP messages
|
||||||
|
typedef struct s1ap_register_enb_req_s {
|
||||||
/* Unique eNB_id to identify the eNB within EPC.
|
/* Unique eNB_id to identify the eNB within EPC.
|
||||||
* For macro eNB ids this field should be 20 bits long.
|
* For macro eNB ids this field should be 20 bits long.
|
||||||
* For home eNB ids this field should be 28 bits long.
|
* For home eNB ids this field should be 28 bits long.
|
||||||
@@ -260,7 +276,18 @@ typedef struct s1ap_register_eNB_s {
|
|||||||
uint8_t nb_mme;
|
uint8_t nb_mme;
|
||||||
/* List of MME to connect to */
|
/* List of MME to connect to */
|
||||||
net_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS];
|
net_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS];
|
||||||
} s1ap_register_eNB_t;
|
} s1ap_register_enb_req_t;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------//
|
||||||
|
// S1AP -> eNB application layer messages
|
||||||
|
typedef struct s1ap_register_enb_cnf_s {
|
||||||
|
/* Nb of MME connected */
|
||||||
|
uint8_t nb_mme;
|
||||||
|
|
||||||
|
} s1ap_register_enb_cnf_t;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------//
|
||||||
|
// RRC -> S1AP messages
|
||||||
|
|
||||||
/* The NAS First Req is the first message exchanged between RRC and S1AP
|
/* The NAS First Req is the first message exchanged between RRC and S1AP
|
||||||
* for an UE.
|
* for an UE.
|
||||||
@@ -291,6 +318,61 @@ typedef struct s1ap_uplink_nas_s {
|
|||||||
nas_pdu_t nas_pdu;
|
nas_pdu_t nas_pdu;
|
||||||
} s1ap_uplink_nas_t;
|
} s1ap_uplink_nas_t;
|
||||||
|
|
||||||
|
typedef struct s1ap_ue_cap_info_ind_s {
|
||||||
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
|
ue_radio_cap_t ue_radio_cap;
|
||||||
|
} s1ap_ue_cap_info_ind_t;
|
||||||
|
|
||||||
|
typedef struct s1ap_initial_context_setup_resp_s {
|
||||||
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
|
|
||||||
|
/* Number of e_rab setup-ed in the list */
|
||||||
|
uint8_t nb_of_e_rabs;
|
||||||
|
/* list of e_rab setup-ed by RRC layers */
|
||||||
|
e_rab_setup_t e_rabs[S1AP_MAX_E_RAB];
|
||||||
|
|
||||||
|
/* Number of e_rab failed to be setup in list */
|
||||||
|
uint8_t nb_of_e_rabs_failed;
|
||||||
|
/* list of e_rabs that failed to be setup */
|
||||||
|
e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
|
||||||
|
} s1ap_initial_context_setup_resp_t;
|
||||||
|
|
||||||
|
typedef struct s1ap_initial_context_setup_fail_s {
|
||||||
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
|
|
||||||
|
/* TODO add cause */
|
||||||
|
} s1ap_initial_context_setup_fail_t, s1ap_ue_ctxt_modification_fail_t;
|
||||||
|
|
||||||
|
typedef struct s1ap_nas_non_delivery_ind_s {
|
||||||
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
|
nas_pdu_t nas_pdu;
|
||||||
|
/* TODO: add cause */
|
||||||
|
} s1ap_nas_non_delivery_ind_t;
|
||||||
|
|
||||||
|
typedef struct s1ap_ue_ctxt_modification_req_s {
|
||||||
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
|
|
||||||
|
/* Bit-mask of possible present parameters */
|
||||||
|
s1ap_ue_ctxt_modification_present_t present;
|
||||||
|
|
||||||
|
/* Following fields are optionnaly present */
|
||||||
|
|
||||||
|
/* Security key */
|
||||||
|
uint8_t security_key[SECURITY_KEY_LENGTH];
|
||||||
|
|
||||||
|
/* UE aggregate maximum bitrate */
|
||||||
|
ambr_t ue_ambr;
|
||||||
|
|
||||||
|
/* Security capabilities */
|
||||||
|
security_capabilities_t security_capabilities;
|
||||||
|
} s1ap_ue_ctxt_modification_req_t;
|
||||||
|
|
||||||
|
typedef struct s1ap_ue_ctxt_modification_resp_s {
|
||||||
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
|
} s1ap_ue_ctxt_modification_resp_t;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------//
|
||||||
|
// S1AP -> RRC messages
|
||||||
typedef struct s1ap_downlink_nas_s {
|
typedef struct s1ap_downlink_nas_s {
|
||||||
/* UE id for initial connection to S1AP */
|
/* UE id for initial connection to S1AP */
|
||||||
uint16_t ue_initial_id;
|
uint16_t ue_initial_id;
|
||||||
@@ -324,69 +406,6 @@ typedef struct s1ap_initial_context_setup_req_s {
|
|||||||
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
|
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
|
||||||
} s1ap_initial_context_setup_req_t;
|
} s1ap_initial_context_setup_req_t;
|
||||||
|
|
||||||
typedef struct s1ap_initial_context_setup_resp_s {
|
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
|
||||||
|
|
||||||
/* Number of e_rab setup-ed in the list */
|
|
||||||
uint8_t nb_of_e_rabs;
|
|
||||||
/* list of e_rab setup-ed by RRC layers */
|
|
||||||
e_rab_setup_t e_rabs[S1AP_MAX_E_RAB];
|
|
||||||
|
|
||||||
/* Number of e_rab failed to be setup in list */
|
|
||||||
uint8_t nb_of_e_rabs_failed;
|
|
||||||
/* list of e_rabs that failed to be setup */
|
|
||||||
e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
|
|
||||||
} s1ap_initial_context_setup_resp_t;
|
|
||||||
|
|
||||||
typedef struct s1ap_initial_context_setup_fail_s {
|
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
|
||||||
|
|
||||||
/* TODO add cause */
|
|
||||||
} s1ap_initial_context_setup_fail_t, s1ap_ue_ctxt_modification_fail_t;
|
|
||||||
|
|
||||||
typedef struct s1ap_ue_cap_info_ind_s {
|
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
|
||||||
ue_radio_cap_t ue_radio_cap;
|
|
||||||
} s1ap_ue_cap_info_ind_t;
|
|
||||||
|
|
||||||
typedef struct s1ap_ue_release_req_s {
|
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
|
||||||
/* TODO: add cause */
|
|
||||||
} s1ap_ue_release_req_t, s1ap_ue_release_resp_t;
|
|
||||||
|
|
||||||
typedef enum s1ap_ue_ctxt_modification_present_s {
|
|
||||||
S1AP_UE_CONTEXT_MODIFICATION_SECURITY_KEY = (1 << 0),
|
|
||||||
S1AP_UE_CONTEXT_MODIFICATION_UE_AMBR = (1 << 1),
|
|
||||||
S1AP_UE_CONTEXT_MODIFICATION_UE_SECU_CAP = (1 << 2),
|
|
||||||
} s1ap_ue_ctxt_modification_present_t;
|
|
||||||
|
|
||||||
typedef struct s1ap_ue_ctxt_modification_req_s {
|
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
|
||||||
|
|
||||||
/* Bit-mask of possible present parameters */
|
|
||||||
s1ap_ue_ctxt_modification_present_t present;
|
|
||||||
|
|
||||||
/* Following fields are optionnaly present */
|
|
||||||
|
|
||||||
/* Security key */
|
|
||||||
uint8_t security_key[SECURITY_KEY_LENGTH];
|
|
||||||
|
|
||||||
/* UE aggregate maximum bitrate */
|
|
||||||
ambr_t ue_ambr;
|
|
||||||
|
|
||||||
/* Security capabilities */
|
|
||||||
security_capabilities_t security_capabilities;
|
|
||||||
} s1ap_ue_ctxt_modification_req_t;
|
|
||||||
|
|
||||||
typedef struct s1ap_ue_ctxt_modification_resp_s {
|
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
|
||||||
} s1ap_ue_ctxt_modification_resp_t;
|
|
||||||
|
|
||||||
typedef enum s1ap_paging_ind_present_s {
|
|
||||||
S1AP_PAGING_IND_PAGING_DRX = (1 << 0),
|
|
||||||
S1AP_PAGING_IND_PAGING_PRIORITY = (1 << 1),
|
|
||||||
} s1ap_paging_ind_present_t;
|
|
||||||
|
|
||||||
typedef struct s1ap_paging_ind_s {
|
typedef struct s1ap_paging_ind_s {
|
||||||
/* UE identity index value.
|
/* UE identity index value.
|
||||||
* Specified in 3GPP TS 36.304
|
* Specified in 3GPP TS 36.304
|
||||||
@@ -405,10 +424,11 @@ typedef struct s1ap_paging_ind_s {
|
|||||||
paging_priority_t paging_priority;
|
paging_priority_t paging_priority;
|
||||||
} s1ap_paging_ind_t;
|
} s1ap_paging_ind_t;
|
||||||
|
|
||||||
typedef struct s1ap_nas_non_delivery_ind_s {
|
//-------------------------------------------------------------------------------------------//
|
||||||
|
// S1AP <-> RRC messages
|
||||||
|
typedef struct s1ap_ue_release_req_s {
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
nas_pdu_t nas_pdu;
|
|
||||||
/* TODO: add cause */
|
/* TODO: add cause */
|
||||||
} s1ap_nas_non_delivery_ind_t;
|
} s1ap_ue_release_req_t, s1ap_ue_release_resp_t;
|
||||||
|
|
||||||
#endif /* S1AP_MESSAGES_TYPES_H_ */
|
#endif /* S1AP_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
+159
-74
@@ -69,6 +69,7 @@ char smbv_ip[16];
|
|||||||
|
|
||||||
#include "UTIL/LOG/vcd_signal_dumper.h"
|
#include "UTIL/LOG/vcd_signal_dumper.h"
|
||||||
#include "UTIL/OTG/otg_kpi.h"
|
#include "UTIL/OTG/otg_kpi.h"
|
||||||
|
#include "assertions.h"
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
#if defined(ENABLE_ITTI)
|
||||||
# include "intertask_interface_init.h"
|
# include "intertask_interface_init.h"
|
||||||
@@ -372,9 +373,8 @@ static s32 UE_id = 0, eNB_id = 0;
|
|||||||
static s32 RN_id=0;
|
static s32 RN_id=0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int itti_create_task_successful(void){
|
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
#if defined(ENABLE_ITTI)
|
||||||
|
int itti_create_task_successful(void){
|
||||||
# if defined(ENABLE_USE_MME)
|
# if defined(ENABLE_USE_MME)
|
||||||
if (itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0) {
|
if (itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0) {
|
||||||
LOG_E(EMU, "Create task failed");
|
LOG_E(EMU, "Create task failed");
|
||||||
@@ -388,103 +388,180 @@ int itti_create_task_successful(void){
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (itti_create_task(TASK_ENB_APP, eNB_app_task, NULL) < 0) {
|
|
||||||
LOG_E(EMU, "Create task failed");
|
|
||||||
LOG_D(EMU, "Initializing eNB APP task interface: FAILED\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itti_create_task(TASK_L2L1, l2l1_task, NULL) < 0) {
|
if (itti_create_task(TASK_L2L1, l2l1_task, NULL) < 0) {
|
||||||
LOG_E(EMU, "Create task failed");
|
LOG_E(EMU, "Create task failed");
|
||||||
LOG_D(EMU, "Initializing L2L1 task interface: FAILED\n");
|
LOG_D(EMU, "Initializing L2L1 task interface: FAILED\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
/* Last task to create, others task must be ready before its start */
|
||||||
|
if (itti_create_task(TASK_ENB_APP, eNB_app_task, NULL) < 0) {
|
||||||
|
LOG_E(EMU, "Create task failed");
|
||||||
|
LOG_D(EMU, "Initializing eNB APP task interface: FAILED\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* later, the enb task will be moved from here
|
|
||||||
*/
|
|
||||||
void *eNB_app_task(void *args_p) {
|
|
||||||
#if defined(ENABLE_ITTI)
|
#if defined(ENABLE_ITTI)
|
||||||
MessageDef *message_p;
|
/*
|
||||||
|
* later, the eNB task will be moved from here
|
||||||
|
*/
|
||||||
|
|
||||||
# if defined(ENABLE_USE_MME)
|
# if defined(ENABLE_USE_MME)
|
||||||
/* Trying to register each eNB */
|
|
||||||
|
#define ENB_REGISTER_RETRY_DELAY 10
|
||||||
|
|
||||||
|
uint32_t eNB_app_register()
|
||||||
|
{
|
||||||
|
MessageDef *msg_p;
|
||||||
|
uint32_t register_enb_pending = 0;
|
||||||
|
|
||||||
for (eNB_id = oai_emulation.info.first_enb_local;
|
for (eNB_id = oai_emulation.info.first_enb_local;
|
||||||
(eNB_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local)) && (oai_emulation.info.cli_start_enb[eNB_id] == 1);
|
(eNB_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local)) && (oai_emulation.info.cli_start_enb[eNB_id] == 1);
|
||||||
eNB_id++) {
|
eNB_id++) {
|
||||||
char *mme_address_v4;
|
char *mme_address_v4;
|
||||||
|
|
||||||
if (EPC_MODE_ENABLED){
|
|
||||||
mme_address_v4 = EPC_MODE_MME_ADDRESS;
|
|
||||||
}else {
|
|
||||||
mme_address_v4 = "192.168.12.87";
|
|
||||||
}
|
|
||||||
char *mme_address_v6 = "2001:660:5502:12:30da:829a:2343:b6cf";
|
|
||||||
s1ap_register_eNB_t *s1ap_register_eNB;
|
|
||||||
uint32_t hash;
|
|
||||||
|
|
||||||
//note: there is an implicit relationship between the data struct and the message name
|
|
||||||
message_p = itti_alloc_new_message(TASK_ENB_APP, S1AP_REGISTER_ENB);
|
|
||||||
|
|
||||||
s1ap_register_eNB = &message_p->ittiMsg.s1ap_register_eNB;
|
|
||||||
|
|
||||||
hash = s1ap_generate_eNB_id();
|
|
||||||
|
|
||||||
/* Some default/random parameters */
|
if (EPC_MODE_ENABLED){
|
||||||
s1ap_register_eNB->eNB_id = eNB_id + (hash & 0xFFFF8);
|
mme_address_v4 = EPC_MODE_MME_ADDRESS;
|
||||||
s1ap_register_eNB->cell_type = CELL_MACRO_ENB;
|
} else {
|
||||||
s1ap_register_eNB->tac = 0;
|
mme_address_v4 = "192.168.12.87";
|
||||||
s1ap_register_eNB->mcc = 208;
|
|
||||||
s1ap_register_eNB->mnc = 34;
|
|
||||||
s1ap_register_eNB->default_drx = PAGING_DRX_256;
|
|
||||||
s1ap_register_eNB->nb_mme = 1;
|
|
||||||
s1ap_register_eNB->mme_ip_address[0].ipv4 = 1;
|
|
||||||
s1ap_register_eNB->mme_ip_address[0].ipv6 = 0;
|
|
||||||
memcpy(s1ap_register_eNB->mme_ip_address[0].ipv4_address, mme_address_v4,
|
|
||||||
strlen(mme_address_v4));
|
|
||||||
memcpy(s1ap_register_eNB->mme_ip_address[0].ipv6_address, mme_address_v6,
|
|
||||||
strlen(mme_address_v6));
|
|
||||||
|
|
||||||
itti_send_msg_to_task(TASK_S1AP, eNB_id, message_p);
|
|
||||||
}
|
}
|
||||||
|
char *mme_address_v6 = "2001:660:5502:12:30da:829a:2343:b6cf";
|
||||||
|
s1ap_register_enb_req_t *s1ap_register_eNB;
|
||||||
|
uint32_t hash;
|
||||||
|
|
||||||
|
//note: there is an implicit relationship between the data struct and the message name
|
||||||
|
msg_p = itti_alloc_new_message(TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
|
||||||
|
|
||||||
|
s1ap_register_eNB = &S1AP_REGISTER_ENB_REQ(msg_p);
|
||||||
|
|
||||||
|
hash = s1ap_generate_eNB_id();
|
||||||
|
|
||||||
|
/* Some default/random parameters */
|
||||||
|
s1ap_register_eNB->eNB_id = eNB_id + (hash & 0xFFFF8);
|
||||||
|
s1ap_register_eNB->cell_type = CELL_MACRO_ENB;
|
||||||
|
s1ap_register_eNB->tac = 0;
|
||||||
|
s1ap_register_eNB->mcc = 208;
|
||||||
|
s1ap_register_eNB->mnc = 34;
|
||||||
|
s1ap_register_eNB->default_drx = PAGING_DRX_256;
|
||||||
|
|
||||||
|
s1ap_register_eNB->nb_mme = 1;
|
||||||
|
s1ap_register_eNB->mme_ip_address[0].ipv4 = 1;
|
||||||
|
s1ap_register_eNB->mme_ip_address[0].ipv6 = 0;
|
||||||
|
memcpy(s1ap_register_eNB->mme_ip_address[0].ipv4_address, mme_address_v4, strlen(mme_address_v4));
|
||||||
|
memcpy(s1ap_register_eNB->mme_ip_address[0].ipv6_address, mme_address_v6, strlen(mme_address_v6));
|
||||||
|
|
||||||
|
# if defined ENB_APP_ENB_REGISTER_2_MME
|
||||||
|
s1ap_register_eNB->nb_mme = 2;
|
||||||
|
s1ap_register_eNB->mme_ip_address[1].ipv4 = 1;
|
||||||
|
s1ap_register_eNB->mme_ip_address[1].ipv6 = 0;
|
||||||
|
mme_address_v4 = "192.168.12.88";
|
||||||
|
memcpy(s1ap_register_eNB->mme_ip_address[1].ipv4_address, mme_address_v4, strlen(mme_address_v4));
|
||||||
|
memcpy(s1ap_register_eNB->mme_ip_address[1].ipv6_address, mme_address_v6, strlen(mme_address_v6));
|
||||||
|
# endif
|
||||||
|
|
||||||
|
itti_send_msg_to_task(TASK_S1AP, eNB_id, msg_p);
|
||||||
|
|
||||||
|
register_enb_pending ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return register_enb_pending;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *eNB_app_task(void *args_p) {
|
||||||
|
#if defined(ENABLE_ITTI)
|
||||||
|
# if defined(ENABLE_USE_MME)
|
||||||
|
static uint32_t register_enb_pending;
|
||||||
|
static uint32_t registered_enb;
|
||||||
|
static long enb_register_retry_timer_id;
|
||||||
|
# endif
|
||||||
|
MessageDef *msg_p;
|
||||||
|
const char *msg_name;
|
||||||
|
instance_t instance;
|
||||||
|
itti_mark_task_ready (TASK_ENB_APP);
|
||||||
|
|
||||||
|
# if defined(ENABLE_USE_MME)
|
||||||
|
/* Try to register each eNB */
|
||||||
|
registered_enb = 0;
|
||||||
|
register_enb_pending = eNB_app_register();
|
||||||
|
# else
|
||||||
|
msg_p = itti_alloc_new_message(TASK_ENB_APP, INITIALIZE_MESSAGE);
|
||||||
|
itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
itti_mark_task_ready (TASK_ENB_APP); // at the end of init for the current task
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Checks if a message has been sent to L2L1 task
|
// Wait for a message
|
||||||
itti_receive_msg (TASK_ENB_APP, &message_p);
|
itti_receive_msg (TASK_ENB_APP, &msg_p);
|
||||||
|
|
||||||
if (message_p != NULL) {
|
msg_name = ITTI_MSG_NAME (msg_p);
|
||||||
switch (ITTI_MSG_ID(message_p)) {
|
instance = ITTI_MSG_INSTANCE (msg_p);
|
||||||
|
|
||||||
|
switch (ITTI_MSG_ID(msg_p)) {
|
||||||
case TERMINATE_MESSAGE:
|
case TERMINATE_MESSAGE:
|
||||||
itti_exit_task ();
|
itti_exit_task ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MESSAGE_TEST:
|
case MESSAGE_TEST:
|
||||||
LOG_D(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
|
LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(msg_p));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
# if defined(ENABLE_USE_MME)
|
||||||
|
case S1AP_REGISTER_ENB_CNF:
|
||||||
|
LOG_I(EMU, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name, S1AP_REGISTER_ENB_CNF(msg_p).nb_mme);
|
||||||
|
|
||||||
|
DevAssert(register_enb_pending > 0);
|
||||||
|
register_enb_pending--;
|
||||||
|
|
||||||
|
/* Check if at least eNB is registered with one MME */
|
||||||
|
if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) {
|
||||||
|
registered_enb ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if all register eNB requests have been processed */
|
||||||
|
if (register_enb_pending == 0) {
|
||||||
|
if (registered_enb == oai_emulation.info.nb_enb_local) {
|
||||||
|
/* If all eNB are registered, start L2L1 task */
|
||||||
|
MessageDef *msg_init_p;
|
||||||
|
|
||||||
|
msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE);
|
||||||
|
itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint32_t not_associated = oai_emulation.info.nb_enb_local - registered_enb;
|
||||||
|
|
||||||
|
LOG_W(EMU, " %d eNB %s not associated with a MME, retrying registration in %d seconds ...\n",
|
||||||
|
not_associated, not_associated > 1 ? "are" : "is", ENB_REGISTER_RETRY_DELAY);
|
||||||
|
|
||||||
|
/* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */
|
||||||
|
if (timer_setup (ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL, &enb_register_retry_timer_id) < 0) {
|
||||||
|
LOG_E(EMU, " Can not start eNB register retry timer!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TIMER_HAS_EXPIRED:
|
||||||
|
LOG_I(EMU, " Received %s: timer_id %d\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);
|
||||||
|
|
||||||
|
if (TIMER_HAS_EXPIRED(msg_p).timer_id == enb_register_retry_timer_id) {
|
||||||
|
/* Restart the registration process */
|
||||||
|
registered_enb = 0;
|
||||||
|
register_enb_pending = eNB_app_register();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
# endif
|
||||||
|
|
||||||
/* case MME_REGISTERED:
|
|
||||||
LOG_D(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
|
|
||||||
itti_mark_task_ready (TASK_L2L1);
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
default:
|
default:
|
||||||
LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
|
LOG_E(EMU, "Received unexpected message %s\n", msg_name);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
free (message_p);
|
|
||||||
}
|
}
|
||||||
} while(1);
|
|
||||||
|
|
||||||
itti_terminate_tasks(TASK_ENB_APP);
|
free (msg_p);
|
||||||
|
} while(1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -503,10 +580,18 @@ void *l2l1_task(void *args_p) {
|
|||||||
char fname[64], vname[64];
|
char fname[64], vname[64];
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
#if defined(ENABLE_ITTI)
|
||||||
MessageDef *message_p;
|
MessageDef *message_p = NULL;
|
||||||
|
|
||||||
itti_mark_task_ready (TASK_L2L1);
|
itti_mark_task_ready (TASK_L2L1);
|
||||||
|
|
||||||
|
/* Wait for the initialize message */
|
||||||
|
do {
|
||||||
|
if (message_p != NULL) {
|
||||||
|
free (message_p);
|
||||||
|
}
|
||||||
|
itti_receive_msg (TASK_L2L1, &message_p);
|
||||||
|
} while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
|
||||||
|
free (message_p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (frame = 0; frame < oai_emulation.info.n_frames; frame++) {
|
for (frame = 0; frame < oai_emulation.info.n_frames; frame++) {
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ void calc_path_loss(node_desc_t* node_tx, node_desc_t* node_rx, channel_desc_t *
|
|||||||
|
|
||||||
void do_OFDM_mod(mod_sym_t **txdataF, s32 **txdata, uint32_t frame, u16 next_slot, LTE_DL_FRAME_PARMS *frame_parms);
|
void do_OFDM_mod(mod_sym_t **txdataF, s32 **txdata, uint32_t frame, u16 next_slot, LTE_DL_FRAME_PARMS *frame_parms);
|
||||||
|
|
||||||
|
void *eNB_app_task(void *args_p);
|
||||||
#ifdef ENABLE_ITTI
|
#ifdef ENABLE_ITTI
|
||||||
int itti_create_task_successful(void);
|
int itti_create_task_successful(void);
|
||||||
void *eNB_app_task(void *args_p);
|
|
||||||
void *l2l1_task(void *args_p);
|
void *l2l1_task(void *args_p);
|
||||||
#endif
|
#endif
|
||||||
#ifdef OPENAIR2
|
#ifdef OPENAIR2
|
||||||
|
|||||||
Reference in New Issue
Block a user