From 022ab574d2ccd17f8988221fcbbed3040a07b521 Mon Sep 17 00:00:00 2001
From: nikaeinn <navid.nikaein@eurecom.fr>
Date: Mon, 22 Aug 2016 17:20:00 +0200
Subject: [PATCH] fix the issue with the number of pending mme/s1ap connections
---
openair2/COMMON/platform_types.h | 2 +
openair2/ENB_APP/enb_app.c | 2 +
openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 54 +++++------
openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 2 +-
openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 5 +-
openair3/S1AP/s1ap_eNB.c | 89 +++++++++++++------
.../S1AP/s1ap_eNB_management_procedures.c | 64 +++++++++++++
.../S1AP/s1ap_eNB_management_procedures.h | 4 +
8 files changed, 167 insertions(+), 55 deletions(-)
diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h
index 6f7722316f..709ecfd9b2 100755
--- a/openair2/COMMON/platform_types.h
+++ b/openair2/COMMON/platform_types.h
@@ -68,6 +68,7 @@ typedef uint32_t frame_t;
typedef int32_t sframe_t;
typedef uint32_t sub_frame_t;
typedef uint8_t module_id_t;
+typedef uint8_t configured_t;
typedef uint8_t eNB_index_t;
typedef uint16_t ue_id_t;
typedef int16_t smodule_id_t;
@@ -215,6 +216,7 @@ typedef struct protocol_ctxt_s {
frame_t frame; /*!< \brief LTE frame number.*/
sub_frame_t subframe; /*!< \brief LTE sub frame number.*/
eNB_index_t eNB_index; /*!< \brief valid for UE indicating the index of connected eNB(s) */
+ configured_t configured; /*!< \brief flag indicating whether the instance is configured or not */
} protocol_ctxt_t;
// warning time hardcoded
#define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame*10+(CtXt_h)->subframe)
diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c
index 6d95c215db..87383f5834 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -255,6 +255,8 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end, con
str = inet_ntoa(addr);
strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str);
+ LOG_I(ENB_APP,"[eNB %d] eNB_app_register for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
+
itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
register_enb_pending++;
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 7b5bec0e22..e0b993891f 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -29,8 +29,9 @@
/*! \file pdcp.c
* \brief pdcp interface with RLC
- * \author Lionel GAUTHIER and Navid Nikaein
+ * \author Navid Nikaein and Lionel GAUTHIER
* \date 2009-2012
+ * \email navid.nikaein@eurecom.fr
* \version 1.0
*/
@@ -83,7 +84,7 @@ extern int otg_enabled;
* code at targets/TEST/PDCP/test_pdcp.c:test_pdcp_data_req()
*/
boolean_t pdcp_data_req(
- const protocol_ctxt_t* const ctxt_pP,
+ protocol_ctxt_t* ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_idP,
const mui_t muiP,
@@ -105,7 +106,6 @@ boolean_t pdcp_data_req(
rlc_op_status_t rlc_status;
boolean_t ret = TRUE;
-
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
hashtable_rc_t h_rc;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_IN);
@@ -116,6 +116,22 @@ boolean_t pdcp_data_req(
T(T_ENB_PDCP_DL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_buffer_sizeP));
#endif
+ if (sdu_buffer_sizeP == 0) {
+ LOG_W(PDCP, "Handed SDU is of size 0! Ignoring...\n");
+ return FALSE;
+ }
+
+ /*
+ * XXX MAX_IP_PACKET_SIZE is 4096, shouldn't this be MAX SDU size, which is 8188 bytes?
+ */
+
+ if (sdu_buffer_sizeP > MAX_IP_PACKET_SIZE) {
+ LOG_E(PDCP, "Requested SDU size (%d) is bigger than that can be handled by PDCP (%u)!\n",
+ sdu_buffer_sizeP, MAX_IP_PACKET_SIZE);
+ // XXX What does following call do?
+ mac_xface->macphy_exit("PDCP sdu buffer size > MAX_IP_PACKET_SIZE");
+ }
+
if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) {
AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti);
} else {
@@ -131,36 +147,24 @@ boolean_t pdcp_data_req(
if (h_rc != HASH_TABLE_OK) {
if (modeP != PDCP_TRANSMISSION_MODE_TRANSPARENT) {
- LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %d Ignoring SDU...\n",
- PROTOCOL_CTXT_ARGS(ctxt_pP),
- rb_idP);
- return FALSE;
+ if ((ctxt_pP->configured == 0) && (ctxt_pP->frame%10 == 0))
+ LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %d Ignoring SDU...\n",
+ PROTOCOL_CTXT_ARGS(ctxt_pP),
+ rb_idP);
+ ctxt_pP->configured=0;
+ return FALSE;
}
+ }else{
+ // instance for a given RB is configured
+ ctxt_pP->configured=1;
}
-
- if (sdu_buffer_sizeP == 0) {
- LOG_W(PDCP, "Handed SDU is of size 0! Ignoring...\n");
- return FALSE;
- }
-
- /*
- * XXX MAX_IP_PACKET_SIZE is 4096, shouldn't this be MAX SDU size, which is 8188 bytes?
- */
-
- if (sdu_buffer_sizeP > MAX_IP_PACKET_SIZE) {
- LOG_E(PDCP, "Requested SDU size (%d) is bigger than that can be handled by PDCP (%u)!\n",
- sdu_buffer_sizeP, MAX_IP_PACKET_SIZE);
- // XXX What does following call do?
- mac_xface->macphy_exit("PDCP sdu buffer size > MAX_IP_PACKET_SIZE");
- }
-
+
if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req);
} else {
start_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req);
}
-
// PDCP transparent mode for MBMS traffic
if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) {
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index 9e5b15f5a3..52322b1348 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -221,7 +221,7 @@ typedef struct pdcp_mbms_s {
* @ingroup _pdcp
*/
public_pdcp(boolean_t pdcp_data_req(
- const protocol_ctxt_t* const ctxt_pP,
+ protocol_ctxt_t* ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const mui_t muiP,
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 4b97b8918b..390ad5a48d 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -29,9 +29,10 @@
/*! \file pdcp_fifo.c
* \brief pdcp interface with linux IP interface, have a look at http://man7.org/linux/man-pages/man7/netlink.7.html for netlink
- * \author Lionel GAUTHIER and Navid Nikaein
- * \date 2009
+ * \author Navid Nikaein and Lionel GAUTHIER
+ * \date 2009 - 2016
* \version 0.5
+ * \email navid.nikaein@eurecom.fr
* \warning This component can be runned only in user-space
* @ingroup pdcp
*/
diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c
index 2003b957fb..b55ba32142 100644
--- a/openair3/S1AP/s1ap_eNB.c
+++ b/openair3/S1AP/s1ap_eNB.c
@@ -113,7 +113,8 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
MessageDef *message_p = NULL;
sctp_new_association_req_t *sctp_new_association_req_p = NULL;
s1ap_eNB_mme_data_t *s1ap_mme_data_p = NULL;
-
+ struct s1ap_eNB_mme_data_s *mme = NULL;
+
DevAssert(instance_p != NULL);
DevAssert(mme_ip_address != NULL);
@@ -134,27 +135,58 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
memcpy(&sctp_new_association_req_p->local_address,
local_ip_addr,
sizeof(*local_ip_addr));
-
- /* Create new MME descriptor */
- 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_fetch_add_global_cnx_id();
- sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
-
- s1ap_mme_data_p->assoc_id = -1;
- s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
-
- STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
-
- /* Insert the new descriptor in list of known MME
- * but not yet associated.
- */
- 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 ++;
-
+
+ S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance);
+
+ mme = s1ap_eNB_get_MME_from_instance(instance_p);
+
+ if ( mme == NULL ) {
+
+ /* Create new MME descriptor */
+ 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_fetch_add_global_cnx_id();
+ sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
+
+ s1ap_mme_data_p->assoc_id = -1;
+ s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
+
+ STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
+
+ /* Insert the new descriptor in list of known MME
+ * but not yet associated.
+ */
+ 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 ++;
+ } else if (mme->state == S1AP_ENB_STATE_WAITING) {
+ instance_p->s1ap_mme_pending_nb ++;
+ sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
+
+ S1AP_INFO("[eNB %d] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
+ instance_p->instance,
+ mme->state, mme->cnx_id,
+ instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb);
+
+ /*s1ap_mme_data_p->cnx_id = mme->cnx_id;
+ sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
+
+ s1ap_mme_data_p->assoc_id = -1;
+ s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
+ */
+ } else {
+
+ S1AP_WARN("[eNB %d] MME already registered but not in the waiting state, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
+ instance_p->instance,
+ mme->state, mme->cnx_id,
+ instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb);
+
+ }
+
+ S1AP_DEBUG("s1ap mme nb %d\n", instance_p->s1ap_mme_nb);
+
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
}
@@ -163,13 +195,14 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
{
s1ap_eNB_instance_t *new_instance;
uint8_t index;
-
+
DevAssert(s1ap_register_eNB != NULL);
/* Look if the provided instance already exists */
new_instance = s1ap_eNB_get_instance(instance);
-
- if (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);
@@ -199,7 +232,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
/* 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[%d] and %s eNB id %u\n",
+ S1AP_INFO("Registered new eNB[%d] and %s eNB id %u\n",
instance,
s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
s1ap_register_eNB->eNB_id);
@@ -211,7 +244,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
/* Trying to connect to provided list of MME ip address */
for (index = 0; index < s1ap_register_eNB->nb_mme; index++) {
s1ap_eNB_register_mme(new_instance,
- &s1ap_register_eNB->mme_ip_address[index],
+ &s1ap_register_eNB->mme_ip_address[index],
&s1ap_register_eNB->enb_ip_address,
s1ap_register_eNB->sctp_in_streams,
s1ap_register_eNB->sctp_out_streams);
@@ -228,6 +261,8 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
instance_p = s1ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
+ S1AP_WARN("s1ap cnx_id %d\n", sctp_new_association_resp->ulp_cnx_id);
+
s1ap_mme_data_p = s1ap_eNB_get_MME(instance_p, -1,
sctp_new_association_resp->ulp_cnx_id);
DevAssert(s1ap_mme_data_p != NULL);
diff --git a/openair3/S1AP/s1ap_eNB_management_procedures.c b/openair3/S1AP/s1ap_eNB_management_procedures.c
index eb30a8dada..d521b7b7d3 100644
--- a/openair3/S1AP/s1ap_eNB_management_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_management_procedures.c
@@ -27,6 +27,15 @@
*******************************************************************************/
+/*! \file s1ap_eNB_management_procedures.c
+ * \brief S1AP eNB task
+ * \author S. Roux and Navid Nikaein
+ * \date 2010 - 2016
+ * \email: navid.nikaein@eurecom.fr
+ * \version 1.0
+ * @ingroup _s1ap
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -116,6 +125,23 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
return NULL;
}
+struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME_from_instance(
+ s1ap_eNB_instance_t *instance_p)
+{
+
+ struct s1ap_eNB_mme_data_s *mme = NULL;
+ struct s1ap_eNB_mme_data_s *mme_next = NULL;
+
+ for (mme = RB_MIN(s1ap_mme_map, &instance_p->s1ap_mme_head); mme!=NULL ; mme = mme_next) {
+ mme_next = RB_NEXT(s1ap_mme_map, &instance_p->s1ap_mme_head, mme);
+ if (mme->s1ap_eNB_instance == instance_p) {
+ return mme;
+ }
+ }
+
+ return NULL;
+}
+
s1ap_eNB_instance_t *s1ap_eNB_get_instance(instance_t instance)
{
s1ap_eNB_instance_t *temp = NULL;
@@ -130,3 +156,41 @@ s1ap_eNB_instance_t *s1ap_eNB_get_instance(instance_t instance)
return NULL;
}
+
+void s1ap_eNB_remove_mme_desc(s1ap_eNB_instance_t * instance)
+{
+
+ struct s1ap_eNB_mme_data_s *mme = NULL;
+ struct s1ap_eNB_mme_data_s *mmeNext = NULL;
+ struct plmn_identity_s* plmnInfo;
+ struct served_group_id_s* groupInfo;
+ struct served_gummei_s* gummeiInfo;
+ struct mme_code_s* mmeCode;
+
+ for (mme = RB_MIN(s1ap_mme_map, &instance->s1ap_mme_head); mme; mme = mmeNext) {
+ mmeNext = RB_NEXT(s1ap_mme_map, &instance->s1ap_mme_head, mme);
+ RB_REMOVE(s1ap_mme_map, &instance->s1ap_mme_head, mme);
+ while (!STAILQ_EMPTY(&mme->served_gummei)) {
+ gummeiInfo = STAILQ_FIRST(&mme->served_gummei);
+ STAILQ_REMOVE_HEAD(&mme->served_gummei, next);
+
+ while (!STAILQ_EMPTY(&gummeiInfo->served_plmns)) {
+ plmnInfo = STAILQ_FIRST(&gummeiInfo->served_plmns);
+ STAILQ_REMOVE_HEAD(&gummeiInfo->served_plmns, next);
+ free(plmnInfo);
+ }
+ while (!STAILQ_EMPTY(&gummeiInfo->served_group_ids)) {
+ groupInfo = STAILQ_FIRST(&gummeiInfo->served_group_ids);
+ STAILQ_REMOVE_HEAD(&gummeiInfo->served_group_ids, next);
+ free(groupInfo);
+ }
+ while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) {
+ mmeCode = STAILQ_FIRST(&gummeiInfo->mme_codes);
+ STAILQ_REMOVE_HEAD(&gummeiInfo->mme_codes, next);
+ free(mmeCode);
+ }
+ free(gummeiInfo);
+ }
+ free(mme);
+ }
+}
diff --git a/openair3/S1AP/s1ap_eNB_management_procedures.h b/openair3/S1AP/s1ap_eNB_management_procedures.h
index 2e00add882..0fd9f84053 100644
--- a/openair3/S1AP/s1ap_eNB_management_procedures.h
+++ b/openair3/S1AP/s1ap_eNB_management_procedures.h
@@ -34,6 +34,10 @@ 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 *s1ap_eNB_get_MME_from_instance(s1ap_eNB_instance_t *instance_p);
+
+void s1ap_eNB_remove_mme_desc(s1ap_eNB_instance_t * instance);
+
void s1ap_eNB_insert_new_instance(s1ap_eNB_instance_t *new_instance_p);
s1ap_eNB_instance_t *s1ap_eNB_get_instance(uint8_t mod_id);
--
GitLab