Merge branch 'feature-44-dedicated-drb' of gitlab.eurecom.fr:oai/openairinterface5g into feature-44-dedicated-drb
This commit is contained in:
@@ -68,6 +68,7 @@ typedef uint32_t frame_t;
|
|||||||
typedef int32_t sframe_t;
|
typedef int32_t sframe_t;
|
||||||
typedef uint32_t sub_frame_t;
|
typedef uint32_t sub_frame_t;
|
||||||
typedef uint8_t module_id_t;
|
typedef uint8_t module_id_t;
|
||||||
|
typedef uint8_t configured_t;
|
||||||
typedef uint8_t eNB_index_t;
|
typedef uint8_t eNB_index_t;
|
||||||
typedef uint16_t ue_id_t;
|
typedef uint16_t ue_id_t;
|
||||||
typedef int16_t smodule_id_t;
|
typedef int16_t smodule_id_t;
|
||||||
@@ -215,6 +216,7 @@ typedef struct protocol_ctxt_s {
|
|||||||
frame_t frame; /*!< \brief LTE frame number.*/
|
frame_t frame; /*!< \brief LTE frame number.*/
|
||||||
sub_frame_t subframe; /*!< \brief LTE sub 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) */
|
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;
|
} protocol_ctxt_t;
|
||||||
// warning time hardcoded
|
// warning time hardcoded
|
||||||
#define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame*10+(CtXt_h)->subframe)
|
#define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame*10+(CtXt_h)->subframe)
|
||||||
|
|||||||
@@ -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);
|
str = inet_ntoa(addr);
|
||||||
strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str);
|
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);
|
itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
|
||||||
|
|
||||||
register_enb_pending++;
|
register_enb_pending++;
|
||||||
|
|||||||
@@ -29,8 +29,9 @@
|
|||||||
|
|
||||||
/*! \file pdcp.c
|
/*! \file pdcp.c
|
||||||
* \brief pdcp interface with RLC
|
* \brief pdcp interface with RLC
|
||||||
* \author Lionel GAUTHIER and Navid Nikaein
|
* \author Navid Nikaein and Lionel GAUTHIER
|
||||||
* \date 2009-2012
|
* \date 2009-2012
|
||||||
|
* \email navid.nikaein@eurecom.fr
|
||||||
* \version 1.0
|
* \version 1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -83,7 +84,7 @@ extern int otg_enabled;
|
|||||||
* code at targets/TEST/PDCP/test_pdcp.c:test_pdcp_data_req()
|
* code at targets/TEST/PDCP/test_pdcp.c:test_pdcp_data_req()
|
||||||
*/
|
*/
|
||||||
boolean_t 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 srb_flag_t srb_flagP,
|
||||||
const rb_id_t rb_idP,
|
const rb_id_t rb_idP,
|
||||||
const mui_t muiP,
|
const mui_t muiP,
|
||||||
@@ -105,7 +106,6 @@ boolean_t pdcp_data_req(
|
|||||||
rlc_op_status_t rlc_status;
|
rlc_op_status_t rlc_status;
|
||||||
boolean_t ret = TRUE;
|
boolean_t ret = TRUE;
|
||||||
|
|
||||||
|
|
||||||
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
|
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
|
||||||
hashtable_rc_t h_rc;
|
hashtable_rc_t h_rc;
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_IN);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_IN);
|
||||||
@@ -116,28 +116,6 @@ 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));
|
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
|
#endif
|
||||||
|
|
||||||
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 {
|
|
||||||
if (srb_flagP) {
|
|
||||||
AssertError (rb_idP < 3, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti);
|
|
||||||
} else {
|
|
||||||
AssertError (rb_idP < maxDRB, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, maxDRB, ctxt_pP->module_id, ctxt_pP->rnti);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
|
|
||||||
h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
|
|
||||||
|
|
||||||
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 (sdu_buffer_sizeP == 0) {
|
if (sdu_buffer_sizeP == 0) {
|
||||||
LOG_W(PDCP, "Handed SDU is of size 0! Ignoring...\n");
|
LOG_W(PDCP, "Handed SDU is of size 0! Ignoring...\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -153,14 +131,40 @@ boolean_t pdcp_data_req(
|
|||||||
// XXX What does following call do?
|
// XXX What does following call do?
|
||||||
mac_xface->macphy_exit("PDCP sdu buffer size > MAX_IP_PACKET_SIZE");
|
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 {
|
||||||
|
if (srb_flagP) {
|
||||||
|
AssertError (rb_idP < 3, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti);
|
||||||
|
} else {
|
||||||
|
AssertError (rb_idP < maxDRB, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, maxDRB, ctxt_pP->module_id, ctxt_pP->rnti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
|
||||||
|
h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
|
||||||
|
|
||||||
|
if (h_rc != HASH_TABLE_OK) {
|
||||||
|
if (modeP != PDCP_TRANSMISSION_MODE_TRANSPARENT) {
|
||||||
|
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 (ctxt_pP->enb_flag == ENB_FLAG_NO) {
|
if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
|
||||||
start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req);
|
start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req);
|
||||||
} else {
|
} else {
|
||||||
start_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req);
|
start_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// PDCP transparent mode for MBMS traffic
|
// PDCP transparent mode for MBMS traffic
|
||||||
|
|
||||||
if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) {
|
if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) {
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ typedef struct pdcp_mbms_s {
|
|||||||
* @ingroup _pdcp
|
* @ingroup _pdcp
|
||||||
*/
|
*/
|
||||||
public_pdcp(boolean_t pdcp_data_req(
|
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 srb_flag_t srb_flagP,
|
||||||
const rb_id_t rb_id,
|
const rb_id_t rb_id,
|
||||||
const mui_t muiP,
|
const mui_t muiP,
|
||||||
|
|||||||
@@ -29,9 +29,10 @@
|
|||||||
|
|
||||||
/*! \file pdcp_fifo.c
|
/*! \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
|
* \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
|
* \author Navid Nikaein and Lionel GAUTHIER
|
||||||
* \date 2009
|
* \date 2009 - 2016
|
||||||
* \version 0.5
|
* \version 0.5
|
||||||
|
* \email navid.nikaein@eurecom.fr
|
||||||
* \warning This component can be runned only in user-space
|
* \warning This component can be runned only in user-space
|
||||||
* @ingroup pdcp
|
* @ingroup pdcp
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public_mem_block(void check_mem_area (void);)
|
|||||||
private_mem_block(void check_free_mem_block (mem_block_t * leP);)
|
private_mem_block(void check_free_mem_block (mem_block_t * leP);)
|
||||||
# endif
|
# endif
|
||||||
#ifdef USER_MODE
|
#ifdef USER_MODE
|
||||||
# define MEM_SCALE /*MAX_RG */ MAX_MOBILES_PER_ENB
|
# define MEM_SCALE MAX_MOBILES_PER_ENB*NB_RB_MAX
|
||||||
#else
|
#else
|
||||||
# ifdef NODE_RG
|
# ifdef NODE_RG
|
||||||
# define MEM_SCALE 2
|
# define MEM_SCALE 2
|
||||||
|
|||||||
+55
-24
@@ -113,7 +113,8 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
|||||||
MessageDef *message_p = NULL;
|
MessageDef *message_p = NULL;
|
||||||
sctp_new_association_req_t *sctp_new_association_req_p = NULL;
|
sctp_new_association_req_t *sctp_new_association_req_p = NULL;
|
||||||
s1ap_eNB_mme_data_t *s1ap_mme_data_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(instance_p != NULL);
|
||||||
DevAssert(mme_ip_address != NULL);
|
DevAssert(mme_ip_address != NULL);
|
||||||
|
|
||||||
@@ -134,27 +135,56 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
|||||||
memcpy(&sctp_new_association_req_p->local_address,
|
memcpy(&sctp_new_association_req_p->local_address,
|
||||||
local_ip_addr,
|
local_ip_addr,
|
||||||
sizeof(*local_ip_addr));
|
sizeof(*local_ip_addr));
|
||||||
|
|
||||||
|
S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance);
|
||||||
|
|
||||||
|
mme = s1ap_eNB_get_MME_from_instance(instance_p);
|
||||||
|
|
||||||
/* Create new MME descriptor */
|
if ( mme == NULL ) {
|
||||||
s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p));
|
|
||||||
DevAssert(s1ap_mme_data_p != 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_mme_data_p->cnx_id = s1ap_eNB_fetch_add_global_cnx_id();
|
S1AP_INFO("[eNB %d] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
|
||||||
sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
|
instance_p->instance,
|
||||||
|
mme->state, mme->cnx_id,
|
||||||
s1ap_mme_data_p->assoc_id = -1;
|
instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb);
|
||||||
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_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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
|
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,13 +193,14 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
|
|||||||
{
|
{
|
||||||
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 */
|
||||||
new_instance = s1ap_eNB_get_instance(instance);
|
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 */
|
/* 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->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->cell_type == s1ap_register_eNB->cell_type, new_instance->cell_type, s1ap_register_eNB->cell_type, 0);
|
||||||
@@ -199,7 +230,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) */
|
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
|
||||||
s1ap_eNB_insert_new_instance(new_instance);
|
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,
|
instance,
|
||||||
s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
|
s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
|
||||||
s1ap_register_eNB->eNB_id);
|
s1ap_register_eNB->eNB_id);
|
||||||
@@ -211,7 +242,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 */
|
/* Trying to connect to provided list of MME ip address */
|
||||||
for (index = 0; index < s1ap_register_eNB->nb_mme; index++) {
|
for (index = 0; index < s1ap_register_eNB->nb_mme; index++) {
|
||||||
s1ap_eNB_register_mme(new_instance,
|
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->enb_ip_address,
|
||||||
s1ap_register_eNB->sctp_in_streams,
|
s1ap_register_eNB->sctp_in_streams,
|
||||||
s1ap_register_eNB->sctp_out_streams);
|
s1ap_register_eNB->sctp_out_streams);
|
||||||
|
|||||||
@@ -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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -116,6 +125,23 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
|
|||||||
return NULL;
|
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 *s1ap_eNB_get_instance(instance_t instance)
|
||||||
{
|
{
|
||||||
s1ap_eNB_instance_t *temp = NULL;
|
s1ap_eNB_instance_t *temp = NULL;
|
||||||
@@ -130,3 +156,41 @@ s1ap_eNB_instance_t *s1ap_eNB_get_instance(instance_t instance)
|
|||||||
|
|
||||||
return NULL;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
|
|||||||
s1ap_eNB_instance_t *instance_p,
|
s1ap_eNB_instance_t *instance_p,
|
||||||
int32_t assoc_id, uint16_t cnx_id);
|
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);
|
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);
|
s1ap_eNB_instance_t *s1ap_eNB_get_instance(uint8_t mod_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user