Commit 1d7925c6 authored by Swetank Srivastava's avatar Swetank Srivastava

Cell Config API Support for 5G SA

parent 5fee4dc4
...@@ -2814,6 +2814,7 @@ target_link_libraries (nr-softmodem ${LIBXML2_LIBRARIES}) ...@@ -2814,6 +2814,7 @@ target_link_libraries (nr-softmodem ${LIBXML2_LIBRARIES})
target_link_libraries (nr-softmodem pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (nr-softmodem pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES})
target_link_libraries (nr-softmodem ${T_LIB}) target_link_libraries (nr-softmodem ${T_LIB})
target_link_libraries (nr-softmodem UDP)
add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
......
...@@ -83,6 +83,7 @@ unsigned short config_frames[4] = {2,9,11,13}; ...@@ -83,6 +83,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "ss_gNB_sys_task.h" #include "ss_gNB_sys_task.h"
#include "ss_gNB_port_man_task.h" #include "ss_gNB_port_man_task.h"
#include "ss_gNB_srb_task.h" #include "ss_gNB_srb_task.h"
#include "udp_eNB_task.h"
pthread_cond_t nfapi_sync_cond; pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex; pthread_mutex_t nfapi_sync_mutex;
...@@ -170,7 +171,7 @@ void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI * ...@@ -170,7 +171,7 @@ void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *
extern void reset_opp_meas(void); extern void reset_opp_meas(void);
extern void print_opp_meas(void); extern void print_opp_meas(void);
extern void *udp_eNB_task(void *args_p); //extern void *udp_eNB_task(void *args_p);
int transmission_mode=1; int transmission_mode=1;
int emulate_rf = 0; int emulate_rf = 0;
...@@ -350,6 +351,7 @@ int create_gNB_tasks(uint32_t gnb_nb) { ...@@ -350,6 +351,7 @@ int create_gNB_tasks(uint32_t gnb_nb) {
} }
if (gnb_nb > 0) { if (gnb_nb > 0) {
RCconfig_nr_ssparam();
if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
LOG_E(GNB_APP, "Create task for gNB APP failed\n"); LOG_E(GNB_APP, "Create task for gNB APP failed\n");
return -1; return -1;
...@@ -370,11 +372,11 @@ int create_gNB_tasks(uint32_t gnb_nb) { ...@@ -370,11 +372,11 @@ int create_gNB_tasks(uint32_t gnb_nb) {
} }
} }
if(itti_create_task(TASK_SS_SRB, ss_gNB_srb_task, NULL) < 0) { if(itti_create_task(TASK_SS_SRB, ss_gNB_srb_task, NULL) < 0) {
LOG_E(SCTP, "Create task for SS SRB failed\n"); LOG_E(SCTP, "Create task for SS SRB failed\n");
return -1; return -1;
} }
LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n");
...@@ -388,6 +390,13 @@ int create_gNB_tasks(uint32_t gnb_nb) { ...@@ -388,6 +390,13 @@ int create_gNB_tasks(uint32_t gnb_nb) {
return -1; return -1;
} }
} }
if (itti_create_task(TASK_UDP, udp_eNB_task, NULL) < 0)
{
LOG_E(GTPU, "Create task for UDP failed\n");
return -1;
}
} }
return 0; return 0;
......
...@@ -55,26 +55,38 @@ ...@@ -55,26 +55,38 @@
extern unsigned char NB_gNB_INST; extern unsigned char NB_gNB_INST;
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
extern int cell_config_5G_done;
#define GNB_REGISTER_RETRY_DELAY 10 #define GNB_REGISTER_RETRY_DELAY 10
pthread_cond_t cell_config_5G_done_cond;
pthread_mutex_t cell_config_5G_done_mutex;
static void wait_cell_config_5G(char *thread_name);
/*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/
static void configure_nr_rrc(uint32_t gnb_id) static void configure_nr_rrc(uint32_t gnb_id)
{ {
MessageDef *msg_p = NULL; MessageDef *msg_p = NULL;
// int CC_id; // int CC_id;
msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ); msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ);
if (RC.nrrrc[gnb_id]) { RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]); if (RC.nrrrc[gnb_id]) {
if (RC.ss.mode == SS_SOFTMODEM)
LOG_I(GNB_APP, "RRC starting with node type %d\n", RC.nrrrc[gnb_id]->node_type); {
LOG_I(GNB_APP,"Sending configuration message to NR_RRC task\n"); /** wait for signal */
itti_send_msg_to_task (TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); wait_cell_config_5G("TASK_SYS_GNB");
LOG_I(GNB_APP, "fxn:%s: Received Cell Config 5G SA\n", __FUNCTION__);
} }
else AssertFatal(0,"NRRRC context for gNB %d not allocated\n",gnb_id);
LOG_I(GNB_APP, "RRC starting with node type %d\n", RC.nrrrc[gnb_id]->node_type);
LOG_I(GNB_APP,"Sending configuration message to NR_RRC task\n");
itti_send_msg_to_task (TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
}
else AssertFatal(0,"NRRRC context for gNB %d not allocated\n",gnb_id);
} }
/*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/
...@@ -138,197 +150,210 @@ static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) ...@@ -138,197 +150,210 @@ static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end)
void *gNB_app_task(void *args_p) void *gNB_app_task(void *args_p)
{ {
uint32_t gnb_nb = RC.nb_nr_inst; uint32_t gnb_nb = RC.nb_nr_inst;
uint32_t gnb_id_start = 0; uint32_t gnb_id_start = 0;
uint32_t gnb_id_end = gnb_id_start + gnb_nb; uint32_t gnb_id_end = gnb_id_start + gnb_nb;
uint32_t gnb_id; uint32_t gnb_id;
MessageDef *msg_p = NULL; MessageDef *msg_p = NULL;
const char *msg_name = NULL; const char *msg_name = NULL;
instance_t instance; instance_t instance;
int result; int result;
/* for no gcc warnings */ /* for no gcc warnings */
(void)instance; (void)instance;
int cell_to_activate = 0;
itti_mark_task_ready (TASK_GNB_APP);
int cell_to_activate = 0; LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
itti_mark_task_ready (TASK_GNB_APP);
RCconfig_NR_L1();
LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__); if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc();
// RCconfig_nr_ssparam();
RCconfig_NR_L1(); LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc(); if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n");
RCconfig_nr_ssparam(); AssertFatal (gnb_nb <= RC.nb_nr_inst,
"Number of gNB is greater than gNB defined in configuration file (%d/%d)!",
gnb_nb, RC.nb_nr_inst);
LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst); LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst);
if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n"); RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST));
LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end);
configure_nr_rrc(gnb_id);
}
if (RC.nb_nr_inst > 0 && !get_softmodem_params()->nsa) {
init_pdcp();
}
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
LOG_I(X2AP, "X2AP enabled \n");
__attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
}
/* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info
* can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/
if ((AMF_MODE_ENABLED || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) ) {
/* Try to register each gNB */
//registered_gnb = 0;
__attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);
}
AssertFatal (gnb_nb <= RC.nb_nr_inst, if (RC.nb_nr_inst > 0) {
"Number of gNB is greater than gNB defined in configuration file (%d/%d)!", if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
gnb_nb, RC.nb_nr_inst);
LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst); if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) {
LOG_E(F1AP, "Create task for F1AP CU failed\n");
RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *)); AssertFatal(1==0,"exiting");
LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc); }
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) { }
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST));
LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end); if (NODE_IS_DU(RC.nrrrc[0]->node_type)) {
configure_nr_rrc(gnb_id);
}
if (RC.nb_nr_inst > 0 && !get_softmodem_params()->nsa) {
init_pdcp();
}
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type) if (itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL) < 0) {
LOG_I(X2AP, "X2AP enabled \n"); LOG_E(F1AP, "Create task for F1AP DU failed\n");
__attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end); AssertFatal(1==0,"exiting");
} }
// configure F1AP here for F1C
LOG_I(GNB_APP,"ngran_gNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_SETUP_REQ);
RCconfig_NR_DU_F1(msg_p, 0);
/* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info itti_send_msg_to_task (TASK_DU_F1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
* can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/ }
if ((AMF_MODE_ENABLED || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) ) { //&& !NODE_IS_CU(RC.nrrrc[0]->node_type)) { }
/* Try to register each gNB */ do {
//registered_gnb = 0; // Wait for a message
__attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end); itti_receive_msg (TASK_GNB_APP, &msg_p);
}
if (RC.nb_nr_inst > 0) {
if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) { msg_name = ITTI_MSG_NAME (msg_p);
LOG_E(F1AP, "Create task for F1AP CU failed\n"); instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p);
AssertFatal(1==0,"exiting");
}
}
if (NODE_IS_DU(RC.nrrrc[0]->node_type)) { switch (ITTI_MSG_ID(msg_p)) {
case TERMINATE_MESSAGE:
LOG_W(GNB_APP, " *** Exiting GNB_APP thread\n");
itti_exit_task ();
break;
if (itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL) < 0) { case MESSAGE_TEST:
LOG_E(F1AP, "Create task for F1AP DU failed\n"); LOG_I(GNB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p));
AssertFatal(1==0,"exiting"); break;
}
// configure F1AP here for F1C
LOG_I(GNB_APP,"ngran_gNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_SETUP_REQ);
RCconfig_NR_DU_F1(msg_p, 0);
itti_send_msg_to_task (TASK_DU_F1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
}
}
do {
// Wait for a message
itti_receive_msg (TASK_GNB_APP, &msg_p);
msg_name = ITTI_MSG_NAME (msg_p);
instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p);
switch (ITTI_MSG_ID(msg_p)) {
case TERMINATE_MESSAGE:
LOG_W(GNB_APP, " *** Exiting GNB_APP thread\n");
itti_exit_task ();
break;
case MESSAGE_TEST: case NGAP_REGISTER_GNB_CNF:
LOG_I(GNB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p)); LOG_I(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name,
break; NGAP_REGISTER_GNB_CNF(msg_p).nb_amf);
/*
DevAssert(register_gnb_pending > 0);
register_gnb_pending--;
// Check if at least gNB is registered with one AMF
if (NGAP_REGISTER_GNB_CNF(msg_p).nb_amf > 0) {
registered_gnb++;
}
// Check if all register gNB requests have been processed
if (register_gnb_pending == 0) {
if (registered_gnb == gnb_nb) {
// If all gNB are registered, start L2L1 task
MessageDef *msg_init_p;
case NGAP_REGISTER_GNB_CNF: msg_init_p = itti_alloc_new_message (TASK_GNB_APP, 0, INITIALIZE_MESSAGE);
LOG_I(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name, itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
NGAP_REGISTER_GNB_CNF(msg_p).nb_amf);
/* } else {
DevAssert(register_gnb_pending > 0); uint32_t not_associated = gnb_nb - registered_gnb;
register_gnb_pending--;
LOG_W(GNB_APP, " %d gNB %s not associated with a AMF, retrying registration in %d seconds ...\n",
not_associated, not_associated > 1 ? "are" : "is", GNB_REGISTER_RETRY_DELAY);
// Restart the gNB registration process in GNB_REGISTER_RETRY_DELAY seconds
if (timer_setup (GNB_REGISTER_RETRY_DELAY, 0, TASK_GNB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
NULL, &gnb_register_retry_timer_id) < 0) {
LOG_E(GNB_APP, " Can not start gNB register retry timer, use \"sleep\" instead!\n");
sleep(GNB_REGISTER_RETRY_DELAY);
// Restart the registration process
registered_gnb = 0;
register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
}
}
}
*/
break;
case F1AP_SETUP_RESP:
AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n");
LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
cell_to_activate = F1AP_SETUP_RESP(msg_p).num_cells_to_activate;
gNB_app_handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p));
break;
case F1AP_GNB_CU_CONFIGURATION_UPDATE:
AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n");
LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).gNB_CU_name,F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate);
cell_to_activate += F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate;
gNB_app_handle_f1ap_gnb_cu_configuration_update(&F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p));
/* Check if at least gNB is registered with one AMF */
AssertFatal(cell_to_activate == 1,"No cells to activate or cells > 1 %d\n",cell_to_activate);
break;
case NGAP_DEREGISTERED_GNB_IND:
LOG_W(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name,
NGAP_DEREGISTERED_GNB_IND(msg_p).nb_amf);
/* TODO handle recovering of registration */
break;
case TIMER_HAS_EXPIRED:
LOG_I(GNB_APP, " Received %s: timer_id %ld\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);
// Check if at least gNB is registered with one AMF //if (TIMER_HAS_EXPIRED (msg_p).timer_id == gnb_register_retry_timer_id) {
if (NGAP_REGISTER_GNB_CNF(msg_p).nb_amf > 0) { /* Restart the registration process */
registered_gnb++; // registered_gnb = 0;
} // register_gnb_pending = gNB_app_register(gnb_id_start, gnb_id_end);//, gnb_properties_p);
//}
// Check if all register gNB requests have been processed break;
if (register_gnb_pending == 0) {
if (registered_gnb == gnb_nb) {
// If all gNB are registered, start L2L1 task
MessageDef *msg_init_p;
msg_init_p = itti_alloc_new_message (TASK_GNB_APP, 0, INITIALIZE_MESSAGE); default:
itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); LOG_E(GNB_APP, "Received unexpected message %s\n", msg_name);
break;
}
} else { result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
uint32_t not_associated = gnb_nb - registered_gnb; AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
} while (1);
LOG_W(GNB_APP, " %d gNB %s not associated with a AMF, retrying registration in %d seconds ...\n", return NULL;
not_associated, not_associated > 1 ? "are" : "is", GNB_REGISTER_RETRY_DELAY); }
// Restart the gNB registration process in GNB_REGISTER_RETRY_DELAY seconds
if (timer_setup (GNB_REGISTER_RETRY_DELAY, 0, TASK_GNB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
NULL, &gnb_register_retry_timer_id) < 0) {
LOG_E(GNB_APP, " Can not start gNB register retry timer, use \"sleep\" instead!\n");
sleep(GNB_REGISTER_RETRY_DELAY);
// Restart the registration process
registered_gnb = 0;
register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
}
}
}
*/
break;
case F1AP_SETUP_RESP:
AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n");
LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
cell_to_activate = F1AP_SETUP_RESP(msg_p).num_cells_to_activate;
gNB_app_handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p));
break;
case F1AP_GNB_CU_CONFIGURATION_UPDATE:
AssertFatal(NODE_IS_DU(RC.nrrrc[0]->node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n");
LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p), static void wait_cell_config_5G(char *thread_name) {
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).gNB_CU_name,F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate); printf( "waiting for [SYS 5G] CELL CONFIG Indication (%s)\n",thread_name);
pthread_mutex_lock( &cell_config_5G_done_mutex );
cell_to_activate += F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p).num_cells_to_activate; while ( cell_config_5G_done < 0 )
gNB_app_handle_f1ap_gnb_cu_configuration_update(&F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p)); pthread_cond_wait( &cell_config_5G_done_cond, &cell_config_5G_done_mutex );
/* Check if at least gNB is registered with one AMF */ pthread_mutex_unlock(&cell_config_5G_done_mutex );
AssertFatal(cell_to_activate == 1,"No cells to activate or cells > 1 %d\n",cell_to_activate); printf( "[SYS 5G]: got cell config (%s)\n", thread_name);
break;
case NGAP_DEREGISTERED_GNB_IND:
LOG_W(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name,
NGAP_DEREGISTERED_GNB_IND(msg_p).nb_amf);
/* TODO handle recovering of registration */
break;
case TIMER_HAS_EXPIRED:
LOG_I(GNB_APP, " Received %s: timer_id %ld\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);
//if (TIMER_HAS_EXPIRED (msg_p).timer_id == gnb_register_retry_timer_id) {
/* Restart the registration process */
// registered_gnb = 0;
// register_gnb_pending = gNB_app_register(gnb_id_start, gnb_id_end);//, gnb_properties_p);
//}
break;
default:
LOG_E(GNB_APP, "Received unexpected message %s\n", msg_name);
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
} while (1);
return NULL;
} }
...@@ -244,6 +244,7 @@ typedef enum { ...@@ -244,6 +244,7 @@ typedef enum {
#define GNB_CONFIG_SS_SRBPORT_IDX 2 #define GNB_CONFIG_SS_SRBPORT_IDX 2
#define GNB_CONFIG_SS_VNGPORT_IDX 3 #define GNB_CONFIG_SS_VNGPORT_IDX 3
#define GNB_CONFIG_SS_MODE_IDX 4 #define GNB_CONFIG_SS_MODE_IDX 4
//#define GNB_CONFIG_SS_NR_MODE_IDX 5
#define GNB_SSPARAMS_DESC { \ #define GNB_SSPARAMS_DESC { \
{GNB_CONFIG_SS_HOSTIP , NULL, 0, uptr:NULL, defstrval:"0.0.0.0", TYPE_STRING, 0}, \ {GNB_CONFIG_SS_HOSTIP , NULL, 0, uptr:NULL, defstrval:"0.0.0.0", TYPE_STRING, 0}, \
......
...@@ -415,9 +415,21 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, ...@@ -415,9 +415,21 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
scs_scaling = scs_scaling0>>2; scs_scaling = scs_scaling0>>2;
scs_scaling2 = scs_scaling0>>2; scs_scaling2 = scs_scaling0>>2;
} }
uint32_t absolute_diff = (*configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - NR_ARFCN_ValueNR_t absoluteFrequencySSB = 0;
uint32_t absolute_diff = 0;
if (RC.ss.mode == SS_SOFTMODEM)
{
LOG_A(NR_RRC, "fxn:%s absoluteFrequencySSB:%d ", __FUNCTION__, absoluteFrequencySSB);
absoluteFrequencySSB = *RC.nrrrc[0]->configuration.scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB;
absolute_diff = absoluteFrequencySSB - configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
}
else
{
absolute_diff = (*configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB -
configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
}
/*TODO: */
sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = scs_scaling2 * (absolute_diff/(12*scs_scaling) - 10); sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = scs_scaling2 * (absolute_diff/(12*scs_scaling) - 10);
LOG_I(NR_RRC,"SIB1 freq: absoluteFrequencySSB %ld, absoluteFrequencyPointA %ld\n", LOG_I(NR_RRC,"SIB1 freq: absoluteFrequencySSB %ld, absoluteFrequencyPointA %ld\n",
......
...@@ -224,6 +224,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu ...@@ -224,6 +224,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
rrc->carrier.sib1_tda = configuration->sib1_tda; rrc->carrier.sib1_tda = configuration->sib1_tda;
rrc->carrier.do_CSIRS = configuration->do_CSIRS; rrc->carrier.do_CSIRS = configuration->do_CSIRS;
rrc->carrier.do_SRS = configuration->do_SRS; rrc->carrier.do_SRS = configuration->do_SRS;
LOG_A(NR_RRC, "fxn:%s rrc->carrier:pci:%d rrc->configuration:pci:%d gnb_mod_idP:%d", __FUNCTION__, rrc->carrier.physCellId, *rrc->configuration.scc->physCellId, gnb_mod_idP);
nr_rrc_config_ul_tda(configuration->scc,configuration->minRXTXTIME); nr_rrc_config_ul_tda(configuration->scc,configuration->minRXTXTIME);
/// System Information INIT /// System Information INIT
pthread_mutex_init(&rrc->cell_info_mutex,NULL); pthread_mutex_init(&rrc->cell_info_mutex,NULL);
......
...@@ -194,7 +194,7 @@ static int sys_send_udp_msg( ...@@ -194,7 +194,7 @@ static int sys_send_udp_msg(
if (message_p) if (message_p)
{ {
LOG_A(ENB_SS, "Sending UDP_DATA_REQ length %u offset %u buffer %d %d %d \n", buffer_len, buffer_offset, buffer[0], buffer[1], buffer[2]); LOG_A(ENB_SS, "Sending UDP_DATA_REQ length %u offset %u buffer %d %d %d to address peerIpAddr:%s and peer port:peerPort\n", buffer_len, buffer_offset, buffer[0], buffer[1], buffer[2], peerIpAddr, peerPort);
udp_data_req_p = &message_p->ittiMsg.udp_data_req; udp_data_req_p = &message_p->ittiMsg.udp_data_req;
udp_data_req_p->peer_address = peerIpAddr; udp_data_req_p->peer_address = peerIpAddr;
udp_data_req_p->peer_port = peerPort; udp_data_req_p->peer_port = peerPort;
......
...@@ -77,7 +77,12 @@ void ss_nr_port_man_send_cnf(struct NR_SYSTEM_CTRL_CNF recvCnf) ...@@ -77,7 +77,12 @@ void ss_nr_port_man_send_cnf(struct NR_SYSTEM_CTRL_CNF recvCnf)
case NR_SystemConfirm_Type_Cell: case NR_SystemConfirm_Type_Cell:
cnf.Confirm.v.Cell = true; cnf.Confirm.v.Cell = true;
break; break;
case NR_SystemConfirm_Type_RadioBearerList:
cnf.Confirm.v.RadioBearerList= true;
break;
case NR_SystemConfirm_Type_CellAttenuationList:
cnf.Confirm.v.CellAttenuationList= true;
break;
default: default:
LOG_A(GNB_APP, "[SYS] Error not handled CNF TYPE to [SS-PORTMAN] %d \n", recvCnf.Confirm.d); LOG_A(GNB_APP, "[SYS] Error not handled CNF TYPE to [SS-PORTMAN] %d \n", recvCnf.Confirm.d);
} }
...@@ -232,14 +237,17 @@ static inline void ss_gNB_read_from_socket(acpCtx_t ctx) ...@@ -232,14 +237,17 @@ static inline void ss_gNB_read_from_socket(acpCtx_t ctx)
// Error handling // Error handling
if (userId < 0) if (userId < 0)
{ {
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] fxn:%s userId:%d\n", __FUNCTION__, userId);
if (userId == -ACP_ERR_SERVICE_NOT_MAPPED) if (userId == -ACP_ERR_SERVICE_NOT_MAPPED)
{ {
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] fxn:%s userId:-ACP_ERR_SERVICE_NOT_MAPPED \n", __FUNCTION__);
// Message not mapped to user id, // Message not mapped to user id,
// this error should not appear on server side for the messages // this error should not appear on server side for the messages
// received from clients // received from clients
} }
else if (userId == -ACP_ERR_SIDL_FAILURE) else if (userId == -ACP_ERR_SIDL_FAILURE)
{ {
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] fxn:%s userId:-ACP_ERR_SIDL_FAILURE\n", __FUNCTION__);
// Server returned service error, // Server returned service error,
// this error should not appear on server side for the messages // this error should not appear on server side for the messages
// received from clients // received from clients
...@@ -248,29 +256,36 @@ static inline void ss_gNB_read_from_socket(acpCtx_t ctx) ...@@ -248,29 +256,36 @@ static inline void ss_gNB_read_from_socket(acpCtx_t ctx)
} }
else else
{ {
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] fxn:%s line:%d\n", __FUNCTION__, __LINE__);
return; return;
} }
} }
else if (userId == 0) else if (userId == 0)
{ {
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] fxn:%s userId:0\n", __FUNCTION__);
// No message (timeout on socket) // No message (timeout on socket)
} }
else else
{ {
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] received msg %d from the client.\n", userId); LOG_A(GNB_APP, "[SS-PORTMAN-GNB] received msg %d from the client.\n", userId);
if (acpNrSysProcessDecSrv(ctx, buffer, msgSize, &req) != 0) if (acpNrSysProcessDecSrv(ctx, buffer, msgSize, &req) != 0)
{
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] fxn:%s line:%d\n", __FUNCTION__, __LINE__);
return; return;
}
ss_dumpReqMsg(req); ss_dumpReqMsg(req);
if (userId == MSG_NrSysProcess_userId) if (userId == MSG_NrSysProcess_userId)
{ {
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] fxn:%s userId: MSG_NrSysProcess_userId\n", __FUNCTION__);
MessageDef *message_p = itti_alloc_new_message(TASK_SS_PORTMAN_GNB, INSTANCE_DEFAULT, SS_NR_SYS_PORT_MSG_IND); MessageDef *message_p = itti_alloc_new_message(TASK_SS_PORTMAN_GNB, INSTANCE_DEFAULT, SS_NR_SYS_PORT_MSG_IND);
if (message_p) if (message_p)
{ {
SS_NR_SYS_PORT_MSG_IND(message_p).req = req; SS_NR_SYS_PORT_MSG_IND(message_p).req = req;
SS_NR_SYS_PORT_MSG_IND(message_p).userId = userId; SS_NR_SYS_PORT_MSG_IND(message_p).userId = userId;
itti_send_msg_to_task(TASK_SYS_GNB, INSTANCE_DEFAULT, message_p); itti_send_msg_to_task(TASK_SYS_GNB, INSTANCE_DEFAULT, message_p);
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] fxn:%s line:%d Msg sent to \n", __FUNCTION__, __LINE__, TASK_SYS_GNB);
} }
} }
} }
...@@ -281,13 +296,13 @@ static inline void ss_gNB_read_from_socket(acpCtx_t ctx) ...@@ -281,13 +296,13 @@ static inline void ss_gNB_read_from_socket(acpCtx_t ctx)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void *ss_port_man_5G_NR_process_itti_msg(void *notUsed) void *ss_port_man_5G_NR_process_itti_msg(void *notUsed)
{ {
MessageDef *received_msg = NULL; MessageDef *received_msg = NULL;
int result; int result;
itti_poll_msg(TASK_SS_PORTMAN_GNB, &received_msg); itti_poll_msg(TASK_SS_PORTMAN_GNB, &received_msg);
/* Check if there is a packet to handle */ /* Check if there is a packet to handle */
if (received_msg != NULL) if (received_msg != NULL)
{ {
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] Received a message id : %d \n", LOG_A(GNB_APP, "[SS-PORTMAN-GNB] Received a message id : %d \n",
...@@ -309,7 +324,10 @@ void *ss_port_man_5G_NR_process_itti_msg(void *notUsed) ...@@ -309,7 +324,10 @@ void *ss_port_man_5G_NR_process_itti_msg(void *notUsed)
} }
break; break;
case TERMINATE_MESSAGE: case TERMINATE_MESSAGE:
itti_exit_task(); {
LOG_A(GNB_APP, "[SS-PORTMAN-GNB] Received TERMINATE_MESSAGE\n");
itti_exit_task();
}
break; break;
default: default:
...@@ -323,9 +341,9 @@ void *ss_port_man_5G_NR_process_itti_msg(void *notUsed) ...@@ -323,9 +341,9 @@ void *ss_port_man_5G_NR_process_itti_msg(void *notUsed)
received_msg = NULL; received_msg = NULL;
} }
ss_gNB_read_from_socket(nrctx_g); ss_gNB_read_from_socket(nrctx_g);
return NULL; return NULL;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
...@@ -361,9 +361,11 @@ void ss_gNB_srb_init(void) ...@@ -361,9 +361,11 @@ void ss_gNB_srb_init(void)
buffer = (unsigned char *)acpMalloc(size); buffer = (unsigned char *)acpMalloc(size);
assert(buffer); assert(buffer);
RC.ss.State = SS_STATE_CELL_ACTIVE; if (RC.ss.mode == SS_SOFTMODEM_SRB)
{
RC.ss.State = SS_STATE_CELL_ACTIVE;
}
itti_subscribe_event_fd(TASK_SS_SRB, fd1); itti_subscribe_event_fd(TASK_SS_SRB, fd1);
itti_mark_task_ready(TASK_SS_SRB); itti_mark_task_ready(TASK_SS_SRB);
} }
......
...@@ -40,6 +40,12 @@ extern RAN_CONTEXT_t RC; ...@@ -40,6 +40,12 @@ extern RAN_CONTEXT_t RC;
extern uint16_t ss_rnti_nr_g; extern uint16_t ss_rnti_nr_g;
extern SSConfigContext_t SS_context; extern SSConfigContext_t SS_context;
extern pthread_cond_t cell_config_5G_done_cond;
extern pthread_mutex_t cell_config_5G_done_mutex;
static int sys_send_udp_msg(uint8_t *buffer, uint32_t buffer_len, uint32_t buffer_offset, uint32_t peerIpAddr, uint16_t peerPort);
char *local_5G_address = "127.0.0.1" ;
typedef enum typedef enum
{ {
UndefinedMsg = 0, UndefinedMsg = 0,
...@@ -48,6 +54,16 @@ typedef enum ...@@ -48,6 +54,16 @@ typedef enum
} sidl_msg_id; } sidl_msg_id;
bool reqCnfFlag_g = false; bool reqCnfFlag_g = false;
void ss_task_sys_nr_handle_deltaValues(struct NR_SYSTEM_CTRL_REQ *req);
int cell_config_5G_done=-1;
int cell_config_5G_done_indication();
bool ss_task_sys_nr_handle_cellConfig5G (struct NR_CellConfigRequest_Type *p_req);
bool ss_task_sys_nr_handle_cellConfigRadioBearer(struct NR_SYSTEM_CTRL_REQ *req);
bool ss_task_sys_nr_handle_cellConfigAttenuation(struct NR_SYSTEM_CTRL_REQ *req);
static int sys_5G_send_init_udp(const udpSockReq_t *req);
static void sys_5G_send_proxy(void *msg, int msgLen);
int proxy_5G_send_port = 7776;
int proxy_5G_recv_port = 7770;
/* /*
...@@ -82,22 +98,26 @@ static void send_sys_cnf(enum ConfirmationResult_Type_Sel resType, ...@@ -82,22 +98,26 @@ static void send_sys_cnf(enum ConfirmationResult_Type_Sel resType,
msgCnf->Common.Result.v.Success = resVal; msgCnf->Common.Result.v.Success = resVal;
msgCnf->Confirm.d = cnfType; msgCnf->Confirm.d = cnfType;
switch (cnfType) switch (cnfType)
{ {
case NR_SystemConfirm_Type_Cell: case NR_SystemConfirm_Type_Cell:
{ {
LOG_A(GNB_APP, "[SYS-GNB] Send confirm for cell configuration\n"); LOG_A(GNB_APP, "[SYS-GNB] Send confirm for cell configuration\n");
msgCnf->Confirm.v.Cell = true; msgCnf->Confirm.v.Cell = true;
break; break;
} }
default: default:
LOG_A(GNB_APP, "[SYS-GNB] Error not handled CNF TYPE to [SS-PORTMAN-GNB]"); LOG_A(GNB_APP, "[SYS-GNB] Error not handled CNF TYPE to [SS-PORTMAN-GNB]");
} }
SS_NR_SYS_PORT_MSG_CNF(message_p).cnf = msgCnf; SS_NR_SYS_PORT_MSG_CNF(message_p).cnf = msgCnf;
int send_res = itti_send_msg_to_task(TASK_SS_PORTMAN_GNB, INSTANCE_DEFAULT, message_p); int send_res = itti_send_msg_to_task(TASK_SS_PORTMAN_GNB, INSTANCE_DEFAULT, message_p);
if (send_res < 0) if (send_res < 0)
{ {
LOG_A(GNB_APP, "[SYS-GNB] Error sending to [SS-PORTMAN-GNB]"); LOG_A(GNB_APP, "[SYS-GNB] Error sending to [SS-PORTMAN-GNB]");
} }
else
{
LOG_A(GNB_APP, "[SYS-GNB] fxn:%s NR_SYSTEM_CTRL_CNF sent for cnfType:%d to Port Manager", __FUNCTION__, cnfType);
}
} }
} }
/* /*
...@@ -143,9 +163,53 @@ static void ss_task_sys_nr_handle_req(struct NR_SYSTEM_CTRL_REQ *req, ss_nrset_t ...@@ -143,9 +163,53 @@ static void ss_task_sys_nr_handle_req(struct NR_SYSTEM_CTRL_REQ *req, ss_nrset_t
{ {
case SS_STATE_NOT_CONFIGURED: case SS_STATE_NOT_CONFIGURED:
if (req->Request.d == NR_SystemRequest_Type_Cell) if (req->Request.d == NR_SystemRequest_Type_Cell)
{ {
LOG_A(GNB_APP, "[SYS-GNB] NR_SystemRequest_Type_Cell received\n"); LOG_A(GNB_APP, "[SYS-GNB] NR_SystemRequest_Type_Cell received\n");
} if (false == ss_task_sys_nr_handle_cellConfig5G(&req->Request.v.Cell) )
{
LOG_A(GNB_APP, "[SYS-GNB] Error handling Cell Config 5G for NR_SystemRequest_Type_Cell \n");
return;
}
cell_config_5G_done_indication();
if (RC.ss.State == SS_STATE_NOT_CONFIGURED)
{
RC.ss.State = SS_STATE_CELL_ACTIVE;
LOG_A(GNB_APP, "[SYS-GNB] RC.ss.State changed to ACTIVE \n");
}
send_sys_cnf(ConfirmationResult_Type_Success, TRUE, NR_SystemConfirm_Type_Cell, NULL);
if (req->Request.v.Cell.d == NR_CellConfigRequest_Type_AddOrReconfigure)
{
CellConfig5GReq_t *cellConfig = NULL;
struct NR_CellConfigInfo_Type *p_cellConfig = NULL;
p_cellConfig = &req->Request.v.Cell.v.AddOrReconfigure;
SS_context.maxRefPower = p_cellConfig->CellConfigCommon.v.InitialCellPower.v.MaxReferencePower;
cellConfig = (CellConfig5GReq_t*)malloc(sizeof(CellConfig5GReq_t));
cellConfig->header.preamble = 0xFEEDC0DE;
cellConfig->header.msg_id = SS_CELL_CONFIG;
cellConfig->header.length = sizeof(proxy_ss_header_t);
cellConfig->initialAttenuation = 0;
cellConfig->header.cell_id = SS_context.eutra_cellId;
cellConfig->maxRefPower= p_cellConfig->CellConfigCommon.v.InitialCellPower.v.MaxReferencePower;
cellConfig->absoluteFrequencySSB= *RC.nrrrc[0]->configuration.scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB;
LOG_A(ENB_SS,"5G Cell configuration received for cell_id: %d Initial attenuation: %d \
Max ref power: %d\n for absoluteFrequencySSB : %d =================================== \n",
cellConfig->header.cell_id,
cellConfig->initialAttenuation, cellConfig->maxRefPower,
cellConfig->absoluteFrequencySSB);
//send_to_proxy();
sys_5G_send_proxy((void *)cellConfig, sizeof(CellConfig5GReq_t));
}
}
else if (req->Request.d == NR_SystemRequest_Type_DeltaValues)
{
/* TBD: Sending the dummy confirmation for now*/
ss_task_sys_nr_handle_deltaValues(req);
LOG_A(GNB_APP, "[SYS-GNB] Sent SYS CNF for NR_SystemRequest_Type_DeltaValues\n");
}
else else
{ {
LOG_E(GNB_APP, "[SYS-GNB] Error ! SS_STATE %d Invalid SystemRequest_Type %d received\n", LOG_E(GNB_APP, "[SYS-GNB] Error ! SS_STATE %d Invalid SystemRequest_Type %d received\n",
...@@ -153,16 +217,40 @@ static void ss_task_sys_nr_handle_req(struct NR_SYSTEM_CTRL_REQ *req, ss_nrset_t ...@@ -153,16 +217,40 @@ static void ss_task_sys_nr_handle_req(struct NR_SYSTEM_CTRL_REQ *req, ss_nrset_t
} }
break; break;
case SS_STATE_CELL_ACTIVE: case SS_STATE_CELL_ACTIVE:
if (req->Request.d == NR_SystemRequest_Type_EnquireTiming) {
{ switch (req->Request.d)
sys_handle_nr_enquire_timing(tinfo); {
LOG_A(GNB_APP, "[SYS-GNB] NR_SystemRequest_Type_EnquireTiming received\n"); case NR_SystemRequest_Type_EnquireTiming:
} {
else sys_handle_nr_enquire_timing(tinfo);
{ LOG_A(GNB_APP, "[SYS-GNB] NR_SystemRequest_Type_EnquireTiming received\n");
LOG_E(GNB_APP, "[SYS-GNB] Error ! SS_STATE %d Invalid SystemRequest_Type %d received\n", }
RC.ss.State, req->Request.d); break;
} case NR_SystemRequest_Type_RadioBearerList:
{
if (false == ss_task_sys_nr_handle_cellConfigRadioBearer(&req) )
{
LOG_A(GNB_APP, "[SYS-GNB] Error handling Cell Config 5G for NR_SystemRequest_Type_Cell \n");
return;
}
}
break;
case NR_SystemRequest_Type_CellAttenuationList:
{
if (false == ss_task_sys_nr_handle_cellConfigAttenuation(&req) )
{
LOG_A(GNB_APP, "[SYS-GNB] Error handling Cell Config 5G for NR_SystemRequest_Type_Cell \n");
return;
}
}
break;
default:
{
LOG_E(GNB_APP, "[SYS-GNB] Error ! SS_STATE %d Invalid SystemRequest_Type %d received\n",
RC.ss.State, req->Request.d);
}
}
}
break; break;
default: default:
LOG_E(GNB_APP, "[SYS-GNB] Error ! SS_STATE %d Invalid SystemRequest_Type %d received\n", LOG_E(GNB_APP, "[SYS-GNB] Error ! SS_STATE %d Invalid SystemRequest_Type %d received\n",
...@@ -213,6 +301,24 @@ bool valid_nr_sys_msg(struct NR_SYSTEM_CTRL_REQ *req) ...@@ -213,6 +301,24 @@ bool valid_nr_sys_msg(struct NR_SYSTEM_CTRL_REQ *req)
valid = TRUE; valid = TRUE;
sendDummyCnf = FALSE; sendDummyCnf = FALSE;
break; break;
case NR_SystemRequest_Type_DeltaValues:
valid = TRUE;
sendDummyCnf = FALSE;
break;
case NR_SystemRequest_Type_RadioBearerList:
valid = TRUE;
sendDummyCnf = FALSE;
break;
case NR_SystemRequest_Type_CellAttenuationList:
valid = TRUE;
sendDummyCnf = FALSE;
cnfType = NR_SystemConfirm_Type_CellAttenuationList;
break;
case NR_SystemRequest_Type_AS_Security:
valid = FALSE;
sendDummyCnf = TRUE;
cnfType = NR_SystemConfirm_Type_AS_Security;
break;
default: default:
valid = FALSE; valid = FALSE;
sendDummyCnf = FALSE; sendDummyCnf = FALSE;
...@@ -239,54 +345,59 @@ bool valid_nr_sys_msg(struct NR_SYSTEM_CTRL_REQ *req) ...@@ -239,54 +345,59 @@ bool valid_nr_sys_msg(struct NR_SYSTEM_CTRL_REQ *req)
void *ss_gNB_sys_process_itti_msg(void *notUsed) void *ss_gNB_sys_process_itti_msg(void *notUsed)
{ {
MessageDef *received_msg = NULL; MessageDef *received_msg = NULL;
int result; int result;
static ss_nrset_timinfo_t tinfo = {.sfn = 0xFFFF, .slot = 0xFF}; static ss_nrset_timinfo_t tinfo = {.sfn = 0xFFFF, .slot = 0xFF};
itti_receive_msg(TASK_SYS_GNB, &received_msg); itti_receive_msg(TASK_SYS_GNB, &received_msg);
/* Check if there is a packet to handle */ LOG_A(GNB_APP, "Entry in fxn:%s \n", __FUNCTION__);
if (received_msg != NULL) /* Check if there is a packet to handle */
{ if (received_msg != NULL)
switch (ITTI_MSG_ID(received_msg)) {
{ switch (ITTI_MSG_ID(received_msg))
case SS_NRUPD_TIM_INFO: {
{ case SS_NRUPD_TIM_INFO:
LOG_D(GNB_APP, "TASK_SYS_GNB received SS_NRUPD_TIM_INFO with sfn=%d slot=%d\n", SS_NRUPD_TIM_INFO(received_msg).sfn, SS_NRUPD_TIM_INFO(received_msg).slot); {
tinfo.slot = SS_NRUPD_TIM_INFO(received_msg).slot; LOG_D(GNB_APP, "TASK_SYS_GNB received SS_NRUPD_TIM_INFO with sfn=%d slot=%d\n", SS_NRUPD_TIM_INFO(received_msg).sfn, SS_NRUPD_TIM_INFO(received_msg).slot);
tinfo.sfn = SS_NRUPD_TIM_INFO(received_msg).sfn; tinfo.slot = SS_NRUPD_TIM_INFO(received_msg).slot;
} tinfo.sfn = SS_NRUPD_TIM_INFO(received_msg).sfn;
break; }
break;
case SS_NR_SYS_PORT_MSG_IND: case SS_NR_SYS_PORT_MSG_IND:
{ {
if (valid_nr_sys_msg(SS_NR_SYS_PORT_MSG_IND(received_msg).req)) if (valid_nr_sys_msg(SS_NR_SYS_PORT_MSG_IND(received_msg).req))
{ {
ss_task_sys_nr_handle_req(SS_NR_SYS_PORT_MSG_IND(received_msg).req, &tinfo); ss_task_sys_nr_handle_req(SS_NR_SYS_PORT_MSG_IND(received_msg).req, &tinfo);
} }
else else
{ {
LOG_A(GNB_APP, "TASK_SYS_GNB: Not handled SYS_PORT message received \n"); LOG_A(GNB_APP, "TASK_SYS_GNB: Not handled SYS_PORT message received \n");
} }
} }
break; break;
case UDP_DATA_IND:
{
LOG_A(GNB_APP, "[TASK_SYS_GNB] received UDP_DATA_IND \n");
}
case TERMINATE_MESSAGE: case TERMINATE_MESSAGE:
{ {
itti_exit_task(); itti_exit_task();
break; break;
} }
default: default:
LOG_A(GNB_APP, "TASK_SYS_GNB: Received unhandled message %d:%s\n", LOG_A(GNB_APP, "TASK_SYS_GNB: Received unhandled message %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
break; break;
} }
result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg); result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
AssertFatal(result == EXIT_SUCCESS, "[SYS] Failed to free memory (%d)!\n", result); AssertFatal(result == EXIT_SUCCESS, "[SYS] Failed to free memory (%d)!\n", result);
received_msg = NULL; received_msg = NULL;
} }
return NULL; return NULL;
} }
/* /*
...@@ -298,20 +409,27 @@ void *ss_gNB_sys_process_itti_msg(void *notUsed) ...@@ -298,20 +409,27 @@ void *ss_gNB_sys_process_itti_msg(void *notUsed)
*/ */
void *ss_gNB_sys_task(void *arg) void *ss_gNB_sys_task(void *arg)
{ {
udpSockReq_t req;
req.address = local_5G_address;
req.port = proxy_5G_recv_port;
sys_5G_send_init_udp(&req);
sleep(5);
if (RC.ss.configured == 0) if (RC.ss.configured == 0)
{ {
RCconfig_nr_ssparam(); //RCconfig_nr_ssparam();
RC.ss.configured = 1; RC.ss.configured = 1;
} }
// Set the state to NOT_CONFIGURED for Cell Config processing mode // Set the state to NOT_CONFIGURED for Cell Config processing mode
if (RC.ss.mode == SS_SOFTMODEM) if (RC.ss.mode == SS_SOFTMODEM)
{ {
RC.ss.State = SS_STATE_NOT_CONFIGURED; RC.ss.State = SS_STATE_NOT_CONFIGURED;
LOG_A(GNB_APP, "TASK_SYS_GNB: fxn:%s line:%d RC.ss.mode:SS_STATE_NOT_CONFIGURED \n", __FUNCTION__, __LINE__);
} }
// Set the state to CELL_ACTIVE for SRB processing mode // Set the state to CELL_ACTIVE for SRB processing mode
else if (RC.ss.mode == SS_SOFTMODEM_SRB) else if (RC.ss.mode == SS_SOFTMODEM_SRB)
{ {
RC.ss.State = SS_STATE_CELL_ACTIVE; RC.ss.State = SS_STATE_CELL_ACTIVE;
LOG_A(GNB_APP, "TASK_SYS_GNB: fxn:%s line:%d RC.ss.mode:SS_STATE_CELL_ACTIVE \n", __FUNCTION__, __LINE__);
} }
while (1) while (1)
...@@ -321,3 +439,270 @@ void *ss_gNB_sys_task(void *arg) ...@@ -321,3 +439,270 @@ void *ss_gNB_sys_task(void *arg)
return NULL; return NULL;
} }
/*
* Function : ss_task_sys_nr_handle_deltaValues
* Description: This function handles the NR_SYSTEM_CTRL_REQ for DeltaValues and updates the CNF structures as
* per cell's band configuration.
* Returns : None
*/
void ss_task_sys_nr_handle_deltaValues(struct NR_SYSTEM_CTRL_REQ *req)
{
struct NR_SYSTEM_CTRL_CNF *msgCnf = CALLOC(1, sizeof(struct NR_SYSTEM_CTRL_CNF));
MessageDef *message_p = itti_alloc_new_message(TASK_SYS_GNB, INSTANCE_DEFAULT, SS_NR_SYS_PORT_MSG_CNF);
if (!message_p)
{
LOG_A(GNB_APP, "[SYS-GNB] Error Allocating Memory for message NR_SYSTEM_CTRL_CNF \n");
return ;
}
msgCnf->Common.CellId = 0;
msgCnf->Common.RoutingInfo.d = NR_RoutingInfo_Type_None;
msgCnf->Common.RoutingInfo.v.None = true;
msgCnf->Common.TimingInfo.d = TimingInfo_Type_None;
msgCnf->Common.TimingInfo.v.None = true;
msgCnf->Common.Result.d = ConfirmationResult_Type_Success;
msgCnf->Common.Result.v.Success = true;
msgCnf->Confirm.d = NR_SystemConfirm_Type_DeltaValues;
struct UE_NR_DeltaValues_Type* vals = &msgCnf->Confirm.v.DeltaValues;
struct DeltaValues_Type* deltaPrimaryBand = &vals->DeltaPrimaryBand;
struct DeltaValues_Type* deltaSecondaryBand = &vals->DeltaSecondaryBand;
deltaPrimaryBand->DeltaNRf1 = 0;
deltaPrimaryBand->DeltaNRf2 = 0;
deltaPrimaryBand->DeltaNRf3 = 0;
deltaPrimaryBand->DeltaNRf4 = 0;
deltaSecondaryBand->DeltaNRf1 = 0;
deltaSecondaryBand->DeltaNRf2 = 0;
deltaSecondaryBand->DeltaNRf3 = 0;
deltaSecondaryBand->DeltaNRf4 = 0;
msgCnf->Confirm.v.Cell = true;
SS_NR_SYS_PORT_MSG_CNF(message_p).cnf = msgCnf;
int send_res = itti_send_msg_to_task(TASK_SS_PORTMAN_GNB, INSTANCE_DEFAULT, message_p);
if (send_res < 0)
{
LOG_A(GNB_APP, "[SYS-GNB] Error sending to [SS-PORTMAN-GNB]");
}
}
/*
* Function : ss_task_sys_nr_handle_cellConfig5G
* Description: This function handles the NR_SYSTEM_CTRL_REQ for request type AddOrReconfigure. TTCN provides the values of for Cell Config Req 5G on SYS Port
* and those values are populated here in corresponding structures of NR RRC.
* Returns : None
*/
bool ss_task_sys_nr_handle_cellConfig5G (struct NR_CellConfigRequest_Type *p_req)
{
uint32_t gnbId = 0;
if (p_req->d == NR_CellConfigRequest_Type_AddOrReconfigure)
{
if (p_req->v.AddOrReconfigure.PhysicalLayer.d = true &&
p_req->v.AddOrReconfigure.PhysicalLayer.v.Common.d == true &&
p_req->v.AddOrReconfigure.PhysicalLayer.v.Common.v.PhysicalCellId.d == true )
{
RC.nrrrc[gnbId]->carrier.physCellId = p_req->v.AddOrReconfigure.PhysicalLayer.v.Common.v.PhysicalCellId.v;
*RC.nrrrc[gnbId]->configuration.scc->physCellId = p_req->v.AddOrReconfigure.PhysicalLayer.v.Common.v.PhysicalCellId.v;
}
if (p_req->v.AddOrReconfigure.PhysicalLayer.d == true &&
p_req->v.AddOrReconfigure.PhysicalLayer.v.Downlink.d == true &&
p_req->v.AddOrReconfigure.PhysicalLayer.v.Downlink.v.FrequencyInfoDL.d == true &&
p_req->v.AddOrReconfigure.PhysicalLayer.v.Downlink.v.FrequencyInfoDL.v.d == NR_ASN1_FrequencyInfoDL_Type_R15 &&
p_req->v.AddOrReconfigure.PhysicalLayer.v.Downlink.v.FrequencyInfoDL.v.v.R15.absoluteFrequencySSB.d == true )
{
/* *RC.nrrrc[gnbId]->configuration.scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB =
p_req->v.AddOrReconfigure.PhysicalLayer.v.Downlink.v.FrequencyInfoDL.v.v.R15.absoluteFrequencySSB.v; */
}
if (RC.nrrrc[0]->configuration.scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB != NULL)
{
LOG_A(GNB_APP,"fxn:%s absoluteFrequencySSB:%ld\n",
__FUNCTION__,*RC.nrrrc[0]->configuration.scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB);
}
else
{
LOG_A(GNB_APP,"fxn:%s absoluteFrequencySSB is NULL\n");
}
}
return true;
}
/*
* Function : cell_config_5G_done_indication
* Description: Sends the cell_config_done_mutex signl to LTE_SOFTMODEM,
* as in SS mode the eNB is waiting for the cell configration to be
* received form TTCN. After receiving this signal only the eNB's init
* is completed and its ready for processing.
*/
int cell_config_5G_done_indication()
{
if (cell_config_5G_done < 0)
{
LOG_A(GNB_APP, "[SYS-GNB] fxn:%s Signal to TASK_GNB_APP about cell configuration complete", __FUNCTION__);
pthread_mutex_lock(&cell_config_5G_done_mutex);
cell_config_5G_done = 0;
pthread_cond_broadcast(&cell_config_5G_done_cond);
pthread_mutex_unlock(&cell_config_5G_done_mutex);
}
return 0;
}
/*
* Function : ss_task_sys_nr_handle_cellConfigRadioBearer
* Description : This function handles the CellConfig 5G API on SYS Port and send processes the request.
* Returns : true/false
*/
bool ss_task_sys_nr_handle_cellConfigRadioBearer(struct NR_SYSTEM_CTRL_REQ *req)
{
struct NR_SYSTEM_CTRL_CNF *msgCnf = CALLOC(1, sizeof(struct NR_SYSTEM_CTRL_CNF));
MessageDef *message_p = itti_alloc_new_message(TASK_SYS_GNB, INSTANCE_DEFAULT, SS_NR_SYS_PORT_MSG_CNF);
if (message_p)
{
LOG_A(GNB_APP, "[SYS-GNB] Send SS_NR_SYS_PORT_MSG_CNF\n");
msgCnf->Common.CellId = SS_context.eutra_cellId;
msgCnf->Common.Result.d = ConfirmationResult_Type_Success;
msgCnf->Common.Result.v.Success = true;
msgCnf->Confirm.d = NR_SystemConfirm_Type_RadioBearerList;
msgCnf->Confirm.v.RadioBearerList = true;
SS_NR_SYS_PORT_MSG_CNF(message_p).cnf = msgCnf;
int send_res = itti_send_msg_to_task(TASK_SS_PORTMAN_GNB, INSTANCE_DEFAULT, message_p);
if (send_res < 0)
{
LOG_A(GNB_APP, "[SYS-GNB] Error sending to [SS-PORTMAN-GNB]");
return false;
}
else
{
LOG_A(GNB_APP, "[SYS-GNB] fxn:%s NR_SYSTEM_CTRL_CNF sent for cnfType:NR_SystemConfirm_Type_RadioBearerList to Port Manager", __FUNCTION__);
}
}
return true;
}
/*
* Function : ss_task_sys_nr_handle_cellConfigAttenuation
* Description : This function handles the CellConfig 5G API on SYS Port for request type CellAttenuation and send processes the request.
* Returns : true/false
*/
bool ss_task_sys_nr_handle_cellConfigAttenuation(struct NR_SYSTEM_CTRL_REQ *req)
{
struct NR_SYSTEM_CTRL_CNF *msgCnf = CALLOC(1, sizeof(struct NR_SYSTEM_CTRL_CNF));
MessageDef *message_p = itti_alloc_new_message(TASK_SYS_GNB, INSTANCE_DEFAULT, SS_NR_SYS_PORT_MSG_CNF);
if (message_p)
{
LOG_A(GNB_APP, "[SYS-GNB] Send SS_NR_SYS_PORT_MSG_CNF\n");
msgCnf->Common.CellId = SS_context.eutra_cellId;
msgCnf->Common.Result.d = ConfirmationResult_Type_Success;
msgCnf->Common.Result.v.Success = true;
msgCnf->Confirm.d = NR_SystemConfirm_Type_CellAttenuationList;
msgCnf->Confirm.v.CellAttenuationList = true;
SS_NR_SYS_PORT_MSG_CNF(message_p).cnf = msgCnf;
int send_res = itti_send_msg_to_task(TASK_SS_PORTMAN_GNB, INSTANCE_DEFAULT, message_p);
if (send_res < 0)
{
LOG_A(GNB_APP, "[SYS-GNB] Error sending to [SS-PORTMAN-GNB]");
return false;
}
else
{
LOG_A(GNB_APP, "[SYS-GNB] fxn:%s NR_SYSTEM_CTRL_CNF sent for cnfType:CellAttenuationList to Port Manager", __FUNCTION__);
}
}
return true;
}
/*
* Function : sys_5G_send_proxy
* Description: Sends the messages from SYS to proxy
*/
static void sys_5G_send_proxy(void *msg, int msgLen)
{
LOG_A(ENB_SS, "Entry in %s\n", __FUNCTION__);
uint32_t peerIpAddr = 0;
uint16_t peerPort = proxy_5G_send_port;
IPV4_STR_ADDR_TO_INT_NWBO(local_5G_address,peerIpAddr, " BAD IP Address");
LOG_A(ENB_SS, "Sending CELL CONFIG 5G to Proxy\n");
int8_t *temp = msg;
/** Send to proxy */
sys_send_udp_msg((uint8_t *)msg, msgLen, 0, peerIpAddr, peerPort);
LOG_A(ENB_SS, "Exit from %s\n", __FUNCTION__);
return;
}
/*
* Function : sys_send_udp_msg
* Description: Sends the UDP_INIT message to UDP_TASK to create the listening socket
*/
static int sys_send_udp_msg(
uint8_t *buffer,
uint32_t buffer_len,
uint32_t buffer_offset,
uint32_t peerIpAddr,
uint16_t peerPort)
{
// Create and alloc new message
MessageDef *message_p = NULL;
udp_data_req_t *udp_data_req_p = NULL;
message_p = itti_alloc_new_message(TASK_SYS_GNB, 0, UDP_DATA_REQ);
if (message_p)
{
LOG_A(ENB_SS, "Sending UDP_DATA_REQ length %u offset %u buffer %d %d %d \n", buffer_len, buffer_offset, buffer[0], buffer[1], buffer[2]);
udp_data_req_p = &message_p->ittiMsg.udp_data_req;
udp_data_req_p->peer_address = peerIpAddr;
udp_data_req_p->peer_port = peerPort;
udp_data_req_p->buffer = buffer;
udp_data_req_p->buffer_length = buffer_len;
udp_data_req_p->buffer_offset = buffer_offset;
return itti_send_msg_to_task(TASK_UDP, 0, message_p);
}
else
{
LOG_A(ENB_SS, "Failed Sending UDP_DATA_REQ length %u offset %u \n", buffer_len, buffer_offset);
return -1;
}
}
/*
* Function : sys_send_init_udp
* Description: Sends the UDP_INIT message to UDP_TASK to create the receiving socket
* for the SYS_TASK from the Proxy for the configuration confirmations.
*/
static int sys_5G_send_init_udp(const udpSockReq_t *req)
{
// Create and alloc new message
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_SYS_GNB, 0, UDP_INIT);
if (message_p == NULL)
{
return -1;
}
UDP_INIT(message_p).port = req->port;
//addr.s_addr = req->ss_ip_addr;
UDP_INIT(message_p).address = req->address; //inet_ntoa(addr);
LOG_A(ENB_SS, "Tx UDP_INIT IP addr %s (%x)\n", UDP_INIT(message_p).address, UDP_INIT(message_p).port);
MSC_LOG_EVENT(
MSC_GTPU_ENB,
"0 UDP bind %s:%u",
UDP_INIT(message_p).address,
UDP_INIT(message_p).port);
return itti_send_msg_to_task(TASK_UDP, 0, message_p);
}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
#include "ss_eNB_proxy_iface.h"
#ifndef SS_GNB_TASK_H_ #ifndef SS_GNB_TASK_H_
#define SS_GNB_TASK_H_ #define SS_GNB_TASK_H_
...@@ -23,4 +24,19 @@ typedef struct udpSockReq_s ...@@ -23,4 +24,19 @@ typedef struct udpSockReq_s
char *address; char *address;
} udpSockReq_t; } udpSockReq_t;
typedef struct CellConfig5GReq_s
{
proxy_ss_header_t header;
int16_t maxRefPower;
uint8_t initialAttenuation;
long absoluteFrequencySSB;
} CellConfig5GReq_t;
typedef enum _sys_Type
{
SYS_TYPE_LTE,
SYS_TYPE_NR,
SYS_TYPE_ENDC
}sys_Type;
#endif /* SS_ENB_TASK_H_ */ #endif /* SS_ENB_TASK_H_ */
...@@ -308,8 +308,10 @@ void *udp_eNB_task(void *args_p) ...@@ -308,8 +308,10 @@ void *udp_eNB_task(void *args_p)
itti_mark_task_ready(TASK_UDP); itti_mark_task_ready(TASK_UDP);
MSC_START_USE(); MSC_START_USE();
LOG_I(UDP_, " Entry in %s\n", __FUNCTION__);
while(1) { while(1) {
LOG_I(UDP_, " Fxn:%s line:%d\n", __FUNCTION__, __LINE__);
itti_receive_msg(TASK_UDP, &received_message_p); itti_receive_msg(TASK_UDP, &received_message_p);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UDP_ENB_TASK, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UDP_ENB_TASK, VCD_FUNCTION_IN);
#if defined(LOG_UDP) && LOG_UDP > 0 #if defined(LOG_UDP) && LOG_UDP > 0
...@@ -343,7 +345,7 @@ void *udp_eNB_task(void *args_p) ...@@ -343,7 +345,7 @@ void *udp_eNB_task(void *args_p)
struct udp_socket_desc_s *udp_sock_p = NULL; struct udp_socket_desc_s *udp_sock_p = NULL;
udp_data_req_t *udp_data_req_p; udp_data_req_t *udp_data_req_p;
struct sockaddr_in peer_addr; struct sockaddr_in peer_addr;
char buffer[INET_ADDRSTRLEN];
udp_data_req_p = &received_message_p->ittiMsg.udp_data_req; udp_data_req_p = &received_message_p->ittiMsg.udp_data_req;
memset(&peer_addr, 0, sizeof(struct sockaddr_in)); memset(&peer_addr, 0, sizeof(struct sockaddr_in));
...@@ -351,6 +353,7 @@ void *udp_eNB_task(void *args_p) ...@@ -351,6 +353,7 @@ void *udp_eNB_task(void *args_p)
peer_addr.sin_family = AF_INET; peer_addr.sin_family = AF_INET;
peer_addr.sin_port = htons(udp_data_req_p->peer_port); peer_addr.sin_port = htons(udp_data_req_p->peer_port);
peer_addr.sin_addr.s_addr = udp_data_req_p->peer_address; peer_addr.sin_addr.s_addr = udp_data_req_p->peer_address;
inet_ntop( AF_INET, &peer_addr.sin_addr, buffer, sizeof( buffer ));
pthread_mutex_lock(&udp_socket_list_mutex); pthread_mutex_lock(&udp_socket_list_mutex);
udp_sock_p = udp_eNB_get_socket_desc(ITTI_MSG_ORIGIN_ID(received_message_p)); udp_sock_p = udp_eNB_get_socket_desc(ITTI_MSG_ORIGIN_ID(received_message_p));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment