diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 6f7722316fcdbe4d51e7442fff87459fd031d111..709ecfd9b2260a9ec3458a664448e2c27b14df36 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 6d95c215db79c556923786942343296287d26cf8..87383f58347777b3057a8986f969e41937488646 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 7b5bec0e22b9b757e575f56276c1b9ee9bcce46a..e0b993891feb2d21b8c32def213ff1a914381cf9 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 9e5b15f5a322667c1c755f2ffca6d2b47a1639fc..52322b1348510309a3f00d6b827f4001ec02cf93 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 4b97b8918b32ec47d8f9539c6cf825ad5873088f..390ad5a48d380bd1f01e5968fbe9f8c8d39655ea 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 2003b957fbae249958a37bc90fc6dcc2da4b8dfc..b55ba321421f2b81cf32efb333b20f6c6cd36d2f 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 eb30a8dadac4a37423c8f23dd61a4fd34712fa2c..d521b7b7d3dcbe945e1f9f512aebbec1d007031a 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 2e00add882e9ff8a866b04ec2567757abbc050b1..0fd9f8405397470e27b850b68e38145bdf3df926 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);