Commit 9918c692 authored by Sakthivel Velumani's avatar Sakthivel Velumani

Merge branch 'develop' into gnb-realtime-quickfix

parents 8cd4c719 f0a1d0c2
...@@ -333,6 +333,11 @@ else (CUDA_FOUND) ...@@ -333,6 +333,11 @@ else (CUDA_FOUND)
) )
endif () endif ()
if (SANITIZE_ADDRESS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
endif ()
add_definitions("-DASN_DISABLE_OER_SUPPORT") add_definitions("-DASN_DISABLE_OER_SUPPORT")
######################### #########################
......
...@@ -68,6 +68,7 @@ USRP_REC_PLAY="False" ...@@ -68,6 +68,7 @@ USRP_REC_PLAY="False"
BUILD_ECLIPSE=0 BUILD_ECLIPSE=0
NR="False" NR="False"
ITTI_SIM="False" ITTI_SIM="False"
SANITIZE_ADDRESS="False"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc" OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc"
trap handle_ctrl_c INT trap handle_ctrl_c INT
...@@ -424,6 +425,9 @@ function main() { ...@@ -424,6 +425,9 @@ function main() {
CMAKE_CMD="$CMAKE_CMD -GNinja" CMAKE_CMD="$CMAKE_CMD -GNinja"
MAKE_CMD=ninja MAKE_CMD=ninja
shift;; shift;;
--sanitize-address | -fsanitize=address)
SANITIZE_ADDRESS=True
shift;;
--ittiSIM) --ittiSIM)
ittiSIM=1 ittiSIM=1
ITTI_SIM="True" ITTI_SIM="True"
...@@ -612,6 +616,7 @@ function main() { ...@@ -612,6 +616,7 @@ function main() {
echo "set ( USRP_REC_PLAY $USRP_REC_PLAY )" >> $cmake_file echo "set ( USRP_REC_PLAY $USRP_REC_PLAY )" >> $cmake_file
echo "set ( SKIP_SHARED_LIB_FLAG $SKIP_SHARED_LIB_FLAG )" >> $cmake_file echo "set ( SKIP_SHARED_LIB_FLAG $SKIP_SHARED_LIB_FLAG )" >> $cmake_file
echo "set ( ITTI_SIM $ITTI_SIM )" >> $cmake_file echo "set ( ITTI_SIM $ITTI_SIM )" >> $cmake_file
echo "set ( SANITIZE_ADDRESS $SANITIZE_ADDRESS )" >> $cmake_file
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
cd $DIR/$build_dir/build cd $DIR/$build_dir/build
eval $CMAKE_CMD eval $CMAKE_CMD
......
...@@ -44,10 +44,11 @@ Our code might not work with all 5G phones yet, but we are constantly improving ...@@ -44,10 +44,11 @@ Our code might not work with all 5G phones yet, but we are constantly improving
* Oppo Reno 5G * Oppo Reno 5G
* Samsung A90 5G * Samsung A90 5G
* Google Pixel 5G * Google Pixel 5G (note1)
* Simcom SIMCOM8200EA * Simcom SIMCOM8200EA
* Quectel RM500Q-GL * Quectel RM500Q-GL
Note1: In the version we have at Eurecom, you need to set the PLMN to 50501, and you also need to change the firmware to "11.0.0 (RD1A.201105.003.B1, Nov 2020, EU carriers)" (see https://developers.google.com/android/images)
## Repository ## Repository
......
...@@ -650,7 +650,7 @@ control: ...@@ -650,7 +650,7 @@ control:
control_decoder = decoder; control_decoder = decoder;
control_e1 = e1; control_e1 = e1;
while (control_e1) { while (control_e1) {
nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder); /* NACK_SN */ nack_sn = nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder);
control_e1 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); control_e1 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
control_e2 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); control_e2 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
control_e3 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); control_e3 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
...@@ -660,17 +660,36 @@ control: ...@@ -660,17 +660,36 @@ control:
} else { } else {
nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder);
} }
/* check range and so_start/so_end consistency */
if (control_e2) { if (control_e2) {
nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOstart */ so_start = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder);
nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOend */ so_end = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder);
} else {
so_start = 0;
so_end = 0xffff;
} }
if (control_e3) { if (control_e3) {
nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder); /* NACK range */ range = nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder);
} else {
range = 1;
}
if (range < 1) {
LOG_E(RLC, "%s:%d:%s: error, bad 'range' in RLC NACK (sn %d)\n",
__FILE__, __LINE__, __FUNCTION__, nack_sn);
goto err;
}
/* so_start can be > so_end if more than one range; they don't refer
* to the same PDU then
*/
if (range == 1 && so_end < so_start) {
LOG_E(RLC, "%s:%d:%s: error, bad so start/end (sn %d)\n",
__FILE__, __LINE__, __FUNCTION__, nack_sn);
goto err;
} }
} }
/* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
* received for the SN 'poll_sn' * received for the SN 'poll_sn' - check ACK case (NACK done below)
*/ */
if (sn_compare_tx(entity, entity->poll_sn, ack_sn) < 0) if (sn_compare_tx(entity, entity->poll_sn, ack_sn) < 0)
entity->t_poll_retransmit_start = 0; entity->t_poll_retransmit_start = 0;
...@@ -697,28 +716,22 @@ control: ...@@ -697,28 +716,22 @@ control:
if (e2) { if (e2) {
so_start = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); so_start = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
so_end = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); so_end = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder);
if (so_end < so_start) {
LOG_W(RLC, "%s:%d:%s: warning, bad so start/end, NACK the whole PDU (sn %d)\n",
__FILE__, __LINE__, __FUNCTION__, nack_sn);
so_start = 0;
so_end = -1;
}
/* special value 0xffff indicates 'all bytes to the end' */
if (so_end == 0xffff)
so_end = -1;
} else { } else {
so_start = 0; so_start = 0;
so_end = -1; so_end = 0xffff;
} }
if (e3) { if (e3) {
range = nr_rlc_pdu_decoder_get_bits(&decoder, 8); R(decoder); range = nr_rlc_pdu_decoder_get_bits(&decoder, 8); R(decoder);
} else { } else {
range = 1; range = 1;
} }
/* special value 0xffff indicates 'all bytes to the end' */
if (so_end == 0xffff)
so_end = -1;
process_received_nack(entity, nack_sn, so_start, so_end, range, sn_set); process_received_nack(entity, nack_sn, so_start, so_end, range, sn_set);
/* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is
* received for the SN 'poll_sn' * received for the SN 'poll_sn' - check NACK case (ACK done above)
*/ */
if (sn_compare_tx(entity, nack_sn, entity->poll_sn) <= 0 && if (sn_compare_tx(entity, nack_sn, entity->poll_sn) <= 0 &&
sn_compare_tx(entity, entity->poll_sn, (nack_sn + range) % entity->sn_modulus) < 0) sn_compare_tx(entity, entity->poll_sn, (nack_sn + range) % entity->sn_modulus) < 0)
......
#!/bin/sh #!/bin/sh
test_count=14 test_count=15
for i in `seq $test_count` for i in `seq $test_count`
do do
......
/*
* am test (SN field size 18):
* test "range" in NACK, generate a case where so_start > so_end
* (so so_start and so_end are not from the same PDU)
*/
TIME, 1,
GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18,
UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18,
GNB_PDU_SIZE, 40,
UE_PDU_SIZE, 80,
GNB_SDU, 0, 50,
GNB_SDU, 1, 50,
GNB_SDU, 2, 50,
TIME, 2,
UE_RECV_FAILS, 1,
TIME, 4,
UE_RECV_FAILS, 0,
TIME, -1
...@@ -67,6 +67,8 @@ ...@@ -67,6 +67,8 @@
#define MAX_NUM_NEIGH_CELLs 6 /* maximum neighbouring cells number */ #define MAX_NUM_NEIGH_CELLs 6 /* maximum neighbouring cells number */
#define MAX_NUM_GNB_CELLs 1 /* maximum gNB cells number */
#define UE_STATE_NOTIFICATION_INTERVAL 50 #define UE_STATE_NOTIFICATION_INTERVAL 50
#define IPV4_ADDR "%u.%u.%u.%u" #define IPV4_ADDR "%u.%u.%u.%u"
...@@ -804,8 +806,13 @@ typedef struct eNB_RRC_INST_s { ...@@ -804,8 +806,13 @@ typedef struct eNB_RRC_INST_s {
int num_neigh_cells_cc[MAX_NUM_CCs]; int num_neigh_cells_cc[MAX_NUM_CCs];
uint32_t neigh_cells_id[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs]; uint32_t neigh_cells_id[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
// gNB cells connected to this eNB
int num_gnb_cells;
int num_gnb_cells_cc[MAX_NUM_GNB_CELLs];
uint32_t gnb_cells_id[MAX_NUM_GNB_CELLs][MAX_NUM_CCs];
// Nr scc freq band and SSB absolute frequency // Nr scc freq band and SSB absolute frequency
uint32_t nr_neigh_freq_band[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs]; uint32_t nr_gnb_freq_band[MAX_NUM_GNB_CELLs][MAX_NUM_CCs];
int nr_scg_ssb_freq; int nr_scg_ssb_freq;
// other RAN parameters // other RAN parameters
......
...@@ -1283,7 +1283,7 @@ rrc_eNB_generate_UECapabilityEnquiry( ...@@ -1283,7 +1283,7 @@ rrc_eNB_generate_UECapabilityEnquiry(
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0]; int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0]; uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
size = do_UECapabilityEnquiry( size = do_UECapabilityEnquiry(
ctxt_pP, ctxt_pP,
buffer, buffer,
...@@ -1333,7 +1333,7 @@ rrc_eNB_generate_NR_UECapabilityEnquiry( ...@@ -1333,7 +1333,7 @@ rrc_eNB_generate_NR_UECapabilityEnquiry(
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0]; int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0]; uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0];
size = do_NR_UECapabilityEnquiry( size = do_NR_UECapabilityEnquiry(
ctxt_pP, ctxt_pP,
buffer, buffer,
...@@ -7588,8 +7588,8 @@ is_en_dc_supported( ...@@ -7588,8 +7588,8 @@ is_en_dc_supported(
) )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
/* to be refined - check that the eNB is connected to a gNB, check that /* to be refined - check that the bands supported by the UE include
* the bands supported by the UE include the band of the gNB * the band of the gNB
*/ */
#define NCE nonCriticalExtension #define NCE nonCriticalExtension
return c != NULL return c != NULL
...@@ -8289,8 +8289,13 @@ rrc_eNB_decode_dcch( ...@@ -8289,8 +8289,13 @@ rrc_eNB_decode_dcch(
ue_context_p->ue_context.UE_Capability = 0; ue_context_p->ue_context.UE_Capability = 0;
} }
if (dec_rval.code == RC_OK) if (dec_rval.code == RC_OK) {
/* do NR only if at least one gNB connected */
if (RC.rrc[ctxt_pP->module_id]->num_gnb_cells != 0)
ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability); ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability);
else
ue_context_p->ue_context.does_nr = 0;
}
if (EPC_MODE_ENABLED) { if (EPC_MODE_ENABLED) {
rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP, rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP,
...@@ -9029,22 +9034,22 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { ...@@ -9029,22 +9034,22 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
} }
void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m) { void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m) {
if (RC.rrc[mod_id]->num_neigh_cells > MAX_NUM_NEIGH_CELLs) { if (RC.rrc[mod_id]->num_gnb_cells >= MAX_NUM_GNB_CELLs) {
LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n"); LOG_E(RRC, "Error: number of gNB cells is exceeded\n");
return; return;
} }
if (m->num_cc > MAX_NUM_CCs) { if (m->num_cc > MAX_NUM_CCs) {
LOG_E(RRC, "Error: number of neighbouring cells carriers is exceeded \n"); LOG_E(RRC, "Error: number of gNB cells carriers is exceeded \n");
return; return;
} }
RC.rrc[mod_id]->num_neigh_cells++; RC.rrc[mod_id]->num_gnb_cells++;
RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc; RC.rrc[mod_id]->num_gnb_cells_cc[RC.rrc[mod_id]->num_gnb_cells-1] = m->num_cc;
for (int i=0; i<m->num_cc; i++) { for (int i=0; i<m->num_cc; i++) {
RC.rrc[mod_id]->neigh_cells_id[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->Nid_cell[i]; RC.rrc[mod_id]->gnb_cells_id[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->Nid_cell[i];
RC.rrc[mod_id]->nr_neigh_freq_band[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->servedNrCell_band[i]; RC.rrc[mod_id]->nr_gnb_freq_band[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->servedNrCell_band[i];
} }
} }
......
...@@ -116,9 +116,7 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa ...@@ -116,9 +116,7 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
/* some sanity check - to be refined at some point */ /* some sanity check - to be refined at some point */
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n"); X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
// Allow for a gracious exit when we kill first the gNB, then the eNB exit(1);
//abort();
return;
} }
x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams; x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams;
......
...@@ -690,9 +690,11 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance, ...@@ -690,9 +690,11 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
// need a FSM to handle all cases // need a FSM to handle all cases
if ((ie->value.choice.Cause.present == X2AP_Cause_PR_misc) && if ((ie->value.choice.Cause.present == X2AP_Cause_PR_misc) &&
(ie->value.choice.Cause.choice.misc == X2AP_CauseMisc_unspecified)) { (ie->value.choice.Cause.choice.misc == X2AP_CauseMisc_unspecified)) {
X2AP_WARN("Received X2 setup failure for eNB ... eNB is not ready\n"); X2AP_ERROR("Received X2 setup failure for eNB ... eNB is not ready\n");
exit(1);
} else { } else {
X2AP_ERROR("Received x2 setup failure for eNB... please check your parameters\n"); X2AP_ERROR("Received x2 setup failure for eNB... please check your parameters\n");
exit(1);
} }
x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING; x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING;
......
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