From 63a5c693b436783bf35328aba30888bb2fe13f85 Mon Sep 17 00:00:00 2001 From: He Shanyun Date: Thu, 28 Nov 2019 10:25:13 +0900 Subject: [PATCH 01/91] modify decode error about supportedCodecList in NAS message --- openair3/NAS/COMMON/IES/SupportedCodecList.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openair3/NAS/COMMON/IES/SupportedCodecList.c b/openair3/NAS/COMMON/IES/SupportedCodecList.c index 3a69eee366..15a2fecaa0 100644 --- a/openair3/NAS/COMMON/IES/SupportedCodecList.c +++ b/openair3/NAS/COMMON/IES/SupportedCodecList.c @@ -43,13 +43,17 @@ int decode_supported_codec_list(SupportedCodecList *supportedcodeclist, uint8_t CHECK_LENGTH_DECODER(len - decoded, ielen); supportedcodeclist->systemidentification = *(buffer + decoded); decoded++; + ielen--; supportedcodeclist->lengthofbitmap = *(buffer + decoded); decoded++; + ielen--; //IES_DECODE_U16(supportedcodeclist->codecbitmap, *(buffer + decoded)); IES_DECODE_U16(buffer, decoded, supportedcodeclist->codecbitmap); + ielen=ielen -2; #if defined (NAS_DEBUG) dump_supported_codec_list_xml(supportedcodeclist, iei); #endif + decoded = decoded + ielen; return decoded; } int encode_supported_codec_list(SupportedCodecList *supportedcodeclist, uint8_t iei, uint8_t *buffer, uint32_t len) From df17a8dd4f220aa9ba4c0ea0b5162939fdb1cbfb Mon Sep 17 00:00:00 2001 From: Wu Jing Date: Wed, 8 Jan 2020 16:50:16 +0900 Subject: [PATCH 02/91] merge NNSF feature based on v1.0.2 (cherry picked from commit b9e93a16379cf261502d9451b60bd787c07da64e) --- openair2/RRC/LTE/rrc_eNB_S1AP.c | 32 ++++++++--- openair3/S1AP/s1ap_eNB_defs.h | 2 + openair3/S1AP/s1ap_eNB_nas_procedures.c | 17 +++--- openair3/S1AP/s1ap_eNB_nnsf.c | 70 ++++++++++++++++++++++--- openair3/S1AP/s1ap_eNB_nnsf.h | 3 +- 5 files changed, 101 insertions(+), 23 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 4be9a50b32..b319491207 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -782,21 +782,37 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei; if (r_mme->plmn_Identity != NULL) { - if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) { - /* Use first indicated PLMN MCC if it is defined */ - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity]; + if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count == 3)) + { + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = (*r_mme->plmn_Identity->mcc->list.array[0] & 0xf) * 100 + + (*r_mme->plmn_Identity->mcc->list.array[1] & 0xf) * 10 + + (*r_mme->plmn_Identity->mcc->list.array[2] & 0xf); LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc, ue_context_pP->ue_context.rnti); } - - if (r_mme->plmn_Identity->mnc.list.count > 0) { - /* Use first indicated PLMN MNC if it is defined */ - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity]; - LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", + if(r_mme->plmn_Identity->mnc.list.count == 3) + { + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 100 + + (*r_mme->plmn_Identity->mnc.list.array[1] & 0xf) * 10 + + (*r_mme->plmn_Identity->mnc.list.array[2] & 0xf); + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 3; + LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len, + ue_context_pP->ue_context.rnti); + } + else if(r_mme->plmn_Identity->mnc.list.count == 2) + { + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 10 + + (*r_mme->plmn_Identity->mnc.list.array[1] & 0xf); + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 2; + LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n", + ctxt_pP->module_id, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len, ue_context_pP->ue_context.rnti); } } else { // end if plmn_Identity != NULL diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h index d4bc6cfc0f..c6f44cdb18 100644 --- a/openair3/S1AP/s1ap_eNB_defs.h +++ b/openair3/S1AP/s1ap_eNB_defs.h @@ -164,6 +164,8 @@ typedef struct s1ap_eNB_mme_data_s { /* Only meaningfull in virtual mode */ struct s1ap_eNB_instance_s *s1ap_eNB_instance; + + uint32_t nb_calls; } s1ap_eNB_mme_data_t; typedef struct s1ap_eNB_instance_s { diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index d931e76bb6..4744ff4e43 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -138,8 +138,9 @@ int s1ap_eNB_handle_nas_first_req( * identity, selects the MME with the highest capacity. */ mme_desc_p = s1ap_eNB_nnsf_select_mme( - instance_p, - s1ap_nas_first_req_p->establishment_cause); + instance_p, + s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->selected_plmn_identity); if (mme_desc_p) { S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", @@ -232,9 +233,9 @@ int s1ap_eNB_handle_nas_first_req( MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id, 0, // Cell ID &ie->value.choice.EUTRAN_CGI.cell_ID); - MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], - instance_p->mnc[ue_desc_p->selected_plmn_identity], - instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], + MCC_MNC_TO_TBCD(instance_p->mcc[mme_desc_p->broadcast_plmn_index[0]], + instance_p->mnc[mme_desc_p->broadcast_plmn_index[0]], + instance_p->mnc_digit_length[mme_desc_p->broadcast_plmn_index[0]], &ie->value.choice.EUTRAN_CGI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* Set the establishment cause according to those provided by RRC */ @@ -494,9 +495,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ ie->criticality = S1AP_Criticality_ignore; ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI; MCC_MNC_TO_PLMNID( - s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], - s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], - s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mcc[ue_context_p->mme_ref->broadcast_plmn_index[0]], + s1ap_eNB_instance_p->mnc[ue_context_p->mme_ref->broadcast_plmn_index[0]], + s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->mme_ref->broadcast_plmn_index[0]], &ie->value.choice.EUTRAN_CGI.pLMNidentity); //#warning "TODO get cell id from RRC" MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id, diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c index 6319f6e054..6577b8f10b 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.c +++ b/openair3/S1AP/s1ap_eNB_nnsf.c @@ -38,13 +38,27 @@ struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, - rrc_establishment_cause_t cause) + rrc_establishment_cause_t cause, + uint32_t plmn_id) { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; - uint8_t current_capacity = 0; + typedef struct MME_nnsf_inf { + struct s1ap_eNB_mme_data_s *mme_p; + uint64_t weight; + } MME_nnsf_inf_t; + + uint16_t capacity_sum = 0; + MME_nnsf_inf_t mme_inf[10]; + int cnt; + int nb_mme = 0; + uint64_t weight = 0; + + memset(mme_inf, 0, sizeof(mme_inf)); RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + struct served_gummei_s *gummei_p = NULL; + capacity_sum = capacity_sum + mme_data_p->relative_mme_capacity; if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) { /* The association between MME and eNB is not ready for the moment, * go to the next known MME. @@ -79,12 +93,56 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, } } - if (current_capacity < mme_data_p->relative_mme_capacity) { - /* We find a better MME, keep a reference to it */ - current_capacity = mme_data_p->relative_mme_capacity; - mme_highest_capacity_p = mme_data_p; + gummei_p = mme_data_p->served_gummei.stqh_first; + if( gummei_p != NULL ) + { + struct plmn_identity_s *served_plmns_p = NULL; + + served_plmns_p = gummei_p->served_plmns.stqh_first; + if( served_plmns_p != 0 ) + for( cnt = 0 ; cnt < 8 ; cnt++) + { + if ( (served_plmns_p->mcc == instance_p->mcc[plmn_id]) && + (served_plmns_p->mnc == instance_p->mnc[plmn_id]) ) + { + mme_inf[nb_mme].mme_p = mme_data_p; + nb_mme++; + break; + } + if( served_plmns_p->next.stqe_next == 0 ) + { + break; + } + served_plmns_p = served_plmns_p->next.stqe_next; + } } } + if( nb_mme != 0 ) + { + for( cnt = 0 ; cnt < nb_mme ; cnt++ ) + { + mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity; + mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1); + } + mme_highest_capacity_p = mme_inf[0].mme_p; + weight = mme_inf[0].weight; + for( cnt = 1 ; cnt < nb_mme ; cnt++ ) + { + if( weight > mme_inf[cnt].weight ) + { + mme_highest_capacity_p = mme_inf[cnt].mme_p; + weight = mme_inf[cnt].weight; + } + } + } + else + { + mme_highest_capacity_p = NULL; + } + if( mme_highest_capacity_p != NULL ) + { + mme_highest_capacity_p->nb_calls++; + } return mme_highest_capacity_p; } diff --git a/openair3/S1AP/s1ap_eNB_nnsf.h b/openair3/S1AP/s1ap_eNB_nnsf.h index d5f080649b..de039b7d30 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.h +++ b/openair3/S1AP/s1ap_eNB_nnsf.h @@ -24,7 +24,8 @@ struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, - rrc_establishment_cause_t cause); + rrc_establishment_cause_t cause, + uint32_t plmn_id); struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, From f006866c74a74554ac694a216f21a30e767bc07d Mon Sep 17 00:00:00 2001 From: Haruki NAOI Date: Thu, 12 Mar 2020 14:55:26 +0900 Subject: [PATCH 03/91] Fix: Drop paging message on sctp stream zero. (cherry picked from commit 2d45f940be267e013781d6baba5b2ab665e64c88) --- openair3/S1AP/s1ap_eNB_handlers.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 79501a1a09..7a3715f61b 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -1105,13 +1105,6 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, // received Paging Message from MME S1AP_DEBUG("[SCTP %d] Received Paging Message From MME\n",assoc_id); - /* Paging procedure -> stream != 0 */ - if (stream == 0) { - LOG_W(S1AP,"[SCTP %d] Received Paging procedure on stream (%d)\n", - assoc_id, stream); - return -1; - } - if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { S1AP_ERROR("[SCTP %d] Received Paging for non " "existing MME context\n", assoc_id); From cead17f2d8efa326392d31cbbf9b79a6ccdcb793 Mon Sep 17 00:00:00 2001 From: Wu Jing Date: Thu, 2 Apr 2020 10:09:02 +0900 Subject: [PATCH 04/91] Fix openair3/NAS/UE cppcheck error --- openair3/NAS/UE/EMM/SAP/emm_as.c | 4 ++-- openair3/NAS/UE/EMM/SecurityModeControl.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 99a3763dea..10b118eac0 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -443,14 +443,14 @@ static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm EPS_MOBILITY_MANAGEMENT_MESSAGE) { /* Process EMM data */ rc = _emm_as_recv(user, plain_msg, bytes, emm_cause); + free(plain_msg); } else if (header.protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) { const OctetString data = {bytes, (uint8_t *)plain_msg}; /* Foward ESM data to EPS session management */ rc = lowerlayer_data_ind(user, &data); + free(plain_msg); } - - free(plain_msg); } } else { /* Process successfull lower layer transfer indication */ diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index 67bfaf784e..b27270fadc 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -296,16 +296,16 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, else { /* Setup EMM cause code */ emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; - - /* Release security mode control internal data */ - if (security_data->kenb.value) { - free(security_data->kenb.value); - security_data->kenb.value = NULL; - security_data->kenb.length = 0; - } } } + /* Release security mode control internal data */ + if (security_data->kenb.value) { + free(security_data->kenb.value); + security_data->kenb.value = NULL; + security_data->kenb.length = 0; + } + /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); From 7631a1dc1df843f328fcb299fd6d39533be84162 Mon Sep 17 00:00:00 2001 From: Ding Yumei Date: Sun, 20 Dec 2020 18:32:40 +0100 Subject: [PATCH 05/91] fix s1ap StreamID issue --- openair3/S1AP/s1ap_eNB_handlers.c | 4 +--- openair3/S1AP/s1ap_eNB_overload.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 7a3715f61b..0895494837 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -1512,7 +1512,6 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, if (stream == 0) { S1AP_ERROR("[SCTP %d] Received s1 path switch request ack on stream (%d)\n", assoc_id, stream); - //return -1; } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { @@ -1667,9 +1666,8 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_ pathSwitchRequestFailure = &pdu->choice.unsuccessfulOutcome.value.choice.PathSwitchRequestFailure; if (stream != 0) { - S1AP_ERROR("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n", + S1AP_WARN("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n", assoc_id, stream); - return -1; } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { diff --git a/openair3/S1AP/s1ap_eNB_overload.c b/openair3/S1AP/s1ap_eNB_overload.c index 9358ae62bd..e331d03b4a 100644 --- a/openair3/S1AP/s1ap_eNB_overload.c +++ b/openair3/S1AP/s1ap_eNB_overload.c @@ -63,7 +63,11 @@ int s1ap_eNB_handle_overload_start(uint32_t assoc_id, S1AP_OverloadResponse_PR_overloadAction, 0, 0); } /* Non UE-associated signalling -> stream 0 */ - DevCheck(stream == 0, stream, 0, 0); + if (stream != 0) { + S1AP_ERROR("[SCTP %d] Received s1 overload start on stream != 0 (%d)\n", + assoc_id, stream); + return -1; + } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { /* No MME context associated */ @@ -93,7 +97,11 @@ int s1ap_eNB_handle_overload_stop(uint32_t assoc_id, s1ap_eNB_mme_data_t *mme_desc_p; /* Non UE-associated signalling -> stream 0 */ - DevCheck(stream == 0, stream, 0, 0); + if (stream != 0) { + S1AP_ERROR("[SCTP %d] Received s1 overload stop on stream != 0 (%d)\n", + assoc_id, stream); + return -1; + } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { /* No MME context associated */ From 46407ca42b51404e0251a2d27bd42ed63ae88b8e Mon Sep 17 00:00:00 2001 From: Haruki NAOI Date: Wed, 8 Apr 2020 11:50:58 +0900 Subject: [PATCH 06/91] Add S1down auto recovery. (cherry picked from commit 2339972ceaeb75fe18c0b2ae9ea69216dd919668) --- cmake_targets/CMakeLists.txt | 1 + openair2/COMMON/s1ap_messages_types.h | 5 + openair2/COMMON/tasks_def.h | 3 +- openair2/ENB_APP/enb_config.c | 59 +++ openair2/ENB_APP/enb_paramdef.h | 15 + openair2/X2AP/x2ap_common.h | 2 +- openair2/X2AP/x2ap_eNB_handler.c | 35 +- openair3/S1AP/s1ap_common.h | 7 +- openair3/S1AP/s1ap_eNB.c | 398 +++++++++++++++-- openair3/S1AP/s1ap_eNB_defs.h | 12 + openair3/S1AP/s1ap_eNB_handlers.c | 409 +++++++++++++++--- .../S1AP/s1ap_eNB_management_procedures.c | 47 +- openair3/S1AP/s1ap_eNB_nas_procedures.c | 12 + openair3/S1AP/s1ap_eNB_overload.c | 4 + openair3/S1AP/s1ap_eNB_timer.c | 300 +++++++++++++ openair3/S1AP/s1ap_eNB_timer.h | 86 ++++ openair3/S1AP/s1ap_eNB_trace.c | 4 + openair3/SCTP/sctp_default_values.h | 4 +- openair3/SCTP/sctp_eNB_task.c | 4 +- 19 files changed, 1289 insertions(+), 118 deletions(-) create mode 100644 openair3/S1AP/s1ap_eNB_timer.c create mode 100644 openair3/S1AP/s1ap_eNB_timer.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 0b9d925017..a85dc7e5ea 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -540,6 +540,7 @@ add_library(S1AP_ENB ${S1AP_DIR}/s1ap_eNB_overload.c ${S1AP_DIR}/s1ap_eNB_trace.c ${S1AP_DIR}/s1ap_eNB_ue_context.c + ${S1AP_DIR}/s1ap_eNB_timer.c ) add_dependencies(S1AP_ENB rrc_flag s1ap_flag) diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index f6b4f3c4e2..38214fc71f 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -393,6 +393,11 @@ typedef struct s1ap_register_enb_req_s { /* Number of SCTP streams used for a mme association */ uint16_t sctp_in_streams; uint16_t sctp_out_streams; + uint16_t s1_setuprsp_wait_timer; + uint16_t s1_setupreq_wait_timer; + uint16_t s1_setupreq_count; + uint16_t sctp_req_timer; + uint16_t sctp_req_count; } s1ap_register_enb_req_t; //-------------------------------------------------------------------------------------------// diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h index 33b6d5f9d4..f84195d5d7 100644 --- a/openair2/COMMON/tasks_def.h +++ b/openair2/COMMON/tasks_def.h @@ -47,7 +47,8 @@ TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000) // GTP_V1U task TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000) -TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200) +//TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200) +TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 2000) TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200) /// M3ap task, acts as both source and target diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index de77d783c7..31d0efb0aa 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2426,6 +2426,65 @@ int RCconfig_S1( "to\n" " tracking_area_code = 1; // no string!!\n" " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); + if(*ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr; + } + else + { + LOG_E(S1AP, + "s1setup_rsp_timer value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = 5; + } + + if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr; + } + else + { + LOG_E(S1AP, + "s1setup_req_timer value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = 5; + } + + if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr; + } + else + { + LOG_E(S1AP, + "s1setup_req_count value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = 0xffff; + } + + if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr; + } + else + { + LOG_E(S1AP, + "sctp_req_timer value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = 180; + } + + if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr; + } + else + { + LOG_E(S1AP, + "sctp_req_count value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = 0xffff; + } config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) { diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index de7e0bbdad..f26863414c 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -214,6 +214,11 @@ typedef enum { #define ENB_CONFIG_STRING_X2 "enable_x2" #define ENB_CONFIG_STRING_ENB_M2 "enable_enb_m2" #define ENB_CONFIG_STRING_MCE_M2 "enable_mce_m2" +#define ENB_CONFIG_STRING_S1SETUP_RSP_TIMER "s1setup_rsp_timer" +#define ENB_CONFIG_STRING_S1SETUP_REQ_TIMER "s1setup_req_timer" +#define ENB_CONFIG_STRING_S1SETUP_REQ_COUNT "s1setup_req_count" +#define ENB_CONFIG_STRING_SCTP_REQ_TIMER "sctp_req_timer" +#define ENB_CONFIG_STRING_SCTP_REQ_COUNT "sctp_req_count" /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -239,6 +244,11 @@ typedef enum { {ENB_CONFIG_STRING_X2, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_MCE_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_S1SETUP_RSP_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_S1SETUP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_S1SETUP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_SCTP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:180, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_SCTP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \ } #define ENB_ENB_ID_IDX 0 @@ -261,6 +271,11 @@ typedef enum { #define ENB_ENABLE_X2 17 #define ENB_ENABLE_ENB_M2 18 #define ENB_ENABLE_MCE_M2 19 +#define ENB_S1SETUP_RSP_TIMER_IDX 20 +#define ENB_S1SETUP_REQ_TIMER_IDX 21 +#define ENB_S1SETUP_REQ_COUNT_IDX 22 +#define ENB_SCTP_REQ_TIMER_IDX 23 +#define ENB_SCTP_REQ_COUNT_IDX 24 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define ENBPARAMS_CHECK { \ diff --git a/openair2/X2AP/x2ap_common.h b/openair2/X2AP/x2ap_common.h index a2f903a737..470a023c31 100644 --- a/openair2/X2AP/x2ap_common.h +++ b/openair2/X2AP/x2ap_common.h @@ -84,7 +84,7 @@ extern int asn1_xer_print; break; \ } \ } \ - if (mandatory) DevAssert(ie != NULL); \ +/* if (mandatory) DevAssert(ie != NULL); \*/ \ } while(0) /** \brief Function callback prototype. diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index bbdeaf0ac8..db03507539 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -536,6 +536,14 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance, return -1; } + if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) || + (x2ap_eNB_data->state == X2AP_ENB_STATE_READY)) + + { + X2AP_ERROR("Received Unexpexted X2 Setup Response Message\n"); + return -1; + } + X2AP_DEBUG("Received a new X2 setup response\n"); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse, @@ -662,6 +670,14 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance, return -1; } + if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) || + (x2ap_eNB_data->state == X2AP_ENB_STATE_READY)) + + { + X2AP_ERROR("Received Unexpexted X2 Setup Failure Message\n"); + return -1; + } + X2AP_DEBUG("Received a new X2 setup failure\n"); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupFailure_IEs_t, ie, x2SetupFailure, @@ -730,6 +746,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -750,7 +767,11 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, //measResultListEUTRA.list.array[ncell_index]->physCellId; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, X2AP_ProtocolIE_ID_id_GUMMEI_ID, true); - + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); + return -1; + } TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, X2AP_HANDOVER_REQ(msg).ue_gummei.mcc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len); OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code); @@ -761,6 +782,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -872,6 +894,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -882,6 +905,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -912,6 +936,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n", __FILE__, __LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; }else{ if (ie->value.choice.E_RABs_Admitted_List.list.count > 0) { @@ -959,6 +984,12 @@ int x2ap_eNB_handle_handover_response (instance_t instance, X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); + return -1; + } + X2AP_TargeteNBtoSource_eNBTransparentContainer_t *c = &ie->value.choice.TargeteNBtoSource_eNBTransparentContainer; if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s */) @@ -1012,6 +1043,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -1022,6 +1054,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h index 77d03f4ae4..efac0201a3 100644 --- a/openair3/S1AP/s1ap_common.h +++ b/openair3/S1AP/s1ap_common.h @@ -106,7 +106,12 @@ extern int asn1_xer_print; if (ie == NULL ) { \ S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\ } \ - if (mandatory) DevAssert(ie != NULL); \ + if (mandatory) { \ + if (ie == NULL) { \ + S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\ + return -1; \ + } \ + } \ } while(0) /** \brief Function callback prototype. **/ diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 2a153acaa2..8452d9e563 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -58,6 +58,8 @@ #include "s1ap_eNB_ue_context.h" // test, to be removed #include "msc.h" +#include "s1ap_eNB_timer.h" + #include "assertions.h" #include "conversions.h" #if defined(TEST_S1C_MME) @@ -73,6 +75,11 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); +static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, + s1ap_eNB_mme_data_t *s1ap_mme_data_p); +void s1ap_eNB_timer_expired(instance_t instance, + s1ap_timer_has_expired_t *msg_p); + uint32_t s1ap_generate_eNB_id(void) { char *out; char hostname[50]; @@ -114,9 +121,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, local_ip_addr, sizeof(*local_ip_addr)); S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance); - mme = NULL; - - if ( mme == NULL ) { +// mme = NULL; +// +// if ( mme == NULL ) { /* Create new MME descriptor */ s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p)); DevAssert(s1ap_mme_data_p != NULL); @@ -136,28 +143,33 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, * 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 ++; +// s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING; + s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED; + memcpy( &(s1ap_mme_data_p->mme_ip_address), mme_ip_address, sizeof(net_ip_address_t) ); + s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD; + s1ap_mme_data_p->sctp_req_cnt++; + s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT; +// 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); - } +// } 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); +// } itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); } @@ -168,6 +180,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * uint8_t index; DevAssert(s1ap_register_eNB != NULL); /* Look if the provided instance already exists */ + s1ap_timer_init(); new_instance = s1ap_eNB_get_instance(instance); if (new_instance != NULL) { @@ -195,7 +208,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * new_instance->eNB_id = s1ap_register_eNB->eNB_id; new_instance->cell_type = s1ap_register_eNB->cell_type; new_instance->tac = s1ap_register_eNB->tac; - + memcpy(&new_instance->eNB_s1_ip, &s1ap_register_eNB->enb_ip_address, sizeof(s1ap_register_eNB->enb_ip_address)); @@ -206,6 +219,15 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * new_instance->mnc_digit_length[i] = s1ap_register_eNB->mnc_digit_length[i]; } + memcpy( &(new_instance->enb_ip_address), &(s1ap_register_eNB->enb_ip_address), sizeof(net_ip_address_t) ); + new_instance->s1_setuprsp_wait_timer = s1ap_register_eNB->s1_setuprsp_wait_timer; + new_instance->s1_setupreq_wait_timer = s1ap_register_eNB->s1_setupreq_wait_timer; + new_instance->s1_setupreq_count = s1ap_register_eNB->s1_setupreq_count; + new_instance->sctp_req_timer = s1ap_register_eNB->sctp_req_timer; + new_instance->sctp_req_count = s1ap_register_eNB->sctp_req_count; + new_instance->sctp_in_streams = s1ap_register_eNB->sctp_in_streams; + new_instance->sctp_out_streams = s1ap_register_eNB->sctp_out_streams; + new_instance->num_plmn = s1ap_register_eNB->num_plmn; new_instance->default_drx = s1ap_register_eNB->default_drx; /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ @@ -216,8 +238,14 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * s1ap_register_eNB->eNB_id); } - DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, - S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0); +// DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, +// S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0); + if( s1ap_register_eNB->nb_mme > S1AP_MAX_NB_MME_IP_ADDRESS ) + { + S1AP_ERROR("Invalid MME number = %d\n ", s1ap_register_eNB->nb_mme); + s1ap_register_eNB->nb_mme = S1AP_MAX_NB_MME_IP_ADDRESS; + } + new_instance->s1ap_mme_nb = s1ap_register_eNB->nb_mme; /* Trying to connect to provided list of MME ip address */ for (index = 0; index < s1ap_register_eNB->nb_mme; index++) { @@ -249,28 +277,153 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { s1ap_eNB_instance_t *instance_p; s1ap_eNB_mme_data_t *s1ap_mme_data_p; + s1ap_eNB_ue_context_t *ue_p = NULL; + MessageDef *message_p = NULL; + uint32_t timer_kind = 0; + struct plmn_identity_s* plmnInfo; + struct served_group_id_s* groupInfo; + struct served_gummei_s* gummeiInfo; + struct mme_code_s* mmeCode; + int8_t cnt = 0; + unsigned enb_s1ap_id[20]; DevAssert(sctp_new_association_resp != NULL); instance_p = s1ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); s1ap_mme_data_p = s1ap_eNB_get_MME(instance_p, -1, sctp_new_association_resp->ulp_cnx_id); DevAssert(s1ap_mme_data_p != NULL); - - if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", - sctp_new_association_resp->sctp_state, - instance, - sctp_new_association_resp->ulp_cnx_id); - s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); - return; + memset(enb_s1ap_id, 0, sizeof(enb_s1ap_id) ); + if( s1ap_mme_data_p->timer_id != S1AP_TIMERID_INIT ) + { + s1ap_timer_remove( s1ap_mme_data_p->timer_id ); + s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT; } + + if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) + { + RB_FOREACH(ue_p, s1ap_ue_map, &instance_p->s1ap_ue_head) + { + if( ue_p->mme_ref == s1ap_mme_data_p ) + { + enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id; + cnt++; + + message_p = NULL; + message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); + + if( message_p != NULL ) + { + S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = ue_p->eNB_ue_s1ap_id; + + if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) + { + S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%d\n", ue_p->eNB_ue_s1ap_id); + } + } + else + { + S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%d\n", ue_p->eNB_ue_s1ap_id); + } + } + } + for( ; cnt > 0 ; ) + { + cnt--; + s1ap_ue_context_release( instance, (uint32_t)enb_s1ap_id[cnt] ); + } + s1ap_mme_data_p->mme_name = 0; + s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD; + s1ap_mme_data_p->nextstream = 0; + s1ap_mme_data_p->in_streams = 0; + s1ap_mme_data_p->out_streams = 0; + s1ap_mme_data_p->assoc_id = -1; + + while (!STAILQ_EMPTY(&s1ap_mme_data_p->served_gummei)) + { + gummeiInfo = STAILQ_FIRST(&s1ap_mme_data_p->served_gummei); + STAILQ_REMOVE_HEAD(&s1ap_mme_data_p->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); + } + + STAILQ_INIT(&s1ap_mme_data_p->served_gummei); + + if( s1ap_mme_data_p->state == S1AP_ENB_STATE_DISCONNECTED ) + { + if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) || + (instance_p->sctp_req_count == 0xffff) ) + { + timer_kind = s1ap_mme_data_p->cnx_id; + timer_kind = timer_kind | S1AP_MMEIND; + timer_kind = timer_kind | SCTP_REQ_WAIT; + + if( s1ap_timer_setup( instance_p->sctp_req_timer, 0, TASK_S1AP, instance_p->instance, + timer_kind, S1AP_TIMER_ONE_SHOT, NULL, &s1ap_mme_data_p->timer_id) < 0 ) + { + S1AP_ERROR("Timer Start NG(SCTP retransmission wait timer) : MME=%d\n",s1ap_mme_data_p->cnx_id); + s1ap_sctp_req( instance_p, s1ap_mme_data_p ); + } + } + else + { + S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id); + } + } + else + { + S1AP_ERROR("SCTP disconnection reception : MME = %d\n",s1ap_mme_data_p->cnx_id); + + if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) || + (instance_p->sctp_req_count == 0xffff) ) + { + s1ap_sctp_req( instance_p, s1ap_mme_data_p ); + } + else + { + S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id); + } + s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED; + } + } +// if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { +// S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", +// sctp_new_association_resp->sctp_state, +// instance, +// sctp_new_association_resp->ulp_cnx_id); +// s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); +// return; +// } + else + { /* Update parameters */ s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; /* Prepare new S1 Setup Request */ - s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p); + s1ap_mme_data_p->s1_setupreq_cnt = 0; + s1ap_mme_data_p->sctp_req_cnt = 0; + if (s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p) == -1) { + S1AP_ERROR("s1ap eNB generate s1 setup request failed\n"); + return; + } } static @@ -288,9 +441,102 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } +void s1ap_eNB_timer_expired( + instance_t instance, + s1ap_timer_has_expired_t *msg_p) +{ + uint32_t timer_kind = 0; + int16_t line_ind = 0; + s1ap_eNB_mme_data_t *mme_desc_p = NULL; + uint32_t timer_ind = 0; + s1ap_eNB_instance_t *instance_p = NULL; + long timer_id = S1AP_TIMERID_INIT; + + instance_p = s1ap_eNB_get_instance(instance); + timer_kind = msg_p->timer_kind; + line_ind = (int16_t)(timer_kind & S1AP_LINEIND); + timer_id = msg_p->timer_id; + + if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) + { + mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind); + if(mme_desc_p != NULL) + { + if( timer_id == mme_desc_p->timer_id ) + { + mme_desc_p->timer_id = S1AP_TIMERID_INIT; + timer_ind = timer_kind & S1AP_TIMERIND; + + switch(timer_ind) + { + case S1_SETRSP_WAIT: + { + if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + (instance_p->s1_setupreq_count == 0xffff) ) + { + s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); + } + else + { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); + } + break; + } + case S1_SETREQ_WAIT: + { + if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + (instance_p->s1_setupreq_count == 0xffff) ) + { + s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); + } + else + { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); + } + break; + } + case SCTP_REQ_WAIT: + { + if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) || + (instance_p->sctp_req_count == 0xffff) ) + { + s1ap_sctp_req( instance_p, mme_desc_p ); + } + else + { + S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind); + } + break; + } + default: + { + S1AP_WARN("Invalid Timer indication\n"); + break; + } + } + } + else + { + S1AP_DEBUG("Unmatch timer id\n"); + return; + } + } + else + { + S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind); + return; + } + } + else + { + } + return; +} + void s1ap_eNB_init(void) { S1AP_DEBUG("Starting S1AP layer\n"); s1ap_eNB_prepare_internal_data(); + s1ap_timer_init(); itti_mark_task_ready(TASK_S1AP); MSC_START_USE(); } @@ -411,6 +657,13 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { } break; + case TIMER_HAS_EXPIRED: + { + s1ap_eNB_timer_expired(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &TIMER_HAS_EXPIRED(received_msg)); + } + break; + default: S1AP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); @@ -451,6 +704,7 @@ static int s1ap_eNB_generate_s1_setup_request( uint8_t *buffer = NULL; uint32_t len = 0; int ret = 0; + uint32_t timer_kind = 0; DevAssert(instance_p != NULL); DevAssert(s1ap_mme_data_p != NULL); s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING; @@ -525,6 +779,17 @@ static int s1ap_eNB_generate_s1_setup_request( return -1; } + timer_kind = s1ap_mme_data_p->cnx_id; + timer_kind = timer_kind | S1AP_MMEIND; + timer_kind = timer_kind | S1_SETRSP_WAIT; + + if( s1ap_timer_setup(instance_p->s1_setuprsp_wait_timer, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT, + NULL, &s1ap_mme_data_p->timer_id) < 0 ) + { + S1AP_ERROR("Timer Start NG(S1 Setup Response) : MME=%d\n",s1ap_mme_data_p->cnx_id); + } + s1ap_mme_data_p->s1_setupreq_cnt++; + /* Non UE-Associated signalling -> stream = 0 */ s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0); return ret; @@ -533,3 +798,64 @@ static int s1ap_eNB_generate_s1_setup_request( +static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, + s1ap_eNB_mme_data_t *s1ap_mme_data_p) +{ + MessageDef *message_p = NULL; + sctp_new_association_req_t *sctp_new_association_req_p = NULL; + + if( instance_p == NULL ) + { + S1AP_ERROR("Invalid instance_p\n"); + return -1; + } + + message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); + sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; + sctp_new_association_req_p->port = S1AP_PORT_NUMBER; + sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; + sctp_new_association_req_p->in_streams = instance_p->sctp_in_streams; + sctp_new_association_req_p->out_streams = instance_p->sctp_out_streams; + sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; + + if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) + { + memcpy(&sctp_new_association_req_p->remote_address, + &s1ap_mme_data_p->mme_ip_address, + sizeof(net_ip_address_t)); + if( instance_p->enb_ip_address.ipv4 != 0 ) + { + memcpy(&sctp_new_association_req_p->local_address, + &instance_p->enb_ip_address, + sizeof(net_ip_address_t)); + } + else + { + S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n"); + return -1; + } + } + else + { + memcpy(&sctp_new_association_req_p->remote_address, + &s1ap_mme_data_p->mme_ip_address, + sizeof(net_ip_address_t)); + if( instance_p->enb_ip_address.ipv6 != 0 ) + { + memcpy(&sctp_new_association_req_p->local_address, + &instance_p->enb_ip_address, + sizeof(net_ip_address_t)); + } + else + { + S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n"); + return -1; + } + } + + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); + + s1ap_mme_data_p->sctp_req_cnt++; + + return 0; +} diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h index c6f44cdb18..78a8866e01 100644 --- a/openair3/S1AP/s1ap_eNB_defs.h +++ b/openair3/S1AP/s1ap_eNB_defs.h @@ -166,6 +166,10 @@ typedef struct s1ap_eNB_mme_data_s { struct s1ap_eNB_instance_s *s1ap_eNB_instance; uint32_t nb_calls; + net_ip_address_t mme_ip_address; + long timer_id; + uint16_t s1_setupreq_cnt; + uint16_t sctp_req_cnt; } s1ap_eNB_mme_data_t; typedef struct s1ap_eNB_instance_s { @@ -218,6 +222,14 @@ typedef struct s1ap_eNB_instance_s { /* Default Paging DRX of the eNB as defined in TS 36.304 */ paging_drx_t default_drx; + net_ip_address_t enb_ip_address; + uint16_t s1_setuprsp_wait_timer; + uint16_t s1_setupreq_wait_timer; + uint16_t s1_setupreq_count; + uint16_t sctp_req_timer; + uint16_t sctp_req_count; + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; } s1ap_eNB_instance_t; typedef struct { diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 0895494837..5d43c5b3fa 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -49,6 +49,7 @@ #include "assertions.h" #include "conversions.h" #include "msc.h" +#include "s1ap_eNB_timer.h" static int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, @@ -109,6 +110,10 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as uint32_t stream, S1AP_S1AP_PDU_t *pdu); +static int s1ap_eNB_snd_s1_setup_request( + s1ap_eNB_instance_t *instance_p, + s1ap_eNB_mme_data_t *s1ap_mme_data_p); + /* Handlers matrix. Only eNB related procedure present here */ s1ap_message_decoded_callback messages_callback[][3] = { { 0, 0, 0 }, /* HandoverPreparation */ @@ -260,6 +265,10 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, S1AP_S1SetupFailure_t *container; S1AP_S1SetupFailureIEs_t *ie; s1ap_eNB_mme_data_t *mme_desc_p; + uint32_t interval_sec = 0; + uint32_t timer_kind = 0; + s1ap_eNB_instance_t *instance_p; + DevAssert(pdu != NULL); container = &pdu->choice.unsuccessfulOutcome.value.choice.S1SetupFailure; @@ -270,7 +279,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { - S1AP_ERROR("[SCTP %d] Received S1 setup response for non existing " + S1AP_ERROR("[SCTP %d] Received S1 setup failure for non existing " "MME context\n", assoc_id); return -1; } @@ -278,6 +287,11 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container, S1AP_ProtocolIE_ID_id_Cause,true); + if(ie == NULL) + { + return -1; + } + if ((ie->value.choice.Cause.present == S1AP_Cause_PR_misc) && (ie->value.choice.Cause.choice.misc == S1AP_CauseMisc_unspecified)) { S1AP_WARN("Received s1 setup failure for MME... MME is not ready\n"); @@ -285,8 +299,65 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n"); } - mme_desc_p->state = S1AP_ENB_STATE_WAITING; - s1ap_handle_s1_setup_message(mme_desc_p, 0); + if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) + { + s1ap_timer_remove( mme_desc_p->timer_id ); + mme_desc_p->timer_id = S1AP_TIMERID_INIT; + } + instance_p = mme_desc_p->s1ap_eNB_instance; + if( ( instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + ( instance_p->s1_setupreq_count == 0xffff) ) + { + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_TimeToWait, false); + if( ie != NULL ) + { + switch(ie->value.choice.TimeToWait) + { + case S1AP_TimeToWait_v1s: + interval_sec = 1; + break; + case S1AP_TimeToWait_v2s: + interval_sec = 2; + break; + case S1AP_TimeToWait_v5s: + interval_sec = 5; + break; + case S1AP_TimeToWait_v10s: + interval_sec = 10; + break; + case S1AP_TimeToWait_v20s: + interval_sec = 20; + break; + case S1AP_TimeToWait_v60s: + interval_sec = 60; + break; + default: + interval_sec = instance_p->s1_setupreq_wait_timer; + break; + } + } + else + { + interval_sec = instance_p->s1_setupreq_wait_timer; + } + + timer_kind = mme_desc_p->cnx_id; + timer_kind = timer_kind | S1AP_MMEIND; + timer_kind = timer_kind | S1_SETREQ_WAIT; + + if( s1ap_timer_setup(interval_sec, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT, + NULL, &mme_desc_p->timer_id) < 0 ) + { + S1AP_ERROR("Timer Start NG(S1 Setup Request) : MME=%d\n",mme_desc_p->cnx_id); + + s1ap_eNB_snd_s1_setup_request( instance_p, mme_desc_p ); + } + } + else + { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id); + } return 0; } @@ -314,9 +385,29 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, return -1; } + /* Set the capacity of this MME */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); + if(ie == NULL) + { + return -1; + } + mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_ServedGUMMEIs, true); + if(ie == NULL) + { + return -1; + } + if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) + { + s1ap_timer_remove( mme_desc_p->timer_id ); + mme_desc_p->timer_id = S1AP_TIMERID_INIT; + } + mme_desc_p->s1_setupreq_cnt = 0; + mme_desc_p->sctp_req_cnt = 0; /* The list of served gummei can contain at most 8 elements. * LTE related gummei is the first element in the list, i.e with an id of 0. */ @@ -370,11 +461,11 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, } /* Set the capacity of this MME */ - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); - - mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; - +// S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, +// S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); +// +// mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; +// /* Optionaly set the mme name */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MMEname, false); @@ -392,7 +483,7 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, */ mme_desc_p->state = S1AP_ENB_STATE_CONNECTED; mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++; - s1ap_handle_s1_setup_message(mme_desc_p, 0); +// s1ap_handle_s1_setup_message(mme_desc_p, 0); return 0; } @@ -725,6 +816,10 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false); if (ie) { + if( ie->value.choice.CriticalityDiagnostics.procedureCode ) + { + S1AP_WARN("Received S1 Error indication CriticalityDiagnostics procedureCode = %d\n", *ie->value.choice.CriticalityDiagnostics.procedureCode); + } // TODO continue } @@ -807,6 +902,33 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, &(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl)); /* id-E-RABToBeSetupListCtxtSUReq */ } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); + return -1; + } + + /* id-UESecurityCapabilities */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_UESecurityCapabilities, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.encryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); + /* id-SecurityKey : Copy the security key */ + } else {/* ie != NULL */ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); + return -1; + } + + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_SecurityKey, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, + ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); + } else {/* ie != NULL */ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -852,34 +974,11 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability; } /* for i... */ } else {/* ie != NULL */ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } - /* id-UESecurityCapabilities */ - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_UESecurityCapabilities, true); - - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.encryption_algorithms = - BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = - BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); - /* id-SecurityKey : Copy the security key */ - } else {/* ie != NULL */ - return -1; - } - - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_SecurityKey, true); - - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, - ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); - } else {/* ie != NULL */ - return -1; - } - return 0; } @@ -904,6 +1003,14 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, return -1; } + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, + S1AP_ProtocolIE_ID_id_Cause, true); + if( ie == NULL ) + { + S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(Cause)\n" ); + return -1; + } + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_UE_S1AP_IDs, true); @@ -951,9 +1058,29 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, //#warning "TODO mapping mme_ue_s1ap_id enb_ue_s1ap_id?" case S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID: - mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; - S1AP_ERROR("TO DO mapping mme_ue_s1ap_id enb_ue_s1ap_id"); - (void)mme_ue_s1ap_id; /* TODO: remove - it's to remove gcc warning about unused var */ +// mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; +// S1AP_ERROR("TO DO mapping mme_ue_s1ap_id enb_ue_s1ap_id"); +// (void)mme_ue_s1ap_id; /* TODO: remove - it's to remove gcc warning about unused var */ + mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.mME_UE_S1AP_ID; + + RB_FOREACH(ue_desc_p, s1ap_ue_map, &mme_desc_p->s1ap_eNB_instance->s1ap_ue_head) + { + if( ue_desc_p->mme_ue_s1ap_id == mme_ue_s1ap_id ) + { + enb_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id; + + message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); + S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + + return 0; + } + } + S1AP_ERROR("[SCTP %d] Received UE context release command(mME_UE_S1AP_ID) for non " + "existing UE context 0x%06lx\n", + assoc_id, + mme_ue_s1ap_id); + return -1; case S1AP_UE_S1AP_IDs_PR_NOTHING: default: @@ -961,12 +1088,10 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, return -1; } } else { + S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(UE_S1AP_IDs)\n" ); return -1; } - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, - S1AP_ProtocolIE_ID_id_Cause, true); - /* TBD */ } static @@ -985,7 +1110,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, container = &pdu->choice.initiatingMessage.value.choice.E_RABSetupRequest; if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { - S1AP_ERROR("[SCTP %d] Received initial context setup request for non " + S1AP_ERROR("[SCTP %d] Received E-RAB setup request for non " "existing MME context\n", assoc_id); return -1; } @@ -1012,7 +1137,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, enb_ue_s1ap_id)) == NULL) { - S1AP_ERROR("[SCTP %d] Received initial context setup request for non " + S1AP_ERROR("[SCTP %d] Received E-RAB setup request for non " "existing UE context 0x%06lx\n", assoc_id, enb_ue_s1ap_id); return -1; @@ -1085,6 +1210,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1132,6 +1258,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0; S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0; } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1159,6 +1286,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, if(i != ie->value.choice.UEPagingID.choice.iMSI.size - 1) { /* invalid paging_p->uePagingID.choise.iMSI.buffer */ S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)\n", assoc_id,i); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } } else { @@ -1169,14 +1297,17 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length >= S1AP_IMSI_LENGTH) { /* invalid paging_p->uePagingID.choise.iMSI.size */ S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)\n", assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length, S1AP_IMSI_LENGTH); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } } else { /* of if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_iMSI) */ /* invalid paging_p->uePagingID.present */ S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.present(%d) is unknown\n", assoc_id, ie->value.choice.UEPagingID.present); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } } else { /* of ie != NULL */ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1209,6 +1340,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, return -1; } } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1236,6 +1368,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, S1AP_PAGING_IND(message_p).tac[i]); } } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1330,6 +1463,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id; } } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1382,6 +1516,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); } else { /* of if (ie != NULL)*/ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1455,6 +1590,24 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_RELEASE_COMMAND); S1AP_E_RAB_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; S1AP_E_RAB_RELEASE_COMMAND(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id; + /* id-E-RABToBeReleasedList */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = ie->value.choice.E_RABList.list.count; + + for (i = 0; i < ie->value.choice.E_RABList.list.count; i++) { + S1AP_E_RABItem_t *item_p; + item_p = &(((S1AP_E_RABItemIEs_t *)ie->value.choice.E_RABList.list.array[i])->value.choice.E_RABItem); + S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID; + S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID); + } + } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); + return -1; + } + /* id-NAS-PDU */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, S1AP_ProtocolIE_ID_id_NAS_PDU, false); @@ -1470,24 +1623,6 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = 0; S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL; } - - /* id-E-RABToBeReleasedList */ - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList, true); - - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = ie->value.choice.E_RABList.list.count; - - for (i = 0; i < ie->value.choice.E_RABList.list.count; i++) { - S1AP_E_RABItem_t *item_p; - item_p = &(((S1AP_E_RABItemIEs_t *)ie->value.choice.E_RABList.list.array[i])->value.choice.E_RABItem); - S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID; - S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID); - } - } else { - return -1; - } - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); return 0; } @@ -1528,6 +1663,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, if (ie == NULL) { S1AP_ERROR("[SCTP %d] Received path switch request ack for non " "ie context is NULL\n", assoc_id); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1550,6 +1686,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, if (ie == NULL) { S1AP_ERROR("[SCTP %d] Received path switch request ack for non " "ie context is NULL\n", assoc_id); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1567,6 +1704,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, if (ie == NULL) { S1AP_ERROR("[SCTP %d] Received path switch request ack for non " "ie context is NULL\n", assoc_id); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1580,14 +1718,10 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, S1AP_ProtocolIE_ID_id_uEaggregateMaximumBitrate, false); if (ie) { - OCTET_STRING_TO_INT32 ( - &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL, - S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul - ); - OCTET_STRING_TO_INT32 ( - &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL, - S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl - ); + asn_INTEGER2ulong(&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL, + &S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul); + asn_INTEGER2ulong(&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL, + &S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl); } else { S1AP_WARN("UEAggregateMaximumBitrate not supported\n"); S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul = 0; @@ -1731,3 +1865,144 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as return 0; } +//----------------------------------------------------------------------------- +/* +* eNB generate a S1 setup request towards MME +*/ +static int s1ap_eNB_snd_s1_setup_request( + s1ap_eNB_instance_t *instance_p, + s1ap_eNB_mme_data_t *s1ap_mme_data_p) +//----------------------------------------------------------------------------- +{ + S1AP_S1AP_PDU_t pdu; + S1AP_S1SetupRequest_t *out = NULL; + S1AP_S1SetupRequestIEs_t *ie = NULL; + S1AP_SupportedTAs_Item_t *ta = NULL; + S1AP_PLMNidentity_t *plmn = NULL; + uint8_t *buffer = NULL; + uint32_t len = 0; + int ret = 0; + uint32_t timer_kind = 0; + + DevAssert(instance_p != NULL); + DevAssert(s1ap_mme_data_p != NULL); + s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING; + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_S1Setup; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_S1SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.S1SetupRequest; + /* mandatory */ + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_Global_ENB_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_Global_ENB_ID; + MCC_MNC_TO_PLMNID(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[0]], + instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[0]], + instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[0]], + &ie->value.choice.Global_ENB_ID.pLMNidentity); + ie->value.choice.Global_ENB_ID.eNB_ID.present = S1AP_ENB_ID_PR_macroENB_ID; + MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, + &ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID); + S1AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, + ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[0], + ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[1], + ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[2]); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (instance_p->eNB_name) { + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNBname; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_ENBname; + OCTET_STRING_fromBuf(&ie->value.choice.ENBname, instance_p->eNB_name, + strlen(instance_p->eNB_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_SupportedTAs; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_SupportedTAs; + { + ta = (S1AP_SupportedTAs_Item_t *)calloc(1, sizeof(S1AP_SupportedTAs_Item_t)); + INT16_TO_OCTET_STRING(instance_p->tac, &ta->tAC); + { + for (int i = 0; i < s1ap_mme_data_p->broadcast_plmn_num; ++i) { + plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t)); + MCC_MNC_TO_TBCD(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[i]], + instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[i]], + instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[i]], + plmn); + ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn); + } + } + ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAs.list, ta); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_DefaultPagingDRX; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_PagingDRX; + ie->value.choice.PagingDRX = instance_p->default_drx; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (0) { + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CSG_IdList; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_CSG_IdList; + // ie->value.choice.CSG_IdList = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ +#if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0)) + + if (0) { + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_UE_RetentionInformation; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_UE_RetentionInformation; + // ie->value.choice.UE_RetentionInformation = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (0) { + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_NB_IoT_DefaultPagingDRX; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_NB_IoT_DefaultPagingDRX; + // ie->value.choice.NB_IoT_DefaultPagingDRX = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + +#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ + + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + S1AP_ERROR("Failed to encode S1 setup request\n"); + return -1; + } + + timer_kind = s1ap_mme_data_p->cnx_id; + timer_kind = timer_kind | S1AP_MMEIND; + timer_kind = timer_kind | S1_SETRSP_WAIT; + + if( s1ap_timer_setup(instance_p->s1_setuprsp_wait_timer, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT, + NULL, &s1ap_mme_data_p->timer_id) < 0 ) + { + S1AP_ERROR("Timer Start NG(S1 Setup Response) : MME=%d\n",s1ap_mme_data_p->cnx_id); + } + s1ap_mme_data_p->s1_setupreq_cnt++; + + /* Non UE-Associated signalling -> stream = 0 */ + s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0); + return ret; +} diff --git a/openair3/S1AP/s1ap_eNB_management_procedures.c b/openair3/S1AP/s1ap_eNB_management_procedures.c index fc7ae70e49..1fdc09664b 100644 --- a/openair3/S1AP/s1ap_eNB_management_procedures.c +++ b/openair3/S1AP/s1ap_eNB_management_procedures.c @@ -95,23 +95,54 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME( { struct s1ap_eNB_mme_data_s temp; struct s1ap_eNB_mme_data_s *found; + struct s1ap_eNB_mme_data_s *mme_p; memset(&temp, 0, sizeof(struct s1ap_eNB_mme_data_s)); temp.assoc_id = assoc_id; temp.cnx_id = cnx_id; - if (instance_p == NULL) { - STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, - s1ap_eNB_entries) { - found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); + if( cnx_id != 0 ) + { + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, + s1ap_eNB_entries) { + found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); - if (found != NULL) { - return found; + if (found != NULL) { + return found; + } + } + } else { + return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); + } + } + else + { + if (instance_p == NULL) + { + STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, + s1ap_eNB_entries) + { + RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) + { + if( mme_p->assoc_id == assoc_id ) + { + return mme_p; + } + } + } + } + else + { + RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) + { + if( mme_p->assoc_id == assoc_id ) + { + return mme_p; + } } } - } else { - return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); } return NULL; diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index 4744ff4e43..c617dc399d 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -359,10 +359,18 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, container = &pdu->choice.initiatingMessage.value.choice.DownlinkNASTransport; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); + if(ie == NULL) + { + return -1; + } mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); + if(ie == NULL) + { + return -1; + } enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance, @@ -417,6 +425,10 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_NAS_PDU, true); + if(ie == NULL) + { + return -1; + } /* Forward the NAS PDU to RRC */ s1ap_eNB_itti_send_nas_downlink_ind(s1ap_eNB_instance->instance, ue_desc_p->ue_initial_id, diff --git a/openair3/S1AP/s1ap_eNB_overload.c b/openair3/S1AP/s1ap_eNB_overload.c index e331d03b4a..64d3fcdf65 100644 --- a/openair3/S1AP/s1ap_eNB_overload.c +++ b/openair3/S1AP/s1ap_eNB_overload.c @@ -62,6 +62,10 @@ int s1ap_eNB_handle_overload_start(uint32_t assoc_id, S1AP_OverloadResponse_PR_overloadAction, S1AP_OverloadResponse_PR_overloadAction, 0, 0); } + else + { + return -1; + } /* Non UE-associated signalling -> stream 0 */ if (stream != 0) { S1AP_ERROR("[SCTP %d] Received s1 overload start on stream != 0 (%d)\n", diff --git a/openair3/S1AP/s1ap_eNB_timer.c b/openair3/S1AP/s1ap_eNB_timer.c new file mode 100644 index 0000000000..d4b5bdbd14 --- /dev/null +++ b/openair3/S1AP/s1ap_eNB_timer.c @@ -0,0 +1,300 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "assertions.h" +#include "intertask_interface.h" +#include "s1ap_eNB_timer.h" +#include "common/utils/LOG/log.h" +#include "queue.h" +#include "s1ap_common.h" + +struct s1ap_timer_elm_s { + task_id_t task_id; ///< Task ID which has requested the timer + int32_t instance; ///< Instance of the task which has requested the timer + uint32_t timer_kind; ///< Instance of the task which has requested the timer + timer_t timer; ///< Unique timer id + timer_type_t type; ///< Timer type + void *timer_arg; ///< Optional argument that will be passed when timer expires + STAILQ_ENTRY(s1ap_timer_elm_s) entries; ///< Pointer to next element +}; + +typedef struct timer_desc_s { + STAILQ_HEAD(timer_list_head, s1ap_timer_elm_s) timer_queue; + pthread_mutex_t timer_list_mutex; + struct timespec timeout; +} timer_desc_t; + +static timer_desc_t timer_desc; + +#define TIMER_SEARCH(vAR, tIMERfIELD, tIMERvALUE, tIMERqUEUE) \ +do { \ + STAILQ_FOREACH(vAR, tIMERqUEUE, entries) { \ + if (((vAR)->tIMERfIELD == tIMERvALUE)) \ + break; \ + } \ +} while(0) + +int s1ap_timer_timeout(sigval_t info) +{ + struct s1ap_timer_elm_s *timer_p; + MessageDef *message_p; + s1ap_timer_has_expired_t *timer_expired_p; + task_id_t task_id; + int32_t instance; + uint32_t timer_kind; + + timer_kind = info.sival_int; + if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 ) + { + S1AP_ERROR("Failed to mutex lock timeout=%x\n", timer_kind); + + return -1; + } + TIMER_SEARCH(timer_p, timer_kind, timer_kind, &timer_desc.timer_queue); + + if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 ) + { + S1AP_ERROR("Failed to mutex unlock timeout=%x\n", timer_kind); + } + if (timer_p == NULL) + { + S1AP_ERROR("Didn't find timer 0x%lx in list\n", timer_kind); + + return -1; + } + S1AP_DEBUG("Timer kind 0x%x has expired\n", timer_kind); + + task_id = timer_p->task_id; + instance = timer_p->instance; + message_p = itti_alloc_new_message(TASK_UNKNOWN, TIMER_HAS_EXPIRED); + + timer_expired_p = &message_p->ittiMsg.timer_has_expired; + + timer_expired_p->timer_id = (long)timer_p->timer; + timer_expired_p->timer_kind = timer_p->timer_kind; + timer_expired_p->arg = timer_p->timer_arg; + + /* Timer is a one shot timer, remove it */ + if( timer_p->type == S1AP_TIMER_ONE_SHOT ) + { + if( s1ap_timer_remove((long)timer_p->timer) != 0 ) + { + S1AP_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer); + } + } + + /* Notify task of timer expiry */ + if( itti_send_msg_to_task(task_id, instance, message_p) < 0 ) + { + S1AP_ERROR("Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id); + free(message_p); + return -1; + } + + return 0; +} + +int s1ap_timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + uint32_t timer_kind, + timer_type_t type, + void *timer_arg, + long *timer_id) +{ + struct sigevent evp; + struct itimerspec its; + struct s1ap_timer_elm_s *timer_p; + timer_t timer; + + if( timer_id == NULL ) + { + S1AP_ERROR("Invalid timer_id\n"); + return -1; + } + + if( type >= S1AP_TIMER_TYPE_MAX ) + { + S1AP_ERROR("Invalid timer type (%d/%d)!\n", type, TIMER_TYPE_MAX); + return -1; + } + + if( *timer_id != S1AP_TIMERID_INIT ) + { + if( s1ap_timer_remove(*timer_id) != 0 ) + { + S1AP_ERROR("Failed to delete timer when the timer start 0x%lx\n", *timer_id); + } + } + + /* Allocate new timer list element */ + timer_p = malloc(sizeof(struct s1ap_timer_elm_s)); + + if( timer_p == NULL ) + { + S1AP_ERROR("Failed to create new timer element\n"); + return -1; + } + + memset(&timer, 0, sizeof(timer_t)); + memset(&evp, 0, sizeof(evp)); + + timer_p->task_id = task_id; + timer_p->instance = instance; + timer_p->timer_kind = timer_kind; + timer_p->type = type; + timer_p->timer_arg = timer_arg; + + evp.sigev_notify = (int)SIGEV_THREAD; + evp.sigev_notify_function = (void *)s1ap_timer_timeout; + evp.sigev_signo = SIGRTMIN; + evp.sigev_notify_attributes = NULL; + evp.sigev_value.sival_int = timer_kind; + + /* At the timer creation, the timer structure will be filled in with timer_id, + * which is unique for this process. This id is allocated by kernel and the + * value might be used to distinguish timers. + */ + if( timer_create(CLOCK_REALTIME, &evp, &timer) < 0 ) + { + S1AP_ERROR("Failed to create timer: (%s:%d)\n", strerror(errno), errno); + free(timer_p); + return -1; + } + + /* Fill in the first expiration value. */ + its.it_value.tv_sec = interval_sec; + its.it_value.tv_nsec = interval_us * 1000; + + if( type == S1AP_TIMER_PERIODIC ) + { + /* Asked for periodic timer. We set the interval time */ + its.it_interval.tv_sec = interval_sec; + its.it_interval.tv_nsec = interval_us * 1000; + } + else + { + /* Asked for one-shot timer. Do not set the interval field */ + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + } + + if( timer_settime(timer, 0, &its, NULL) ) + { + S1AP_ERROR("Failed to Settimer: (%s:%d)\n", strerror(errno), errno); + free(timer_p); + return -1; + } + + /* Simply set the timer_id argument. so it can be used by caller */ + *timer_id = (long)timer; + + timer_p->timer = timer; + + /* Lock the queue and insert the timer at the tail */ + if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 ) + { + S1AP_ERROR("Failed to mutex lock\n"); + if( timer_delete(timer_p->timer) < 0 ) + { + S1AP_ERROR("Failed to delete timer 0x%lx\n", (long)timer_p->timer); + } + free(timer_p); + timer_p = NULL; + + return -1; + } + + STAILQ_INSERT_TAIL(&timer_desc.timer_queue, timer_p, entries); + if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 ) + { + S1AP_ERROR("Failed to mutex unlock\n"); + } + + return 0; +} + +int s1ap_timer_remove(long timer_id) +{ + int rc = 0; + struct s1ap_timer_elm_s *timer_p; + + + if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 ) + { + S1AP_ERROR("Failed to mutex lock\n"); + if( timer_delete(timer_id) < 0 ) + { + S1AP_ERROR("Failed to delete timer 0x%lx\n", (long)timer_id); + } + + return -1; + } + + TIMER_SEARCH(timer_p, timer, ((timer_t)timer_id), &timer_desc.timer_queue); + + /* We didn't find the timer in list */ + if (timer_p == NULL) + { + S1AP_ERROR("Didn't find timer 0x%lx in list\n", timer_id); + if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 ) + { + S1AP_ERROR("Failed to mutex unlock\n"); + } + + return -1; + } + + timer_delete(timer_p->timer); + + STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, s1ap_timer_elm_s, entries); + + if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 ) + { + S1AP_ERROR("Failed to mutex unlock\n"); + } + + free(timer_p); + timer_p = NULL; + return rc; +} + +int s1ap_timer_init(void) +{ + memset(&timer_desc, 0, sizeof(timer_desc_t)); + + STAILQ_INIT(&timer_desc.timer_queue); + pthread_mutex_init(&timer_desc.timer_list_mutex, NULL); + + return 0; +} diff --git a/openair3/S1AP/s1ap_eNB_timer.h b/openair3/S1AP/s1ap_eNB_timer.h new file mode 100644 index 0000000000..7af80eb806 --- /dev/null +++ b/openair3/S1AP/s1ap_eNB_timer.h @@ -0,0 +1,86 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef TIMER_H_ +#define TIMER_H_ + +#include + +#define SIGTIMER SIGRTMIN + +typedef enum s1ap_timer_type_s { + S1AP_TIMER_PERIODIC, + S1AP_TIMER_ONE_SHOT, + S1AP_TIMER_TYPE_MAX, +} s1ap_timer_type_t; + +typedef struct { + void *arg; + long timer_id; + int32_t timer_kind; +} s1ap_timer_has_expired_t; + + +int s1ap_timer_timeout(sigval_t info); + +/** \brief Request a new timer + * \param interval_sec timer interval in seconds + * \param interval_us timer interval in micro seconds + * \param task_id task id of the task requesting the timer + * \param instance instance of the task requesting the timer + * \param type timer type + * \param timer_id unique timer identifier + * @returns -1 on failure, 0 otherwise + **/ +int s1ap_timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + uint32_t timer_kind, + timer_type_t type, + void *timer_arg, + long *timer_id); + +/** \brief Remove the timer from list + * \param timer_id unique timer id + * @returns -1 on failure, 0 otherwise + **/ + +int s1ap_timer_remove(long timer_id); + +/** \brief Initialize timer task and its API + * \param mme_config MME common configuration + * @returns -1 on failure, 0 otherwise + **/ +int s1ap_timer_init(void); + +#define S1AP_MMEIND 0x80000000 +#define S1AP_UEIND 0x00000000 +#define S1_SETRSP_WAIT 0x00010000 +#define S1_SETREQ_WAIT 0x00020000 +#define SCTP_REQ_WAIT 0x00030000 +#define S1AP_LINEIND 0x0000ffff +#define S1AP_TIMERIND 0x00ff0000 + +#define S1AP_TIMERID_INIT 0xffffffffffffffff + +#endif diff --git a/openair3/S1AP/s1ap_eNB_trace.c b/openair3/S1AP/s1ap_eNB_trace.c index 19f5059238..695eeb4ef8 100644 --- a/openair3/S1AP/s1ap_eNB_trace.c +++ b/openair3/S1AP/s1ap_eNB_trace.c @@ -121,6 +121,10 @@ int s1ap_eNB_handle_trace_start(uint32_t assoc_id, if (ie != NULL) { ue_desc_p = s1ap_eNB_get_ue_context(mme_ref_p->s1ap_eNB_instance, ie->value.choice.ENB_UE_S1AP_ID); + } + else + { + return -1; } if (ue_desc_p == NULL) { /* Could not find context associated with this eNB_ue_s1ap_id -> generate diff --git a/openair3/SCTP/sctp_default_values.h b/openair3/SCTP/sctp_default_values.h index 528ffb5a05..0f8f94dca9 100644 --- a/openair3/SCTP/sctp_default_values.h +++ b/openair3/SCTP/sctp_default_values.h @@ -24,8 +24,8 @@ #define SCTP_OUT_STREAMS (16) #define SCTP_IN_STREAMS (16) -#define SCTP_MAX_ATTEMPTS (2) -#define SCTP_TIMEOUT (5) +#define SCTP_MAX_ATTEMPTS (8) +#define SCTP_TIMEOUT (60000) #define SCTP_RECV_BUFFER_SIZE (8192) #endif /* SCTP_DEFAULT_VALUES_H_ */ diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index ee006338c5..ec9e62bb3f 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -943,10 +943,12 @@ sctp_eNB_read_from_socket( &sinfo, &flags); if (n < 0) { - if (errno == ENOTCONN) { + if( (errno == ENOTCONN) || (errno == ECONNRESET) || (errno == ETIMEDOUT) || (errno == ECONNREFUSED) ) + { itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd); SCTP_DEBUG("Received not connected for sd %d\n", sctp_cnx->sd); + SCTP_ERROR("sctp_recvmsg (fd %d, len %d ): %s:%d\n", sctp_cnx->sd, n, strerror(errno), errno); sctp_itti_send_association_resp( sctp_cnx->task_id, sctp_cnx->instance, -1, From 8c607fe85bcae0baea227a783674403459ff85f5 Mon Sep 17 00:00:00 2001 From: "Wu.Jing" Date: Thu, 9 Apr 2020 11:39:57 +0800 Subject: [PATCH 07/91] Fix build error in --UE because of s1ap_eNB.c (cherry picked from commit 519e6628d572c9b6cf8031632d4e22e2f8dc5b93) --- openair3/S1AP/s1ap_eNB.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 8452d9e563..b3ceb7ff2c 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -329,7 +329,13 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa for( ; cnt > 0 ; ) { cnt--; - s1ap_ue_context_release( instance, (uint32_t)enb_s1ap_id[cnt] ); + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + struct s1ap_eNB_ue_context_s *s1ap_ue_context_p = NULL; + ue_context_p = s1ap_eNB_get_ue_context(instance_p, (uint32_t)enb_s1ap_id[cnt]); + if (ue_context_p != NULL) { + s1ap_ue_context_p = RB_REMOVE(s1ap_ue_map, &instance_p->s1ap_ue_head, ue_context_p); + s1ap_eNB_free_ue_context(s1ap_ue_context_p); + } } s1ap_mme_data_p->mme_name = 0; s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD; From 4c75866a549bd70ae39b33c853f3ad9643387ecf Mon Sep 17 00:00:00 2001 From: "Wu.Jing" Date: Thu, 9 Apr 2020 12:34:02 +0800 Subject: [PATCH 08/91] Fix cppcheck warning (cherry picked from commit aaa4d390fdefc4e8071b80edc90a580907c9dec3) --- openair3/S1AP/s1ap_eNB.c | 4 ++-- openair3/S1AP/s1ap_eNB_timer.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index b3ceb7ff2c..9eebb68fe7 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -317,12 +317,12 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) { - S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%d\n", ue_p->eNB_ue_s1ap_id); + S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); } } else { - S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%d\n", ue_p->eNB_ue_s1ap_id); + S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); } } } diff --git a/openair3/S1AP/s1ap_eNB_timer.c b/openair3/S1AP/s1ap_eNB_timer.c index d4b5bdbd14..4e9fb166d3 100644 --- a/openair3/S1AP/s1ap_eNB_timer.c +++ b/openair3/S1AP/s1ap_eNB_timer.c @@ -82,11 +82,11 @@ int s1ap_timer_timeout(sigval_t info) if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 ) { - S1AP_ERROR("Failed to mutex unlock timeout=%x\n", timer_kind); + S1AP_ERROR("Failed to mutex unlock timeout=0x%x\n", timer_kind); } if (timer_p == NULL) { - S1AP_ERROR("Didn't find timer 0x%lx in list\n", timer_kind); + S1AP_ERROR("Didn't find timer 0x%x in list\n", timer_kind); return -1; } From 52acfc75de38e86f3c3396dec30e428b9600c20e Mon Sep 17 00:00:00 2001 From: Cai Yang Date: Thu, 9 Apr 2020 15:28:55 +0900 Subject: [PATCH 09/91] Fix s1ap_eNB_timer.c warnings (cherry picked from commit 39850dcfadb37e24ccfe41e0a85a9f2136eeff4a) --- openair3/S1AP/s1ap_eNB_timer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB_timer.c b/openair3/S1AP/s1ap_eNB_timer.c index 4e9fb166d3..ccb294cb54 100644 --- a/openair3/S1AP/s1ap_eNB_timer.c +++ b/openair3/S1AP/s1ap_eNB_timer.c @@ -96,14 +96,14 @@ int s1ap_timer_timeout(sigval_t info) instance = timer_p->instance; message_p = itti_alloc_new_message(TASK_UNKNOWN, TIMER_HAS_EXPIRED); - timer_expired_p = &message_p->ittiMsg.timer_has_expired; + timer_expired_p = (s1ap_timer_has_expired_t *)(&message_p->ittiMsg.timer_has_expired); timer_expired_p->timer_id = (long)timer_p->timer; timer_expired_p->timer_kind = timer_p->timer_kind; timer_expired_p->arg = timer_p->timer_arg; /* Timer is a one shot timer, remove it */ - if( timer_p->type == S1AP_TIMER_ONE_SHOT ) + if( (int)timer_p->type == (int)S1AP_TIMER_ONE_SHOT ) { if( s1ap_timer_remove((long)timer_p->timer) != 0 ) { @@ -143,7 +143,7 @@ int s1ap_timer_setup( return -1; } - if( type >= S1AP_TIMER_TYPE_MAX ) + if( (int)type >= (int)S1AP_TIMER_TYPE_MAX ) { S1AP_ERROR("Invalid timer type (%d/%d)!\n", type, TIMER_TYPE_MAX); return -1; @@ -196,7 +196,7 @@ int s1ap_timer_setup( its.it_value.tv_sec = interval_sec; its.it_value.tv_nsec = interval_us * 1000; - if( type == S1AP_TIMER_PERIODIC ) + if( (int)type == (int)S1AP_TIMER_PERIODIC ) { /* Asked for periodic timer. We set the interval time */ its.it_interval.tv_sec = interval_sec; @@ -253,7 +253,7 @@ int s1ap_timer_remove(long timer_id) if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 ) { S1AP_ERROR("Failed to mutex lock\n"); - if( timer_delete(timer_id) < 0 ) + if( timer_delete((timer_t)timer_id) < 0 ) { S1AP_ERROR("Failed to delete timer 0x%lx\n", (long)timer_id); } From 4a14c4c706400311326adab8e2a8dad73bdf79a4 Mon Sep 17 00:00:00 2001 From: Wu Jing Date: Mon, 13 Apr 2020 14:37:50 +0900 Subject: [PATCH 10/91] fix build waning (cherry picked from commit 624fe21f52117959940066a6cfc5f8beac70e462) # Conflicts: # openair2/LAYER2/MAC/eNB_scheduler_RA.c # openair2/LAYER2/MAC/eNB_scheduler_dlsch.c # openair2/LAYER2/MAC/eNB_scheduler_fairRR.c # openair3/S1AP/s1ap_eNB.c # Conflicts: # openair3/S1AP/s1ap_eNB.c --- openair3/S1AP/s1ap_eNB.c | 4 ++-- openair3/S1AP/s1ap_eNB_handlers.c | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 9eebb68fe7..742766909b 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -105,7 +105,7 @@ 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; +// struct s1ap_eNB_mme_data_s *mme = NULL; DevAssert(instance_p != NULL); DevAssert(mme_ip_address != NULL); message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); @@ -666,7 +666,7 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { case TIMER_HAS_EXPIRED: { s1ap_eNB_timer_expired(ITTI_MESSAGE_GET_INSTANCE(received_msg), - &TIMER_HAS_EXPIRED(received_msg)); + (s1ap_timer_has_expired_t *) &TIMER_HAS_EXPIRED(received_msg)); } break; diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 5d43c5b3fa..89f82fa485 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -38,6 +38,9 @@ #include "s1ap_eNB_defs.h" #include "s1ap_eNB_handlers.h" #include "s1ap_eNB_decoder.h" +#include "s1ap_eNB_encoder.h" + +#include "s1ap_eNB_itti_messaging.h" #include "s1ap_eNB_ue_context.h" #include "s1ap_eNB_trace.h" @@ -818,7 +821,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, if (ie) { if( ie->value.choice.CriticalityDiagnostics.procedureCode ) { - S1AP_WARN("Received S1 Error indication CriticalityDiagnostics procedureCode = %d\n", *ie->value.choice.CriticalityDiagnostics.procedureCode); + S1AP_WARN("Received S1 Error indication CriticalityDiagnostics procedureCode = %ld\n", *ie->value.choice.CriticalityDiagnostics.procedureCode); } // TODO continue } From cf41c788d682c301e6cb0f981add5681e3dff626 Mon Sep 17 00:00:00 2001 From: Haruki NAOI Date: Mon, 27 Jul 2020 12:34:14 +0900 Subject: [PATCH 11/91] fix s1ap stack overflow. (cherry picked from commit f6b51079021347c19d528200f04d7cdba1dde0e5) # Conflicts: # openair3/S1AP/s1ap_eNB.c --- openair3/S1AP/s1ap_eNB.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 742766909b..2501fe334c 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -285,7 +285,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa struct served_gummei_s* gummeiInfo; struct mme_code_s* mmeCode; int8_t cnt = 0; - unsigned enb_s1ap_id[20]; + unsigned enb_s1ap_id[NUMBER_OF_UE_MAX]; DevAssert(sctp_new_association_resp != NULL); instance_p = s1ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); @@ -305,6 +305,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa { if( ue_p->mme_ref == s1ap_mme_data_p ) { + if(cnt < NUMBER_OF_UE_MAX){ enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id; cnt++; @@ -324,6 +325,9 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa { S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); } + }else{ + S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt); + } } } for( ; cnt > 0 ; ) @@ -419,18 +423,18 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa // } else { - /* Update parameters */ - s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; - s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; - s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; - /* Prepare new S1 Setup Request */ - s1ap_mme_data_p->s1_setupreq_cnt = 0; - s1ap_mme_data_p->sctp_req_cnt = 0; - if (s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p) == -1) { - S1AP_ERROR("s1ap eNB generate s1 setup request failed\n"); - return; + /* Update parameters */ + s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; + s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; + s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; + /* Prepare new S1 Setup Request */ + s1ap_mme_data_p->s1_setupreq_cnt = 0; + s1ap_mme_data_p->sctp_req_cnt = 0; + if (s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p) == -1) { + S1AP_ERROR("s1ap eNB generate s1 setup request failed\n"); + return; + } } -} static void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { From 27413fc4fc58347f18abe8aaab4de4d39119a768 Mon Sep 17 00:00:00 2001 From: "masayuki.harada" Date: Fri, 20 Nov 2020 22:13:27 +0900 Subject: [PATCH 12/91] Fix merge miss. --- openair2/COMMON/tasks_def.h | 3 +- openair2/X2AP/x2ap_common.h | 2 +- openair3/S1AP/s1ap_eNB.c | 123 +++++++++++++----------------------- 3 files changed, 47 insertions(+), 81 deletions(-) diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h index f84195d5d7..33b6d5f9d4 100644 --- a/openair2/COMMON/tasks_def.h +++ b/openair2/COMMON/tasks_def.h @@ -47,8 +47,7 @@ TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000) // GTP_V1U task TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000) -//TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200) -TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 2000) +TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200) /// M3ap task, acts as both source and target diff --git a/openair2/X2AP/x2ap_common.h b/openair2/X2AP/x2ap_common.h index 470a023c31..a2f903a737 100644 --- a/openair2/X2AP/x2ap_common.h +++ b/openair2/X2AP/x2ap_common.h @@ -84,7 +84,7 @@ extern int asn1_xer_print; break; \ } \ } \ -/* if (mandatory) DevAssert(ie != NULL); \*/ \ + if (mandatory) DevAssert(ie != NULL); \ } while(0) /** \brief Function callback prototype. diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 2501fe334c..c011653f76 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -121,55 +121,31 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, local_ip_addr, sizeof(*local_ip_addr)); S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance); -// mme = NULL; -// -// 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->broadcast_plmn_num = broadcast_plmn_num; - memcpy(&s1ap_mme_data_p->mme_s1_ip, - mme_ip_address, - sizeof(*mme_ip_address)); - for (int i = 0; i < broadcast_plmn_num; ++i) - s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; + /* 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->broadcast_plmn_num = broadcast_plmn_num; + memcpy(&s1ap_mme_data_p->mme_s1_ip, + mme_ip_address, + sizeof(*mme_ip_address)); + for (int i = 0; i < broadcast_plmn_num; ++i) + s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; - 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; - s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED; - memcpy( &(s1ap_mme_data_p->mme_ip_address), mme_ip_address, sizeof(net_ip_address_t) ); - s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD; - s1ap_mme_data_p->sctp_req_cnt++; - s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT; -// 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_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_DISCONNECTED; + memcpy( &(s1ap_mme_data_p->mme_ip_address), mme_ip_address, sizeof(net_ip_address_t) ); + s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD; + s1ap_mme_data_p->sctp_req_cnt++; + s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT; + instance_p->s1ap_mme_pending_nb ++; itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); } @@ -210,8 +186,8 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * new_instance->tac = s1ap_register_eNB->tac; memcpy(&new_instance->eNB_s1_ip, - &s1ap_register_eNB->enb_ip_address, - sizeof(s1ap_register_eNB->enb_ip_address)); + &s1ap_register_eNB->enb_ip_address, + sizeof(s1ap_register_eNB->enb_ip_address)); for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) { new_instance->mcc[i] = s1ap_register_eNB->mcc[i]; @@ -238,8 +214,6 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * s1ap_register_eNB->eNB_id); } -// DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, -// S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0); if( s1ap_register_eNB->nb_mme > S1AP_MAX_NB_MME_IP_ADDRESS ) { S1AP_ERROR("Invalid MME number = %d\n ", s1ap_register_eNB->nb_mme); @@ -306,27 +280,27 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa if( ue_p->mme_ref == s1ap_mme_data_p ) { if(cnt < NUMBER_OF_UE_MAX){ - enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id; - cnt++; - - message_p = NULL; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); - - if( message_p != NULL ) - { - S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = ue_p->eNB_ue_s1ap_id; + enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id; + cnt++; - if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) + message_p = NULL; + message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); + + if( message_p != NULL ) { - S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); + S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = ue_p->eNB_ue_s1ap_id; + + if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) + { + S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); + } + } + else + { + S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); } - } - else - { - S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); - } }else{ - S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt); + S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt); } } } @@ -396,7 +370,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa { S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id); } - } + } else { S1AP_ERROR("SCTP disconnection reception : MME = %d\n",s1ap_mme_data_p->cnx_id); @@ -413,14 +387,6 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED; } } -// if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { -// S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", -// sctp_new_association_resp->sctp_state, -// instance, -// sctp_new_association_resp->ulp_cnx_id); -// s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); -// return; -// } else { /* Update parameters */ @@ -435,6 +401,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa return; } } +} static void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { From 674339237fd94c7c79dc8c1af49f90b9a31da1f7 Mon Sep 17 00:00:00 2001 From: "masayuki.harada" Date: Tue, 24 Nov 2020 11:11:54 +0900 Subject: [PATCH 13/91] Add handling of error case. --- openair3/GTPV1-U/gtpv1u_eNB.c | 2 +- openair3/NAS/COMMON/EMM/MSG/AttachAccept.c | 1 - openair3/S1AP/s1ap_eNB.c | 6 ++++-- openair3/S1AP/s1ap_eNB_decoder.c | 2 -- openair3/SCTP/sctp_eNB_task.c | 8 ++++---- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 1e2954ba95..25f506f9a1 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -1211,7 +1211,7 @@ int gtpv1u_eNB_init(void) { //gtpv1u_data_g.udp_data; RC.gtpv1u_data_g->seq_num = 0; RC.gtpv1u_data_g->restart_counter = 0; - + RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up = 0; /* Initializing GTPv1-U stack */ if ((rc = nwGtpv1uInitialize(&RC.gtpv1u_data_g->gtpv1u_stack, GTPU_STACK_ENB)) != NW_GTPV1U_OK) { LOG_E(GTPU, "Failed to setup nwGtpv1u stack %x\n", rc); diff --git a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c index 8ac43cf7b1..637d930226 100644 --- a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c +++ b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c @@ -190,7 +190,6 @@ int decode_attach_accept(attach_accept_msg *attach_accept, uint8_t *buffer, uint default: errorCodeDecoder = TLV_DECODE_UNEXPECTED_IEI; LOG_TRACE(WARNING, "DECODE_UNEXPECTED_IEI %x (4 bits)", ieiDecoded); - AssertFatal(0, " "); return TLV_DECODE_UNEXPECTED_IEI; } } diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index c011653f76..9435296371 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -411,8 +411,10 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { mme_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream, sctp_data_ind->buffer, sctp_data_ind->buffer_length); #else - s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream, - sctp_data_ind->buffer, sctp_data_ind->buffer_length); + if (s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length) == -1) { + S1AP_ERROR("Failed to handle s1ap eNB message\n"); + } #endif result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c index 4635946a05..14e4b49238 100644 --- a/openair3/S1AP/s1ap_eNB_decoder.c +++ b/openair3/S1AP/s1ap_eNB_decoder.c @@ -89,8 +89,6 @@ static int s1ap_eNB_decode_initiating_message(S1AP_S1AP_PDU_t *pdu) { default: S1AP_ERROR("Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage.procedureCode); - AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n", - (int)pdu->choice.initiatingMessage.procedureCode); return -1; } diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index ec9e62bb3f..abaae7090f 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -270,7 +270,7 @@ sctp_handle_new_association_req_multi( sctp_new_association_req_p->remote_address.ipv6_address); //close(sd); //return; - exit(1); + exit_fun("sctp_handle_new_association_req_multi fatal: inet_pton error"); } SCTP_DEBUG("Converted ipv6 address %*s to network type\n", @@ -290,7 +290,7 @@ sctp_handle_new_association_req_multi( sctp_new_association_req_p->remote_address.ipv4_address); //close(sd); //return; - exit(1); + exit_fun("sctp_handle_new_association_req_multi fatal: inet_pton error"); } SCTP_DEBUG("Converted ipv4 address %*s to network type\n", @@ -329,7 +329,7 @@ sctp_handle_new_association_req_multi( if (ns == -1) { perror("sctp_peeloff"); printf("sctp_peeloff: sd=%d assoc_id=%d\n", sd, assoc_id); - exit(1); + exit_fun("sctp_handle_new_association_req_multi fatal: sctp_peeloff error"); } sctp_cnx = calloc(1, sizeof(*sctp_cnx)); @@ -971,7 +971,7 @@ sctp_eNB_read_from_socket( if (!(flags & MSG_EOR)) { SCTP_ERROR("fatal: partial SCTP messages are not handled\n"); - exit(1); + exit_fun("fatal: partial SCTP messages are not handled" ); } if (flags & MSG_NOTIFICATION) { From 9c71e941dd420d57c377946ec73e8dcafd32d504 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 18 Jan 2021 12:41:09 +0000 Subject: [PATCH 14/91] Trigger RA after SIB1 reception --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 4 +- openair2/RRC/NR_UE/rrc_UE.c | 81 ++++++++++++++++++++++++++++- openair2/RRC/NR_UE/rrc_defs.h | 11 ++++ 3 files changed, 92 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 042c419241..4864d30f21 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -373,7 +373,7 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, // TODO: add connEstFailureControl //si-SchedulingInfo - /*sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo)); + sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo)); asn_set_empty(&sib1->si_SchedulingInfo->schedulingInfoList.list); sib1->si_SchedulingInfo->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s20; struct NR_SchedulingInfo *schedulingInfo = CALLOC(1,sizeof(struct NR_SchedulingInfo)); @@ -383,7 +383,7 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, e_NR_SIB_TypeInfo__type *sib_type = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); *sib_type = NR_SIB_TypeInfo__type_sibType3; ASN_SEQUENCE_ADD(&schedulingInfo->sib_MappingInfo.list,sib_type); - ASN_SEQUENCE_ADD(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo);*/ + ASN_SEQUENCE_ADD(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo); // servingCellConfigCommon sib1->servingCellConfigCommon = CALLOC(1,sizeof(struct NR_ServingCellConfigCommonSIB)); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 093ecdf788..0221e1c5e1 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -403,6 +403,15 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ for(nr_ue=0;nr_ueschedulingInfoList.list.array) { + + bool SIB_to_request[32] = {}; + + LOG_I(RRC, "SIBs broadcasting: "); + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2); + } + printf("\n"); + + LOG_I(RRC, "SIBs needed by UE: "); + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) { + + printf("SIB%i ", j + 2); + + SIB_to_request[j] = true; + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) { + SIB_to_request[j] = false; + break; + } + } + + } + } + printf("\n"); + + LOG_I(RRC, "SIBs to request by UE: "); + bool do_ra = false; + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if(SIB_to_request[j]) { + printf("SIB%i ", j + 2); + do_ra = true; + } + } + printf("\n"); + + if(do_ra) { + + if(sib1.si_SchedulingInfo->si_RequestConfig) { + LOG_I(RRC, "Starting contention-free RA procedure\n"); + } else { + LOG_I(RRC, "Starting contention-based RA procedure\n"); + get_softmodem_params()->do_ra = 1; + } + + } + + } + + } + + + printf("\n\n"); + + return 0; +} + /*brief decode SIB1 message*/ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { @@ -1500,8 +1573,12 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index } sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; if (*(int64_t*)sib1 != 1) { - LOG_D(RRC, "SIB1 address: %lx\n", *(int64_t*)sib1); - xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); + LOG_D(RRC, "SIB1 address: %lx\n", *(int64_t*)sib1); + + if( g_log->log_component[RRC].level >= OAILOG_DEBUG ) + xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); + + check_requested_SI_List(NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); } else LOG_E(PHY, "sib1 is starting by 8 times 0\n"); diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index c164434d85..0e9ec4514f 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -78,6 +78,15 @@ typedef struct OAI_NR_UECapability_s { NR_UE_NR_Capability_t *UE_NR_Capability; } OAI_NR_UECapability_t; +typedef enum requested_SI_List_e { + SIB2 = 0x1, + SIB3 = 0x2, + SIB4 = 0x4, + SIB5 = 0x8, + SIB6 = 0x16, + SIB7 = 0x32 +} requested_SI_List_t; + typedef struct NR_UE_RRC_INST_s { NR_MeasConfig_t *meas_config; @@ -104,6 +113,8 @@ typedef struct NR_UE_RRC_INST_s { uint8_t *UECapability; uint8_t UECapability_size; + BIT_STRING_t requested_SI_List; + NR_SystemInformation_t *si[NB_CNX_UE]; NR_SIB1_t *sib1[NB_CNX_UE]; NR_SIB2_t *sib2[NB_CNX_UE]; From f93413e132fabe1ed3f3b6775dfd38ce54c8fb18 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 18 Jan 2021 16:08:30 +0000 Subject: [PATCH 15/91] Define trigger_RA_List --- openair2/RRC/NR_UE/rrc_UE.c | 79 +++++++++++++++++------------------ openair2/RRC/NR_UE/rrc_defs.h | 17 +++++++- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 0221e1c5e1..ef5a494c9f 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -404,6 +404,7 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ // fill UE-NR-Capability @ UE-CapabilityRAT-Container here. NR_UE_rrc_inst[nr_ue].selected_plmn_identity = 1; + // TODO: Put the appropriate list of SIBs NR_UE_rrc_inst[nr_ue].requested_SI_List.buf = CALLOC(1,4); NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[0] = SIB2 | SIB3 | SIB5; // SIB2 - SIB9 NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[1] = 0; // SIB10 - SIB17 @@ -412,6 +413,8 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ NR_UE_rrc_inst[nr_ue].requested_SI_List.size= 4; NR_UE_rrc_inst[nr_ue].requested_SI_List.bits_unused= 0; + NR_UE_rrc_inst[nr_ue].do_ra = RA_NOT_RUNNING; + // init RRC lists RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RLC_Bearer_Config_list, NR_maxLC_ID); RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SchedulingRequest_list, NR_maxNrofSR_ConfigPerCellGroup); @@ -1486,67 +1489,61 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB return rval; } -int8_t check_requested_SI_List(BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) { - - printf("\n\n"); +int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) { if(sib1.si_SchedulingInfo) { - if(sib1.si_SchedulingInfo->schedulingInfoList.list.array) { - bool SIB_to_request[32] = {}; + bool SIB_to_request[32] = {}; - LOG_I(RRC, "SIBs broadcasting: "); - for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { - printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2); - } - printf("\n"); + LOG_I(RRC, "SIBs broadcasting: "); + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2); + } + printf("\n"); - LOG_I(RRC, "SIBs needed by UE: "); - for(int j = 0; j < 8*requested_SI_List.size; j++) { - if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) { + LOG_I(RRC, "SIBs needed by UE: "); + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) { - printf("SIB%i ", j + 2); + printf("SIB%i ", j + 2); - SIB_to_request[j] = true; - for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { - if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) { - SIB_to_request[j] = false; - break; - } + SIB_to_request[j] = true; + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) { + SIB_to_request[j] = false; + break; } - } + } - printf("\n"); + } + printf("\n"); - LOG_I(RRC, "SIBs to request by UE: "); - bool do_ra = false; - for(int j = 0; j < 8*requested_SI_List.size; j++) { - if(SIB_to_request[j]) { - printf("SIB%i ", j + 2); - do_ra = true; - } + LOG_I(RRC, "SIBs to request by UE: "); + bool do_ra = false; + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if(SIB_to_request[j]) { + printf("SIB%i ", j + 2); + do_ra = true; } - printf("\n"); + } + printf("\n"); - if(do_ra) { + if(do_ra) { - if(sib1.si_SchedulingInfo->si_RequestConfig) { - LOG_I(RRC, "Starting contention-free RA procedure\n"); - } else { - LOG_I(RRC, "Starting contention-based RA procedure\n"); - get_softmodem_params()->do_ra = 1; - } + NR_UE_rrc_inst[module_id].do_ra = REQUEST_FOR_OTHER_SI; + get_softmodem_params()->do_ra = 1; + if(sib1.si_SchedulingInfo->si_RequestConfig) { + LOG_I(RRC, "Trigger contention-free RA procedure (do_ra = %i)\n", NR_UE_rrc_inst[module_id].do_ra); + } else { + LOG_I(RRC, "Trigger contention-based RA procedure (do_ra = %i)\n", NR_UE_rrc_inst[module_id].do_ra); } } } - - printf("\n\n"); - return 0; } @@ -1578,7 +1575,7 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index if( g_log->log_component[RRC].level >= OAILOG_DEBUG ) xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); - check_requested_SI_List(NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); + check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); } else LOG_E(PHY, "sib1 is starting by 8 times 0\n"); diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 0e9ec4514f..d736d507c8 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -84,9 +84,23 @@ typedef enum requested_SI_List_e { SIB4 = 0x4, SIB5 = 0x8, SIB6 = 0x16, - SIB7 = 0x32 + SIB7 = 0x32, + SIB8 = 0x64, + SIB9 = 0x128 } requested_SI_List_t; +typedef enum trigger_RA_List_e { + RA_NOT_RUNNING, + INITIAL_ACCESS_FROM_RRC_IDLE, + RRC_CONNECTION_REESTABLISHMENT, + DURING_HANDOVER, + NON_SYNCHRONISED, + TRANSITION_FROM_RRC_INACTIVE, + TO_ESTABLISH_TA, + REQUEST_FOR_OTHER_SI, + BEAM_FAILURE_RECOVERY, +} trigger_RA_List_t; + typedef struct NR_UE_RRC_INST_s { NR_MeasConfig_t *meas_config; @@ -113,6 +127,7 @@ typedef struct NR_UE_RRC_INST_s { uint8_t *UECapability; uint8_t UECapability_size; + trigger_RA_List_t do_ra; BIT_STRING_t requested_SI_List; NR_SystemInformation_t *si[NB_CNX_UE]; From 681706b6da8f5f35a22234c645776b6a8383c819 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 18 Jan 2021 20:11:51 +0000 Subject: [PATCH 16/91] Define RA_trigger --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 13 +++++++++++++ openair2/LAYER2/NR_MAC_UE/config_ue.c | 3 ++- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 2 ++ openair2/RRC/NR_UE/rrc_UE.c | 9 ++++----- openair2/RRC/NR_UE/rrc_defs.h | 17 ++--------------- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index e41ca67229..e13ae1424c 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -160,6 +160,19 @@ typedef struct Type0_PDCCH_CSS_config_s { uint32_t cset_start_rb; } NR_Type0_PDCCH_CSS_config_t; +// 3GPP TS 38.300 Section 9.2.6 +typedef enum RA_trigger_e { + RA_NOT_RUNNING, + INITIAL_ACCESS_FROM_RRC_IDLE, + RRC_CONNECTION_REESTABLISHMENT, + DURING_HANDOVER, + NON_SYNCHRONISED, + TRANSITION_FROM_RRC_INACTIVE, + TO_ESTABLISH_TA, + REQUEST_FOR_OTHER_SI, + BEAM_FAILURE_RECOVERY, +} RA_trigger_t; + uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 20fe84d819..e9ebd16d0f 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -272,8 +272,9 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, } // PRACH configuration - uint8_t nb_preambles = 64; + mac->ra_trigger = RA_NOT_RUNNING; + if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 6bbbc00c00..fefe712e43 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -185,6 +185,8 @@ typedef struct { /* Random Access parameters */ /// state of RA procedure RA_state_t ra_state; + /// trigger of RA procedure + RA_trigger_t ra_trigger; /// RA rx frame offset: compensate RA rx offset introduced by OAI gNB. uint8_t RA_offset; /// RA-rnti diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index ef5a494c9f..2fcf9b93fc 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -413,8 +413,6 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ NR_UE_rrc_inst[nr_ue].requested_SI_List.size= 4; NR_UE_rrc_inst[nr_ue].requested_SI_List.bits_unused= 0; - NR_UE_rrc_inst[nr_ue].do_ra = RA_NOT_RUNNING; - // init RRC lists RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RLC_Bearer_Config_list, NR_maxLC_ID); RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SchedulingRequest_list, NR_maxNrofSR_ConfigPerCellGroup); @@ -1531,13 +1529,14 @@ int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_ if(do_ra) { - NR_UE_rrc_inst[module_id].do_ra = REQUEST_FOR_OTHER_SI; + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + mac->ra_trigger = REQUEST_FOR_OTHER_SI; get_softmodem_params()->do_ra = 1; if(sib1.si_SchedulingInfo->si_RequestConfig) { - LOG_I(RRC, "Trigger contention-free RA procedure (do_ra = %i)\n", NR_UE_rrc_inst[module_id].do_ra); + LOG_I(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", mac->ra_trigger); } else { - LOG_I(RRC, "Trigger contention-based RA procedure (do_ra = %i)\n", NR_UE_rrc_inst[module_id].do_ra); + LOG_I(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", mac->ra_trigger); } } diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index d736d507c8..0283ade69c 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -89,18 +89,6 @@ typedef enum requested_SI_List_e { SIB9 = 0x128 } requested_SI_List_t; -typedef enum trigger_RA_List_e { - RA_NOT_RUNNING, - INITIAL_ACCESS_FROM_RRC_IDLE, - RRC_CONNECTION_REESTABLISHMENT, - DURING_HANDOVER, - NON_SYNCHRONISED, - TRANSITION_FROM_RRC_INACTIVE, - TO_ESTABLISH_TA, - REQUEST_FOR_OTHER_SI, - BEAM_FAILURE_RECOVERY, -} trigger_RA_List_t; - typedef struct NR_UE_RRC_INST_s { NR_MeasConfig_t *meas_config; @@ -123,11 +111,10 @@ typedef struct NR_UE_RRC_INST_s { NR_SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE]; uint8_t MBMS_flag; - OAI_NR_UECapability_t *UECap; - uint8_t *UECapability; + OAI_NR_UECapability_t *UECap; + uint8_t *UECapability; uint8_t UECapability_size; - trigger_RA_List_t do_ra; BIT_STRING_t requested_SI_List; NR_SystemInformation_t *si[NB_CNX_UE]; From ee3f939692fffbc5fafa8e74f42ff48646f2c622 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Wed, 20 Jan 2021 23:57:31 +0000 Subject: [PATCH 17/91] Fill msg3 for the RA --- openair1/SIMULATION/NR_PHY/nr_unitary_defs.h | 13 --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 13 --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 3 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 2 - openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 44 ++++------ openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- openair2/RRC/NR/nr_rrc_types.h | 6 +- openair2/RRC/NR_UE/L2_interface_ue.c | 30 ++++++- openair2/RRC/NR_UE/rrc_UE.c | 86 ++++++++++++++----- openair2/RRC/NR_UE/rrc_defs.h | 14 +++ openair2/RRC/NR_UE/rrc_proto.h | 11 +-- openair2/SIMULATION/NR_RRC/itti_sim.c | 2 +- 12 files changed, 136 insertions(+), 90 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h index a7150fb2f9..e9e3039c71 100644 --- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h +++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h @@ -55,19 +55,6 @@ signed char quantize(double D, double x, unsigned char B) { return ((char) qxd); } - -int8_t -mac_rrc_data_req_ue( - const module_id_t Mod_idP, - const int CC_id, - const frame_t frameP, - const rb_id_t Srb_id, - const uint8_t Nb_tb, - uint8_t *const buffer_pP, - const mac_enb_index_t eNB_indexP, - const uint8_t mbsfn_sync_area - ) { return(0);} - int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);} //NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index e13ae1424c..e41ca67229 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -160,19 +160,6 @@ typedef struct Type0_PDCCH_CSS_config_s { uint32_t cset_start_rb; } NR_Type0_PDCCH_CSS_config_t; -// 3GPP TS 38.300 Section 9.2.6 -typedef enum RA_trigger_e { - RA_NOT_RUNNING, - INITIAL_ACCESS_FROM_RRC_IDLE, - RRC_CONNECTION_REESTABLISHMENT, - DURING_HANDOVER, - NON_SYNCHRONISED, - TRANSITION_FROM_RRC_INACTIVE, - TO_ESTABLISH_TA, - REQUEST_FOR_OTHER_SI, - BEAM_FAILURE_RECOVERY, -} RA_trigger_t; - uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index e9ebd16d0f..20fe84d819 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -272,9 +272,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, } // PRACH configuration - uint8_t nb_preambles = 64; - mac->ra_trigger = RA_NOT_RUNNING; + uint8_t nb_preambles = 64; if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index fefe712e43..6bbbc00c00 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -185,8 +185,6 @@ typedef struct { /* Random Access parameters */ /// state of RA procedure RA_state_t ra_state; - /// trigger of RA procedure - RA_trigger_t ra_trigger; /// RA rx frame offset: compensate RA rx offset introduced by OAI gNB. uint8_t RA_offset; /// RA-rnti diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 1f5d81060e..f297ae1ded 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -50,6 +50,7 @@ /* RRC */ #include "NR_RACH-ConfigCommon.h" +#include "RRC/NR_UE/rrc_proto.h" /* PHY */ #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" @@ -456,36 +457,20 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, prach_resources->RA_SCALING_FACTOR_BI = 1; prach_resources->RA_PCMAX = 0; // currently hardcoded to 0 - payload = (uint8_t*) &mac->CCCH_pdu.payload; + payload = (uint8_t*) mac->CCCH_pdu.payload; mac_ce_len = 0; num_sdus = 1; post_padding = 1; + sdu_lcids[0] = lcid; - if (0){ - // initialisation by RRC - // CCCH PDU - // size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id, - // CC_id, - // frame, - // CCCH, - // 1, - // mac_sdus, - // gNB_id, - // 0); - LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu); - } else { - // fill ulsch_buffer with random data - for (int i = 0; i < TBS_bytes; i++){ - mac_sdus[i] = (unsigned char) (lrand48()&0xff); - } - //Sending SDUs with size 1 - //Initialize elements of sdu_lcids and sdu_lengths - sdu_lcids[0] = lcid; - sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len; - header_length_total += 2 + (sdu_lengths[0] >= 128); - size_sdu += sdu_lengths[0]; - } + // initialisation by RRC + // CCCH PDU + size_sdu = (uint16_t) nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, mac_sdus); + + sdu_lengths[0] = size_sdu; + + LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu); //mac->RA_tx_frame = frame; //mac->RA_tx_slot = nr_slot_tx; @@ -529,7 +514,14 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, for (int j = 0; j < (TBS_bytes - offset); j++) payload[offset + j] = 0; // mac_pdu[offset + j] = 0; } - } + } + + LOG_I(MAC,"size_sdu = %i\n", size_sdu); + LOG_I(MAC,"offset = %i\n", offset); + for(int k = 0; kMsg3[k]); + } + } else if (mac->RA_window_cnt != -1) { // RACH is active //////////////////////////////////////////////////////////////// diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index be476c2775..b69ecafc89 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -987,7 +987,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id, LOG_D(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred); LOG_D(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection); LOG_D(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit); - LOG_I(MAC,"ssb index(extra bits): %d\n", (int)ssb_index); + LOG_D(MAC,"ssb index(extra bits): %d\n", (int)ssb_index); //storing ssb index in the mac structure mac->mib_ssb = ssb_index; diff --git a/openair2/RRC/NR/nr_rrc_types.h b/openair2/RRC/NR/nr_rrc_types.h index 02495591a9..61f90e3572 100644 --- a/openair2/RRC/NR/nr_rrc_types.h +++ b/openair2/RRC/NR/nr_rrc_types.h @@ -32,11 +32,11 @@ #define RRC_TYPES_NR_H_ typedef enum Rrc_State_NR_e { - RRC_STATE_INACTIVE_NR=0, - RRC_STATE_IDLE_NR, + RRC_STATE_IDLE_NR=0, + RRC_STATE_INACTIVE_NR, RRC_STATE_CONNECTED_NR, - RRC_STATE_FIRST_NR = RRC_STATE_INACTIVE_NR, + RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR, RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR, } Rrc_State_NR_t; diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 22e17f6266..c56d75e48b 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -33,6 +33,7 @@ #include "rrc_defs.h" #include "rrc_proto.h" #include "assertions.h" +#include "rrc_vars.h" typedef uint32_t channel_t; @@ -59,13 +60,36 @@ nr_mac_rrc_data_ind_ue( return(0); } -int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP, +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, const int CC_id, + const uint8_t gNB_id, const frame_t frameP, const rb_id_t Srb_id, - uint8_t *const buffer_pP ){ + uint8_t *buffer_pP){ - // todo + switch(Srb_id){ + + case CCCH: + + // TODO: Enable timer T300 + //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_active = 1; + //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_cnt = 0; + + LOG_I(RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); + memcpy(buffer_pP, (uint8_t*)NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.Payload, NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); + for(int i = 0; imodule_id].MBMS_flag < 3) // see -Q option if (AMF_MODE_ENABLED) { - rrc_ue_generate_RRCSetupRequest( ctxt_pP, gNB_index ); + nr_rrc_ue_generate_RRCSetupRequest( ctxt_pP->module_id, gNB_index ); } if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_IDLE) { @@ -1287,7 +1289,7 @@ int nr_decode_BCCH_DLSCH_Message( if (nr_rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) { //if ( (NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!AMF_MODE_ENABLED)) { - rrc_ue_generate_RRCSetupRequest(ctxt_pP, 0); + nr_rrc_ue_generate_RRCSetupRequest(ctxt_pP->module_id, 0); nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING ); //} } @@ -1493,13 +1495,13 @@ int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_ bool SIB_to_request[32] = {}; - LOG_I(RRC, "SIBs broadcasting: "); + LOG_D(RRC, "SIBs broadcasting: "); for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2); } printf("\n"); - LOG_I(RRC, "SIBs needed by UE: "); + LOG_D(RRC, "SIBs needed by UE: "); for(int j = 0; j < 8*requested_SI_List.size; j++) { if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) { @@ -1517,7 +1519,7 @@ int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_ } printf("\n"); - LOG_I(RRC, "SIBs to request by UE: "); + LOG_D(RRC, "SIBs to request by UE: "); bool do_ra = false; for(int j = 0; j < 8*requested_SI_List.size; j++) { if(SIB_to_request[j]) { @@ -1529,14 +1531,13 @@ int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_ if(do_ra) { - NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - mac->ra_trigger = REQUEST_FOR_OTHER_SI; + NR_UE_rrc_inst[module_id].ra_trigger = REQUEST_FOR_OTHER_SI; get_softmodem_params()->do_ra = 1; if(sib1.si_SchedulingInfo->si_RequestConfig) { - LOG_I(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", mac->ra_trigger); + LOG_D(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); } else { - LOG_I(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", mac->ra_trigger); + LOG_D(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); } } @@ -1546,6 +1547,41 @@ int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_ return 0; } +int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) { + + switch(NR_UE_rrc_inst[module_id].ra_trigger){ + case INITIAL_ACCESS_FROM_RRC_IDLE: + nr_rrc_ue_generate_RRCSetupRequest(module_id,gNB_index); + break; + case RRC_CONNECTION_REESTABLISHMENT: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case DURING_HANDOVER: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case NON_SYNCHRONISED: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case TRANSITION_FROM_RRC_INACTIVE: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case TO_ESTABLISH_TA: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case REQUEST_FOR_OTHER_SI: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case BEAM_FAILURE_RECOVERY: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + default: + AssertFatal(1==0, "Invalid ra_trigger value!\n"); + break; + } + +} + + /*brief decode SIB1 message*/ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { @@ -1574,7 +1610,15 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index if( g_log->log_component[RRC].level >= OAILOG_DEBUG ) xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); - check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); + // FIXME: fix condition for the RA trigger + if( nr_rrc_get_state(module_id) == RRC_STATE_IDLE_NR ) { + NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE; + get_softmodem_params()->do_ra = 1; + } else { + check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); + } + + nr_rrc_ue_generate_ra_msg(module_id,gNB_index); } else LOG_E(PHY, "sib1 is starting by 8 times 0\n"); @@ -1844,10 +1888,10 @@ nr_rrc_ue_process_securityModeCommand( } //----------------------------------------------------------------------------- -void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) { +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index ) { uint8_t i=0,rv[6]; - if(NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) { + if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) { // Get RRCConnectionRequest, fill random for now // Generate random byte stream for contention resolution for (i=0; i<6; i++) { @@ -1861,16 +1905,16 @@ void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, cons } LOG_T(NR_RRC,"\n"); - // NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size = - // do_RRCSetupRequest( - // ctxt_pP->module_id, - // (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, - // rv); - LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, eNB %d)\n", - ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index); + NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size = + do_RRCSetupRequest( + module_id, + (uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload, + rv); + LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n", + module_id, NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index); - for (i=0; imodule_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) { - LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]); + for (i=0; i Date: Thu, 21 Jan 2021 20:10:23 +0000 Subject: [PATCH 18/91] Fix in the msg3 transmission for the RA --- openair2/LAYER2/MAC/mac.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 41 ++++++----- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 69 +++++++------------ openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c | 1 + openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 14 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 8 +++ openair2/RRC/NR/MESSAGES/asn1_msg.c | 54 +++++++++++++-- openair2/RRC/NR_UE/L2_interface_ue.c | 4 +- openair2/RRC/NR_UE/rrc_UE.c | 4 +- 9 files changed, 116 insertions(+), 81 deletions(-) diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 7eccc6222d..a1312cff54 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -489,7 +489,7 @@ typedef struct { /*! \brief Uplink SCH PDU Structure */ typedef struct { - int8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */ + uint8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */ uint16_t Pdu_size; } __attribute__ ((__packed__)) ULSCH_PDU; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index f297ae1ded..50e5aa3572 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -420,7 +420,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, uint8_t sdu_lcids[NB_RB_MAX] = {0}; uint16_t sdu_lengths[NB_RB_MAX] = {0}; - int TBS_bytes = 848, header_length_total=0, num_sdus, offset, preambleTransMax, mac_ce_len; + int num_sdus, offset = 0, preambleTransMax; AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n"); @@ -457,9 +457,9 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, prach_resources->RA_SCALING_FACTOR_BI = 1; prach_resources->RA_PCMAX = 0; // currently hardcoded to 0 + uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); payload = (uint8_t*) mac->CCCH_pdu.payload; - mac_ce_len = 0; num_sdus = 1; post_padding = 1; sdu_lcids[0] = lcid; @@ -472,22 +472,17 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu); - //mac->RA_tx_frame = frame; - //mac->RA_tx_slot = nr_slot_tx; - //mac->RA_backoff_frame = frame; - //mac->RA_backoff_slot = nr_slot_tx; - if (size_sdu > 0) { LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame); mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; mac->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; - mac->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); mac->RA_prachMaskIndex = 0; // todo: add the backoff condition here mac->RA_backoff_cnt = 0; mac->RA_active = 1; + prach_resources->Msg3 = payload; nr_get_RA_window(mac); @@ -501,27 +496,35 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, num_sdus, // num sdus sdu_lengths, // sdu length sdu_lcids, // sdu lcid - 0, // power headroom - 0, // crnti - 0, // truncated bsr - 0, // short bsr - 0, // long_bsr + 0, // power headroom + 0, // crnti + 0, // truncated bsr + 0, // short bsr + 0, // long_bsr post_padding, 0); + AssertFatal(TBS_max > offset, "Frequency resources are not enough for Msg3!\n"); + // Padding: fill remainder with 0 if (post_padding > 0){ - for (int j = 0; j < (TBS_bytes - offset); j++) - payload[offset + j] = 0; // mac_pdu[offset + j] = 0; + for (int j = 0; j < (TBS_max - offset); j++) + payload[offset + j] = 0; } } - LOG_I(MAC,"size_sdu = %i\n", size_sdu); - LOG_I(MAC,"offset = %i\n", offset); - for(int k = 0; kMsg3[k]); + LOG_D(MAC,"size_sdu = %i\n", size_sdu); + LOG_D(MAC,"offset = %i\n", offset); + for(int k = 0; k < TBS_max; k++) { + LOG_D(MAC,"(%i): %i\n", k, prach_resources->Msg3[k]); } + // Msg3 was initialized with TBS_max bytes because the mac->RA_Msg3_size will only be known after + // receiving Msg2 (which contains the Msg3 resource reserve). + // Msg3 will be transmitted with mac->RA_Msg3_size bytes, removing unnecessary 0s. + mac->ulsch_pdu.Pdu_size = TBS_max; + memcpy(mac->ulsch_pdu.payload, prach_resources->Msg3, TBS_max); + } else if (mac->RA_window_cnt != -1) { // RACH is active //////////////////////////////////////////////////////////////// diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index b69ecafc89..5da999846e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1337,69 +1337,46 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } - } else if (get_softmodem_params()->do_ra){ - - NR_UE_MAC_INST_t *mac = get_mac_inst(ul_info->module_id); + } else if (mac->ra_state == WAIT_RAR){ if (ul_info->slot_tx == mac->msg3_slot && ul_info->frame_tx == mac->msg3_frame){ - uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; - nr_scheduled_response_t scheduled_response; - fapi_nr_tx_request_t tx_req; - //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx); - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0]; - fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus]; - uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size; - - //if (IS_SOFTMODEM_NOS1){ - // // Getting IP traffic to be transmitted - // data_existing = nr_ue_get_sdu(mod_id, - // cc_id, - // frame_tx, - // slot_tx, - // 0, - // ulsch_input_buffer, - // TBS_bytes, - // &access_mode); - //} - - //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity - //if (!IS_SOFTMODEM_NOS1 || !data_existing) { - //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid - //and block this traffic from being forwarded to the upper layers at the gNB - LOG_D(MAC, "Random data to be tranmsitted (TBS_bytes %d): \n", TBS_bytes); - //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) - //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should - //have a valid LCID (nr_process_mac_pdu function) - ulsch_input_buffer[0] = 0x31; - for (int i = 1; i < TBS_bytes; i++) { - ulsch_input_buffer[i] = (unsigned char) rand(); - //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - } - //} - - LOG_I(MAC, "[UE %d] Frame %d, Subframe %d Adding Msg3 UL Config Request for rnti: %x\n", - ul_info->module_id, - ul_info->frame_tx, - ul_info->slot_tx, - mac->t_crnti); - // Config UL TX PDU + fapi_nr_tx_request_t tx_req; tx_req.slot = ul_info->slot_tx; tx_req.sfn = ul_info->frame_tx; tx_req.number_of_pdus = 1; - tx_req.tx_request_body[0].pdu_length = TBS_bytes; + tx_req.tx_request_body[0].pdu_length = mac->RA_Msg3_size; tx_req.tx_request_body[0].pdu_index = 0; - tx_req.tx_request_body[0].pdu = ulsch_input_buffer; + tx_req.tx_request_body[0].pdu = mac->ulsch_pdu.payload; + + fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0]; + fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus]; ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; ul_config->number_pdus++; + // scheduled_response + nr_scheduled_response_t scheduled_response; fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx, ul_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ mac->if_module->scheduled_response(&scheduled_response); } mac->msg3_frame = -1; // re-initialize to an invalid value after scheduling mac->msg3_slot = -1; + + LOG_I(MAC, "[UE %d] Frame %d, Subframe %d Adding Msg3 UL Config Request for rnti: %x\n", + ul_info->module_id, + ul_info->frame_tx, + ul_info->slot_tx, + mac->t_crnti); + + printf("\n"); + LOG_I(MAC,"[RAPROC] Msg3 to be transmitted:\n"); + for (int k = 0; k < mac->RA_Msg3_size; k++) { + LOG_I(MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]); + } + printf("\n"); + } } } diff --git a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c index 8273c9caff..771d7dca4a 100644 --- a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c +++ b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c @@ -122,6 +122,7 @@ void nr_config_Msg3_pdu(NR_UE_MAC_INST_t *mac, // virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211) pusch_config_pdu->rb_start += ibwp_start - abwp_start; + mac->RA_Msg3_size = pusch_config_pdu->rb_size; // Time domain allocation SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e15963f355..4fc41cd049 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -584,7 +584,8 @@ void nr_get_Msg3alloc(module_id_t module_id, NR_RA_t *ra) { // msg3 is schedulend in mixed slot in the following TDD period - // for now we consider a TBS of 18 bytes + + uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing; int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot; @@ -614,21 +615,22 @@ void nr_get_Msg3alloc(module_id_t module_id, uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * 275]; const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275); - /* search 18 free RBs */ + + /* search ra_tbs free RBs */ int rbSize = 0; int rbStart = 0; - while (rbSize < 18) { + while (rbSize < msg3_nb_rb) { rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ rbSize = 0; while (rbStart < bwpSize && vrb_map_UL[rbStart]) rbStart++; - AssertFatal(rbStart < bwpSize - 18, "no space to allocate Msg 3 for RA!\n"); + AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n"); while (rbStart + rbSize < bwpSize && !vrb_map_UL[rbStart + rbSize] - && rbSize < 18) + && rbSize < msg3_nb_rb) rbSize++; } - ra->msg3_nb_rb = 18; + ra->msg3_nb_rb = msg3_nb_rb; ra->msg3_first_rb = rbStart; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 75b00ea6ba..7f7def6571 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -417,6 +417,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, current_rnti, UE_id, ra->rnti); + + printf("\n"); + LOG_I(MAC,"[RAPROC] Received Msg3:\n"); + for (int k = 0; k < sdu_lenP; k++) { + LOG_I(MAC,"(%i): 0x%x\n",k,sduP[k]); + } + printf("\n"); + // re-initialize ta update variables afrer RA procedure completion UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 4864d30f21..e26e0aea2f 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -373,7 +373,7 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, // TODO: add connEstFailureControl //si-SchedulingInfo - sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo)); + /*sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo)); asn_set_empty(&sib1->si_SchedulingInfo->schedulingInfoList.list); sib1->si_SchedulingInfo->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s20; struct NR_SchedulingInfo *schedulingInfo = CALLOC(1,sizeof(struct NR_SchedulingInfo)); @@ -383,7 +383,7 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, e_NR_SIB_TypeInfo__type *sib_type = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); *sib_type = NR_SIB_TypeInfo__type_sibType3; ASN_SEQUENCE_ADD(&schedulingInfo->sib_MappingInfo.list,sib_type); - ASN_SEQUENCE_ADD(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo); + ASN_SEQUENCE_ADD(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo);*/ // servingCellConfigCommon sib1->servingCellConfigCommon = CALLOC(1,sizeof(struct NR_ServingCellConfigCommonSIB)); @@ -420,7 +420,51 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon; sib1->servingCellConfigCommon->n_TimingAdvanceOffset = configuration->scc->n_TimingAdvanceOffset; - sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.shortBitmap; + + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.buf = calloc(1, sizeof(uint8_t)); + uint8_t bitmap8,temp_bitmap=0; + switch (configuration->scc->ssb_PositionsInBurst->present) { + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.shortBitmap; + break; + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.mediumBitmap; + break; + /* + groupPresence: This field is present when maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1. + The first/leftmost bit corresponds to the SS/PBCH index 0-7, the second bit corresponds to SS/PBCH block 8-15, and so on. + Value 0 in the bitmap indicates that the SSBs according to inOneGroup are absent. Value 1 indicates that the SS/PBCH blocks are transmitted in accordance with inOneGroup. + inOneGroup: When maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1, all 8 bit are valid; + The first/ leftmost bit corresponds to the first SS/PBCH block index in the group (i.e., to SSB index 0, 8, and so on); the second bit corresponds to the second SS/PBCH block index in the group + (i.e., to SSB index 1, 9, and so on), and so on. Value 0 in the bitmap indicates that the corresponding SS/PBCH block is not transmitted while value 1 indicates that the corresponding SS/PBCH block is transmitted. + */ + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.size = 1; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.bits_unused = 0; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence = calloc(1, sizeof(BIT_STRING_t)); + memset(sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence, 0, sizeof(BIT_STRING_t)); + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->size = 1; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->bits_unused = 0; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->buf = calloc(1, sizeof(uint8_t)); + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->buf[0] = 0; + for (int i=0; i<8; i++){ + bitmap8 = configuration->scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]; + if (bitmap8!=0){ + if(temp_bitmap==0) + temp_bitmap = bitmap8; + else + AssertFatal(temp_bitmap==bitmap8,"For longBitmap the groups of 8 SSBs containing at least 1 transmitted SSB should be all the same\n"); + + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.buf[0] = bitmap8; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->buf[0] |= 1<<(7-i); + } + } + break; + default: + AssertFatal(false,"ssb_PositionsInBurst not present\n"); + break; + } + sib1->servingCellConfigCommon->ssb_PeriodicityServingCell = *configuration->scc->ssb_periodicityServingCell; sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon = CALLOC(1,sizeof(struct NR_TDD_UL_DL_ConfigCommon)); sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = configuration->scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing; @@ -1251,9 +1295,9 @@ uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) { rrcSetupRequest->rrcSetupRequest.spare.size=1; rrcSetupRequest->rrcSetupRequest.spare.bits_unused = 7; - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg); - } + //} enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message, NULL, diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index c56d75e48b..c560677b86 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -75,10 +75,10 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_active = 1; //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_cnt = 0; - LOG_I(RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); + LOG_D(RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); memcpy(buffer_pP, (uint8_t*)NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.Payload, NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); for(int i = 0; ido_ra = 1; - } else { - check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); } nr_rrc_ue_generate_ra_msg(module_id,gNB_index); From 0f57529b48b55d96c304ca44f988d714de6695c4 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 15 Jan 2021 10:05:28 +0100 Subject: [PATCH 19/91] fixing benetel4g driver by setting ru->has_ctrl_prt =1 and thus starting the RU control thread, which is required for the 4G RRU. In the future we should revisit this and harmonize with the 5G version. --- targets/RT/USER/lte-ru.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 56c2cb23dd..368fd78f9e 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2986,6 +2986,7 @@ void RCconfig_RU(void) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + RC.ru[j]->has_ctrl_prt =1; LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); } @@ -3039,6 +3040,7 @@ else { RC.ru[j]->if_south = REMOTE_IF4p5; RC.ru[j]->function = NGFI_RAU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + RC.ru[j]->has_ctrl_prt = 1; if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1; else RC.ru[j]->is_slave=0; From a5b5d6f9b0b8c77b15aaa0a5b6f8235496e57fc1 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 22 Jan 2021 10:25:38 +0100 Subject: [PATCH 20/91] fixing RRC power levels at 5G side to avoid saturation --- common/utils/T/T_defs.h | 4 ++-- common/utils/T/T_messages.txt | 4 ++++ executables/nr-gnb.c | 6 ++++++ .../PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 4 ++++ openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 4 ++++ openair1/SCHED_NR/phy_procedures_nr_gNB.c | 7 +++++++ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 7 ++++--- targets/ARCH/ETHERNET/benetel/5g/benetel.c | 8 ++++++-- .../PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf | 12 ++++++------ .../PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf | 13 +++++++++---- 10 files changed, 52 insertions(+), 17 deletions(-) diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 7b5304b1cb..11c816f002 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -44,7 +44,7 @@ /* let's have 100 RBs functional for the basic simulator */ # define T_BUFFER_MAX (1024*64*2) #else -# define T_BUFFER_MAX (1024*64) +# define T_BUFFER_MAX (1024*64*2) #endif /* size of the local cache for messages (must be pow(2,something)) */ @@ -52,7 +52,7 @@ /* we don't need much space for the basic simulator */ # define T_CACHE_SIZE 1024 #else -# define T_CACHE_SIZE (8192 * 2) +# define T_CACHE_SIZE (8192) #endif /* maximum number of bytes a message can contain */ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 06ee5bf12b..bad6444e13 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1,3 +1,7 @@ +ID = BENETEL + GROUP = ALL + FORMAT = int,frame : int,slot : buffer,rxdataF + #general logs ID = ENB_MASTER_TICK DESC = eNodeB master tick - one tick per ms, to be used as "reference clock", mostly for ticktime view diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index be9261a117..7966c5b6ce 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -1001,7 +1001,13 @@ void init_eNB_afterRU(void) { for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa); gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i]; +#if 0 +printf("before %p\n", gNB->common_vars.rxdataF[aa]); +#endif gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i]; +#if 0 +printf("after %p\n", gNB->common_vars.rxdataF[aa]); +#endif } } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 713e71674b..d2baa40451 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -67,6 +67,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates; int **rxdataF = gNB->common_vars.rxdataF; +#if 0 +printf("nr_pusch_channel_estimation rxdataF %p\n", &rxdataF[0][0]); +#endif + nushift = (p>>1)&1; gNB->frame_parms.nushift = nushift; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 7e6becb4a8..25c9fee832 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -250,6 +250,10 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, uint8_t is_dmrs_re; start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size; +#if 0 +printf("frame_parms->first_carrier_offset in nr_ulsch_extract_rbs_single %d\n", frame_parms->first_carrier_offset); +printf("rxdataF in nr_ulsch_extract_rbs_single %p\n", &rxdataF[0][0]); +#endif nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size; #ifdef __AVX2__ int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6b5c1a9b22..d67d7c8efa 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -551,6 +551,11 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) gNB_I0_measurements(gNB); + // measure enegry in SS=10 L=4, nb_rb = 18, first_rb = 0 (corresponds to msg3) + int offset = 10*gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset; + int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12*18); + LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF); + for (int i=0;ipucch[i]; if (pucch) { @@ -646,6 +651,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } #endif +T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], 2048*4*14)); + uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index; uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index b92ee1dba3..468a43a0c7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -334,7 +334,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP; - LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d sduP %p\n", gnb_mod_idP, harq_pid, CC_idP, @@ -342,7 +342,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, slotP, current_rnti, UE_id, - ul_cqi); + ul_cqi, + sduP); // if not missed detection (10dB threshold for now) if (UE_scheduling_control->ul_rssi < (100+rssi)) { @@ -627,7 +628,7 @@ void nr_schedule_ulsch(module_id_t module_id, if (cur_harq->round == 0) { UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size; } else { - LOG_W(MAC, + LOG_D(MAC, "%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n", frame, slot, diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index 2f60e7dc49..ab9f970931 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -228,11 +228,15 @@ next: fp = ru->nr_frame_parms; for (symbol = 0; symbol < 14; symbol++) { int i; - uint16_t *p = (uint16_t *)(&s->buffers.ul[*slot][symbol*1272*4]); + int16_t *p = (int16_t *)(&s->buffers.ul[*slot][symbol*1272*4]); for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]); + p[i] = (int16_t)(ntohs(p[i])) / 16; } rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; +#if 0 +if (*slot == 0 && symbol == 0) +printf("rxdata in benetel_fh_if4p5_south_in %p\n", &ru->common.rxdataF[antenna][0]); +#endif #if 1 memcpy(rxdata + 2048 - 1272/2, &s->buffers.ul[*slot][symbol*1272*4], diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf index 49b4e4441e..aab3876d96 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf @@ -230,12 +230,12 @@ RUs = ( local_if_name = "dpdk"; sdr_addrs = "softmodem -m 2048 -l 35 -n 2 -b 0000:81:00.3 --proc-type auto --file-prefix ggg -- -p 0x1"; #sdr_addrs = "softmodem -l 8 -n 2 -- -p 0x2"; - remote_address = "127.0.0.2"; - local_address = "127.0.0.1"; - local_portc = 50000; - remote_portc = 50000; - local_portd = 50001; - remote_portd = 50001; + #remote_address = "127.0.0.2"; + #local_address = "127.0.0.1"; + #local_portc = 50000; + #remote_portc = 50000; + #local_portd = 50001; + #remote_portd = 50001; local_rf = "no" tr_preference = "raw_if4p5" nb_tx = 1 diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 037de199df..251a76f36e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -23,6 +23,8 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; + #pusch_TargetSNRx10 = 200; + #pucch_TargetSNRx10 = 200; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; @@ -103,7 +105,8 @@ gNBs = prach_msg1_FrequencyStart = 74; zeroCorrelationZoneConfig = 13; #preambleReceivedTargetPower = -118; - preambleReceivedTargetPower = -104; + #preambleReceivedTargetPower = -104; + preambleReceivedTargetPower = -108; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) preambleTransMax = 6; #powerRampingStep @@ -149,14 +152,16 @@ gNBs = initialULBWPstartSymbolAndLength_2 = 52; msg3_DeltaPreamble = 1; - p0_NominalWithGrant =-90; + #p0_NominalWithGrant =-90; + p0_NominalWithGrant =-108; # pucch-ConfigCommon setup : # pucchGroupHopping # 0 = neither, 1= group hopping, 2=sequence hopping pucchGroupHopping = 0; hoppingId = 40; - p0_nominal = -90; + #p0_nominal = -90; + p0_nominal = -108; # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; @@ -189,7 +194,7 @@ gNBs = nrofUplinkSymbols = 4; //0; //4; #ssPBCH_BlockPower = 10; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); From 857f9179f35216e36ca16ed08cde193e81a418bc Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 1 Feb 2021 10:08:59 +0100 Subject: [PATCH 21/91] shifting also the TX 4 bits to the left to exploit dynamic range. adapted ssb_block_power but proper calibration still necessary. --- targets/ARCH/ETHERNET/benetel/5g/benetel.c | 2 +- targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index ab9f970931..75706f591d 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -317,7 +317,7 @@ void benetel_fh_if4p5_south_out(RU_t *ru, int i; uint16_t *p = (uint16_t *)(&s->buffers.dl[slot][symbol*1272*4]); for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]); + p[i] = htons(p[i]<<4); } } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 251a76f36e..ba44e989b9 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -194,7 +194,7 @@ gNBs = nrofUplinkSymbols = 4; //0; //4; #ssPBCH_BlockPower = 10; - ssPBCH_BlockPower = -25; + ssPBCH_BlockPower = -10; } ); From aecf2dfa1336caeabe6834a14756ab85658b0736 Mon Sep 17 00:00:00 2001 From: cig Date: Fri, 29 Jan 2021 16:43:25 +0100 Subject: [PATCH 22/91] Hack to make FDD compatible with current UL scheduling design - temporary solution since scheduler does not support FDD - modified is_NR_UL_slot to return always 1 when is FDD mode - this is necessary because currently the scheduler assumes that is TDD and tdd_UL_DL_ConfigurationCommon is always initialied --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 8 ++++++-- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 5 +++-- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 3 ++- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 2 +- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index d056b06450..fa4363ebd9 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2808,11 +2808,15 @@ int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) { else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); } -int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) { +int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slot, lte_frame_type_t frame_type) { int period,period1,period2=0; - if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1); + // Note: condition on frame_type + // goal: the UL scheduler assumes mode is TDD therefore this hack is needed to make FDD work + if (scc->tdd_UL_DL_ConfigurationCommon == NULL || frame_type == FDD) { + return(1); + } if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 && scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index e41ca67229..538a2277ef 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -174,7 +174,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); -int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); +int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slotP, lte_frame_type_t frame_type); uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, NR_CellGroupConfig_t *secondaryCellGroup, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index bf95e38ae2..2f886d5164 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1054,8 +1054,9 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { * from MAC instance . */ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) { + //Check if request to access ul_config is for a UL slot - if (is_nr_UL_slot(mac->scc, slot) == 0) { + if (is_nr_UL_slot(mac->scc, slot, mac->phy_config.config_req.cell_config.frame_duplex_type) == 0) { LOG_W(MAC, "Slot %d is not a UL slot. get_ul_config_request() called for wrong slot!!!\n", slot); return NULL; } @@ -1509,7 +1510,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s mac->RA_offset = 2; // to compensate the rx frame offset at the gNB mac->generate_nr_prach = 0; // Reset flag for PRACH generation - if (is_nr_UL_slot(scc, slotP)) { + if (is_nr_UL_slot(scc, slotP, mac->phy_config.config_req.cell_config.frame_duplex_type)) { uint8_t selected_gnb_ssb_idx = mac->mib_ssb; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e15963f355..53bd1eeb47 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -210,7 +210,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][slotP]; nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; - if (is_nr_UL_slot(scc,slotP)) { + if (is_nr_UL_slot(scc, slotP, cc->frame_type)) { + uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot; uint16_t RA_sfn_index = -1; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 195c42f387..828749b17b 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -109,7 +109,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ ret = nr_ue_scheduler(NULL, ul_info); - if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra) + if (is_nr_UL_slot(mac->scc, ul_info->slot_tx, mac->phy_config.config_req.cell_config.frame_duplex_type) && get_softmodem_params()->do_ra) nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id); switch(ret){ From 682f868c94ad9112878d3796ed700c5b2540ffa1 Mon Sep 17 00:00:00 2001 From: cig Date: Fri, 29 Jan 2021 16:45:20 +0100 Subject: [PATCH 23/91] Reduced output logging in UE RF configuration for unused channels --- openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c index 7cf64b28bb..76fc5f298f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c @@ -78,13 +78,15 @@ void nr_rf_card_config(openair0_config_t *openair0_cfg, openair0_cfg->autocal[i] = 1; - LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n", - i, - rf_chain, - openair0_cfg->tx_gain[i], - openair0_cfg->rx_gain[i], - openair0_cfg->tx_freq[i], - openair0_cfg->rx_freq[i]); + if (i < openair0_cfg->rx_num_channels) { + LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n", + i, + rf_chain, + openair0_cfg->tx_gain[i], + openair0_cfg->rx_gain[i], + openair0_cfg->tx_freq[i], + openair0_cfg->rx_freq[i]); + } } } \ No newline at end of file From 68856682737353823638f730e62425e21feaeb91 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Mon, 1 Feb 2021 20:55:58 +0000 Subject: [PATCH 24/91] Fix AssertFatal in replay_node when file size is not a multiple of block size --- cmake_targets/CMakeLists.txt | 4 ++-- targets/ARCH/rfsimulator/stored_node.c | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 39d1c31273..f560d48daf 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2833,7 +2833,7 @@ add_executable(measurement_display ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c) target_link_libraries (measurement_display minimal_lib) -add_executable(test5Gnas +add_executable(test5Gnas ${OPENAIR_DIR}/openair3/TEST/test5Gnas.c ) target_link_libraries (test5Gnas LIB_5GNAS_GNB CONFIG_LIB minimal_lib ) @@ -3068,7 +3068,7 @@ add_executable(ocp-gnb target_link_libraries (ocp-gnb -Wl,--start-group UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA - ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB + ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON -Wl,--end-group z dl) diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c index daf0133af2..dcea69b9dd 100644 --- a/targets/ARCH/rfsimulator/stored_node.c +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -200,7 +200,10 @@ int main(int argc, char *argv[]) { int bufSize=100000; void *buff=malloc(bufSize); uint64_t timestamp=0; - const int blockSize=1000; + const int blockSize=1920; + + // If fileSize is not multiple of blockSize*4 then discard remaining samples + fileSize = (fileSize/(blockSize<<2))*(blockSize<<2); while (1) { //Rewind the file to loop on the samples From 7700e61861b75a12f0a077a696aefbef4ef9b46f Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Mon, 1 Feb 2021 21:04:14 +0000 Subject: [PATCH 25/91] Fix Tables 7.4.1.1.2-1/2 from 38.211 --- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 764885dbf8..b6e99b9e41 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -40,9 +40,9 @@ #include "PHY/defs_gNB.h" /*Table 7.4.1.1.2-1/2 from 38.211 */ -int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}}; +int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}}; int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}}; -int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1},{1,1},{1,-1},{1,1},{1,1}}; +int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}}; int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}}; // complex conjugate of mod table From 1717c1c6ab6b5b2445b886a415da9104218324e7 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Tue, 2 Feb 2021 14:48:18 +0000 Subject: [PATCH 26/91] PDCCH add support for search space candidate_idx > 0 --- openair1/PHY/NR_TRANSPORT/nr_dci.c | 13 +++++++++++++ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 11 +++++------ openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + openair2/RRC/NR/rrc_gNB_reconfig.c | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 7395586dd6..4f32631216 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -182,6 +182,19 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, } } + printf("\n"); + for(int qq = 0; qqdci_pdu.AggregationLevel[d]; qq++ ) { + printf("gNB->cce_list[d][p2].reg_list[0].reg_idx = %i\n", gNB->cce_list[d][qq].reg_list[0].reg_idx); + } + printf("\n"); + for(int qq = 0; qqdci_pdu.AggregationLevel[d]; qq++ ) { + printf("reg_list_order[qq] = %i\n", reg_list_order[qq]); + } + printf("\n"); + + getchar(); + + /*Mapping the encoded DCI along with the DMRS */ for (int cce_count = 0; cce_count < pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]; cce_count ++) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 66766535e8..eb8be094da 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -230,6 +230,7 @@ void schedule_control_sib1(module_id_t module_id, int time_domain_allocation, uint8_t mcsTableIdx, uint8_t mcs, + uint8_t candidate_idx, int num_total_bytes) { gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; @@ -261,13 +262,10 @@ void schedule_control_sib1(module_id_t module_id, gNB_mac->sched_ctrlCommon->coreset, gNB_mac->sched_ctrlCommon->aggregation_level, 0, - 0, + candidate_idx, nr_of_candidates); - if (gNB_mac->sched_ctrlCommon->cce_index < 0) { - LOG_E(MAC, "%s(): could not find CCE for coreset0\n", __func__); - return; - } + AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n"); const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs; int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb; @@ -454,6 +452,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) int time_domain_allocation = 0; uint8_t mcsTableIdx = 0; uint8_t mcs = 6; + uint8_t candidate_idx = 0; gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; @@ -469,7 +468,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) for (int i=0;inrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; ss0->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; - ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2; ss0->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; ss0->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; From b654e282dd17be838e98add5f30bcdd721c5ef33 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Tue, 2 Feb 2021 15:10:51 +0000 Subject: [PATCH 27/91] Minor code clean up --- openair1/PHY/NR_TRANSPORT/nr_dci.c | 13 ------------- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 2 -- 2 files changed, 15 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 4f32631216..7395586dd6 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -182,19 +182,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, } } - printf("\n"); - for(int qq = 0; qqdci_pdu.AggregationLevel[d]; qq++ ) { - printf("gNB->cce_list[d][p2].reg_list[0].reg_idx = %i\n", gNB->cce_list[d][qq].reg_list[0].reg_idx); - } - printf("\n"); - for(int qq = 0; qqdci_pdu.AggregationLevel[d]; qq++ ) { - printf("reg_list_order[qq] = %i\n", reg_list_order[qq]); - } - printf("\n"); - - getchar(); - - /*Mapping the encoded DCI along with the DMRS */ for (int cce_count = 0; cce_count < pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]; cce_count ++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index fb53f8460d..917a41c9e6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -158,7 +158,6 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, if ((reg % reg_bundle_size_L) == 0) r++; } - // Get cce_list indices by reg_idx in ascending order int f_bundle_j_list_id = 0; int f_bundle_j_list_ord[NR_MAX_PDCCH_AGG_LEVEL] = {}; @@ -175,7 +174,6 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, } } - for(int reg=0; reg<((coreset_nbr_rb*coreset_time_dur)); reg++) { f_reg = (f_bundle_j_list_ord[reg/6]*reg_bundle_size_L)+(reg%reg_bundle_size_L); From c4ccc6616980f1d063de7a556addba1d99413380 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Tue, 2 Feb 2021 18:12:11 +0000 Subject: [PATCH 28/91] Log SIB1 decoded --- openair2/RRC/NR_UE/rrc_UE.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 6852507d29..428db0ca08 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1606,8 +1606,7 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index } sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; if (*(int64_t*)sib1 != 1) { - LOG_D(RRC, "SIB1 address: %lx\n", *(int64_t*)sib1); - + LOG_I(RRC, "SIB1 decoded\n"); if( g_log->log_component[RRC].level >= OAILOG_DEBUG ) xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); From a9f57407c70fc290910cf6f9b9cfad962e5f1a4d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 3 Feb 2021 17:07:18 +0100 Subject: [PATCH 29/91] benetel 4g: support two antennas --- targets/ARCH/ETHERNET/benetel/4g/benetel.c | 76 ++++++++++--------- .../ARCH/ETHERNET/benetel/4g/dpdk_driver.c | 36 +++------ targets/ARCH/ETHERNET/benetel/4g/low.c | 41 +++++----- targets/ARCH/ETHERNET/benetel/4g/low.h | 7 +- targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c | 3 +- .../ARCH/ETHERNET/benetel/4g/shared_buffers.c | 9 ++- .../ARCH/ETHERNET/benetel/4g/shared_buffers.h | 9 ++- 7 files changed, 91 insertions(+), 90 deletions(-) diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/targets/ARCH/ETHERNET/benetel/4g/benetel.c index 76855111e1..d3b72463b4 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/4g/benetel.c @@ -163,8 +163,8 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) cap->FH_fmt = OAI_IF4p5_only; cap->num_bands = 1; cap->band_list[0] = 7; - cap->nb_rx[0] = 1; - cap->nb_tx[0] = 1; + cap->nb_rx[0] = device->openair0_cfg->rx_num_channels; + cap->nb_tx[0] = device->openair0_cfg->tx_num_channels; cap->max_pdschReferenceSignalPower[0] = -27; cap->max_rxgain[0] = 90; @@ -194,11 +194,12 @@ void benetel_fh_if4p5_south_in(RU_t *ru, LTE_DL_FRAME_PARMS *fp; int symbol; int32_t *rxdata; - int antenna = 0; + int antenna; lock_ul_buffer(&s->buffers, *subframe); next: - while (!(s->buffers.ul_busy[*subframe] == 0x3fff || + while (!((s->buffers.ul_busy[0][*subframe] == 0x3fff && + s->buffers.ul_busy[1][*subframe] == 0x3fff) || s->buffers.prach_busy[*subframe] == 1)) wait_ul_buffer(&s->buffers, *subframe); if (s->buffers.prach_busy[*subframe] == 1) { @@ -217,24 +218,27 @@ next: eNB = eNB_list[0]; fp = &eNB->frame_parms; - for (symbol = 0; symbol < 14; symbol++) { - int i; - uint16_t *p = (uint16_t *)(&s->buffers.ul[*subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; + for (antenna = 0; antenna < ru->nb_rx; antenna++) { + for (symbol = 0; symbol < 14; symbol++) { + int i; + uint16_t *p = (uint16_t *)(&s->buffers.ul[antenna][*subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(rxdata + 2048 - 600, - &s->buffers.ul[*subframe][symbol*1200*4], - 600 * 4); - memcpy(rxdata, - &s->buffers.ul[*subframe][symbol*1200*4] + 600*4, - 600 * 4); + memcpy(rxdata + 2048 - 600, + &s->buffers.ul[antenna][*subframe][symbol*1200*4], + 600 * 4); + memcpy(rxdata, + &s->buffers.ul[antenna][*subframe][symbol*1200*4] + 600*4, + 600 * 4); #endif + } } - s->buffers.ul_busy[*subframe] = 0; + s->buffers.ul_busy[0][*subframe] = 0; + s->buffers.ul_busy[1][*subframe] = 0; signal_ul_buffer(&s->buffers, *subframe); unlock_ul_buffer(&s->buffers, *subframe); @@ -272,45 +276,49 @@ void benetel_fh_if4p5_south_out(RU_t *ru, LTE_DL_FRAME_PARMS *fp; int symbol; int32_t *txdata; - int aa = 0; + int aa; //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); lock_dl_buffer(&s->buffers, subframe); - if (s->buffers.dl_busy[subframe]) { + if (s->buffers.dl_busy[0][subframe] || + s->buffers.dl_busy[1][subframe]) { printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe); unlock_dl_buffer(&s->buffers, subframe); return; } eNB = eNB_list[0]; fp = &eNB->frame_parms; - if (ru->num_eNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + if (ru->num_eNB != 1 || fp->ofdm_symbol_size != 2048 || fp->Ncp != NORMAL || fp->symbols_per_tti != 14) { printf("%s:%d:%s: unsupported configuration\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; + for (aa = 0; aa < ru->nb_tx; aa++) { + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(&s->buffers.dl[subframe][symbol*1200*4], - txdata + 2048 - 600, - 600 * 4); - memcpy(&s->buffers.dl[subframe][symbol*1200*4] + 600*4, - txdata + 1, - 600 * 4); + memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4], + txdata + 2048 - 600, + 600 * 4); + memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4] + 600*4, + txdata + 1, + 600 * 4); #endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } } } - s->buffers.dl_busy[subframe] = 0x3fff; + s->buffers.dl_busy[0][subframe] = 0x3fff; + s->buffers.dl_busy[1][subframe] = 0x3fff; unlock_dl_buffer(&s->buffers, subframe); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx); diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c index 42953d1d4a..2b6ef37e6f 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c @@ -233,19 +233,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00) { + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce) { p.frame = FRAME; p.subframe = SUBFRAME >> 4; p.slot = 0; /* unused */ p.symbol = SYMBOL; - p.antenna = 0; + p.antenna = ANT_NUM; memcpy(p.iq, IQ_ptr, 4800); store_ul(bs, &p); } - // U-PLANE UL ANT_0 PROCESSING - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00 && dl_start == 1) + // U-PLANE UL PROCESSING + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && dl_start == 1) { + int a = ANT_NUM; int tx_frame = FRAME; int tx_subframe = SUBFRAME >> 4; int tx_symbol = SYMBOL + 5; @@ -266,33 +267,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) SUBFRAME = tx_subframe << 4; SYMBOL = tx_symbol; - /* antenna 0 - send actual DL data (if available) */ + /* send actual DL data (if available) */ lock_dl_buffer(bs->buffers, tx_subframe); - if (!(bs->buffers->dl_busy[tx_subframe] & (1 << tx_symbol))) { - printf("%s: warning, DL underflow (sf.symbol %d.%d)\n", __FUNCTION__, + if (!(bs->buffers->dl_busy[a][tx_subframe] & (1 << tx_symbol))) { + printf("%s: warning, DL underflow (antenna %d sf.symbol %d.%d)\n", + __FUNCTION__, + a, tx_subframe, tx_symbol); memset(IQ_ptr, 0, 1200 * 4); } else { - memcpy(IQ_ptr, bs->buffers->dl[tx_subframe] + tx_symbol * 1200*4, + memcpy(IQ_ptr, bs->buffers->dl[a][tx_subframe] + tx_symbol * 1200*4, 1200*4); } - bs->buffers->dl_busy[tx_subframe] &= ~(1 << tx_symbol); + bs->buffers->dl_busy[a][tx_subframe] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, tx_subframe); - - // fill DL Data for ant 0 with 0 value -// memset(IQ_ptr, 0, 4800); - } - - // U-PLANE UL ANT_1 PROCESSING - else if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x01 && dl_start == 1) - { - -// ANT_NUM = 0x01; - SYMBOL = (SYMBOL + 5) % 14; - PAYLOAD_2 = 0xc8; - - // fill DL Data for ant 1 with 0 value - memset(IQ_ptr, 0, 4800); } // U-PLANE PRACH PROCESSING diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.c b/targets/ARCH/ETHERNET/benetel/4g/low.c index 038592d596..14783a700b 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low.c +++ b/targets/ARCH/ETHERNET/benetel/4g/low.c @@ -27,37 +27,36 @@ void store_ul(benetel_t *bs, ul_packet_t *ul) { - /* only antenna 0 for the moment */ - if (ul->antenna != 0) - return; + int a = ul->antenna; - if (ul->subframe != bs->next_subframe || - ul->symbol != bs->next_symbol) { - printf("%s: fatal, expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", + if (ul->subframe != bs->next_subframe[a] || + ul->symbol != bs->next_symbol[a]) { + printf("%s: fatal, antenna %d expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, - bs->expected_benetel_frame, bs->next_subframe, bs->next_symbol, + a, + bs->expected_benetel_frame[a], bs->next_subframe[a], bs->next_symbol[a], ul->frame, ul->subframe, ul->symbol); exit(1); } - lock_ul_buffer(bs->buffers, bs->next_subframe); - if (bs->buffers->ul_busy[bs->next_subframe] & (1 << bs->next_symbol)) { + lock_ul_buffer(bs->buffers, bs->next_subframe[a]); + if (bs->buffers->ul_busy[a][bs->next_subframe[a]] & (1 << bs->next_symbol[a])) { printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__, - bs->next_subframe, bs->next_symbol); + bs->next_subframe[a], bs->next_symbol[a]); } - memcpy(bs->buffers->ul[bs->next_subframe] + bs->next_symbol * 1200*4, + memcpy(bs->buffers->ul[a][bs->next_subframe[a]] + bs->next_symbol[a] * 1200*4, ul->iq, 1200*4); - bs->buffers->ul_busy[bs->next_subframe] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_subframe); - unlock_ul_buffer(bs->buffers, bs->next_subframe); + bs->buffers->ul_busy[a][bs->next_subframe[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_subframe[a]); + unlock_ul_buffer(bs->buffers, bs->next_subframe[a]); - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_subframe = (bs->next_subframe + 1) % 10; - if (bs->next_subframe == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_subframe[a] = (bs->next_subframe[a] + 1) % 10; + if (bs->next_subframe[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.h b/targets/ARCH/ETHERNET/benetel/4g/low.h index 5e75d9181e..e74bf89163 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low.h +++ b/targets/ARCH/ETHERNET/benetel/4g/low.h @@ -26,9 +26,10 @@ typedef struct { shared_buffers *buffers; - int next_subframe; - int next_symbol; - int expected_benetel_frame; + /* [2] is for two antennas */ + int next_subframe[2]; + int next_symbol[2]; + int expected_benetel_frame[2]; char *dpdk_main_command_line; } benetel_t; diff --git a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c index ecff473010..edf62a67e0 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c +++ b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c @@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_ bs->buffers = buffers; - bs->expected_benetel_frame = 255; + bs->expected_benetel_frame[0] = 255; + bs->expected_benetel_frame[1] = 255; bs->dpdk_main_command_line = dpdk_main_command_line; diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c index 492a15dfc3..380cbabc73 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c @@ -44,9 +44,12 @@ void init_buffers(shared_buffers *s) /* in FDD the eNB's first transmitted DL subframe is 4 but the device * needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready. */ - s->dl_busy[1] = 0x3fff; - s->dl_busy[2] = 0x3fff; - s->dl_busy[3] = 0x3fff; + s->dl_busy[0][1] = 0x3fff; + s->dl_busy[0][2] = 0x3fff; + s->dl_busy[0][3] = 0x3fff; + s->dl_busy[1][1] = 0x3fff; + s->dl_busy[1][2] = 0x3fff; + s->dl_busy[1][3] = 0x3fff; } void lock_dl_buffer(shared_buffers *s, int subframe) diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h index 1d5040b95b..ed174265c5 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h @@ -26,10 +26,11 @@ #include typedef struct { - unsigned char dl[10][14*1200*4]; - unsigned char ul[10][14*1200*4]; - uint16_t dl_busy[10]; - uint16_t ul_busy[10]; + /* [2] is for two antennas */ + unsigned char dl[2][10][14*1200*4]; + unsigned char ul[2][10][14*1200*4]; + uint16_t dl_busy[2][10]; + uint16_t ul_busy[2][10]; pthread_mutex_t m_ul[10]; pthread_cond_t c_ul[10]; From 2a45e3199b2e0cd01311db72199d4829a06ccc09 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 5 Feb 2021 13:58:24 +0100 Subject: [PATCH 30/91] CI: adding FDD mode to 5G RF sim test Signed-off-by: Raphael Defosseux --- ci-scripts/reportTestLocally.sh | 2 +- ci-scripts/runTestOnVM.sh | 89 +++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 8562f4b2de..415ded57a4 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -749,7 +749,7 @@ function report_test { echo " " >> ./test_simulator_results.html EPC_CONFIGS=("noS1") - TRANS_MODES=("tdd") + TRANS_MODES=("fdd" "tdd") BW_CASES=(106) for CN_CONFIG in ${EPC_CONFIGS[@]} do diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 70eabb7b69..4fc740235e 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -379,7 +379,7 @@ function check_iperf { local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl` local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim` local LOC_IS_RF_SIM=`echo $LOC_BASE_LOG | grep -c rf_sim` - local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c tdd_106prb` + local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c _106prb` if [ -f ${LOC_BASE_LOG}_client.txt ] then local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt` @@ -2189,39 +2189,49 @@ function run_test_on_vm { if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] then - CN_CONFIG="noS1" - CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf - S1_NOS1_CFG=0 - PRB=106 - FREQUENCY=3510 - if [ ! -d $ARCHIVES_LOC ] then mkdir --parents $ARCHIVES_LOC fi - local try_cnt=0 - NR_STATUS=0 + CN_CONFIG="noS1" + S1_NOS1_CFG=0 ######### start of RA TEST loop - while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI + # for the moment only TDD + TRANS_MODES=("tdd") + for TMODE in ${TRANS_MODES[@]} do + if [[ $TMODE =~ .*fdd.* ]] + then + CONF_FILE=gnb.band66.tm1.106PRB.usrpn300.conf + PRB=106 + FREQUENCY=37000 + else + CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf + PRB=106 + FREQUENCY=3510 + fi + local try_cnt=0 + NR_STATUS=0 + while [ $try_cnt -lt 1 ] + do SYNC_STATUS=0 RA_STATUS=0 - rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}*ra_test.log + rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}*ra_test.log echo "############################################################" - echo "${CN_CONFIG} : Starting the gNB" + echo "${CN_CONFIG} : Starting the gNB in ${TMODE} mode (RA TEST)" echo "############################################################" - CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb_ra_test.log + CURRENT_GNB_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_gnb_ra_test.log #last argument = 1 is to enable --do-ra for RA test start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 1 echo "############################################################" - echo "${CN_CONFIG} : Starting the NR-UE" + echo "${CN_CONFIG} : Starting the NR-UE in ${TMODE} mode (RA TEST)" echo "############################################################" - CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_ra_test.log + CURRENT_NR_UE_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ue_ra_test.log #last argument = 1 is to enable --do-ra for RA test start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1 if [ $NR_UE_SYNC -eq 0 ] @@ -2260,35 +2270,47 @@ function run_test_on_vm { else try_cnt=$((try_cnt+10)) fi + done done ########### end RA test sleep 30 - ######### start of PHY TEST loop - try_cnt=0 - while [ $try_cnt -lt 4 ] + SYNC_STATUS=0 + PING_STATUS=0 + IPERF_STATUS=0 + TRANS_MODES=("fdd tdd") + for TMODE in ${TRANS_MODES[@]} do + if [[ $TMODE =~ .*fdd.* ]] + then + CONF_FILE=gnb.band66.tm1.106PRB.usrpn300.conf + PRB=106 + FREQUENCY=37000 + else + CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf + PRB=106 + FREQUENCY=3510 + fi - - SYNC_STATUS=0 - PING_STATUS=0 - IPERF_STATUS=0 - rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ue.log - rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log - rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_dl*txt $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_ul*txt + try_cnt=0 + while [ $try_cnt -lt 1 ] + do + rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log + rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log + rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_dl*txt $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_ul*txt echo "############################################################" - echo "${CN_CONFIG} : Starting the gNB" + echo "${CN_CONFIG} : Starting the gNB in ${TMODE} mode (PHY TEST)" echo "############################################################" - CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log + CURRENT_GNB_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_gnb.log start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 0 echo "############################################################" - echo "${CN_CONFIG} : Starting the NR-UE" + echo "${CN_CONFIG} : Starting the NR-UE in ${TMODE} mode (PHY TEST)" echo "############################################################" - CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log + CURRENT_NR_UE_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 0 if [ $NR_UE_SYNC -eq 0 ] then @@ -2306,7 +2328,7 @@ function run_test_on_vm { echo "${CN_CONFIG} : Pinging the gNB from NR-UE" echo "############################################################" get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR - PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log + PING_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log ping_epc_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $ENB_IP_ADDR $PING_LOG_FILE 1 0 scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 @@ -2315,7 +2337,7 @@ function run_test_on_vm { echo "${CN_CONFIG} : Pinging the NR-UE from gNB" echo "############################################################" get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1 - PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log + PING_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log ping_enb_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0 scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 @@ -2324,7 +2346,7 @@ function run_test_on_vm { echo "${CN_CONFIG} : iperf DL -- NR-UE is server and gNB is client" echo "############################################################" THROUGHPUT="30K" - CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl + CURR_IPERF_LOG_BASE=${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_dl get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1 generic_iperf $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 @@ -2346,7 +2368,7 @@ function run_test_on_vm { echo "${CN_CONFIG} : iperf UL -- gNB is server and NR-UE is client" echo "############################################################" THROUGHPUT="30K" - CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_ul + CURR_IPERF_LOG_BASE=${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_ul get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1 generic_iperf $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 @@ -2368,6 +2390,7 @@ function run_test_on_vm { else try_cnt=$((try_cnt+10)) fi + done done ######### end of loop full_l2_sim_destroy From b7ea4e0f6da205c0c7af52b956efa76d14ca1763 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 5 Feb 2021 16:36:18 +0100 Subject: [PATCH 31/91] benetel 5g: support for two antennas --- targets/ARCH/ETHERNET/benetel/5g/benetel.c | 77 +++++++++++-------- .../ARCH/ETHERNET/benetel/5g/dpdk_driver.c | 76 +++++++----------- targets/ARCH/ETHERNET/benetel/5g/low.c | 76 +++++++++--------- targets/ARCH/ETHERNET/benetel/5g/low.h | 7 +- targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c | 3 +- .../ARCH/ETHERNET/benetel/5g/shared_buffers.c | 15 ++-- .../ARCH/ETHERNET/benetel/5g/shared_buffers.h | 9 ++- 7 files changed, 129 insertions(+), 134 deletions(-) diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index 75706f591d..cededa968e 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -162,8 +162,9 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) cap->FH_fmt = OAI_IF4p5_only; cap->num_bands = 1; cap->band_list[0] = 78; - cap->nb_rx[0] = 1; - cap->nb_tx[0] = 1; + /* TODO: hardcoded to 1 for the moment, get the real value somehow... */ + cap->nb_rx[0] = 1; //device->openair0_cfg->rx_num_channels; + cap->nb_tx[0] = 1; //device->openair0_cfg->tx_num_channels; cap->max_pdschReferenceSignalPower[0] = -27; cap->max_rxgain[0] = 90; @@ -201,12 +202,13 @@ void benetel_fh_if4p5_south_in(RU_t *ru, NR_DL_FRAME_PARMS *fp; int symbol; int32_t *rxdata; - int antenna = 0; + int antenna; lock_ul_buffer(&s->buffers, *slot); #if 1 next: - while (!(s->buffers.ul_busy[*slot] == 0x3fff || + while (!((s->buffers.ul_busy[0][*slot] == 0x3fff && + s->buffers.ul_busy[1][*slot] == 0x3fff) || s->buffers.prach_busy[*slot] == 1)) wait_ul_buffer(&s->buffers, *slot); if (s->buffers.prach_busy[*slot] == 1) { @@ -226,28 +228,31 @@ next: #endif fp = ru->nr_frame_parms; - for (symbol = 0; symbol < 14; symbol++) { - int i; - int16_t *p = (int16_t *)(&s->buffers.ul[*slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = (int16_t)(ntohs(p[i])) / 16; - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; + for (antenna = 0; antenna < ru->nb_rx; antenna++) { + for (symbol = 0; symbol < 14; symbol++) { + int i; + int16_t *p = (int16_t *)(&s->buffers.ul[antenna][*slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = (int16_t)(ntohs(p[i])) / 16; + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; #if 0 if (*slot == 0 && symbol == 0) printf("rxdata in benetel_fh_if4p5_south_in %p\n", &ru->common.rxdataF[antenna][0]); #endif #if 1 - memcpy(rxdata + 2048 - 1272/2, - &s->buffers.ul[*slot][symbol*1272*4], - (1272/2) * 4); - memcpy(rxdata, - &s->buffers.ul[*slot][symbol*1272*4] + (1272/2)*4, - (1272/2) * 4); + memcpy(rxdata + 2048 - 1272/2, + &s->buffers.ul[antenna][*slot][symbol*1272*4], + (1272/2) * 4); + memcpy(rxdata, + &s->buffers.ul[antenna][*slot][symbol*1272*4] + (1272/2)*4, + (1272/2) * 4); #endif + } } - s->buffers.ul_busy[*slot] = 0; + s->buffers.ul_busy[0][*slot] = 0; + s->buffers.ul_busy[1][*slot] = 0; signal_ul_buffer(&s->buffers, *slot); unlock_ul_buffer(&s->buffers, *slot); @@ -285,43 +290,47 @@ void benetel_fh_if4p5_south_out(RU_t *ru, NR_DL_FRAME_PARMS *fp; int symbol; int32_t *txdata; - int aa = 0; + int aa; //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, slot, timestamp); lock_dl_buffer(&s->buffers, slot); - if (s->buffers.dl_busy[slot]) { + if (s->buffers.dl_busy[0][slot] || + s->buffers.dl_busy[1][slot]) { printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, slot); unlock_dl_buffer(&s->buffers, slot); return; } fp = ru->nr_frame_parms; - if (ru->num_gNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + if (ru->num_gNB != 1 || fp->ofdm_symbol_size != 2048 || fp->Ncp != NORMAL || fp->symbols_per_slot != 14) { printf("%s:%d:%s: unsupported configuration\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; + for (aa = 0; aa < ru->nb_tx; aa++) { + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(&s->buffers.dl[slot][symbol*1272*4], - txdata + 2048 - (1272/2), - (1272/2) * 4); - memcpy(&s->buffers.dl[slot][symbol*1272*4] + (1272/2)*4, - txdata, - (1272/2) * 4); + memcpy(&s->buffers.dl[aa][slot][symbol*1272*4], + txdata + 2048 - (1272/2), + (1272/2) * 4); + memcpy(&s->buffers.dl[aa][slot][symbol*1272*4] + (1272/2)*4, + txdata, + (1272/2) * 4); #endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]<<4); + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = htons(p[i]); + } } } - s->buffers.dl_busy[slot] = 0x3fff; + s->buffers.dl_busy[0][slot] = 0x3fff; + s->buffers.dl_busy[1][slot] = 0x3fff; unlock_dl_buffer(&s->buffers, slot); } diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c index dd50603ec5..88f4ecb4cd 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c @@ -243,21 +243,22 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00) { + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4) { int subframe = SUBFRAME >> 4; int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); p.frame = FRAME; p.slot = subframe * 2 + slot; p.symbol = SYMBOL & 0x3f; - p.antenna = 0; + p.antenna = ANT_NUM; memcpy(p.iq, IQ_ptr, 5088); store_ul(bs, &p); // if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol); } - // U-PLANE UL ANT_0 PROCESSING - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00 && dl_start == 1) + // U-PLANE UL PROCESSING + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && dl_start == 1) { + int a = ANT_NUM & 0x01; int frame = FRAME; int subframe = SUBFRAME >> 4; int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); @@ -282,66 +283,45 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } } - ANT_NUM = 0x00; - // Mask the symbol bits from UL packet received and apply the shift. SYMBOL = ((SYMBOL & 0b00111111) + 10) % 14; - ANT_NUM = 0x00; + ANT_NUM = a; SUBFRAME = sf; + if (a == 1) + slot_id_ctrl++; + // Slot id control for DL - if(slot_id_ctrl > 13){ - SYMBOL = SYMBOL | 0b01000000; + if (slot_id_ctrl > 13) { + SYMBOL = SYMBOL | 0b01000000; + + if (a == 1) { + if (slot_id_ctrl > 27) { + slot_id_ctrl = 0; + sf = sf + 0x10; + + if (sf > 0x90){ + sf = 0; + } + } + } } - /* antenna 0 - send actual DL data (if available) */ + /* send actual DL data (if available) */ oai_slot = tx_subframe * 2 + tx_slot; lock_dl_buffer(bs->buffers, oai_slot); - if (!(bs->buffers->dl_busy[oai_slot] & (1 << tx_symbol))) { - printf("%s: warning, DL underflow (sl.symbol %d.%d)\n", __FUNCTION__, - oai_slot, tx_symbol); + if (!(bs->buffers->dl_busy[a][oai_slot] & (1 << tx_symbol))) { + printf("%s: warning, DL underflow (antenna %d sl.symbol %d.%d)\n", __FUNCTION__, + a, oai_slot, tx_symbol); memset(IQ_ptr, 0, 1272 * 4); } else { - memcpy(IQ_ptr, bs->buffers->dl[oai_slot] + tx_symbol * 1272*4, + memcpy(IQ_ptr, bs->buffers->dl[a][oai_slot] + tx_symbol * 1272*4, 1272*4); } //printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf); - bs->buffers->dl_busy[oai_slot] &= ~(1 << tx_symbol); + bs->buffers->dl_busy[a][oai_slot] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, oai_slot); - - // fill DL Data for ant 0 with 0 value -// memset(IQ_ptr, 0, 5088); - } - - // U-PLANE UL ANT_1 PROCESSING - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x01 && dl_start == 1) - { - - // Mask the symbol bits from UL packet received and apply the shift. - SYMBOL = ((SYMBOL & 0b00111111) +10) % 14; - - ANT_NUM = 0x01; - SUBFRAME = sf; - - slot_id_ctrl++; - - // Slot id control for DL - if(slot_id_ctrl > 13){ - SYMBOL = SYMBOL | 0b01000000; - - if(slot_id_ctrl > 27){ - slot_id_ctrl = 0; - sf = sf + 0x10; - - if (sf >0x90){ - sf = 0; - } - } - } - - // fill DL Data for ant 1 with 0 value - memset(IQ_ptr, 0, 5088); } // U-PLANE PRACH PROCESSING diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.c b/targets/ARCH/ETHERNET/benetel/5g/low.c index 52c9f24127..b34d69784f 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low.c @@ -35,63 +35,61 @@ printf("store_ul %d.%ld (%ld)\n", (int)(t.tv_sec % 60), t.tv_nsec, t.tv_nsec - o old = t; #endif - /* only antenna 0 for the moment */ - if (ul->antenna != 0) - return; + int a = ul->antenna; - if (ul->slot != bs->next_slot || - ul->symbol != bs->next_symbol) { - printf("%s: error, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", + if (ul->slot != bs->next_slot[a] || + ul->symbol != bs->next_symbol[a]) { + printf("%s: error, antenna %d expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, - bs->expected_benetel_frame, bs->next_slot, bs->next_symbol, + a, bs->expected_benetel_frame[a], bs->next_slot[a], bs->next_symbol[a], ul->frame, ul->slot, ul->symbol); } /* fill missing data with 0s */ - while (ul->slot != bs->next_slot || - ul->symbol != bs->next_symbol) { - lock_ul_buffer(bs->buffers, bs->next_slot); - if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) { - printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, - bs->next_slot, bs->next_symbol); + while (ul->slot != bs->next_slot[a] || + ul->symbol != bs->next_symbol[a]) { + lock_ul_buffer(bs->buffers, bs->next_slot[a]); + if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { + printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + a, bs->next_slot[a], bs->next_symbol[a]); } - memset(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + memset(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4, 0, 1272*4); - bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_slot); - unlock_ul_buffer(bs->buffers, bs->next_slot); + bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_slot[a]); + unlock_ul_buffer(bs->buffers, bs->next_slot[a]); - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_slot = (bs->next_slot + 1) % 20; - if (bs->next_slot == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; + if (bs->next_slot[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } - lock_ul_buffer(bs->buffers, bs->next_slot); - if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) { - printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, - bs->next_slot, bs->next_symbol); + lock_ul_buffer(bs->buffers, bs->next_slot[a]); + if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { + printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + a, bs->next_slot[a], bs->next_symbol[a]); } - memcpy(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + memcpy(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4, ul->iq, 1272*4); - bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_slot); - unlock_ul_buffer(bs->buffers, bs->next_slot); + bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_slot[a]); + unlock_ul_buffer(bs->buffers, bs->next_slot[a]); - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_slot = (bs->next_slot + 1) % 20; - if (bs->next_slot == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; + if (bs->next_slot[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.h b/targets/ARCH/ETHERNET/benetel/5g/low.h index 5e1daee9d1..659819296a 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.h +++ b/targets/ARCH/ETHERNET/benetel/5g/low.h @@ -26,9 +26,10 @@ typedef struct { shared_buffers *buffers; - int next_slot; - int next_symbol; - int expected_benetel_frame; + /* [2] is for two antennas */ + int next_slot[2]; + int next_symbol[2]; + int expected_benetel_frame[2]; char *dpdk_main_command_line; } benetel_t; diff --git a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c index 5e26f6782e..b26df07723 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c @@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_ bs->buffers = buffers; - bs->expected_benetel_frame = 255; + bs->expected_benetel_frame[0] = 255; + bs->expected_benetel_frame[1] = 255; bs->dpdk_main_command_line = dpdk_main_command_line; diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c index b9da10b380..a302400eb4 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c @@ -45,11 +45,16 @@ void init_buffers(shared_buffers *s) * needs to have slots 1, 2 and 3, 4 and 5 ready. Let's pretend * they are ready. */ - s->dl_busy[1] = 0x3fff; - s->dl_busy[2] = 0x3fff; - s->dl_busy[3] = 0x3fff; - s->dl_busy[4] = 0x3fff; - s->dl_busy[5] = 0x3fff; + s->dl_busy[0][1] = 0x3fff; + s->dl_busy[0][2] = 0x3fff; + s->dl_busy[0][3] = 0x3fff; + s->dl_busy[0][4] = 0x3fff; + s->dl_busy[0][5] = 0x3fff; + s->dl_busy[1][1] = 0x3fff; + s->dl_busy[1][2] = 0x3fff; + s->dl_busy[1][3] = 0x3fff; + s->dl_busy[1][4] = 0x3fff; + s->dl_busy[1][5] = 0x3fff; } void lock_dl_buffer(shared_buffers *s, int slot) diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h index ca7dbd9c8f..9d51b8138d 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h @@ -26,10 +26,11 @@ #include typedef struct { - unsigned char dl[20][14*1272*4]; - unsigned char ul[20][14*1272*4]; - uint16_t dl_busy[20]; - uint16_t ul_busy[20]; + /* [2] is for two antennas */ + unsigned char dl[2][20][14*1272*4]; + unsigned char ul[2][20][14*1272*4]; + uint16_t dl_busy[2][20]; + uint16_t ul_busy[2][20]; pthread_mutex_t m_ul[20]; pthread_cond_t c_ul[20]; From f4fd79c4d99901606dc9f4f6f887341dadb34f7f Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Mon, 8 Feb 2021 01:06:30 +0100 Subject: [PATCH 32/91] First commit Created 3 threadpools for L1 rx, L1 tx and RU tx processing --- executables/nr-gnb.c | 53 +++- executables/nr-ru.c | 280 +++++++++++++++++- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- openair1/PHY/defs_gNB.h | 8 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 +- 5 files changed, 331 insertions(+), 16 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index be9261a117..fbbe5813a9 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -870,7 +870,7 @@ void init_gNB_proc(int inst) { pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); sync_phy_proc.phy_proc_CC_id = 0; - gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); + gNB->threadPool_ulsch = (tpool_t*)malloc(sizeof(tpool_t)); gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); int numCPU = sysconf(_SC_NPROCESSORS_ONLN); uint32_t num_threads_pusch; @@ -884,10 +884,50 @@ void init_gNB_proc(int inst) { sprintf(ul_pool+2+s_offset,",-1"); s_offset += 3; } - initTpool(ul_pool, gNB->threadPool, false); + initTpool(ul_pool, gNB->threadPool_ulsch, false); initNotifiedFIFO(gNB->respDecode); } +void init_gNB_Tpool(int inst) { + PHY_VARS_gNB *gNB; + gNB = RC.gNB[inst]; + + // ULSCH decoding threadpool + gNB->threadPool_ulsch = (tpool_t*)malloc(sizeof(tpool_t)); + gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + int numCPU = sysconf(_SC_NPROCESSORS_ONLN); + uint32_t num_threads_pusch; + paramdef_t PUSCHThreads[] = NUM_THREADS_DESC; + config_get( PUSCHThreads,sizeof(PUSCHThreads)/sizeof(paramdef_t),NULL); + int threadCnt = min(numCPU, num_threads_pusch); + char ul_pool[80]; + sprintf(ul_pool,"-1"); + int s_offset = 0; + for (int icpu=1; icputhreadPool_ulsch, false); + initNotifiedFIFO(gNB->respDecode); + + // L1 RX threadpool + gNB->threadPool_L1 = (tpool_t*)malloc(sizeof(tpool_t)); + gNB->resp_L1 = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + initTpool("-1", gNB->threadPool_L1, false); + initNotifiedFIFO(gNB->resp_L1); + + // L1 TX threadpool + gNB->threadPool_L1_tx = (tpool_t*)malloc(sizeof(tpool_t)); + gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + initTpool("-1",gNB->threadPool_L1_tx, false); + initNotifiedFIFO(gNB->resp_L1_tx); + + // RU TX threadpool + gNB->threadPool_RU_tx = (tpool_t*)malloc(sizeof(tpool_t)); + gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + initTpool("-1",gNB->threadPool_RU_tx, false); + initNotifiedFIFO(gNB->resp_RU_tx); +} /*! @@ -1010,15 +1050,10 @@ void init_eNB_afterRU(void) { * (not tested in other modes). */ //init_precoding_weights(RC.gNB[inst]); - init_gNB_proc(inst); + //init_gNB_proc(inst); + init_gNB_Tpool(inst); } - for (ru_id=0; ru_idnr_wakeup_rxtx = wakeup_rxtx; - // RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_gNB; - RC.ru[ru_id]->gNB_top = gNB_top; - } } void init_gNB(int single_thread_flag,int wait_for_sync) { diff --git a/executables/nr-ru.c b/executables/nr-ru.c index feff0c29c2..fa5ad3fa6e 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -120,6 +120,20 @@ extern int emulate_rf; extern int numerology; extern int usrp_tx_thread; +typedef struct processingData_L1 { + int frame_rx; + int frame_tx; + int slot_rx; + int slot_tx; + PHY_VARS_gNB *gNB; +} processingData_L1_t; + +typedef struct processingData_RU { + int frame_tx; + int slot_tx; + RU_t *ru; +} processingData_RU_t; + /*************************************************************/ /* Functions to attach and configure RRU */ @@ -1298,6 +1312,63 @@ void *ru_stats_thread(void *param) { return(NULL); } +void ru_tx_func(void *param) { + + processingData_RU_t *info = (processingData_RU_t *) param; + RU_t *ru = info->ru; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + int frame_tx = info->frame_tx; + int slot_tx = info->slot_tx; + int print_frame = 8; + char filename[40]; + + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,slot_tx); + + // do OFDM with/without TX front-end processing if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,slot_tx); + + if(!emulate_rf) { + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,slot_tx,ru->proc.timestamp_tx); + + if (ru->fh_north_out) ru->fh_north_out(ru); + } else { + if(frame_tx == print_frame) { + for (int i=0; inb_tx; i++) { + + if(slot_tx == 0) { + sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, slot_tx); + LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); + + sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, slot_tx); + LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); + + sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, slot_tx); + LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); + } + + if(slot_tx == 9) { + sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); + LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); + sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); + FILE *output_fd = fopen(filename,"w"); + + if (output_fd) { + fwrite(&ru->common.txdata[i][0], + sizeof(int32_t), + fp->samples_per_frame, + output_fd); + fclose(output_fd); + } else { + LOG_E(PHY,"Cannot write to file %s\n",filename); + } + }//if(slot_tx == 9) + }//for (i=0; inb_tx; i++) + }//if(frame_tx == print_frame) + }//else emulate_rf +} + void *ru_thread_tx( void *param ) { RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; @@ -1430,11 +1501,201 @@ void *ru_thread_tx( void *param ) { return 0; } +void tx_func(void *param) { + + processingData_L1_t *info = (processingData_L1_t *) param; + PHY_VARS_gNB *gNB = info->gNB; + int frame_tx = info->frame_tx; + int slot_tx = info->slot_tx; + + phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); + + // start FH TX processing + notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_RU_t),0,gNB->resp_RU_tx,ru_tx_func); + processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(msg); + notifiedFIFO_elt_t *res; + syncMsg->frame_tx = frame_tx; + syncMsg->slot_tx = slot_tx; + syncMsg->ru = gNB->RU_list[0]; + + res = tryPullTpool(gNB->resp_RU_tx, gNB->threadPool_RU_tx); + if (res == NULL) { + LOG_W(PHY,"RU TX of previous slot is still being processed. Adding current slot to queue (%d.%d)\n", frame_tx, slot_tx); + } + msg->key = slot_tx; + pushTpool(gNB->threadPool_RU_tx, msg); +} + +void rx_func(void *param) { + + processingData_L1_t *info = (processingData_L1_t *) param; + PHY_VARS_gNB *gNB = info->gNB; + int frame_rx = info->frame_rx; + int slot_rx = info->slot_rx; + int frame_tx = info->frame_tx; + int slot_tx = info->slot_tx; + sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; + + //start_meas(&softmodem_stats_rxtx_sf); + + T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx)); + + /* hack to remove UEs */ + extern int rnti_to_remove[10]; + extern volatile int rnti_to_remove_count; + extern pthread_mutex_t rnti_to_remove_mutex; + if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1); + int up_removed = 0; + int down_removed = 0; + int pucch_removed = 0; + for (int i = 0; i < rnti_to_remove_count; i++) { + LOG_W(PHY, "to remove rnti %d\n", rnti_to_remove[i]); + void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); + void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); + int j; + for (j = 0; j < NUMBER_OF_NR_ULSCH_MAX; j++) + if (gNB->ulsch[j][0]->rnti == rnti_to_remove[i]) { + gNB->ulsch[j][0]->rnti = 0; + gNB->ulsch[j][0]->harq_mask = 0; + //clean_gNB_ulsch(gNB->ulsch[j][0]); + int h; + for (h = 0; h < NR_MAX_ULSCH_HARQ_PROCESSES; h++) { + gNB->ulsch[j][0]->harq_processes[h]->status = SCH_IDLE; + gNB->ulsch[j][0]->harq_processes[h]->round = 0; + gNB->ulsch[j][0]->harq_processes[h]->handled = 0; + } + up_removed++; + } + for (j = 0; j < NUMBER_OF_NR_DLSCH_MAX; j++) + if (gNB->dlsch[j][0]->rnti == rnti_to_remove[i]) { + gNB->dlsch[j][0]->rnti = 0; + gNB->dlsch[j][0]->harq_mask = 0; + //clean_gNB_dlsch(gNB->dlsch[j][0]); + down_removed++; + } + for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++) + if (gNB->pucch[j]->active > 0 && + gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) { + gNB->pucch[j]->active = 0; + gNB->pucch[j]->pucch_pdu.rnti = 0; + pucch_removed++; + } +#if 0 + for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++) + gNB->pdcch_pdu[j].frame = -1; + for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++) + gNB->ul_pdcch_pdu[j].frame = -1; + for (j = 0; j < NUMBER_OF_NR_PRACH_MAX; j++) + gNB->prach_vars.list[j].frame = -1; +#endif + } + if (rnti_to_remove_count) LOG_W(PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed); + rnti_to_remove_count = 0; + if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1); + + // Call the scheduler + + pthread_mutex_lock(&gNB->UL_INFO_mutex); + gNB->UL_INFO.frame = frame_rx; + gNB->UL_INFO.slot = slot_rx; + gNB->UL_INFO.module_id = gNB->Mod_id; + gNB->UL_INFO.CC_id = gNB->CC_id; + gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); + pthread_mutex_unlock(&gNB->UL_INFO_mutex); + + // RX processing + int tx_slot_type = nr_slot_select(cfg,frame_tx,slot_tx); + int rx_slot_type = nr_slot_select(cfg,frame_rx,slot_rx); + + if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { + // UE-specific RX processing for subframe n + // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT + + // Do PRACH RU processing + L1_nr_prach_procedures(gNB,frame_rx,slot_rx); + + //apply the rx signal rotation here + apply_nr_rotation_ul(&gNB->frame_parms, + gNB->common_vars.rxdataF[0], + slot_rx, + 0, + gNB->frame_parms.Ncp==EXTENDED?12:14, + gNB->frame_parms.ofdm_symbol_size); + + phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); + } + + if (oai_exit) return(-1); + + //stop_meas( &softmodem_stats_rxtx_sf ); + LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); + + notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1_tx,tx_func); + processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(msg); + notifiedFIFO_elt_t *res; + syncMsg->gNB = gNB; + syncMsg->frame_rx = frame_rx; + syncMsg->slot_rx = slot_rx; + syncMsg->frame_tx = frame_tx; + syncMsg->slot_tx = slot_tx; + + if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { + res = tryPullTpool(gNB->resp_L1_tx, gNB->threadPool_L1_tx); + if (res == NULL) { + LOG_W(PHY,"L1 TX of previous slot is still being processed. Adding current slot to queue (%d.%d)\n", frame_tx, slot_tx); + } + msg->key = slot_tx; + pushTpool(gNB->threadPool_L1_tx, msg); + } + +#if 0 + LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", + softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now, + TICK_TO_US(gNB->phy_proc), + TICK_TO_US(gNB->phy_proc_tx), + TICK_TO_US(gNB->phy_proc_rx), + TICK_TO_US(gNB->rx_prach), + TICK_TO_US(gNB->ofdm_mod_stats), + softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now); + LOG_D(PHY, + "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ", + TICK_TO_US(gNB->dlsch_encoding_stats), + TICK_TO_US(gNB->dlsch_modulation_stats), + TICK_TO_US(gNB->dlsch_scrambling_stats), + TICK_TO_US(gNB->dlsch_rate_matching_stats), + TICK_TO_US(gNB->dlsch_turbo_encoding_stats), + TICK_TO_US(gNB->dlsch_interleaving_stats), + TICK_TO_US(gNB->rx_dft_stats)); + LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ", + TICK_TO_US(gNB->ulsch_channel_estimation_stats), + TICK_TO_US(gNB->ulsch_freq_offset_estimation_stats), + TICK_TO_US(gNB->ulsch_decoding_stats), + TICK_TO_US(gNB->ulsch_demodulation_stats), + TICK_TO_US(gNB->ulsch_rate_unmatching_stats)); + LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ", + TICK_TO_US(gNB->ulsch_turbo_decoding_stats), + TICK_TO_US(gNB->ulsch_deinterleaving_stats), + TICK_TO_US(gNB->ulsch_demultiplexing_stats), + TICK_TO_US(gNB->ulsch_llr_stats), + TICK_TO_US(gNB->ulsch_tc_init_stats)); + LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n", + TICK_TO_US(gNB->ulsch_tc_alpha_stats), + TICK_TO_US(gNB->ulsch_tc_beta_stats), + TICK_TO_US(gNB->ulsch_tc_gamma_stats), + TICK_TO_US(gNB->ulsch_tc_ext_stats), + TICK_TO_US(gNB->ulsch_tc_intl1_stats), + TICK_TO_US(gNB->ulsch_tc_intl2_stats) + ); +#endif +} + void *ru_thread( void *param ) { static int ru_thread_status; RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + PHY_VARS_gNB *gNB = RC.gNB[0]; int ret; int slot = fp->slots_per_frame-1; int frame = 1023; @@ -1500,6 +1761,10 @@ void *ru_thread( void *param ) { pthread_mutex_unlock(&RC.ru_mutex); wait_sync("ru_thread"); + notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1,rx_func); + processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(msg); + notifiedFIFO_elt_t *res; + if(!emulate_rf) { // Start RF device if any if (ru->start_rf) { @@ -1580,7 +1845,6 @@ void *ru_thread( void *param ) { int slot_type = nr_slot_select(cfg,proc->frame_rx,proc->tti_rx); if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { - //if (proc->tti_rx==8) { if (ru->feprx) { ru->feprx(ru,proc->tti_rx); @@ -1630,9 +1894,19 @@ void *ru_thread( void *param ) { } // At this point, all information for subframe has been received on FH interface + syncMsg->gNB = gNB; + syncMsg->frame_rx = proc->frame_rx; + syncMsg->slot_rx = proc->tti_rx; + syncMsg->frame_tx = proc->frame_tx; + syncMsg->slot_tx = proc->tti_tx; - // wakeup all gNB processes waiting for this RU - if (ru->num_gNB>0) wakeup_gNB_L1s(ru); + // check if previous L1 slot processing is finished + res = tryPullTpool(gNB->resp_L1, gNB->threadPool_L1); + if (res == NULL) { + LOG_W(PHY,"L1 RX of previous slot is still being processed. Adding current slot to queue (%d.%d)\n", proc->frame_rx, proc->tti_rx); + } + msg->key = proc->tti_rx; + pushTpool(gNB->threadPool_L1, msg); if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_gNB==0) { // do TX front-end processing if needed (precoding and/or IDFTs) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index d990176d79..b9cf21c04c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -640,7 +640,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, rdata->offset = offset; rdata->ulsch = ulsch; rdata->ulsch_id = UE_id; - pushTpool(phy_vars_gNB->threadPool,req); + pushTpool(phy_vars_gNB->threadPool_ulsch,req); phy_vars_gNB->nbDecode++; LOG_D(PHY,"Added a block to decode, in pipe: %d\n",phy_vars_gNB->nbDecode); r_offset += E; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 7b33b2040f..ed9c992173 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -832,7 +832,13 @@ typedef struct PHY_VARS_gNB_s { time_stats_t ulsch_freq_offset_estimation_stats; */ notifiedFIFO_t *respDecode; - tpool_t *threadPool; + notifiedFIFO_t *resp_L1; + notifiedFIFO_t *resp_L1_tx; + notifiedFIFO_t *resp_RU_tx; + tpool_t *threadPool_ulsch; + tpool_t *threadPool_L1; + tpool_t *threadPool_L1_tx; + tpool_t *threadPool_RU_tx; int nbDecode; } PHY_VARS_gNB; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6b5c1a9b22..ea8b0370f9 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -243,7 +243,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { } else { if ( rdata->nbSegments != ulsch_harq->processedSegments ) { - int nb=abortTpool(gNB->threadPool, req->key); + int nb=abortTpool(gNB->threadPool_ulsch, req->key); nb+=abortNotifiedFIFO(gNB->respDecode, req->key); gNB->nbDecode-=nb; LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb); @@ -353,7 +353,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH G); while (gNB->nbDecode > 0) { - notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool); + notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool_ulsch); nr_postDecode(gNB, req); delNotifiedFIFO_elt(req); } From ff05ec89f63aa12b5e4df1d7beb38f9667cd6e5a Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Mon, 8 Feb 2021 18:23:41 +0100 Subject: [PATCH 33/91] Slot tx compute in ru_thread --- executables/nr-ru.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index fa5ad3fa6e..97d865a930 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1821,6 +1821,9 @@ void *ru_thread( void *param ) { if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); else AssertFatal(1==0, "No fronthaul interface at south port"); + proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx; + proc->tti_tx = (proc->tti_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; + LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n", frame,slot, proc->frame_rx,proc->tti_rx, From 5b7ae1228feb97fc61b21b9f154d2243e78f1e8c Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 8 Feb 2021 19:18:00 +0000 Subject: [PATCH 34/91] Fix develop merge conflicts --- cmake_targets/CMakeLists.txt | 100 ++++++------- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 4 +- openair2/LAYER2/NR_MAC_UE/mac_vars.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 61 ++++---- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 14 +- openair2/RRC/NR_UE/rrc_UE.c | 141 ++++++++++++++++-- 7 files changed, 222 insertions(+), 102 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 22e0e480eb..61850dcf59 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -316,7 +316,7 @@ if (CUDA_FOUND) set(CUDA_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 -D CUDA_FLAG" ) - + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER} -D CUDA_FLAG" ) @@ -483,7 +483,7 @@ add_custom_target ( DEPENDS ${NR_RRC_GRAMMAR} ) -add_library(NR_RRC_LIB ${nr_rrc_h} ${nr_rrc_source} +add_library(NR_RRC_LIB ${nr_rrc_h} ${nr_rrc_source} ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1_msg.c ) add_dependencies(NR_RRC_LIB nr_rrc_flag) @@ -514,7 +514,7 @@ file(GLOB S1AP_source ${S1AP_C_DIR}/*.c) add_custom_target ( s1ap_flag ALL ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" "S1AP_" -fno-include-deps - DEPENDS "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" + DEPENDS "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" ) add_library(S1AP_LIB @@ -568,7 +568,7 @@ file(GLOB NGAP_source ${NGAP_C_DIR}/*.c) add_custom_target ( ngap_flag ALL ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${NGAP_C_DIR}" "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" "NGAP_" -fno-include-deps - DEPENDS "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" + DEPENDS "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" ) add_library(NGAP_LIB @@ -1468,11 +1468,11 @@ add_dependencies(SCHED_UE_LIB rrc_flag) set(SCHED_SRC_NR_UE ${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c ${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c - ${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c + ${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c ${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr_ue.c ${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c ${OPENAIR1_DIR}/SCHED_NR_UE/pucch_uci_ue_nr.c - ${OPENAIR1_DIR}/SCHED_NR_UE/pucch_power_control_ue_nr.c + ${OPENAIR1_DIR}/SCHED_NR_UE/pucch_power_control_ue_nr.c ) add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE}) @@ -1783,7 +1783,7 @@ set(PHY_SRC_UE ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} ${PHY_NR_CODINGIF} - ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c ) set(PHY_NR_UE_SRC @@ -1962,7 +1962,7 @@ set(NR_RLC_SRC ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c ) - + set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c @@ -1991,7 +1991,7 @@ set(L2_SRC ${RRC_DIR}/L2_interface_common.c ${RRC_DIR}/L2_interface_ue.c ) - + set(L2_RRC_SRC ${OPENAIR2_DIR}/LAYER2/openair2_proc.c # ${RRC_DIR}/rrc_UE.c @@ -2037,14 +2037,14 @@ set(L2_SRC_UE ${RRC_DIR}/L2_interface_common.c ${RRC_DIR}/L2_interface_ue.c ) - + set(L2_RRC_SRC_UE ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_common.c ${RRC_DIR}/L2_interface_common.c ${RRC_DIR}/L2_interface_ue.c - ) - + ) + set(NR_L2_SRC_UE ${NR_RLC_SRC} ${NR_PDCP_SRC} @@ -2102,7 +2102,7 @@ set (MAC_SRC_UE ${MAC_DIR}/rar_tools_ue.c ${MAC_DIR}/config_ue.c ) - + set (MAC_NR_SRC_UE ${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c ${NR_UE_MAC_DIR}/config_ue.c @@ -2165,7 +2165,7 @@ add_library(L2_LTE_NR ${ENB_APP_SRC} ${MCE_APP_SRC} ) - + add_dependencies(L2_NR rrc_flag nr_rrc_flag s1ap_flag x2_flag) add_library(L2_UE @@ -2706,7 +2706,7 @@ add_library(SIMU_COMMON # Simulation library ########################## -set (SIMUSRC +set (SIMUSRC ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_channel.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_tv_channel.c @@ -2769,14 +2769,14 @@ add_library(nrscope MODULE ${XFORMS_SOURCE_NR}) target_link_libraries(nrscope ${XFORMS_LIBRARIES}) -add_library(rfsimulator MODULE +add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c ${OPENAIR_TARGETS}/ARCH/rfsimulator/apply_channelmod.c ${OPENAIR_TARGETS}/ARCH/rfsimulator/new_channel_sim.c ) target_link_libraries(rfsimulator SIMU_COMMON ${ATLAS_LIBRARIES}) -add_library(oai_iqplayer MODULE +add_library(oai_iqplayer MODULE ${OPENAIR_TARGETS}/ARCH/iqplayer/iqplayer_lib.c ) set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}") @@ -2843,7 +2843,7 @@ add_executable(measurement_display ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c) target_link_libraries (measurement_display minimal_lib) -add_executable(test5Gnas +add_executable(test5Gnas ${OPENAIR_DIR}/openair3/TEST/test5Gnas.c ) target_link_libraries (test5Gnas LIB_5GNAS_GNB CONFIG_LIB minimal_lib ) @@ -2884,11 +2884,11 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer) target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB + RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) - + target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) @@ -2925,7 +2925,7 @@ add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_l target_link_libraries (ocp-enb -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB + RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) @@ -3038,7 +3038,7 @@ add_executable(nr-softmodem target_link_libraries (nr-softmodem -Wl,--start-group UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA - ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB + ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} -Wl,--end-group z dl) @@ -3078,7 +3078,7 @@ add_executable(ocp-gnb target_link_libraries (ocp-gnb -Wl,--start-group UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA - ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB + ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON -Wl,--end-group z dl) @@ -3154,7 +3154,7 @@ target_link_libraries (dlsim_tm4 pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${T_LIB} ) -add_executable(polartest +add_executable(polartest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c @@ -3167,7 +3167,7 @@ target_link_libraries(polartest m pthread ${ATLAS_LIBRARIES} dl ) -add_executable(smallblocktest +add_executable(smallblocktest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c @@ -3185,17 +3185,17 @@ target_link_libraries(smallblocktest # temp_C_flag = CMAKE_C_FLAGS #set(CMAKE_C_FLAGS " ") -set (TEMP_C_FLAG ${CMAKE_C_FLAGS}) +set (TEMP_C_FLAG ${CMAKE_C_FLAGS}) set (CMAKE_C_FLAGS ${CUDA_CMAKE_C_FLAGS}) -set (TEMP_CXX_FLAG ${CMAKE_CXX_FLAGS}) +set (TEMP_CXX_FLAG ${CMAKE_CXX_FLAGS}) set (CMAKE_CXX_FLAGS ${CUDA_CMAKE_CXX_FLAGS}) if (CUDA_FOUND) ################################################### -# For CUDA library +# For CUDA library ################################################### - - CUDA_ADD_LIBRARY(LDPC_CU + + CUDA_ADD_LIBRARY(LDPC_CU ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu ) CUDA_ADD_CUFFT_TO_TARGET(LDPC_CU) @@ -3205,14 +3205,14 @@ if (CUDA_FOUND) ${SHLIB_LOADER_SOURCES} ) target_link_libraries(ldpctest -ldl - -Wl,--start-group - LDPC_CU UTIL SIMU PHY_NR CONFIG_LIB + -Wl,--start-group + LDPC_CU UTIL SIMU PHY_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} dl ) else (CUDA_FOUND) - add_executable(ldpctest + add_executable(ldpctest ${PHY_NR_CODINGIF} ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c ${T_SOURCE} @@ -3224,21 +3224,21 @@ set (CMAKE_C_FLAGS ${TEMP_C_FLAG}) set (CMAKE_CXX_FLAGS ${TEMP_CXX_FLAG}) -# add_executable(ldpctest +# add_executable(ldpctest # ${PHY_NR_CODINGIF} # ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c # ${T_SOURCE} # ${SHLIB_LOADER_SOURCES} # ) -add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) +add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) target_link_libraries(ldpctest -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} dl ) -add_executable(nr_dlschsim - ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c +add_executable(nr_dlschsim + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/utils.c @@ -3247,13 +3247,13 @@ add_executable(nr_dlschsim ${T_SOURCE} ${SHLIB_LOADER_SOURCES} ) -target_link_libraries(nr_dlschsim +target_link_libraries(nr_dlschsim -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) -add_executable(nr_pbchsim - ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c +add_executable(nr_pbchsim + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/utils.c @@ -3268,8 +3268,8 @@ target_link_libraries(nr_pbchsim ) #PUCCH ---> Prashanth -add_executable(nr_pucchsim - ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c +add_executable(nr_pucchsim + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/system.c @@ -3297,7 +3297,7 @@ add_executable(nr_dlsim ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} - ) + ) target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl @@ -3305,7 +3305,7 @@ target_link_libraries(nr_dlsim target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR) add_executable(nr_prachsim - ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c @@ -3317,7 +3317,7 @@ add_executable(nr_prachsim ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES}) -target_link_libraries(nr_prachsim +target_link_libraries(nr_prachsim -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) @@ -3357,7 +3357,7 @@ target_link_libraries(nr_ulsim target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR) foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim) - + add_executable(${myExe} ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c @@ -3374,7 +3374,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) - + endforeach(myExe) add_executable(test_epc_generate_scenario @@ -3437,13 +3437,13 @@ endforeach(myExe) if (${T_TRACER}) foreach(i #all "add_executable" definitions (except tests, rb_tool, updatefw) - lte-softmodem lte-uesoftmodem nr-softmodem + lte-softmodem lte-uesoftmodem nr-softmodem nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 nr-ittisim ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim nr_ulschsim ldpctest polartest smallblocktest cu_test du_test #all "add_library" definitions - ITTI RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP + ITTI RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP params_libconfig oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_iqplayer oai_eth_transpro oai_mobipass tcp_bridge tcp_bridge_oai coding FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO @@ -3559,7 +3559,7 @@ add_executable(nr-ittisim target_link_libraries (nr-ittisim -Wl,--start-group UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA - ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB + ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} PHY_NR_UE SCHED_NR_UE_LIB NR_L2_UE diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index abc944bc00..917a41c9e6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -917,7 +917,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, n_rnti = rel15->rnti; if (crc == n_rnti) { - LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", + LOG_I(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", proc->frame_rx, proc->nr_slot_rx,n_rnti,rel15->dci_format_options[k],CCEind,dci_length,*(unsigned long long*)dci_estimation); dci_ind->SFN = proc->frame_rx; dci_ind->slot = proc->nr_slot_rx; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f516ad8639..a7bb4e0dbc 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -132,6 +132,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, } switch (pdu_type){ + case FAPI_NR_RX_PDU_TYPE_SIB: case FAPI_NR_RX_PDU_TYPE_DLSCH: case FAPI_NR_RX_PDU_TYPE_RAR: harq_pid = dlsch0->current_harq_pid; @@ -1208,7 +1209,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, eNB_id, ue, dlsch0, number_pdus); break; case SI_PDSCH: - rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_SIB; + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id); + nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, eNB_id, ue, dlsch0, number_pdus); break; default: break; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_vars.c b/openair2/LAYER2/NR_MAC_UE/mac_vars.c index ecabdb870c..383267090f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_vars.c +++ b/openair2/LAYER2/NR_MAC_UE/mac_vars.c @@ -32,7 +32,7 @@ #include -const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC"}; +const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC", "NR_RNTI_SP_CSI", "NR_RNTI_SI"}; const char *dci_formats[]={"1_0", "1_1", "2_0", "2_1", "2_2", "2_3", "0_0", "0_1"}; // table_7_3_1_1_2_2_3_4_5 contains values for number of layers and precoding information for tables 7.3.1.1.2-2/3/4/5 from TS 38.212 subclause 7.3.1.1.2 diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index b4b63e0064..579dd49a3b 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -35,6 +35,7 @@ /* RRC */ #include "NR_RACH-ConfigCommon.h" +#include "RRC/NR_UE/rrc_proto.h" /* PHY */ #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" @@ -514,7 +515,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, uint8_t sdu_lcids[NB_RB_MAX] = {0}; uint16_t sdu_lengths[NB_RB_MAX] = {0}; - int TBS_bytes = 848, header_length_total=0, num_sdus, offset, mac_ce_len; + int num_sdus, offset = 0, preambleTransMax; // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side if (!prach_resources->init_msg1) { @@ -532,35 +533,20 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, LOG_D(MAC, "RA not active. Checking for data to transmit from upper layers...\n"); - payload = (uint8_t*) &mac->CCCH_pdu.payload; - mac_ce_len = 0; + uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); + payload = (uint8_t*) mac->CCCH_pdu.payload; + num_sdus = 1; post_padding = 1; + sdu_lcids[0] = lcid; - if (0){ - // initialisation by RRC - // CCCH PDU - // size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id, - // CC_id, - // frame, - // CCCH, - // 1, - // mac_sdus, - // gNB_id, - // 0); - LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu); - } else { - // fill ulsch_buffer with random data - for (int i = 0; i < TBS_bytes; i++){ - mac_sdus[i] = (unsigned char) (lrand48()&0xff); - } - //Sending SDUs with size 1 - //Initialize elements of sdu_lcids and sdu_lengths - sdu_lcids[0] = lcid; - sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len; - header_length_total += 2 + (sdu_lengths[0] >= 128); - size_sdu += sdu_lengths[0]; - } + // initialisation by RRC + // CCCH PDU + size_sdu = (uint16_t) nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, mac_sdus); + + sdu_lengths[0] = size_sdu; + + LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu); if (size_sdu > 0) { @@ -589,12 +575,27 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, post_padding, 0); + AssertFatal(TBS_max > offset, "Frequency resources are not enough for Msg3!\n"); + // Padding: fill remainder with 0 if (post_padding > 0){ - for (int j = 0; j < (TBS_bytes - offset); j++) - payload[offset + j] = 0; // mac_pdu[offset + j] = 0; + for (int j = 0; j < (TBS_max - offset); j++) + payload[offset + j] = 0; } - } + } + + LOG_D(MAC,"size_sdu = %i\n", size_sdu); + LOG_D(MAC,"offset = %i\n", offset); + for(int k = 0; k < TBS_max; k++) { + LOG_D(MAC,"(%i): %i\n", k, prach_resources->Msg3[k]); + } + + // Msg3 was initialized with TBS_max bytes because the mac->RA_Msg3_size will only be known after + // receiving Msg2 (which contains the Msg3 resource reserve). + // Msg3 will be transmitted with mac->RA_Msg3_size bytes, removing unnecessary 0s. + mac->ulsch_pdu.Pdu_size = TBS_max; + memcpy(mac->ulsch_pdu.payload, prach_resources->Msg3, TBS_max); + } else if (ra->RA_window_cnt != -1) { // RACH is active LOG_D(MAC, "In %s [%d.%d] RA is active: RA window count %d, RA backoff count %d\n", __FUNCTION__, frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 09eff5c056..a3e084e738 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -584,7 +584,8 @@ void nr_get_Msg3alloc(module_id_t module_id, NR_RA_t *ra) { // msg3 is schedulend in mixed slot in the following TDD period - // for now we consider a TBS of 18 bytes + + uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing; int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot; @@ -614,21 +615,22 @@ void nr_get_Msg3alloc(module_id_t module_id, uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE]; const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - /* search 18 free RBs */ + + /* search msg3_nb_rb free RBs */ int rbSize = 0; int rbStart = 0; - while (rbSize < 18) { + while (rbSize < msg3_nb_rb) { rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ rbSize = 0; while (rbStart < bwpSize && vrb_map_UL[rbStart]) rbStart++; - AssertFatal(rbStart < bwpSize - 18, "no space to allocate Msg 3 for RA!\n"); + AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n"); while (rbStart + rbSize < bwpSize && !vrb_map_UL[rbStart + rbSize] - && rbSize < 18) + && rbSize < msg3_nb_rb) rbSize++; } - ra->msg3_nb_rb = 18; + ra->msg3_nb_rb = msg3_nb_rb; ra->msg3_first_rb = rbStart; } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index b6c0ae4b45..491d815827 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -413,6 +413,18 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ for(nr_ue=0;nr_uemodule_id].MBMS_flag < 3) // see -Q option if (AMF_MODE_ENABLED) { - rrc_ue_generate_RRCSetupRequest( ctxt_pP, gNB_index ); + nr_rrc_ue_generate_RRCSetupRequest( ctxt_pP->module_id, gNB_index ); } if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_IDLE) { @@ -1287,7 +1299,7 @@ int nr_decode_BCCH_DLSCH_Message( if (nr_rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) { //if ( (NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!AMF_MODE_ENABLED)) { - rrc_ue_generate_RRCSetupRequest(ctxt_pP, 0); + nr_rrc_ue_generate_RRCSetupRequest(ctxt_pP->module_id, 0); nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING ); //} } @@ -1488,6 +1500,100 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB return rval; } +int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) { + + if(sib1.si_SchedulingInfo) { + + bool SIB_to_request[32] = {}; + + LOG_D(RRC, "SIBs broadcasting: "); + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2); + } + printf("\n"); + + LOG_D(RRC, "SIBs needed by UE: "); + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) { + + printf("SIB%i ", j + 2); + + SIB_to_request[j] = true; + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) { + SIB_to_request[j] = false; + break; + } + } + + } + } + printf("\n"); + + LOG_D(RRC, "SIBs to request by UE: "); + bool do_ra = false; + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if(SIB_to_request[j]) { + printf("SIB%i ", j + 2); + do_ra = true; + } + } + printf("\n"); + + if(do_ra) { + + NR_UE_rrc_inst[module_id].ra_trigger = REQUEST_FOR_OTHER_SI; + get_softmodem_params()->do_ra = 1; + + if(sib1.si_SchedulingInfo->si_RequestConfig) { + LOG_D(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); + } else { + LOG_D(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); + } + + } + + } + + return 0; +} + +int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) { + + switch(NR_UE_rrc_inst[module_id].ra_trigger){ + case INITIAL_ACCESS_FROM_RRC_IDLE: + nr_rrc_ue_generate_RRCSetupRequest(module_id,gNB_index); + break; + case RRC_CONNECTION_REESTABLISHMENT: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case DURING_HANDOVER: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case NON_SYNCHRONISED: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case TRANSITION_FROM_RRC_INACTIVE: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case TO_ESTABLISH_TA: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case REQUEST_FOR_OTHER_SI: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case BEAM_FAILURE_RECOVERY: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + default: + AssertFatal(1==0, "Invalid ra_trigger value!\n"); + break; + } + + return 0; +} + + /*brief decode SIB1 message*/ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { @@ -1514,6 +1620,15 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index LOG_I(RRC, "SIB1 decoded\n"); if( g_log->log_component[RRC].level >= OAILOG_DEBUG ) xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); + + // FIXME: fix condition for the RA trigger + check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); + if( nr_rrc_get_state(module_id) == RRC_STATE_IDLE_NR ) { + NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE; + get_softmodem_params()->do_ra = 1; + } + + nr_rrc_ue_generate_ra_msg(module_id,gNB_index); } else LOG_E(PHY, "sib1 is starting by 8 times 0\n"); @@ -1783,10 +1898,10 @@ nr_rrc_ue_process_securityModeCommand( } //----------------------------------------------------------------------------- -void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) { +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index ) { uint8_t i=0,rv[6]; - if(NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) { + if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) { // Get RRCConnectionRequest, fill random for now // Generate random byte stream for contention resolution for (i=0; i<6; i++) { @@ -1800,16 +1915,16 @@ void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, cons } LOG_T(NR_RRC,"\n"); - NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size = - do_RRCSetupRequest( - ctxt_pP->module_id, - (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, - rv); - LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, eNB %d)\n", - ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index); + NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size = + do_RRCSetupRequest( + module_id, + (uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload, + rv); + LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n", + module_id, NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index); - for (i=0; imodule_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) { - LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]); + for (i=0; i Date: Mon, 8 Feb 2021 21:15:40 +0100 Subject: [PATCH 35/91] Replacing tryPull by pull for L1 rx --- executables/nr-gnb.c | 3 ++- executables/nr-ru.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index fbbe5813a9..efc1b31c51 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -915,11 +915,12 @@ void init_gNB_Tpool(int inst) { gNB->resp_L1 = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); initTpool("-1", gNB->threadPool_L1, false); initNotifiedFIFO(gNB->resp_L1); + pushNotifiedFIFO_nothreadSafe(gNB->resp_L1, newNotifiedFIFO_elt(20, 0,NULL,NULL)); // L1 TX threadpool gNB->threadPool_L1_tx = (tpool_t*)malloc(sizeof(tpool_t)); gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); - initTpool("-1",gNB->threadPool_L1_tx, false); + initTpool("-1,-1,-1",gNB->threadPool_L1_tx, false); initNotifiedFIFO(gNB->resp_L1_tx); // RU TX threadpool diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 97d865a930..f3e1857eaf 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1821,6 +1821,7 @@ void *ru_thread( void *param ) { if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); else AssertFatal(1==0, "No fronthaul interface at south port"); + proc->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx; proc->tti_tx = (proc->tti_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; @@ -1904,7 +1905,7 @@ void *ru_thread( void *param ) { syncMsg->slot_tx = proc->tti_tx; // check if previous L1 slot processing is finished - res = tryPullTpool(gNB->resp_L1, gNB->threadPool_L1); + res = pullTpool(gNB->resp_L1, gNB->threadPool_L1); if (res == NULL) { LOG_W(PHY,"L1 RX of previous slot is still being processed. Adding current slot to queue (%d.%d)\n", proc->frame_rx, proc->tti_rx); } From 2b9d0f95c9355e040a362105946e524add40e755 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 8 Feb 2021 22:40:23 +0000 Subject: [PATCH 36/91] Fix develop merge conflicts in the RA-Msg3 --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 6 +-- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 55 ++++++++++++-------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 579dd49a3b..8e2087922a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -515,7 +515,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, uint8_t sdu_lcids[NB_RB_MAX] = {0}; uint16_t sdu_lengths[NB_RB_MAX] = {0}; - int num_sdus, offset = 0, preambleTransMax; + int num_sdus, offset = 0; // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side if (!prach_resources->init_msg1) { @@ -590,9 +590,9 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, LOG_D(MAC,"(%i): %i\n", k, prach_resources->Msg3[k]); } - // Msg3 was initialized with TBS_max bytes because the mac->RA_Msg3_size will only be known after + // Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after // receiving Msg2 (which contains the Msg3 resource reserve). - // Msg3 will be transmitted with mac->RA_Msg3_size bytes, removing unnecessary 0s. + // Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s. mac->ulsch_pdu.Pdu_size = TBS_max; memcpy(mac->ulsch_pdu.payload, prach_resources->Msg3, TBS_max); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 0a6af58dee..f76ef818e8 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -889,32 +889,41 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; - if (IS_SOFTMODEM_NOS1){ - // Getting IP traffic to be transmitted - data_existing = nr_ue_get_sdu(mod_id, - cc_id, - frame_tx, - slot_tx, - 0, - ulsch_input_buffer, - TBS_bytes, - &access_mode); - } + if (ra->ra_state == WAIT_RAR){ + memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes); + printf("\n"); + LOG_I(MAC,"[RAPROC] Msg3 to be transmitted:\n"); + for (int k = 0; k < TBS_bytes; k++) { + LOG_I(MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]); + } + printf("\n"); + } else { + if (IS_SOFTMODEM_NOS1){ + // Getting IP traffic to be transmitted + data_existing = nr_ue_get_sdu(mod_id, + cc_id, + frame_tx, + slot_tx, + 0, + ulsch_input_buffer, + TBS_bytes, + &access_mode); + } - //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity - if (!IS_SOFTMODEM_NOS1 || !data_existing) { - //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid - //and block this traffic from being forwarded to the upper layers at the gNB - LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes); + //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity + if (!IS_SOFTMODEM_NOS1 || !data_existing) { + //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid + //and block this traffic from being forwarded to the upper layers at the gNB + LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes); - //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) - //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should - //have a valid LCID (nr_process_mac_pdu function) - ulsch_input_buffer[0] = 0x31; + //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) + //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should + //have a valid LCID (nr_process_mac_pdu function) + ulsch_input_buffer[0] = 0x31; - for (int i = 1; i < TBS_bytes; i++) { - ulsch_input_buffer[i] = (unsigned char) rand(); - //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + for (int i = 1; i < TBS_bytes; i++) { + ulsch_input_buffer[i] = (unsigned char) rand(); + } } } From d29e09cdb16c56ab7b03a1b42574a635f1ea3e3f Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Mon, 8 Feb 2021 23:59:33 +0100 Subject: [PATCH 37/91] Passing tx timestamp through pipeline --- executables/nr-ru.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index f3e1857eaf..23454e2d50 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -125,12 +125,14 @@ typedef struct processingData_L1 { int frame_tx; int slot_rx; int slot_tx; + openair0_timestamp timestamp_tx; PHY_VARS_gNB *gNB; } processingData_L1_t; typedef struct processingData_RU { int frame_tx; int slot_tx; + openair0_timestamp timestamp_tx; RU_t *ru; } processingData_RU_t; @@ -1330,7 +1332,7 @@ void ru_tx_func(void *param) { if(!emulate_rf) { // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,slot_tx,ru->proc.timestamp_tx); + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,slot_tx,info->timestamp_tx); if (ru->fh_north_out) ru->fh_north_out(ru); } else { @@ -1516,6 +1518,7 @@ void tx_func(void *param) { notifiedFIFO_elt_t *res; syncMsg->frame_tx = frame_tx; syncMsg->slot_tx = slot_tx; + syncMsg->timestamp_tx = info->timestamp_tx; syncMsg->ru = gNB->RU_list[0]; res = tryPullTpool(gNB->resp_RU_tx, gNB->threadPool_RU_tx); @@ -1639,6 +1642,7 @@ void rx_func(void *param) { syncMsg->slot_rx = slot_rx; syncMsg->frame_tx = frame_tx; syncMsg->slot_tx = slot_tx; + syncMsg->timestamp_tx = info->timestamp_tx; if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { res = tryPullTpool(gNB->resp_L1_tx, gNB->threadPool_L1_tx); @@ -1903,6 +1907,7 @@ void *ru_thread( void *param ) { syncMsg->slot_rx = proc->tti_rx; syncMsg->frame_tx = proc->frame_tx; syncMsg->slot_tx = proc->tti_tx; + syncMsg->timestamp_tx = proc->timestamp_tx; // check if previous L1 slot processing is finished res = pullTpool(gNB->resp_L1, gNB->threadPool_L1); From 09230ceb5ef2aa69480c3c7ade8a5a2e3448e620 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 9 Feb 2021 09:38:23 +0100 Subject: [PATCH 38/91] CI: forgot to add 5G GNB FDD conf file for RF sim test Signed-off-by: Raphael Defosseux --- .../gnb.band66.tm1.106PRB.usrpn300.conf | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf new file mode 100644 index 0000000000..9e13d493a8 --- /dev/null +++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf @@ -0,0 +1,284 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 2150 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 433096; + dl_frequencyBand = 66; + # this is 2150 MHz + dl_absoluteFrequencyPointA = 430000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 + initialDLBWPstartSymbolAndLength_3 = 57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 66; + ul_absoluteFrequencyPointA = 350000; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + clock_src = "external"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + From 12517f02e2794cf87379fb98e61a737cfba6c937 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 9 Feb 2021 11:10:58 +0100 Subject: [PATCH 39/91] Reverting shifting the TX 4 bits to the left to exploit dynamic range. adapted ssb_block_power to measured value This partially reverts commit 857f9179f35216e36ca16ed08cde193e81a418bc. Conflicts: targets/ARCH/ETHERNET/benetel/5g/benetel.c --- targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index ba44e989b9..940d619a51 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -194,7 +194,7 @@ gNBs = nrofUplinkSymbols = 4; //0; //4; #ssPBCH_BlockPower = 10; - ssPBCH_BlockPower = -10; + ssPBCH_BlockPower = -35; } ); From 5a1e2b1db7e59728dae3003847879904b1b66fb9 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Tue, 9 Feb 2021 15:32:17 +0000 Subject: [PATCH 40/91] Add support for SIB1 and SI in BCCH-DL-SCH --- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 4 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 12 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 2 +- openair2/RRC/NR_UE/L2_interface_ue.c | 2 +- openair2/RRC/NR_UE/rrc_UE.c | 478 ++++++------------- openair2/RRC/NR_UE/rrc_proto.h | 10 +- 6 files changed, 155 insertions(+), 353 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index c4909c1384..14d1ea63fb 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -56,14 +56,14 @@ int8_t nr_ue_decode_mib( void *pduP, uint16_t cell_id ); -/**\brief decode sib1 pdu in NR_UE, from if_module dl_ind +/**\brief decode SIB1 and other SIs pdus in NR_UE, from if_module dl_ind \param module_id module id \param cc_id component carrier id \param gNB_index gNB index \param sibs_mask sibs mask \param pduP pointer to pdu \param pdu_length length of pdu */ -int8_t nr_ue_decode_sib1(module_id_t module_id, +int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 8a329f5269..f02daf9c30 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -154,12 +154,12 @@ int8_t nr_ue_decode_mib(module_id_t module_id, return 0; } -int8_t nr_ue_decode_sib1(module_id_t module_id, - int cc_id, - unsigned int gNB_index, - uint32_t sibs_mask, - uint8_t *pduP, - uint32_t pdu_len) { +int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, + int cc_id, + unsigned int gNB_index, + uint32_t sibs_mask, + uint8_t *pduP, + uint32_t pdu_len) { LOG_D(MAC, "Decode sib1\n"); nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); return 0; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index edaef6d1ce..dfbbd0db6b 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -62,7 +62,7 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, ui // L2 Abstraction Layer int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len){ - return nr_ue_decode_sib1(module_id, cc_id, gNB_index, sibs_mask, pduP, pdu_len); + return nr_ue_decode_BCCH_DL_SCH(module_id, cc_id, gNB_index, sibs_mask, pduP, pdu_len); } // L2 Abstraction Layer diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 3ea525d6bf..6c791ae9ee 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -51,7 +51,7 @@ nr_mac_rrc_data_ind_ue( AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n"); break; case NR_BCCH_DL_SCH: - AssertFatal( nr_rrc_ue_decode_NR_SIB1_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-DLSCH error!\n"); + AssertFatal( nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len, 0, 0) == 0, "UE decode BCCH-DL-SCH error!\n"); break; default: break; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 491d815827..979b9b9d32 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1040,205 +1040,119 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index return 0; } -int nr_decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t rsrq, const uint8_t rsrp ) { - NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index]; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN ); - LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id ); - const int n = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count; - for (int i = 0; i < n; ++i) { - NR_PLMN_Identity_t *PLMN_identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[i]->plmn_IdentityList.list.array[0]; - int mccdigits = PLMN_identity->mcc->list.count; - int mncdigits = PLMN_identity->mnc.list.count; +int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) { - int mcc; - if (mccdigits == 2) { - mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1]; - } else { - mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2]; + if(sib1.si_SchedulingInfo) { + + bool SIB_to_request[32] = {}; + + LOG_D(RRC, "SIBs broadcasting: "); + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2); } + printf("\n"); - int mnc; - if (mncdigits == 2) { - mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1]; - } else { - mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2]; - } + LOG_D(RRC, "SIBs needed by UE: "); + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) { - LOG_I( RRC, "PLMN %d MCC %0*d, MNC %0*d\n", i + 1, mccdigits, mcc, mncdigits, mnc); - // search internal table for provider name - int plmn_ind = 0; + printf("SIB%i ", j + 2); - while (plmn_data[plmn_ind].mcc > 0) { - if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) { - LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short ); - break; - } - - plmn_ind++; - } - } - LOG_I( RRC, "TAC 0x%04x\n", - ((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->size == 2)?((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[0]<<8) + sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[1]):0)); - LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse, - nr_SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) ); - - LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n", - BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity ), - sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[0], - sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[1], - sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[2], - sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[3] >> sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.bits_unused); - //LOG_I( RRC, "cellAccessRelatedInfo.cellBarred : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.cellBarred, SIBbarred(sib1->cellAccessRelatedInfo.cellBarred) ); - //LOG_I( RRC, "cellAccessRelatedInfo.intraFreqReselection : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.intraFreqReselection, SIBallowed(sib1->cellAccessRelatedInfo.intraFreqReselection) ); - //LOG_I( RRC, "cellAccessRelatedInfo.csg_Indication : %d\n", sib1->cellAccessRelatedInfo.csg_Indication ); - - //if (sib1->cellAccessRelatedInfo.csg_Identity) - // LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : %"PRIu32"\n", BIT_STRING_to_uint32(sib1->cellAccessRelatedInfo.csg_Identity) ); - //else - // LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : not defined\n" ); - - LOG_I( RRC, "cellSelectionInfo.q_RxLevMin : %ld\n", sib1->cellSelectionInfo->q_RxLevMin ); - - if (sib1->cellSelectionInfo->q_RxLevMinOffset) - LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : %ld\n", *sib1->cellSelectionInfo->q_RxLevMinOffset ); - else - LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : not defined\n" ); - - //if (sib1->p_Max) - // LOG_I( RRC, "p_Max : %ld\n", *sib1->p_Max ); - //else - // LOG_I( RRC, "p_Max : not defined\n" ); - - //LOG_I( RRC, "freqBandIndicator : %ld\n", sib1->freqBandIndicator ); - - if (sib1->si_SchedulingInfo->schedulingInfoList.list.count > 0) { - for (int i=0; isi_SchedulingInfo->schedulingInfoList.list.count; i++) { - LOG_I( RRC, "si_Periodicity[%d] : %s\n", i, SIBPeriod[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->si_Periodicity,7)]); - - if (sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count > 0) { - char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32 - - for (int j=0; jsi_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count; j++) { - sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0]->type,11)] ); + SIB_to_request[j] = true; + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) { + SIB_to_request[j] = false; + break; + } } - LOG_I( RRC, "siSchedulingInfoSIBType[%d] : %s\n", i, temp ); + } + } + printf("\n"); + + LOG_D(RRC, "SIBs to request by UE: "); + bool do_ra = false; + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if(SIB_to_request[j]) { + printf("SIB%i ", j + 2); + do_ra = true; + } + } + printf("\n"); + + if(do_ra) { + + NR_UE_rrc_inst[module_id].ra_trigger = REQUEST_FOR_OTHER_SI; + get_softmodem_params()->do_ra = 1; + + if(sib1.si_SchedulingInfo->si_RequestConfig) { + LOG_D(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); } else { - LOG_I( RRC, "mapping list %d is null\n", i ); + LOG_D(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); } + } - } else { - LOG_E( RRC, "siSchedulingInfoPeriod[0] : PROBLEM!!!\n" ); - return -1; + } - if (sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon) { - //TODO - } - - LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1->si_SchedulingInfo->si_WindowLength,8)] ); - //LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1->systemInfoValueTag ); - NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIperiod = siPeriod_int[sib1->si_SchedulingInfo->schedulingInfoList.list.array[0]->si_Periodicity]; - NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIwindowsize = siWindowLength_int[sib1->si_SchedulingInfo->si_WindowLength]; - LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", - ctxt_pP->module_id, gNB_index, ctxt_pP->module_id ); - //rrc_mac_config_req_ue - LOG_I(RRC,"Setting SIStatus bit 0 to 1\n"); - NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus = 1; - //NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag; - - if (AMF_MODE_ENABLED) { - int cell_valid = 0; - - //if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) { - /* Cell is not barred */ - int plmn; - int plmn_number; - plmn_number = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count; - - /* Compare requested PLMN and PLMNs from SIB1*/ - for (plmn = 0; plmn < plmn_number; plmn++) { - NR_PLMN_Identity_t *plmn_Identity; - plmn_Identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_IdentityList.list.array[0]; - - if ( - ( - (plmn_Identity->mcc == NULL) - || - ( - (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit1 == *(plmn_Identity->mcc->list.array[0])) && - (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit2 == *(plmn_Identity->mcc->list.array[1])) && - (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit3 == *(plmn_Identity->mcc->list.array[2])) - ) - ) - && - (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit1 == *(plmn_Identity->mnc.list.array[0])) - && - (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit2 == *(plmn_Identity->mnc.list.array[1])) - && - ( - ((NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == 0xf) && (plmn_Identity->mnc.list.count == 2)) - || - (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == *(plmn_Identity->mnc.list.array[2])) - ) - ) { - /* PLMN match, send a confirmation to NAS */ - MessageDef *msg_p; - msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CELL_SELECTION_CNF); - NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS; - NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity); - NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode); - NAS_CELL_SELECTION_CNF (msg_p).rat = 0xFF; - NAS_CELL_SELECTION_CNF (msg_p).rsrq = rsrq; - NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp; - itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); - cell_valid = 1; - NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity = plmn + 1; - break; - } - } - //} - - if (cell_valid == 0) { - /* Cell can not be used, ask PHY to try the next one */ - MessageDef *msg_p; - msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, PHY_FIND_NEXT_CELL_REQ); - itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); - LOG_E(RRC, - "Synched with a cell, but PLMN doesn't match our SIM " - "(selected_plmn_identity %ld), the message PHY_FIND_NEXT_CELL_REQ " - "is sent but lost in current UE implementation!\n", - NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT ); return 0; } -int nr_decode_BCCH_DLSCH_Message( - const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - uint8_t *const Sdu, - const uint8_t Sdu_len, - const uint8_t rsrq, - const uint8_t rsrp ) { +int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) { + + switch(NR_UE_rrc_inst[module_id].ra_trigger){ + case INITIAL_ACCESS_FROM_RRC_IDLE: + nr_rrc_ue_generate_RRCSetupRequest(module_id,gNB_index); + break; + case RRC_CONNECTION_REESTABLISHMENT: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case DURING_HANDOVER: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case NON_SYNCHRONISED: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case TRANSITION_FROM_RRC_INACTIVE: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case TO_ESTABLISH_TA: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case REQUEST_FOR_OTHER_SI: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case BEAM_FAILURE_RECOVERY: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + default: + AssertFatal(1==0, "Invalid ra_trigger value!\n"); + break; + } + + return 0; +} + +int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message( + module_id_t module_id, + const uint8_t gNB_index, + uint8_t *const Sdu, + const uint8_t Sdu_len, + const uint8_t rsrq, + const uint8_t rsrp) { + NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; - NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index]; + NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN ); - if (((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) && // SIB1 received - (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) { + if (((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) && // SIB1 received + (NR_UE_rrc_inst[module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) { // to prevent memory bloating VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); return 0; } - nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR ); - - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message ); - } + nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR ); asn_dec_rval_t dec_rval = uper_decode_complete( NULL, &asn_DEF_NR_BCCH_DL_SCH_Message, @@ -1246,11 +1160,15 @@ int nr_decode_BCCH_DLSCH_Message( (const void *)Sdu, Sdu_len ); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message ); + } + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E( RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", - ctxt_pP->module_id, + LOG_E( NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", + module_id, dec_rval.consumed ); - log_dump(RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" ); + log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" ); // free the memory SEQUENCE_free( &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); @@ -1260,35 +1178,55 @@ int nr_decode_BCCH_DLSCH_Message( if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) { switch (bcch_message->message.choice.c1->present) { case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: - if ((ctxt_pP->frame % 2) == 0) { - // even frame - if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 0) { - NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index]; - memcpy( (void *)sib1, - (void *)bcch_message->message.choice.c1->choice.systemInformationBlockType1, - sizeof(NR_SIB1_t) ); - LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id ); - nr_decode_SIB1( ctxt_pP, gNB_index, rsrq, rsrp ); + if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 0) { + NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index]; + if(sib1 != NULL){ + SEQUENCE_free(&asn_DEF_NR_BCCH_BCH_Message, (void *)sib1, 1 ); + } + + sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; + if (*(int64_t*)sib1 != 1) { + if( g_log->log_component[RRC].level >= OAILOG_DEBUG ) { + xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); + } + LOG_I(NR_RRC, "SIB1 decoded\n"); + + // TODO: prepare RRCConnectionRequest + // After SIB1 is received, prepare RRCConnectionRequest + + // FIXME: fix condition for the RA trigger + // Check for on-demand not broadcasted SI + check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); + if( nr_rrc_get_state(module_id) == RRC_STATE_IDLE_NR ) { + NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE; + // TODO: remove flag after full RA procedures implemented + get_softmodem_params()->do_ra = 1; + } + nr_rrc_ue_generate_ra_msg(module_id,gNB_index); + } else { + LOG_E(NR_RRC, "SIB1 not decoded\n"); } } - break; case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: - if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) { + if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) { + LOG_W(NR_RRC, "Decoding SI not implemented yet\n"); + // TODO: Decode SI + /* // SIB1 with schedulingInfoList is available - NR_SystemInformation_t *si = NR_UE_rrc_inst[ctxt_pP->module_id].si[gNB_index]; + NR_SystemInformation_t *si = NR_UE_rrc_inst[module_id].si[gNB_index]; + memcpy( si, bcch_message->message.choice.c1->choice.systemInformation, sizeof(NR_SystemInformation_t) ); - LOG_I( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n", - ctxt_pP->module_id, - ctxt_pP->frame ); + LOG_I(NR_RRC, "[UE %"PRIu8"] Decoding SI\n", module_id); nr_decode_SI( ctxt_pP, gNB_index ); - //if (nfapi_mode == 3) - //UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1; - } + if (nfapi_mode == 3) + UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1; + */ + } break; case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: @@ -1297,10 +1235,10 @@ int nr_decode_BCCH_DLSCH_Message( } } - if (nr_rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) { + if (nr_rrc_get_sub_state(module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) { //if ( (NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!AMF_MODE_ENABLED)) { - nr_rrc_ue_generate_RRCSetupRequest(ctxt_pP->module_id, 0); - nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING ); + nr_rrc_ue_generate_RRCSetupRequest(module_id, 0); + nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_CONNECTING ); //} } @@ -1500,144 +1438,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB return rval; } -int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) { - - if(sib1.si_SchedulingInfo) { - - bool SIB_to_request[32] = {}; - - LOG_D(RRC, "SIBs broadcasting: "); - for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { - printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2); - } - printf("\n"); - - LOG_D(RRC, "SIBs needed by UE: "); - for(int j = 0; j < 8*requested_SI_List.size; j++) { - if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) { - - printf("SIB%i ", j + 2); - - SIB_to_request[j] = true; - for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { - if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) { - SIB_to_request[j] = false; - break; - } - } - - } - } - printf("\n"); - - LOG_D(RRC, "SIBs to request by UE: "); - bool do_ra = false; - for(int j = 0; j < 8*requested_SI_List.size; j++) { - if(SIB_to_request[j]) { - printf("SIB%i ", j + 2); - do_ra = true; - } - } - printf("\n"); - - if(do_ra) { - - NR_UE_rrc_inst[module_id].ra_trigger = REQUEST_FOR_OTHER_SI; - get_softmodem_params()->do_ra = 1; - - if(sib1.si_SchedulingInfo->si_RequestConfig) { - LOG_D(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); - } else { - LOG_D(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); - } - - } - - } - - return 0; -} - -int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) { - - switch(NR_UE_rrc_inst[module_id].ra_trigger){ - case INITIAL_ACCESS_FROM_RRC_IDLE: - nr_rrc_ue_generate_RRCSetupRequest(module_id,gNB_index); - break; - case RRC_CONNECTION_REESTABLISHMENT: - AssertFatal(1==0, "ra_trigger not implemented yet!\n"); - break; - case DURING_HANDOVER: - AssertFatal(1==0, "ra_trigger not implemented yet!\n"); - break; - case NON_SYNCHRONISED: - AssertFatal(1==0, "ra_trigger not implemented yet!\n"); - break; - case TRANSITION_FROM_RRC_INACTIVE: - AssertFatal(1==0, "ra_trigger not implemented yet!\n"); - break; - case TO_ESTABLISH_TA: - AssertFatal(1==0, "ra_trigger not implemented yet!\n"); - break; - case REQUEST_FOR_OTHER_SI: - AssertFatal(1==0, "ra_trigger not implemented yet!\n"); - break; - case BEAM_FAILURE_RECOVERY: - AssertFatal(1==0, "ra_trigger not implemented yet!\n"); - break; - default: - AssertFatal(1==0, "Invalid ra_trigger value!\n"); - break; - } - - return 0; -} - - -/*brief decode SIB1 message*/ -int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { - - NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; - - asn_dec_rval_t dec_rval = uper_decode_complete(NULL, - &asn_DEF_NR_BCCH_DL_SCH_Message, - (void **)&bcch_message, - (const void *)bufferP, - buffer_len); - - if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { - LOG_D(RRC,"NR_BCCH_DL_SCH decode error\n"); - SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1 ); - return -1; - } - else { - NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index]; - if(sib1 != NULL){ - SEQUENCE_free(&asn_DEF_NR_BCCH_BCH_Message, (void *)sib1, 1 ); - } - sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; - if (*(int64_t*)sib1 != 1) { - LOG_I(RRC, "SIB1 decoded\n"); - if( g_log->log_component[RRC].level >= OAILOG_DEBUG ) - xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); - - // FIXME: fix condition for the RA trigger - check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); - if( nr_rrc_get_state(module_id) == RRC_STATE_IDLE_NR ) { - NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE; - get_softmodem_params()->do_ra = 1; - } - - nr_rrc_ue_generate_ra_msg(module_id,gNB_index); - } - else - LOG_E(PHY, "sib1 is starting by 8 times 0\n"); - } - - return 0; -} - - // from NR SRB3 int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message( const module_id_t module_id, @@ -2672,7 +2472,7 @@ void *rrc_nrue_task( void *args_p ) { NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); // PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); - nr_decode_BCCH_DLSCH_Message (&ctxt, + nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index, NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu, NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size, diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 0731c82467..9b051be71a 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -86,12 +86,14 @@ int8_t nr_rrc_ue_process_radio_bearer_config(NR_RadioBearerConfig_t *radio_beare \param sdu_len length of buffer*/ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len); -/**\brief decode NR SIB1 message +/**\brief decode NR BCCH-DLSCH (SI) messages \param module_idP module id \param gNB_index gNB index - \param sduP pointer to buffer of ASN message - \param sdu_len length of buffer*/ -int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len); + \param sduP pointer to buffer of ASN message BCCH-DLSCH + \param sdu_len length of buffer + \param rsrq RSRQ + \param rsrp RSRP*/ +int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len, const uint8_t rsrq, const uint8_t rsrp); /**\brief Decode NR DCCH from gNB, sent from lower layer through SRB3 \param module_id module id From f59a9360f57f2c71ed19cf1513c896070326d2cb Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 10 Feb 2021 13:43:35 +0100 Subject: [PATCH 41/91] Apply 2 suggestion(s) to 1 file(s) --- ci-scripts/runTestOnVM.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 4fc740235e..f818685049 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -2215,7 +2215,8 @@ function run_test_on_vm { local try_cnt=0 NR_STATUS=0 - while [ $try_cnt -lt 1 ] + while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI + do SYNC_STATUS=0 RA_STATUS=0 @@ -2295,7 +2296,7 @@ function run_test_on_vm { fi try_cnt=0 - while [ $try_cnt -lt 1 ] + while [ $try_cnt -lt 4 ] do rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log From f4b3a869a6e6576e763c5fa2dabfde6a966dbd47 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Wed, 10 Feb 2021 13:07:04 +0000 Subject: [PATCH 42/91] minor fix at SIB1 decoding --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- openair2/RRC/NR_UE/rrc_UE.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f02daf9c30..01a59b4d8d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -160,7 +160,7 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len) { - LOG_D(MAC, "Decode sib1\n"); + LOG_D(MAC, "Decoding NR-BCCH-DL-SCH-Message\n"); nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); return 0; } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 979b9b9d32..d929e7ba68 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1181,13 +1181,14 @@ int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message( if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 0) { NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index]; if(sib1 != NULL){ - SEQUENCE_free(&asn_DEF_NR_BCCH_BCH_Message, (void *)sib1, 1 ); + SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1 ); } sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; if (*(int64_t*)sib1 != 1) { - if( g_log->log_component[RRC].level >= OAILOG_DEBUG ) { - xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); + NR_UE_rrc_inst[module_id].sib1[gNB_index] = sib1; + if( g_log->log_component[NR_RRC].level >= OAILOG_DEBUG ) { + xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) NR_UE_rrc_inst[module_id].sib1[gNB_index]); } LOG_I(NR_RRC, "SIB1 decoded\n"); From 2e0ed038d3471ade1fa58ecb259dafceee0b29ea Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 10 Feb 2021 15:45:40 +0100 Subject: [PATCH 43/91] Using only one threadPool for nr-softmodem --- executables/nr-gnb.c | 24 ++-- executables/nr-ru.c | 104 +++++------------- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 2 +- openair1/PHY/defs_gNB.h | 5 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 +- 5 files changed, 42 insertions(+), 97 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index efc1b31c51..c36db7b1ef 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -870,7 +870,7 @@ void init_gNB_proc(int inst) { pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); sync_phy_proc.phy_proc_CC_id = 0; - gNB->threadPool_ulsch = (tpool_t*)malloc(sizeof(tpool_t)); + gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); int numCPU = sysconf(_SC_NPROCESSORS_ONLN); uint32_t num_threads_pusch; @@ -884,7 +884,7 @@ void init_gNB_proc(int inst) { sprintf(ul_pool+2+s_offset,",-1"); s_offset += 3; } - initTpool(ul_pool, gNB->threadPool_ulsch, false); + initTpool(ul_pool, gNB->threadPool, false); initNotifiedFIFO(gNB->respDecode); } @@ -893,8 +893,7 @@ void init_gNB_Tpool(int inst) { gNB = RC.gNB[inst]; // ULSCH decoding threadpool - gNB->threadPool_ulsch = (tpool_t*)malloc(sizeof(tpool_t)); - gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); int numCPU = sysconf(_SC_NPROCESSORS_ONLN); uint32_t num_threads_pusch; paramdef_t PUSCHThreads[] = NUM_THREADS_DESC; @@ -907,26 +906,21 @@ void init_gNB_Tpool(int inst) { sprintf(ul_pool+2+s_offset,",-1"); s_offset += 3; } - initTpool(ul_pool, gNB->threadPool_ulsch, false); + initTpool(ul_pool, gNB->threadPool, false); + // ULSCH decoder result FIFO + gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); initNotifiedFIFO(gNB->respDecode); - // L1 RX threadpool - gNB->threadPool_L1 = (tpool_t*)malloc(sizeof(tpool_t)); + // L1 RX result FIFO gNB->resp_L1 = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); - initTpool("-1", gNB->threadPool_L1, false); initNotifiedFIFO(gNB->resp_L1); - pushNotifiedFIFO_nothreadSafe(gNB->resp_L1, newNotifiedFIFO_elt(20, 0,NULL,NULL)); - // L1 TX threadpool - gNB->threadPool_L1_tx = (tpool_t*)malloc(sizeof(tpool_t)); + // L1 TX result FIFO gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); - initTpool("-1,-1,-1",gNB->threadPool_L1_tx, false); initNotifiedFIFO(gNB->resp_L1_tx); - // RU TX threadpool - gNB->threadPool_RU_tx = (tpool_t*)malloc(sizeof(tpool_t)); + // RU TX result FIFO gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); - initTpool("-1",gNB->threadPool_RU_tx, false); initNotifiedFIFO(gNB->resp_RU_tx); } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 23454e2d50..dec62469da 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1513,20 +1513,15 @@ void tx_func(void *param) { phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); // start FH TX processing - notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_RU_t),0,gNB->resp_RU_tx,ru_tx_func); - processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(msg); notifiedFIFO_elt_t *res; + res = pullTpool(gNB->resp_RU_tx, gNB->threadPool); + processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res); syncMsg->frame_tx = frame_tx; syncMsg->slot_tx = slot_tx; syncMsg->timestamp_tx = info->timestamp_tx; syncMsg->ru = gNB->RU_list[0]; - - res = tryPullTpool(gNB->resp_RU_tx, gNB->threadPool_RU_tx); - if (res == NULL) { - LOG_W(PHY,"RU TX of previous slot is still being processed. Adding current slot to queue (%d.%d)\n", frame_tx, slot_tx); - } - msg->key = slot_tx; - pushTpool(gNB->threadPool_RU_tx, msg); + res->key = slot_tx; + pushTpool(gNB->threadPool, res); } void rx_func(void *param) { @@ -1634,23 +1629,19 @@ void rx_func(void *param) { //stop_meas( &softmodem_stats_rxtx_sf ); LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); - notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1_tx,tx_func); - processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(msg); notifiedFIFO_elt_t *res; - syncMsg->gNB = gNB; - syncMsg->frame_rx = frame_rx; - syncMsg->slot_rx = slot_rx; - syncMsg->frame_tx = frame_tx; - syncMsg->slot_tx = slot_tx; - syncMsg->timestamp_tx = info->timestamp_tx; if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { - res = tryPullTpool(gNB->resp_L1_tx, gNB->threadPool_L1_tx); - if (res == NULL) { - LOG_W(PHY,"L1 TX of previous slot is still being processed. Adding current slot to queue (%d.%d)\n", frame_tx, slot_tx); - } - msg->key = slot_tx; - pushTpool(gNB->threadPool_L1_tx, msg); + res = pullTpool(gNB->resp_L1_tx, gNB->threadPool); + processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res); + syncMsg->gNB = gNB; + syncMsg->frame_rx = frame_rx; + syncMsg->slot_rx = slot_rx; + syncMsg->frame_tx = frame_tx; + syncMsg->slot_tx = slot_tx; + syncMsg->timestamp_tx = info->timestamp_tx; + res->key = slot_tx; + pushTpool(gNB->threadPool, res); } #if 0 @@ -1703,9 +1694,7 @@ void *ru_thread( void *param ) { int ret; int slot = fp->slots_per_frame-1; int frame = 1023; - char filename[40], threadname[40]; - int print_frame = 8; - int i = 0; + char threadname[40]; int aa; nfapi_nr_config_request_scf_t *cfg = &ru->config; @@ -1766,8 +1755,13 @@ void *ru_thread( void *param ) { wait_sync("ru_thread"); notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1,rx_func); - processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(msg); + notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1_tx,tx_func); + notifiedFIFO_elt_t *msgRUTx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_RU_tx,ru_tx_func); + processingData_L1_t *syncMsg; notifiedFIFO_elt_t *res; + pushNotifiedFIFO(gNB->resp_L1,msg); // to unblock the process in the beginning + pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning + pushNotifiedFIFO(gNB->resp_RU_tx,msgRUTx); // to unblock the process in the beginning if(!emulate_rf) { // Start RF device if any @@ -1902,61 +1896,17 @@ void *ru_thread( void *param ) { } // At this point, all information for subframe has been received on FH interface + res = pullTpool(gNB->resp_L1, gNB->threadPool); + syncMsg = (processingData_L1_t *)NotifiedFifoData(res); syncMsg->gNB = gNB; syncMsg->frame_rx = proc->frame_rx; syncMsg->slot_rx = proc->tti_rx; syncMsg->frame_tx = proc->frame_tx; syncMsg->slot_tx = proc->tti_tx; syncMsg->timestamp_tx = proc->timestamp_tx; + res->key = proc->tti_rx; + pushTpool(gNB->threadPool, res); - // check if previous L1 slot processing is finished - res = pullTpool(gNB->resp_L1, gNB->threadPool_L1); - if (res == NULL) { - LOG_W(PHY,"L1 RX of previous slot is still being processed. Adding current slot to queue (%d.%d)\n", proc->frame_rx, proc->tti_rx); - } - msg->key = proc->tti_rx; - pushTpool(gNB->threadPool_L1, msg); - - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_gNB==0) { - // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); - - // do OFDM with/without TX front-end processing if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); - - if(!emulate_rf) { - // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx); - - if (ru->fh_north_out) ru->fh_north_out(ru); - } else { - if(proc->frame_tx == print_frame) { - for (i=0; inb_tx; i++) { - sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_slot_wCP, 1, 1); - - if(proc->tti_tx == 9) { - sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); - LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); - sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); - FILE *output_fd = fopen(filename,"w"); - - if (output_fd) { - fwrite(&ru->common.txdata[i][0], - sizeof(int32_t), - fp->samples_per_frame, - output_fd); - fclose(output_fd); - } else { - LOG_E(PHY,"Cannot write to file %s\n",filename); - } - }//if(proc->tti_tx == 9) - }//for (i=0; inb_tx; i++) - }//if(proc->frame_tx == print_frame) - }//else emulate_rf - - proc->emulate_rf_busy = 0; - }//if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) } printf( "Exiting ru_thread \n"); @@ -1967,6 +1917,10 @@ void *ru_thread( void *param ) { else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); } + delNotifiedFIFO_elt(msg); + delNotifiedFIFO_elt(msgL1Tx); + delNotifiedFIFO_elt(msgRUTx); + ru_thread_status = 0; return &ru_thread_status; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index b9cf21c04c..d990176d79 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -640,7 +640,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, rdata->offset = offset; rdata->ulsch = ulsch; rdata->ulsch_id = UE_id; - pushTpool(phy_vars_gNB->threadPool_ulsch,req); + pushTpool(phy_vars_gNB->threadPool,req); phy_vars_gNB->nbDecode++; LOG_D(PHY,"Added a block to decode, in pipe: %d\n",phy_vars_gNB->nbDecode); r_offset += E; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index ed9c992173..440cfc7a69 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -835,10 +835,7 @@ typedef struct PHY_VARS_gNB_s { notifiedFIFO_t *resp_L1; notifiedFIFO_t *resp_L1_tx; notifiedFIFO_t *resp_RU_tx; - tpool_t *threadPool_ulsch; - tpool_t *threadPool_L1; - tpool_t *threadPool_L1_tx; - tpool_t *threadPool_RU_tx; + tpool_t *threadPool; int nbDecode; } PHY_VARS_gNB; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index ea8b0370f9..6b5c1a9b22 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -243,7 +243,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { } else { if ( rdata->nbSegments != ulsch_harq->processedSegments ) { - int nb=abortTpool(gNB->threadPool_ulsch, req->key); + int nb=abortTpool(gNB->threadPool, req->key); nb+=abortNotifiedFIFO(gNB->respDecode, req->key); gNB->nbDecode-=nb; LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb); @@ -353,7 +353,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH G); while (gNB->nbDecode > 0) { - notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool_ulsch); + notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool); nr_postDecode(gNB, req); delNotifiedFIFO_elt(req); } From 79e80983829ef77997135b11aae5d3a8e2b154fd Mon Sep 17 00:00:00 2001 From: rmagueta Date: Wed, 10 Feb 2021 15:15:35 +0000 Subject: [PATCH 44/91] Minor code clean up --- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 6 +++--- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 6 ++---- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 16 +++++++--------- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 917a41c9e6..abc944bc00 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -917,7 +917,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, n_rnti = rel15->rnti; if (crc == n_rnti) { - LOG_I(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", + LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", proc->frame_rx, proc->nr_slot_rx,n_rnti,rel15->dci_format_options[k],CCEind,dci_length,*(unsigned long long*)dci_estimation); dci_ind->SFN = proc->frame_rx; dci_ind->slot = proc->nr_slot_rx; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index b9245640c7..2863405217 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -617,13 +617,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break; - LOG_I(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1); + LOG_I(PHY,"DLSCH: AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1); err_flag = 1; } } if (err_flag == 1) { - LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", + LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); harq_process->harq_ack.ack = 0; @@ -639,7 +639,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if(is_crnti) { - LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 01a59b4d8d..9df4d74bf2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -160,7 +160,7 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len) { - LOG_D(MAC, "Decoding NR-BCCH-DL-SCH-Message\n"); + LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message\n"); nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); return 0; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index f76ef818e8..b113ed54a1 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -891,12 +891,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in if (ra->ra_state == WAIT_RAR){ memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes); - printf("\n"); - LOG_I(MAC,"[RAPROC] Msg3 to be transmitted:\n"); + LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n"); for (int k = 0; k < TBS_bytes; k++) { - LOG_I(MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]); + LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]); } - printf("\n"); } else { if (IS_SOFTMODEM_NOS1){ // Getting IP traffic to be transmitted diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index a46540a705..5cf3a0487c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -334,7 +334,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP; - LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n", gnb_mod_idP, harq_pid, CC_idP, @@ -350,7 +350,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (timing_advance != 0xffff) UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->ul_rssi = rssi; - LOG_D(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); + LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); } else{ UE_scheduling_control->tpc0 = 1; @@ -369,7 +369,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, #endif if (sduP != NULL){ - LOG_D(MAC, "Received PDU at MAC gNB \n"); + LOG_D(NR_MAC, "Received PDU at MAC gNB \n"); nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP); } else { @@ -410,7 +410,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, "uplinkBWP_ToAddModList has %d BWP!\n", ubwpList->list.count); UE_info->UE_sched_ctrl[UE_id].active_ubwp = ubwpList->list.array[bwp_id - 1]; - LOG_I(MAC, + LOG_I(NR_MAC, "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, " "adding UE MAC Context UE_id %d/RNTI %04x\n", gnb_mod_idP, @@ -418,19 +418,17 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, UE_id, ra->rnti); - printf("\n"); - LOG_I(MAC,"[RAPROC] Received Msg3:\n"); + LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n"); for (int k = 0; k < sdu_lenP; k++) { - LOG_I(MAC,"(%i): 0x%x\n",k,sduP[k]); + LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]); } - printf("\n"); // re-initialize ta update variables afrer RA procedure completion UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP; free(ra->preambles.preamble_list); ra->state = RA_IDLE; - LOG_I(MAC, + LOG_I(NR_MAC, "reset RA state information for RA-RNTI %04x/index %d\n", ra->rnti, i); From 7854133bc2f573d574b49c83a52341d2722f13fc Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 10 Feb 2021 22:00:09 +0100 Subject: [PATCH 45/91] Removing some of the old pthreads Leaving ru_thread and L1 stats thread --- executables/nr-gnb.c | 700 +++------------------------------ executables/nr-ru.c | 642 ------------------------------ executables/softmodem-common.h | 4 + openair1/PHY/defs_RU.h | 6 + openair1/PHY/defs_gNB.h | 9 + 5 files changed, 71 insertions(+), 1290 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index c36db7b1ef..a23a8a4a5d 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -81,7 +81,7 @@ #include "s1ap_eNB.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" - +#include #include "T.h" @@ -111,30 +111,15 @@ time_stats_t softmodem_stats_rxtx_sf; // total tx time time_stats_t nfapi_meas; // total tx time time_stats_t softmodem_stats_rx_sf; // total rx time -/* mutex, cond and variable to serialize phy proc TX calls - * (this mechanism may be relaxed in the future for better - * performances) - */ -static struct { - pthread_mutex_t mutex_phy_proc_tx; - pthread_cond_t cond_phy_proc_tx; - volatile uint8_t phy_proc_CC_id; -} sync_phy_proc; - extern double cpuf; void init_gNB(int,int); void stop_gNB(int nb_inst); -int wakeup_txfh(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int frame_tx, int slot_tx, uint64_t timestamp_tx); -int wakeup_tx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, uint64_t timestamp_tx); #include "executables/thread-common.h" //extern PARALLEL_CONF_t get_thread_parallel_conf(void); //extern WORKER_CONF_t get_thread_worker_conf(void); - -void wakeup_prach_gNB(PHY_VARS_gNB *gNB, RU_t *ru, int frame, int subframe); - extern uint8_t nfapi_mode; extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); @@ -142,41 +127,42 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); //#define TICK_TO_US(ts) (ts.diff) #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) -static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { +extern void init_td_thread(PHY_VARS_gNB *); +extern void init_te_thread(PHY_VARS_gNB *); +void tx_func(void *param) { + + processingData_L1_t *info = (processingData_L1_t *) param; + PHY_VARS_gNB *gNB = info->gNB; + int frame_tx = info->frame_tx; + int slot_tx = info->slot_tx; + + phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); + + // start FH TX processing + notifiedFIFO_elt_t *res; + res = pullTpool(gNB->resp_RU_tx, gNB->threadPool); + processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res); + syncMsg->frame_tx = frame_tx; + syncMsg->slot_tx = slot_tx; + syncMsg->timestamp_tx = info->timestamp_tx; + syncMsg->ru = gNB->RU_list[0]; + res->key = slot_tx; + pushTpool(gNB->threadPool, res); +} + +void rx_func(void *param) { + + processingData_L1_t *info = (processingData_L1_t *) param; + PHY_VARS_gNB *gNB = info->gNB; + int frame_rx = info->frame_rx; + int slot_rx = info->slot_rx; + int frame_tx = info->frame_tx; + int slot_tx = info->slot_tx; sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - start_meas(&softmodem_stats_rxtx_sf); - - // ******************************************************************* - // NFAPI not yet supported for NR - this code has to be revised - if (nfapi_mode == 1) { - // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick - //add_subframe(&frame, &subframe, 4); - //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); - //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe); - start_meas(&nfapi_meas); - oai_subframe_ind(frame_rx, slot_rx); - stop_meas(&nfapi_meas); - - /*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| - gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs || - gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs || - gNB->UL_INFO.rach_ind.number_of_pdus || - gNB->UL_INFO.cqi_ind.number_of_cqis - ) { - LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d rach_pdus:%0d.%d:%d cqis:%d] RX:%04d%d TX:%04d%d \n", - NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, - NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, - NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, - gNB->UL_INFO.rach_ind.sfn, gNB->UL_INFO.rach_ind.slot,gNB->UL_INFO.rach_ind.number_of_pdus, - gNB->UL_INFO.cqi_ind.number_of_cqis, - frame_rx, slot_rx, - frame_tx, slot_tx); - }*/ - } - // **************************************** + //start_meas(&softmodem_stats_rxtx_sf); T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx)); @@ -233,12 +219,6 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t rnti_to_remove_count = 0; if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1); - /* - // if this is IF5 or 3GPP_gNB - if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) { - wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx); - } - */ // Call the scheduler pthread_mutex_lock(&gNB->UL_INFO_mutex); @@ -273,21 +253,24 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t if (oai_exit) return(-1); - // ***************************************** - // TX processing for subframe n+sf_ahead - // run PHY TX procedures the one after the other for all CCs to avoid race conditions - // (may be relaxed in the future for performance reasons) - // ***************************************** + //stop_meas( &softmodem_stats_rxtx_sf ); + LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); + + notifiedFIFO_elt_t *res; if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { - - if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) { - phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); - } + res = pullTpool(gNB->resp_L1_tx, gNB->threadPool); + processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res); + syncMsg->gNB = gNB; + syncMsg->frame_rx = frame_rx; + syncMsg->slot_rx = slot_rx; + syncMsg->frame_tx = frame_tx; + syncMsg->slot_tx = slot_tx; + syncMsg->timestamp_tx = info->timestamp_tx; + res->key = slot_tx; + pushTpool(gNB->threadPool, res); } - - stop_meas( &softmodem_stats_rxtx_sf ); - LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); + #if 0 LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now, @@ -327,466 +310,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t TICK_TO_US(gNB->ulsch_tc_intl2_stats) ); #endif - return(0); } - -static void *gNB_L1_thread_tx(void *param) { - PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; - gNB_L1_proc_t *gNB_proc = &gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB_proc->L1_proc_tx; - //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; - char thread_name[100]; - - sprintf(thread_name,"gNB_L1_thread_tx\n"); - - while (!oai_exit) { - if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 ); - - if (oai_exit) break; - - // ***************************************** - // TX processing for subframe n+4 - // run PHY TX procedures the one after the other for all CCs to avoid race conditions - // (may be relaxed in the future for performance reasons) - // ***************************************** - int frame_tx = L1_proc_tx->frame_tx; - int slot_tx = L1_proc_tx->slot_tx; - uint64_t timestamp_tx = L1_proc_tx->timestamp_tx; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx); - phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 1 ); - pthread_mutex_lock( &L1_proc_tx->mutex ); - L1_proc_tx->instance_cnt = -1; - - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc_tx->cond) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - } - pthread_mutex_unlock(&L1_proc_tx->mutex); - - wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 0 ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); - } - - return 0; -} - -/*! - * \brief The RX UE-specific and TX thread of gNB. - * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ - -static void *gNB_L1_thread( void *param ) { - static int gNB_thread_rxtx_status; - PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; - gNB_L1_proc_t *gNB_proc = &gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc; - //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; - char thread_name[100]; - // set default return value - // set default return value - gNB_thread_rxtx_status = 0; - - sprintf(thread_name,"gNB_L1_thread"); - - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 ); - if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_proc->instance_cnt,thread_name)<0) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 ); - - int frame_rx = L1_proc->frame_rx; - int slot_rx = L1_proc->slot_rx; - int frame_tx = L1_proc->frame_tx; - int slot_tx = L1_proc->slot_tx; - uint64_t timestamp_tx = L1_proc->timestamp_tx; - - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,frame_rx); - - if (oai_exit) break; - - if (gNB->CC_id==0) { - if (rxtx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,thread_name) < 0) break; - } - - if (release_thread(&L1_proc->mutex,&L1_proc->instance_cnt,thread_name)<0) break; - - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,timestamp_tx); - else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(gNB,L1_proc,frame_tx,slot_tx,timestamp_tx); - } // while !oai_exit - - LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n"); - gNB_thread_rxtx_status = 0; - return &gNB_thread_rxtx_status; -} - - -#if 0 -// Wait for gNB application initialization to be complete (gNB registration to MME) -static void wait_system_ready (char *message, volatile int *start_flag) { - static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....", - " ....", " ...", " ..", " .", " " - }; - int i = 0; - - while ((!oai_exit) && (*start_flag == 0)) { - LOG_N(EMU, message, indicator[i]); - fflush(stdout); - i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0])); - usleep(200000); - } - - LOG_D(EMU,"\n"); -} -#endif - - - - - -void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru) { - gNB_L1_proc_t *proc = &gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *ru_proc=&ru->proc; - proc->frame_rx = frame_rx; - proc->slot_rx = slot_rx; - sl_ahead = sf_ahead*fp->slots_per_subframe; - - if (!oai_exit) { - T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx)); - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); - L1_proc->frame_rx = ru_proc->frame_rx; - L1_proc->slot_rx = ru_proc->tti_rx; - L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; - L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; - - if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id); - - ru_proc->timestamp_tx = L1_proc->timestamp_tx; - ru_proc->tti_tx = L1_proc->slot_tx; - ru_proc->frame_tx = L1_proc->frame_tx; - } -} - -int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) { - - RU_t *ru; - RU_proc_t *ru_proc; - - int waitret = 0, ret = 0, time_ns = 1000*1000; - struct timespec now, abstime; - // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time - // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); - time_ns = time_ns/gNB->frame_parms.slots_per_subframe; - AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); - while (proc->instance_cnt_RUs < 0) { - clock_gettime(CLOCK_REALTIME, &now); - abstime.tv_sec = now.tv_sec; - abstime.tv_nsec = now.tv_nsec + time_ns; - - if (abstime.tv_nsec >= 1000*1000*1000) { - abstime.tv_nsec -= 1000*1000*1000; - abstime.tv_sec += 1; - } - if((waitret = pthread_cond_timedwait(&proc->cond_RUs,&proc->mutex_RUs_tx,&abstime)) == 0) break; // this unlocks mutex_rxtx while waiting and then locks it again - } - proc->instance_cnt_RUs = -1; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); - AssertFatal((ret = pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); - - if (waitret == ETIMEDOUT) { - LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx); - - AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); - gNB->proc.RU_mask_tx = 0; - AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); - AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); - proc->instance_cnt_RUs = 0; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); - AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0); - - return(-1); - } - - for(int i=0; inum_RU; i++) - { - ru = gNB->RU_list[i]; - ru_proc = &ru->proc; - - - if (ru_proc->instance_cnt_gNBs == 0) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1); - LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx); - AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); - gNB->proc.RU_mask_tx = 0; - AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0); - return(-1); - } - AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); - - ru_proc->instance_cnt_gNBs = 0; - ru_proc->timestamp_tx = timestamp_tx; - ru_proc->tti_tx = slot_tx; - ru_proc->frame_tx = frame_tx; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs); - - LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx); - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&ru_proc->cond_gNBs) == 0, - "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); - AssertFatal((ret=pthread_mutex_unlock(&ru_proc->mutex_gNBs))==0,"mutex_unlock returned %d\n",ret); - - } - return(0); -} - -int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) { - - - gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx; - - int ret; - - - AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret); - - - while(L1_proc_tx->instance_cnt == 0) { - pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex); - } - - L1_proc_tx->instance_cnt = 0; - - - L1_proc_tx->slot_rx = slot_rx; - L1_proc_tx->frame_rx = frame_rx; - L1_proc_tx->slot_tx = slot_tx; - L1_proc_tx->frame_tx = frame_tx; - L1_proc_tx->timestamp_tx = timestamp_tx; - - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0); - // the thread can now be woken up - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n"); - - AssertFatal((ret=pthread_mutex_unlock(&L1_proc_tx->mutex))==0,"mutex_unlock returns %d\n",ret); - - return(0); -} - -int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { - gNB_L1_proc_t *proc=&gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc; - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - RU_proc_t *ru_proc=&ru->proc; - int ret; - int i; - struct timespec abstime; - int time_ns = 50000; - int wait_timer = 0; - bool do_last_check = 1; - - AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret); - for (i=0; inum_RU; i++) { - if (ru == gNB->RU_list[i]) { - if ((proc->RU_mask&(1< 0) - LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", - gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask); - proc->RU_mask |= (1<RU_mask != (1<num_RU)-1) { // not all RUs have provided their information so return - LOG_E(PHY,"Not all RUs have provided their info\n"); - AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"mutex_unlock returns %d\n",ret); - return(0); - } - else { // all RUs have provided their information so continue on and wakeup gNB processing - proc->RU_mask = 0; - AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret); - } - - // wake up TX for subframe n+sf_ahead - // lock the TX mutex and make sure the thread is ready - while (wait_timer < 200) { - clock_gettime(CLOCK_REALTIME, &abstime); - abstime.tv_nsec = abstime.tv_nsec + time_ns; - - if (abstime.tv_nsec >= 1000*1000*1000) { - abstime.tv_nsec -= 1000*1000*1000; - abstime.tv_sec += 1; - } - - AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret); - - if (L1_proc->instance_cnt == 0) { // L1_thread is busy so wait for a bit - AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret); - wait_timer += 50; - usleep(50); - } - else { - do_last_check = 0; - break; - } - } - if (do_last_check) { - AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret); - if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe - AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret); - LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx); - return (-1); - } - } - - ++L1_proc->instance_cnt; - // We have just received and processed the common part of a subframe, say n. - // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired - // transmitted timestamp of the next TX slot (first). - - // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, - // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, - // and proc->slot_tx = proc->slot_rx+sf_ahead - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); - L1_proc->frame_rx = ru_proc->frame_rx; - L1_proc->slot_rx = ru_proc->tti_rx; - L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; - L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; - - LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sf_ahead); - - pthread_mutex_unlock( &L1_proc->mutex ); - - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc->cond) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - - return(0); -} -/* -void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) { - - gNB_L1_proc_t *proc = &gNB->proc; - LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms; - int i; - - if (ru!=NULL) { - pthread_mutex_lock(&proc->mutex_RU_PRACH); - for (i=0;inum_RU;i++) { - if (ru == gNB->RU_list[i]) { - LOG_D(PHY,"frame %d, subframe %d: RU %d for gNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,gNB->Mod_id,proc->RU_mask_prach,gNB->num_RU); - if ((proc->RU_mask_prach&(1< 0) - LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n", - gNB->Mod_id,frame,subframe,ru->idx,gNB->num_RU,proc->RU_mask_prach); - proc->RU_mask_prach |= (1<RU_mask_prach != (1<num_RU)-1) { // not all RUs have provided their information so return - pthread_mutex_unlock(&proc->mutex_RU_PRACH); - return; - } - else { // all RUs have provided their information so continue on and wakeup gNB processing - proc->RU_mask_prach = 0; - pthread_mutex_unlock(&proc->mutex_RU_PRACH); - } - } - - // check if we have to detect PRACH first - if (is_prach_subframe(fp,frame,subframe)>0) { - LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe); - if (proc->instance_cnt_prach == 0) { - LOG_W(PHY,"[gNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe); - return; - } - - // wake up thread for PRACH RX - if (pthread_mutex_lock(&proc->mutex_prach) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach); - exit_fun( "error locking mutex_prach" ); - return; - } - - ++proc->instance_cnt_prach; - // set timing for prach thread - proc->frame_prach = frame; - proc->subframe_prach = subframe; - - // the thread can now be woken up - if (pthread_cond_signal(&proc->cond_prach) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB PRACH thread %d\n", proc->thread_index); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } - - pthread_mutex_unlock( &proc->mutex_prach ); - } - -}*/ - -/*! - * \brief The prach receive thread of gNB. - * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -/* -static void* gNB_thread_prach( void* param ) { - static int gNB_thread_prach_status; - - - PHY_VARS_gNB *gNB= (PHY_VARS_gNB *)param; - gNB_L1_proc_t *proc = &gNB->proc; - - // set default return value - gNB_thread_prach_status = 0; - - - - while (!oai_exit) { - - if (oai_exit) break; - - - if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break; - - LOG_D(PHY,"Running gNB prach procedures\n"); - prach_procedures(gNB ,0); - - if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break; - } - - LOG_I(PHY, "Exiting gNB thread PRACH\n"); - - gNB_thread_prach_status = 0; - return &gNB_thread_prach_status; -} -*/ - -extern void init_td_thread(PHY_VARS_gNB *); -extern void init_te_thread(PHY_VARS_gNB *); - static void *process_stats_thread(void *param) { PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; @@ -807,90 +331,10 @@ static void *process_stats_thread(void *param) { return(NULL); } - -void init_gNB_proc(int inst) { - int i=0; - int CC_id = 0; - PHY_VARS_gNB *gNB; - gNB_L1_proc_t *proc; - gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx; -// LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]); - gNB = RC.gNB[inst]; - LOG_I(PHY,"Initializing gNB processes instance:%d CC_id %d \n",inst,CC_id); - - proc = &gNB->proc; - L1_proc = &proc->L1_proc; - L1_proc_tx = &proc->L1_proc_tx; - L1_proc->instance_cnt = -1; - L1_proc_tx->instance_cnt = -1; - L1_proc->instance_cnt_RUs = 0; - L1_proc_tx->instance_cnt_RUs = 0; - proc->instance_cnt_prach = -1; - proc->instance_cnt_asynch_rxtx = -1; - proc->CC_id = CC_id; - proc->first_rx =1; - proc->first_tx =1; - proc->RU_mask =0; - proc->RU_mask_tx = (1<num_RU)-1; - proc->RU_mask_prach =0; - pthread_mutex_init( &gNB->UL_INFO_mutex, NULL); - pthread_mutex_init( &L1_proc->mutex, NULL); - pthread_mutex_init( &L1_proc_tx->mutex, NULL); - pthread_cond_init( &L1_proc->cond, NULL); - pthread_cond_init( &L1_proc_tx->cond, NULL); - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); - pthread_mutex_init( &proc->mutex_RU,NULL); - pthread_mutex_init( &proc->mutex_RU_tx,NULL); - pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_asynch_rxtx, NULL); - LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag); - - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - threadCreate( &L1_proc->pthread, gNB_L1_thread, gNB, "L1_proc", -1, OAI_PRIORITY_RT ); - threadCreate( &L1_proc_tx->pthread, gNB_L1_thread_tx, gNB,"L1_proc_tx", -1, OAI_PRIORITY_RT); - } - - if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW); - //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB ); - char name[16]; - - if (gNB->single_thread_flag==0) { - snprintf( name, sizeof(name), "L1 %d", i ); - pthread_setname_np( L1_proc->pthread, name ); - snprintf( name, sizeof(name), "L1TX %d", i ); - pthread_setname_np( L1_proc_tx->pthread, name ); - } - - AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); - - /* setup PHY proc TX sync mechanism */ - pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); - pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); - sync_phy_proc.phy_proc_CC_id = 0; - - gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); - gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); - int numCPU = sysconf(_SC_NPROCESSORS_ONLN); - uint32_t num_threads_pusch; - paramdef_t PUSCHThreads[] = NUM_THREADS_DESC; - config_get( PUSCHThreads,sizeof(PUSCHThreads)/sizeof(paramdef_t),NULL); - int threadCnt = min(numCPU, num_threads_pusch); - char ul_pool[80]; - sprintf(ul_pool,"-1"); - int s_offset = 0; - for (int icpu=1; icputhreadPool, false); - initNotifiedFIFO(gNB->respDecode); -} - void init_gNB_Tpool(int inst) { PHY_VARS_gNB *gNB; gNB = RC.gNB[inst]; + gNB_L1_proc_t *proc = &gNB->proc; // ULSCH decoding threadpool gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); @@ -922,6 +366,9 @@ void init_gNB_Tpool(int inst) { // RU TX result FIFO gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); initNotifiedFIFO(gNB->resp_RU_tx); + + // Stats measurement thread + if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW); } @@ -929,56 +376,13 @@ void init_gNB_Tpool(int inst) { * \brief Terminate gNB TX and RX threads. */ void kill_gNB_proc(int inst) { - int *status; PHY_VARS_gNB *gNB; - gNB_L1_proc_t *proc; - gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx; gNB=RC.gNB[inst]; - proc = &gNB->proc; - L1_proc = &proc->L1_proc; - L1_proc_tx = &proc->L1_proc_tx; - LOG_I(PHY, "Killing TX inst %d\n",inst ); - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - pthread_mutex_lock(&L1_proc->mutex); - L1_proc->instance_cnt = 0; - pthread_cond_signal(&L1_proc->cond); - pthread_mutex_unlock(&L1_proc->mutex); - pthread_mutex_lock(&L1_proc_tx->mutex); - L1_proc_tx->instance_cnt = 0; - pthread_cond_signal(&L1_proc_tx->cond); - pthread_mutex_unlock(&L1_proc_tx->mutex); - } - - proc->instance_cnt_prach = 0; - pthread_cond_signal( &proc->cond_prach ); - pthread_cond_signal( &proc->cond_asynch_rxtx ); - pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); - // LOG_D(PHY, "joining pthread_prach\n"); - // pthread_join( proc->pthread_prach, (void**)&status ); - LOG_I(PHY, "Destroying prach mutex/cond\n"); - pthread_mutex_destroy( &proc->mutex_prach ); - pthread_cond_destroy( &proc->cond_prach ); LOG_I(PHY, "Destroying UL_INFO mutex\n"); pthread_mutex_destroy(&gNB->UL_INFO_mutex); - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - LOG_I(PHY, "Joining L1_proc mutex/cond\n"); - pthread_join( L1_proc->pthread, (void **)&status ); - LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n"); - pthread_join( L1_proc_tx->pthread, (void **)&status ); - } - - LOG_I(PHY, "Destroying L1_proc mutex/cond\n"); - pthread_mutex_destroy( &L1_proc->mutex ); - pthread_cond_destroy( &L1_proc->cond ); - LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n"); - pthread_mutex_destroy( &L1_proc_tx->mutex ); - pthread_cond_destroy( &L1_proc_tx->cond ); - pthread_mutex_destroy( &proc->mutex_RU ); - pthread_mutex_destroy( &proc->mutex_RU_tx ); - } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index dec62469da..9fd83bab76 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -120,22 +120,6 @@ extern int emulate_rf; extern int numerology; extern int usrp_tx_thread; -typedef struct processingData_L1 { - int frame_rx; - int frame_tx; - int slot_rx; - int slot_tx; - openair0_timestamp timestamp_tx; - PHY_VARS_gNB *gNB; -} processingData_L1_t; - -typedef struct processingData_RU { - int frame_tx; - int slot_tx; - openair0_timestamp timestamp_tx; - RU_t *ru; -} processingData_RU_t; - /*************************************************************/ /* Functions to attach and configure RRU */ @@ -805,101 +789,6 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { -/*! - * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU. - * This handles the RX FH for an asynchronous RRU/UE - * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -void *ru_thread_asynch_rxtx( void *param ) { - static int ru_thread_asynch_rxtx_status; - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; - nfapi_nr_config_request_scf_t *cfg = &ru->config; - int slot=0, frame=0; - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe - wait_sync("ru_thread_asynch_rxtx"); - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe - printf( "waiting for devices (ru_thread_asynch_rx)\n"); - wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch"); - printf( "devices ok (ru_thread_asynch_rx)\n"); - - while (!oai_exit) { - - if (slot==ru->nr_frame_parms->slots_per_frame) { - slot=0; - frame++; - frame&=1023; - } else { - slot++; - } - - LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n"); - - // asynchronous receive from north (RRU IF4/IF5) - if (ru->fh_north_asynch_in) { - if ((nr_slot_select(cfg,frame,slot) & NR_DOWNLINK_SLOT)>0) - ru->fh_north_asynch_in(ru,&frame,&slot); - } else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n"); - } - - ru_thread_asynch_rxtx_status=0; - return(&ru_thread_asynch_rxtx_status); -} - - - - -/*! - * \brief The prach receive thread of RU. - * \param param is a \ref RU_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -void *ru_thread_prach( void *param ) { - static int ru_thread_prach_status; - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = (RU_proc_t *)&ru->proc; - // set default return value - ru_thread_prach_status = 0; - - while (RC.ru_mask>0) { - usleep(1e6); - LOG_I(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__); - } - - LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__); - - while (!oai_exit) { - - - if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; - - /*VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); - - if (ru->gNB_list[0]){ - prach_procedures( - ru->gNB_list[0],0 - ); - } - else { - rx_prach(NULL, - ru, - NULL, - NULL, - NULL, - proc->frame_prach, - 0,0 - ); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/ - if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; - } - - LOG_I(PHY, "Exiting RU thread PRACH\n"); - ru_thread_prach_status = 0; - return &ru_thread_prach_status; -} - int wakeup_synch(RU_t *ru) { struct timespec wait; @@ -999,63 +888,6 @@ void do_ru_synch(RU_t *ru) { ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); } - - -void wakeup_gNB_L1s(RU_t *ru) { - int i; - PHY_VARS_gNB **gNB_list = ru->gNB_list; - LOG_D(PHY,"wakeup_gNB_L1s (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top); - - if (ru->num_gNB==1 && ru->gNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { - // call gNB function directly - char string[20]; - sprintf(string,"Incoming RU %u",ru->idx); - LOG_D(PHY,"RU %d Call gNB_top\n",ru->idx); - ru->gNB_top(gNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string,ru); - } else { - LOG_D(PHY,"ru->num_gNB:%d\n", ru->num_gNB); - - for (i=0; inum_gNB; i++) { - LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->nr_wakeup_rxtx); - - if (ru->nr_wakeup_rxtx!=0 && ru->nr_wakeup_rxtx(gNB_list[i],ru) < 0) { - LOG_E(PHY,"could not wakeup gNB rxtx process for subframe %d\n", ru->proc.tti_rx); - } - } - } -} - -int wakeup_prach_ru(RU_t *ru) { - struct timespec wait; - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - if (pthread_mutex_timedlock(&ru->proc.mutex_prach,&wait) !=0) { - LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU prach thread (IC %d)\n", ru->proc.instance_cnt_prach); - exit_fun( "error locking mutex_rxtx" ); - return(-1); - } - - if (ru->proc.instance_cnt_prach==-1) { - ++ru->proc.instance_cnt_prach; - ru->proc.frame_prach = ru->proc.frame_rx; - ru->proc.subframe_prach = ru->proc.tti_rx; - - // DJP - think prach_procedures() is looking at gNB frame_prach - if (ru->gNB_list[0]) { - ru->gNB_list[0]->proc.frame_prach = ru->proc.frame_rx; - ru->gNB_list[0]->proc.slot_prach = ru->proc.tti_rx; - } - - LOG_I(PHY,"RU %d: waking up PRACH thread\n",ru->idx); - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n"); - } else LOG_W(PHY,"RU prach thread busy, skipping\n"); - - pthread_mutex_unlock( &ru->proc.mutex_prach ); - return(0); -} - // this is for RU with local RF unit void fill_rf_config(RU_t *ru, char *rf_config_file) { int i; @@ -1371,320 +1203,6 @@ void ru_tx_func(void *param) { }//else emulate_rf } -void *ru_thread_tx( void *param ) { - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - PHY_VARS_gNB *gNB; - gNB_L1_proc_t *gNB_proc; - gNB_L1_rxtx_proc_t *L1_proc; - char filename[40]; - int print_frame = 8; - int i = 0; - int ret; - - - wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); - printf( "ru_thread_tx ready\n"); - - while (!oai_exit) { - - LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); - // wait until eNBs are finished subframe RX n and TX n+4 - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 1 ); - wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 0 ); - - ret = pthread_mutex_lock(&proc->mutex_gNBs); - AssertFatal(ret == 0,"mutex_lock return %d\n",ret); - int frame_tx=proc->frame_tx; - int tti_tx =proc->tti_tx; - uint64_t timestamp_tx = proc->timestamp_tx; - - ret = pthread_mutex_unlock(&proc->mutex_gNBs); - AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); - - if (oai_exit) break; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx ); - - // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx); - - // do OFDM with/without TX front-end processing if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx); - - if(!emulate_rf) { - // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx); - - if (ru->fh_north_out) ru->fh_north_out(ru); - } else { - if(proc->frame_tx == print_frame) { - for (i=0; inb_tx; i++) { - - if(proc->tti_tx == 0) { - sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); - - sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); - - sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); - } - - if(proc->tti_tx == 9) { - sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); - LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); - sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); - FILE *output_fd = fopen(filename,"w"); - - if (output_fd) { - fwrite(&ru->common.txdata[i][0], - sizeof(int32_t), - fp->samples_per_frame, - output_fd); - fclose(output_fd); - } else { - LOG_E(PHY,"Cannot write to file %s\n",filename); - } - }//if(proc->tti_tx == 9) - }//for (i=0; inb_tx; i++) - }//if(proc->frame_tx == print_frame) - }//else emulate_rf - - release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, proc->instance_cnt_gNBs); - - for(i = 0; inum_gNB; i++) { - gNB = ru->gNB_list[i]; - gNB_proc = &gNB->proc; - L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc; - ret = pthread_mutex_lock(&gNB_proc->mutex_RU_tx); - AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); - - for (int j=0; jnum_RU; j++) { - if (ru == gNB->RU_list[j]) { - if ((gNB_proc->RU_mask_tx&(1< 0) - LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", - gNB->Mod_id,gNB_proc->frame_rx,gNB_proc->slot_rx,ru->idx,gNB->num_RU,gNB_proc->RU_mask_tx); - - gNB_proc->RU_mask_tx |= (1<RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return - ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); - AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); - } else { // all RUs TX are finished so send the ready signal to gNB processing - gNB_proc->RU_mask_tx = 0; - ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); - AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); - - ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx); - AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); - // the thread can now be woken up - if (L1_proc->instance_cnt_RUs == -1) { - L1_proc->instance_cnt_RUs = 0; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); - AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, - "ERROR pthread_cond_signal for gNB_L1_thread\n"); - } //else AssertFatal(1==0,"gNB TX thread is not ready\n"); - ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx); - AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); - } - } - } - - release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); - return 0; -} - -void tx_func(void *param) { - - processingData_L1_t *info = (processingData_L1_t *) param; - PHY_VARS_gNB *gNB = info->gNB; - int frame_tx = info->frame_tx; - int slot_tx = info->slot_tx; - - phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); - - // start FH TX processing - notifiedFIFO_elt_t *res; - res = pullTpool(gNB->resp_RU_tx, gNB->threadPool); - processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res); - syncMsg->frame_tx = frame_tx; - syncMsg->slot_tx = slot_tx; - syncMsg->timestamp_tx = info->timestamp_tx; - syncMsg->ru = gNB->RU_list[0]; - res->key = slot_tx; - pushTpool(gNB->threadPool, res); -} - -void rx_func(void *param) { - - processingData_L1_t *info = (processingData_L1_t *) param; - PHY_VARS_gNB *gNB = info->gNB; - int frame_rx = info->frame_rx; - int slot_rx = info->slot_rx; - int frame_tx = info->frame_tx; - int slot_tx = info->slot_tx; - sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe; - nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - - //start_meas(&softmodem_stats_rxtx_sf); - - T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx)); - - /* hack to remove UEs */ - extern int rnti_to_remove[10]; - extern volatile int rnti_to_remove_count; - extern pthread_mutex_t rnti_to_remove_mutex; - if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1); - int up_removed = 0; - int down_removed = 0; - int pucch_removed = 0; - for (int i = 0; i < rnti_to_remove_count; i++) { - LOG_W(PHY, "to remove rnti %d\n", rnti_to_remove[i]); - void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); - void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); - int j; - for (j = 0; j < NUMBER_OF_NR_ULSCH_MAX; j++) - if (gNB->ulsch[j][0]->rnti == rnti_to_remove[i]) { - gNB->ulsch[j][0]->rnti = 0; - gNB->ulsch[j][0]->harq_mask = 0; - //clean_gNB_ulsch(gNB->ulsch[j][0]); - int h; - for (h = 0; h < NR_MAX_ULSCH_HARQ_PROCESSES; h++) { - gNB->ulsch[j][0]->harq_processes[h]->status = SCH_IDLE; - gNB->ulsch[j][0]->harq_processes[h]->round = 0; - gNB->ulsch[j][0]->harq_processes[h]->handled = 0; - } - up_removed++; - } - for (j = 0; j < NUMBER_OF_NR_DLSCH_MAX; j++) - if (gNB->dlsch[j][0]->rnti == rnti_to_remove[i]) { - gNB->dlsch[j][0]->rnti = 0; - gNB->dlsch[j][0]->harq_mask = 0; - //clean_gNB_dlsch(gNB->dlsch[j][0]); - down_removed++; - } - for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++) - if (gNB->pucch[j]->active > 0 && - gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) { - gNB->pucch[j]->active = 0; - gNB->pucch[j]->pucch_pdu.rnti = 0; - pucch_removed++; - } -#if 0 - for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++) - gNB->pdcch_pdu[j].frame = -1; - for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++) - gNB->ul_pdcch_pdu[j].frame = -1; - for (j = 0; j < NUMBER_OF_NR_PRACH_MAX; j++) - gNB->prach_vars.list[j].frame = -1; -#endif - } - if (rnti_to_remove_count) LOG_W(PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed); - rnti_to_remove_count = 0; - if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1); - - // Call the scheduler - - pthread_mutex_lock(&gNB->UL_INFO_mutex); - gNB->UL_INFO.frame = frame_rx; - gNB->UL_INFO.slot = slot_rx; - gNB->UL_INFO.module_id = gNB->Mod_id; - gNB->UL_INFO.CC_id = gNB->CC_id; - gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); - pthread_mutex_unlock(&gNB->UL_INFO_mutex); - - // RX processing - int tx_slot_type = nr_slot_select(cfg,frame_tx,slot_tx); - int rx_slot_type = nr_slot_select(cfg,frame_rx,slot_rx); - - if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { - // UE-specific RX processing for subframe n - // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT - - // Do PRACH RU processing - L1_nr_prach_procedures(gNB,frame_rx,slot_rx); - - //apply the rx signal rotation here - apply_nr_rotation_ul(&gNB->frame_parms, - gNB->common_vars.rxdataF[0], - slot_rx, - 0, - gNB->frame_parms.Ncp==EXTENDED?12:14, - gNB->frame_parms.ofdm_symbol_size); - - phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); - } - - if (oai_exit) return(-1); - - //stop_meas( &softmodem_stats_rxtx_sf ); - LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); - - notifiedFIFO_elt_t *res; - - if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { - res = pullTpool(gNB->resp_L1_tx, gNB->threadPool); - processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res); - syncMsg->gNB = gNB; - syncMsg->frame_rx = frame_rx; - syncMsg->slot_rx = slot_rx; - syncMsg->frame_tx = frame_tx; - syncMsg->slot_tx = slot_tx; - syncMsg->timestamp_tx = info->timestamp_tx; - res->key = slot_tx; - pushTpool(gNB->threadPool, res); - } - -#if 0 - LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", - softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now, - TICK_TO_US(gNB->phy_proc), - TICK_TO_US(gNB->phy_proc_tx), - TICK_TO_US(gNB->phy_proc_rx), - TICK_TO_US(gNB->rx_prach), - TICK_TO_US(gNB->ofdm_mod_stats), - softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now); - LOG_D(PHY, - "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ", - TICK_TO_US(gNB->dlsch_encoding_stats), - TICK_TO_US(gNB->dlsch_modulation_stats), - TICK_TO_US(gNB->dlsch_scrambling_stats), - TICK_TO_US(gNB->dlsch_rate_matching_stats), - TICK_TO_US(gNB->dlsch_turbo_encoding_stats), - TICK_TO_US(gNB->dlsch_interleaving_stats), - TICK_TO_US(gNB->rx_dft_stats)); - LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ", - TICK_TO_US(gNB->ulsch_channel_estimation_stats), - TICK_TO_US(gNB->ulsch_freq_offset_estimation_stats), - TICK_TO_US(gNB->ulsch_decoding_stats), - TICK_TO_US(gNB->ulsch_demodulation_stats), - TICK_TO_US(gNB->ulsch_rate_unmatching_stats)); - LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ", - TICK_TO_US(gNB->ulsch_turbo_decoding_stats), - TICK_TO_US(gNB->ulsch_deinterleaving_stats), - TICK_TO_US(gNB->ulsch_demultiplexing_stats), - TICK_TO_US(gNB->ulsch_llr_stats), - TICK_TO_US(gNB->ulsch_tc_init_stats)); - LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n", - TICK_TO_US(gNB->ulsch_tc_alpha_stats), - TICK_TO_US(gNB->ulsch_tc_beta_stats), - TICK_TO_US(gNB->ulsch_tc_gamma_stats), - TICK_TO_US(gNB->ulsch_tc_ext_stats), - TICK_TO_US(gNB->ulsch_tc_intl1_stats), - TICK_TO_US(gNB->ulsch_tc_intl2_stats) - ); -#endif -} - void *ru_thread( void *param ) { static int ru_thread_status; RU_t *ru = (RU_t *)param; @@ -1771,16 +1289,6 @@ void *ru_thread( void *param ) { else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); } else LOG_I(PHY,"RU %d no rf device\n",ru->idx); - // if an asnych_rxtx thread exists - // wakeup the thread because the devices are ready at this point - - if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) { - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->instance_cnt_asynch_rxtx=0; - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - pthread_cond_signal(&proc->cond_asynch_rxtx); - } else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx); - // if this is a slave RRU, try to synchronize on the DL frequency if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); @@ -1797,11 +1305,6 @@ void *ru_thread( void *param ) { } } - pthread_mutex_lock(&proc->mutex_FH1); - proc->instance_cnt_FH1 = 0; - pthread_mutex_unlock(&proc->mutex_FH1); - pthread_cond_signal(&proc->cond_FH1); - // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (!oai_exit) { // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. @@ -1829,18 +1332,7 @@ void *ru_thread( void *param ) { proc->frame_tx,proc->tti_tx, RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx, RC.gNB[0]->proc.frame_tx); - /* - LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", - ru->do_prach, - is_prach_subframe(fp, proc->frame_rx, proc->tti_rx), - proc->frame_rx,proc->tti_rx); - if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->tti_rx)==1)) { - wakeup_prach_ru(ru); - }*/ - - // adjust for timing offset between RU - //printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->tti_rx); if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; // do RX front-end processing (frequency-shift, dft) if needed @@ -1924,82 +1416,6 @@ void *ru_thread( void *param ) { ru_thread_status = 0; return &ru_thread_status; } -/* -// This thread run the initial synchronization like a UE -void *ru_thread_synch(void *arg) { - - RU_t *ru = (RU_t*)arg; - NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; - int32_t sync_pos,sync_pos2; - uint32_t peak_val; - uint32_t sync_corr[307200] __attribute__((aligned(32))); - static int ru_thread_synch_status; - - - - wait_sync("ru_thread_synch"); - - // initialize variables for PSS detection - lte_sync_time_init(ru->nr_frame_parms); - - while (!oai_exit) { - - // wait to be woken up - if (wait_on_condition(&ru->proc.mutex_synch,&ru->proc.cond_synch,&ru->proc.instance_cnt_synch,"ru_thread_synch")<0) break; - - // if we're not in synch, then run initial synch - if (ru->in_synch == 0) { - // run intial synch like UE - LOG_I(PHY,"Running initial synchronization\n"); - - sync_pos = lte_sync_time_gNB(ru->common.rxdata, - fp, - fp->samples_per_subframe*5, - &peak_val, - sync_corr); - LOG_I(PHY,"RU synch: %d, val %d\n",sync_pos,peak_val); - - if (sync_pos >= 0) { - if (sync_pos >= fp->nb_prefix_samples) - sync_pos2 = sync_pos - fp->nb_prefix_samples; - else - sync_pos2 = sync_pos + (fp->samples_per_subframe*10) - fp->nb_prefix_samples; - - if (fp->frame_type == FDD) { - - // PSS is hypothesized in last symbol of first slot in Frame - int sync_pos_slot = (fp->samples_per_subframe>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples; - - if (sync_pos2 >= sync_pos_slot) - ru->rx_offset = sync_pos2 - sync_pos_slot; - else - ru->rx_offset = (fp->samples_per_subframe*10) + sync_pos2 - sync_pos_slot; - } - else { - - } - - LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset); - - if ((peak_val > 300000) && (sync_pos > 0)) { - // if (sync_pos++ > 3) { - write_output("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_subframe*5,1,2); - write_output("ru_rx.m","rxs",(void*)ru->ru_time.rxdata[0][0],fp->samples_per_subframe*10,1,1); - exit(-1); - } - - ru->in_synch=1; - } - } - - if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break; - } // oai_exit - - ru_thread_synch_status = 0; - return &ru_thread_synch_status; - -} -*/ int nr_start_if(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB) { return(ru->ifdevice.trx_start_func(&ru->ifdevice)); @@ -2026,12 +1442,7 @@ void init_RU_proc(RU_t *ru) { proc = &ru->proc; memset((void *)proc,0,sizeof(RU_proc_t)); proc->ru = ru; - proc->instance_cnt_prach = -1; proc->instance_cnt_synch = -1; - proc->instance_cnt_FH = -1; - proc->instance_cnt_FH1 = -1; - proc->instance_cnt_gNBs = -1; - proc->instance_cnt_asynch_rxtx = -1; proc->instance_cnt_emulateRF = -1; proc->first_rx = 1; proc->first_tx = 1; @@ -2042,44 +1453,15 @@ void init_RU_proc(RU_t *ru) { for (i=0; i<10; i++) proc->symbol_mask[i]=0; - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_synch,NULL); - pthread_mutex_init( &proc->mutex_FH,NULL); - pthread_mutex_init( &proc->mutex_FH1,NULL); pthread_mutex_init( &proc->mutex_emulateRF,NULL); - pthread_mutex_init( &proc->mutex_gNBs, NULL); - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_FH, NULL); - pthread_cond_init( &proc->cond_FH1, NULL); pthread_cond_init( &proc->cond_emulateRF, NULL); - pthread_cond_init( &proc->cond_asynch_rxtx, NULL); pthread_cond_init( &proc->cond_synch,NULL); - pthread_cond_init( &proc->cond_gNBs, NULL); threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "thread_FH", -1, OAI_PRIORITY_RT_MAX ); - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) - threadCreate( &proc->pthread_FH1, ru_thread_tx, (void *)ru, "thread_FH1", -1, OAI_PRIORITY_RT ); - if(emulate_rf) threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT ); - if (ru->function == NGFI_RRU_IF4p5) { - threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru, "RACH", -1, OAI_PRIORITY_RT ); - ///tmp deactivation of synch thread - // if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void*)ru); - - if ((ru->if_timing == synch_to_other) || - (ru->function == NGFI_RRU_IF5) || - (ru->function == NGFI_RRU_IF4p5)) threadCreate( &proc->pthread_asynch_rxtx, ru_thread_asynch_rxtx, (void *)ru, "asynch_rxtx", -1, OAI_PRIORITY_RT ); - - snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx ); - pthread_setname_np( proc->pthread_FH, name ); - } else if (ru->function == gNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF - LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__); - threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru,"RACH", -1, OAI_PRIORITY_RT ); - } - if (get_thread_worker_conf() == WORKER_ENABLE) { if (ru->feprx) nr_init_feprx_thread(ru); @@ -2092,26 +1474,10 @@ void init_RU_proc(RU_t *ru) { void kill_NR_RU_proc(int inst) { RU_t *ru = RC.ru[inst]; RU_proc_t *proc = &ru->proc; - pthread_mutex_lock(&proc->mutex_FH); - proc->instance_cnt_FH = 0; - pthread_mutex_unlock(&proc->mutex_FH); - pthread_cond_signal(&proc->cond_FH); - pthread_mutex_lock(&proc->mutex_prach); - proc->instance_cnt_prach = 0; - pthread_mutex_unlock(&proc->mutex_prach); - pthread_cond_signal(&proc->cond_prach); pthread_mutex_lock(&proc->mutex_synch); proc->instance_cnt_synch = 0; pthread_mutex_unlock(&proc->mutex_synch); pthread_cond_signal(&proc->cond_synch); - pthread_mutex_lock(&proc->mutex_gNBs); - proc->instance_cnt_gNBs = 0; - pthread_mutex_unlock(&proc->mutex_gNBs); - pthread_cond_signal(&proc->cond_gNBs); - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->instance_cnt_asynch_rxtx = 0; - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - pthread_cond_signal(&proc->cond_asynch_rxtx); LOG_D(PHY, "Joining pthread_FH\n"); pthread_join(proc->pthread_FH, NULL); @@ -2161,16 +1527,8 @@ void kill_NR_RU_proc(int inst) { pthread_join(ru->ru_stats_thread, NULL); } - pthread_mutex_destroy(&proc->mutex_prach); - pthread_mutex_destroy(&proc->mutex_asynch_rxtx); pthread_mutex_destroy(&proc->mutex_synch); - pthread_mutex_destroy(&proc->mutex_FH); - pthread_mutex_destroy(&proc->mutex_gNBs); - pthread_cond_destroy(&proc->cond_prach); - pthread_cond_destroy(&proc->cond_FH); - pthread_cond_destroy(&proc->cond_asynch_rxtx); pthread_cond_destroy(&proc->cond_synch); - pthread_cond_destroy(&proc->cond_gNBs); } int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index a6035122c0..47aecd7b10 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -240,6 +240,10 @@ extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr); extern void set_softmodem_sighandler(void); extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + +void tx_func(void *param); +void rx_func(void *param); +void ru_tx_func(void *param); #ifdef __cplusplus } #endif diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index b465a51a2a..885f955a2a 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -741,4 +741,10 @@ typedef struct RRU_config_s { MBSFN_config_t MBSFN_config[8]; } RRU_config_t; +typedef struct processingData_RU { + int frame_tx; + int slot_tx; + openair0_timestamp timestamp_tx; + RU_t *ru; +} processingData_RU_t; #endif //__PHY_DEFS_RU__H__ diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 440cfc7a69..24cecc85da 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -875,4 +875,13 @@ union ldpcReqUnion { uint64_t p; }; +typedef struct processingData_L1 { + int frame_rx; + int frame_tx; + int slot_rx; + int slot_tx; + openair0_timestamp timestamp_tx; + PHY_VARS_gNB *gNB; +} processingData_L1_t; + #endif From e2f749d8b24b9cf24da422e9c3487b96ec113e48 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Thu, 11 Feb 2021 10:56:08 +0000 Subject: [PATCH 46/91] Fix nr_dlsim, nr_ulsim and nr_prachsim --- openair1/SIMULATION/NR_PHY/dlsim.c | 14 ++++++++++---- openair1/SIMULATION/NR_PHY/prachsim.c | 12 +++++++++--- openair1/SIMULATION/NR_PHY/ulsim.c | 8 +++++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index d8eb8849a3..cc71c20e22 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -97,6 +97,16 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, return 0; } +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, + const int CC_id, + const uint8_t gNB_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *buffer_pP) +{ + return 0; +} + void rrc_data_ind( const protocol_ctxt_t *const ctxt_pP, @@ -172,10 +182,6 @@ int is_x2ap_enabled(void) return 0; } -int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { - return 0; -} - // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 941a06128f..d49ca70bea 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -127,13 +127,19 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;} -// Dummy function to avoid linking error at compilation of nr-prachsim -int is_x2ap_enabled(void) +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, + const int CC_id, + const uint8_t gNB_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *buffer_pP) { return 0; } -int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { +// Dummy function to avoid linking error at compilation of nr-prachsim +int is_x2ap_enabled(void) +{ return 0; } diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index fd2e1dc0b7..2bb7c0a038 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -154,7 +154,13 @@ int is_x2ap_enabled(void) return 0; } -int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, + const int CC_id, + const uint8_t gNB_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *buffer_pP) +{ return 0; } From d0c5bea3be102f0ba701705fd101e005c80a60e3 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Thu, 11 Feb 2021 13:01:39 +0000 Subject: [PATCH 47/91] Log improvements --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 172967b5f5..59b4863c2d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -160,7 +160,7 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len) { - LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message\n"); + LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); return 0; } From d2e9ca590c7f30ac2872816e69726801d8dbb134 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Thu, 11 Feb 2021 22:21:45 +0000 Subject: [PATCH 48/91] Fix segmentation fault in PDSCH DMRS when using additional DMRS symbols --- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 4 ++++ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 4 +--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 1cce5e1174..17c5ef68a2 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -159,7 +159,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs*dmrs_len-xOverhead)*rel15->rbSize*rel15->nrOfLayers; uint8_t Qm = rel15->qamModOrder[0]; uint32_t encoded_length = nb_re*Qm; - int16_t mod_dmrs[14][n_dmrs] __attribute__ ((aligned(16))); + int16_t mod_dmrs[14][n_dmrs<<1] __attribute__ ((aligned(16))); /* PTRS */ uint16_t beta_ptrs = 1; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 8e2087922a..6d619183e1 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -541,6 +541,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, sdu_lcids[0] = lcid; // initialisation by RRC + if(get_softmodem_params()->do_ra) { + nr_rrc_ue_generate_RRCSetupRequest(mod_id,gNB_id); + } + // CCCH PDU size_sdu = (uint16_t) nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, mac_sdus); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 7aca8163e3..3f69cfbe74 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -299,9 +299,7 @@ void schedule_control_sib1(module_id_t module_id, TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3; - - // FIXME: Something is not working in nr_modulation() for TBS = 84, so we need to skip it - } while ( (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes) || (TBS==84) ); + } while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes); gNB_mac->sched_ctrlCommon->rbSize = rbSize; gNB_mac->sched_ctrlCommon->rbStart = 0; From 7011b04b75947c6004ef15815e10a8c3bfa08e30 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Fri, 12 Feb 2021 00:24:31 +0000 Subject: [PATCH 49/91] Code clean up and minor correction in RA for SA --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 2 ++ openair2/LAYER2/NR_MAC_gNB/main.c | 2 +- openair2/RRC/NR/rrc_gNB_nsa.c | 2 +- openair2/RRC/NR/rrc_gNB_reconfig.c | 2 +- openair2/RRC/NR_UE/L2_interface_ue.c | 4 ++-- openair2/RRC/NR_UE/rrc_UE.c | 6 ++---- .../CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf | 11 +++-------- 7 files changed, 12 insertions(+), 17 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 6d619183e1..61b5efe39c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -541,6 +541,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, sdu_lcids[0] = lcid; // initialisation by RRC + + // TODO: To be removed after RA procedures fully implemented if(get_softmodem_params()->do_ra) { nr_rrc_ue_generate_RRCSetupRequest(mod_id,gNB_id); } diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 8dc1303801..33e575d2b9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -96,7 +96,7 @@ void mac_top_init_gNB(void) // These should be out of here later pdcp_layer_init(); - if(IS_SOFTMODEM_NOS1 && !get_softmodem_params()->do_ra) + if(IS_SOFTMODEM_NOS1 && !(get_softmodem_params()->do_ra || get_softmodem_params()->sa) ) nr_DRB_preconfiguration(0x1234); rrc_init_nr_global_param(); diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index a390d05a08..39dc5ca2d8 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -255,7 +255,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ 1024); X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3; itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding - } else if (get_softmodem_params()->do_ra) { + } else if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) { PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id); } diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index bc70b97a8c..4fc4d8c023 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -172,7 +172,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->cellGroupId = scg_id; NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); nr_rlc_bearer_init(RLC_BearerConfig); - if (get_softmodem_params()->do_ra) + if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional); else nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_am); diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 6c791ae9ee..e21859ded8 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -75,10 +75,10 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_active = 1; //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_cnt = 0; - LOG_D(RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); + LOG_D(NR_RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); memcpy(buffer_pP, (uint8_t*)NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.Payload, NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); for(int i = 0; i Date: Fri, 12 Feb 2021 12:28:17 +0000 Subject: [PATCH 50/91] Fix build errors in physical unitary tests simulators, minor update in the documentation --- doc/RUNMODEM.md | 9 +++++---- openair1/SIMULATION/NR_PHY/dlsim.c | 5 +++++ openair1/SIMULATION/NR_PHY/prachsim.c | 5 +++++ openair1/SIMULATION/NR_PHY/ulsim.c | 5 +++++ openair2/RRC/NR_UE/rrc_UE.c | 2 +- openair2/RRC/NR_UE/rrc_proto.h | 2 +- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index d13b193ff9..20eae5d8d1 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -132,9 +132,9 @@ With the RF simulator (on the same machine): `sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --do-ra --rfsim --parallel-config PARALLEL_SINGLE_THREAD` -## sa setup with OAI +## SA setup with OAI -The sa flag is used to run gNB in standalone mode. Currently OAI in NR standalone mode transmits and receives SIB1. +The sa flag is used to run gNB in standalone mode. Currently OAI in NR standalone mode transmits and receives SIB1 and triggers the RA procedure for initial access. In order to run gNB in standalone mode, the following flag is needed at gNB: @@ -147,8 +147,9 @@ At the gNB the --sa flag does the following - it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw - the RRC encodes SIB1 according the configuration file and transmits it through PDSCH -At the UE the --sa flag will -- read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them. +At the UE the --sa flag will: +- Read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them +- After the successful decoding of a SIB1 at RRC, the UE will start the 5G NR Initial Access Procedure by triggering the RA procedure. From the `cmake_targets/ran_build/build` folder: diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 750e355077..a4ab792394 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -97,6 +97,11 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, return 0; } +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) +{ + return; +} + int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, const int CC_id, const uint8_t gNB_id, diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index d49ca70bea..2ba4b96ff1 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -127,6 +127,11 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;} +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) +{ + return; +} + int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, const int CC_id, const uint8_t gNB_id, diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 2bb7c0a038..68874a70a3 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -154,6 +154,11 @@ int is_x2ap_enabled(void) return 0; } +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) +{ + return; +} + int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, const int CC_id, const uint8_t gNB_id, diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 0865db85bb..b398ca7ce8 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1697,7 +1697,7 @@ nr_rrc_ue_process_securityModeCommand( } //----------------------------------------------------------------------------- -void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index ) { +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) { uint8_t i=0,rv[6]; if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) { diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 9b051be71a..0acf6db634 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -132,7 +132,7 @@ void *rrc_nrue_task(void *args_p); /**\brief RRC UE generate RRCSetupRequest message. \param module_id module id \param gNB_index gNB index */ -void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index ); +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index); /** @}*/ #endif From 24fc20e2e2e0f19feb1951f0cdc524844f68a307 Mon Sep 17 00:00:00 2001 From: cig Date: Fri, 12 Feb 2021 17:02:20 +0100 Subject: [PATCH 51/91] Bugfix in USRP flags configuration for NR UE - missing check on duplex mode before fetching the TDD period - missing flags configuration for FDD mode --- executables/nr-ue.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 6be23582b1..8d10a19f3d 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -707,12 +707,17 @@ void *UE_thread(void *arg) { uint8_t num_UL_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots + (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0); uint8_t first_tx_slot = tdd_period - num_UL_slots; - if (slot_tx_usrp%tdd_period==first_tx_slot) - flags=2; - else if (slot_tx_usrp%tdd_period==first_tx_slot+num_UL_slots-1) - flags = 3; - else if (slot_tx_usrp%tdd_period>first_tx_slot) + + if (openair0_cfg[0].duplex_mode == TDD) { + if (slot_tx_usrp % tdd_period == first_tx_slot) + flags = 2; + else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1) + flags = 3; + else if (slot_tx_usrp % tdd_period > first_tx_slot) + flags = 1; + } else { flags = 1; + } if (flags || IS_SOFTMODEM_RFSIM) AssertFatal( writeBlockSize == From d5877d75bfd912e2ef4ca2bec7e71f2fb9212328 Mon Sep 17 00:00:00 2001 From: cig Date: Fri, 12 Feb 2021 18:41:19 +0100 Subject: [PATCH 52/91] Bugfix in gNB RA scheduling for FDD duplex mode - the RA SFN index wasn't increased in the FDD case, therefore the PRACH RX was never scheduled --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 407bc72714..35bebb351e 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1220,6 +1220,11 @@ int get_nr_prach_occasion_info_from_index(uint8_t index, else { // FDD x = table_6_3_3_2_2_prachConfig_Index[index][2]; s_map = table_6_3_3_2_2_prachConfig_Index[index][4]; + for(int i = 0; i < 64 ; i++) { + if ( (s_map >> i) & 0x01) { + (*N_RA_sfn)++; + } + } *N_RA_slot = table_6_3_3_2_2_prachConfig_Index[index][6]; if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ *start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5]; @@ -1429,6 +1434,11 @@ int get_nr_prach_info_from_index(uint8_t index, if ( (table_6_3_3_2_2_prachConfig_Index[index][6] <= 1) && (slot%2 == 0) ) return 0; // no prach in even slots @ 30kHz for 1 prach per subframe } + for(int i = 0; i <= subframe ; i++) { + if ( (s_map >> i) & 0x01) { + (*RA_sfn_index)++; + } + } if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ *start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5]; *N_t_slot = table_6_3_3_2_2_prachConfig_Index[index][7]; From e7fb928758eacd23c26f109c9865dd0b53cca64d Mon Sep 17 00:00:00 2001 From: rmagueta Date: Fri, 12 Feb 2021 21:40:04 +0000 Subject: [PATCH 53/91] Fix dlsch_config_pdu for DCI with format 1.1 --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 10 ++++++++++ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 59b4863c2d..250cf856bc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -814,7 +814,17 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti; + + // FIXME: fix number of additional dmrs + if(pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition == NULL) + pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition=calloc(1,sizeof(*pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition)); + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_1 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; + + dlsch_config_pdu_1_1->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_1->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_1->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + /* IDENTIFIER_DCI_FORMATS */ /* CARRIER_IND */ /* BANDWIDTH_PART_IND */ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 4d491b2843..30a89cce77 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1045,7 +1045,7 @@ void nr_schedule_ue_spec(module_id_t module_id, size += 3; } } - else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) { + else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra || get_softmodem_params()->sa) { /* we will need the large header, phy-test typically allocates all * resources and fills to the last byte below */ NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf; From 08ab23450189f3bde995c0a5da425020d097180b Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Sat, 13 Feb 2021 15:14:03 +0100 Subject: [PATCH 54/91] Removing sync_thread --- executables/nr-gnb.c | 2 - executables/nr-ru.c | 132 ------------------------------------------- 2 files changed, 134 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index a23a8a4a5d..50ba578bc0 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -251,8 +251,6 @@ void rx_func(void *param) { phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); } - if (oai_exit) return(-1); - //stop_meas( &softmodem_stats_rxtx_sf ); LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 9fd83bab76..c941e84947 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -787,107 +787,6 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { } } - - - -int wakeup_synch(RU_t *ru) { - struct timespec wait; - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - // wake up synch thread - // lock the synch mutex and make sure the thread is ready - if (pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait) != 0) { - LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU synch thread (IC %d)\n", ru->proc.instance_cnt_synch ); - exit_fun( "error locking mutex_synch" ); - return(-1); - } - - ++ru->proc.instance_cnt_synch; - - // the thread can now be woken up - if (pthread_cond_signal(&ru->proc.cond_synch) != 0) { - LOG_E( PHY, "[RU] ERROR pthread_cond_signal for RU synch thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - - pthread_mutex_unlock( &ru->proc.mutex_synch ); - return(0); -} - -void do_ru_synch(RU_t *ru) { - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *proc = &ru->proc; - int i; - void *rxp[2],*rxp2[2]; - int32_t dummy_rx[ru->nb_rx][fp->samples_per_subframe] __attribute__((aligned(32))); - int rxs; - int ic; - - // initialize the synchronization buffer to the common_vars.rxdata - for (int i=0; inb_rx; i++) - rxp[i] = &ru->common.rxdata[i][0]; - - double temp_freq1 = ru->rfdevice.openair0_cfg->rx_freq[0]; - double temp_freq2 = ru->rfdevice.openair0_cfg->tx_freq[0]; - - for (i=0; i<4; i++) { - ru->rfdevice.openair0_cfg->rx_freq[i] = ru->rfdevice.openair0_cfg->tx_freq[i]; - ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1; - } - - ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); - - while ((ru->in_synch ==0)&&(!oai_exit)) { - // read in frame - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp, - fp->samples_per_subframe*10, - ru->nb_rx); - - if (rxs != fp->samples_per_subframe*10) LOG_E(PHY,"requested %d samples, got %d\n",fp->samples_per_subframe*10,rxs); - - // wakeup synchronization processing thread - wakeup_synch(ru); - ic=0; - - while ((ic>=0)&&(!oai_exit)) { - // continuously read in frames, 1ms at a time, - // until we are done with the synchronization procedure - for (i=0; inb_rx; i++) - rxp2[i] = (void *)&dummy_rx[i][0]; - - for (i=0; i<10; i++) - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp2, - fp->samples_per_subframe, - ru->nb_rx); - - pthread_mutex_lock(&ru->proc.mutex_synch); - ic = ru->proc.instance_cnt_synch; - pthread_mutex_unlock(&ru->proc.mutex_synch); - } // ic>=0 - } // in_synch==0 - - // read in rx_offset samples - LOG_I(PHY,"Resynchronizing by %d samples\n",ru->rx_offset); - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp, - ru->rx_offset, - ru->nb_rx); - - for (i=0; i<4; i++) { - ru->rfdevice.openair0_cfg->rx_freq[i] = temp_freq1; - ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq2; - } - - ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); -} - // this is for RU with local RF unit void fill_rf_config(RU_t *ru, char *rf_config_file) { int i; @@ -1289,9 +1188,6 @@ void *ru_thread( void *param ) { else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); } else LOG_I(PHY,"RU %d no rf device\n",ru->idx); - // if this is a slave RRU, try to synchronize on the DL frequency - if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); - // start trx write thread if(usrp_tx_thread == 1){ if (ru->start_write_thread){ @@ -1437,12 +1333,10 @@ int start_write_thread(RU_t *ru) { void init_RU_proc(RU_t *ru) { int i=0; RU_proc_t *proc; - char name[100]; LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); proc = &ru->proc; memset((void *)proc,0,sizeof(RU_proc_t)); proc->ru = ru; - proc->instance_cnt_synch = -1; proc->instance_cnt_emulateRF = -1; proc->first_rx = 1; proc->first_tx = 1; @@ -1453,10 +1347,8 @@ void init_RU_proc(RU_t *ru) { for (i=0; i<10; i++) proc->symbol_mask[i]=0; - pthread_mutex_init( &proc->mutex_synch,NULL); pthread_mutex_init( &proc->mutex_emulateRF,NULL); pthread_cond_init( &proc->cond_emulateRF, NULL); - pthread_cond_init( &proc->cond_synch,NULL); threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "thread_FH", -1, OAI_PRIORITY_RT_MAX ); if(emulate_rf) @@ -1474,30 +1366,9 @@ void init_RU_proc(RU_t *ru) { void kill_NR_RU_proc(int inst) { RU_t *ru = RC.ru[inst]; RU_proc_t *proc = &ru->proc; - pthread_mutex_lock(&proc->mutex_synch); - proc->instance_cnt_synch = 0; - pthread_mutex_unlock(&proc->mutex_synch); - pthread_cond_signal(&proc->cond_synch); LOG_D(PHY, "Joining pthread_FH\n"); pthread_join(proc->pthread_FH, NULL); - if (ru->function == NGFI_RRU_IF4p5) { - LOG_D(PHY, "Joining pthread_prach\n"); - pthread_join(proc->pthread_prach, NULL); - - if (ru->is_slave) { - LOG_D(PHY, "Joining pthread_\n"); - pthread_join(proc->pthread_synch, NULL); - } - - if ((ru->if_timing == synch_to_other) || - (ru->function == NGFI_RRU_IF5) || - (ru->function == NGFI_RRU_IF4p5)) { - LOG_D(PHY, "Joining pthread_asynch_rxtx\n"); - pthread_join(proc->pthread_asynch_rxtx, NULL); - } - } - if (get_nprocs() >= 2) { if (ru->feprx) { pthread_mutex_lock(&proc->mutex_fep); @@ -1526,9 +1397,6 @@ void kill_NR_RU_proc(int inst) { LOG_D(PHY, "Joining ru_stats_thread\n"); pthread_join(ru->ru_stats_thread, NULL); } - - pthread_mutex_destroy(&proc->mutex_synch); - pthread_cond_destroy(&proc->cond_synch); } int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) From 94d956fa559cdd6dfdbca91c4fb12415d97f9621 Mon Sep 17 00:00:00 2001 From: cig Date: Mon, 15 Feb 2021 12:28:11 +0100 Subject: [PATCH 55/91] Fixed warning about use of wrong enum --- executables/nr-ue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 8d10a19f3d..0c97552c15 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -708,7 +708,7 @@ void *UE_thread(void *arg) { (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0); uint8_t first_tx_slot = tdd_period - num_UL_slots; - if (openair0_cfg[0].duplex_mode == TDD) { + if (openair0_cfg[0].duplex_mode == duplex_mode_TDD) { if (slot_tx_usrp % tdd_period == first_tx_slot) flags = 2; else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1) From 9d498e1a0923ae0d3e30813be4abeedcc3dd332e Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Mon, 15 Feb 2021 16:49:07 +0000 Subject: [PATCH 56/91] Improve PDSCH DMRS modulation for numDmrsCdmGrpsNoData=1 --- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 17c5ef68a2..66fc987f6d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -147,12 +147,11 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, uint16_t n_dmrs; if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) { nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData; - n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1; } else { nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData; - n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1; } + n_dmrs = (rel15->rbSize+rel15->rbStart)*nb_re_dmrs; uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100 uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos); @@ -271,10 +270,10 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, /// DMRS QPSK modulation for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { if (rel15->dlDmrsSymbPos & (1 << l)) { - nr_modulation(pdsch_dmrs[l][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated #ifdef DEBUG_DLSCH - printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs>>1, dmrs_Type); + printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs, dmrs_Type); for (int i=0; i>4; i++) { for (int j=0; j<8; j++) { printf("%d %d\t", mod_dmrs[l][((i<<3)+j)<<1], mod_dmrs[l][(((i<<3)+j)<<1)+1]); From f62095fb32375315b59a9952f7532eac6698f6df Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 16 Feb 2021 10:29:38 +0100 Subject: [PATCH 57/91] Updated nr_dlsim to generate matlab files Updated matlab file write function to write multiple vectors to a single file. --- common/utils/LOG/log.c | 9 +++++---- common/utils/LOG/log.h | 10 ++++++---- openair1/SIMULATION/NR_PHY/dlsim.c | 15 ++++++++++++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 2340c78bf1..be0a5b3bcd 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -88,7 +88,8 @@ int write_file_matlab(const char *fname, void *data, int length, int dec, - char format) + char format, + int multiVec) { FILE *fp=NULL; int i; @@ -98,7 +99,7 @@ int write_file_matlab(const char *fname, //printf("Writing %d elements of type %d to %s\n",length,format,fname); - if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) { + if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14 || multiVec) { fp = fopen(fname,"a+"); } else if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) { fp = fopen(fname,"w+"); @@ -109,7 +110,7 @@ int write_file_matlab(const char *fname, return(-1); } - if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) + if ((format != 10 && format !=11 && format != 12 && format != 13 && format != 14) || multiVec) fprintf(fp,"%s = [",vname); switch (format) { @@ -216,7 +217,7 @@ int write_file_matlab(const char *fname, break; } - if (format != 10 && format !=11 && format !=12 && format != 13 && format != 15) { + if ((format != 10 && format !=11 && format !=12 && format != 13 && format != 15) || multiVec) { fprintf(fp,"];\n"); fclose(fp); return(0); diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index d893708a8b..a8dae8d027 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -335,8 +335,9 @@ typedef struct { @param length length of data vector to output @param dec decimation level @param format data format (0 = real 16-bit, 1 = complex 16-bit,2 real 32-bit, 3 complex 32-bit,4 = real 8-bit, 5 = complex 8-bit) +@param multiVec create new file or append to existing (useful for writing multiple vectors to same file. Just call the function multiple times with same file name and with this parameter set to 1) */ -int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, char format); +int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, char format, int multiVec); /*----------------macro definitions for reading log configuration from the config module */ #define CONFIG_STRING_LOG_PREFIX "log_config" @@ -396,7 +397,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int /* bitmask dependent macros, to generate debug file such as matlab file or message dump */ # define LOG_DUMPFLAG(D) (g_log->dump_mask & D) -# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)/* */ +# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)/* */ /* define variable only used in LOG macro's */ # define LOG_VAR(A,B) A B # else /* T_TRACER: remove all debugging and tracing messages, except errors */ @@ -413,7 +414,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # define LOG_DUMPFLAG(D) (g_log->debug_mask & D) # define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */ -# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0) +# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0) # define LOG_VAR(A,B) A B # endif /* T_TRACER */ /* avoid warnings for variables only used in LOG macro's but set outside debug section */ @@ -421,9 +422,10 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int #define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B /* unfiltered macros, useful for simulators or messages at init time, before log is configured */ -#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0) +#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0) #define LOG_UI(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0) #define LOG_UDUMPMSG(c, b, s, f, x...) do { log_dump(c, b, s, f, x) ;} while (0) /* */ +# define LOG_MM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 1);} while(0) /* @}*/ diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 9581038283..a0d18b3da9 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -235,7 +235,10 @@ int main(int argc, char **argv) int i,aa;//,l; double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0; uint8_t snr1set=0; - float roundStats[50]; + double roundStats[500] = {0}; + double blerStats[500] = {0}; + double berStats[500] = {0}; + double snrStats[500] = {0}; float effRate; //float psnr; float eff_tp_check = 0.7; @@ -1101,7 +1104,9 @@ int main(int argc, char **argv) if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round; } // noise trials + blerStats[snrRun] = (float) n_errors / (float) n_trials; roundStats[snrRun]/=((float)n_trials); + berStats[snrRun] = (double)errors_scrambling/available_bits/n_trials; effRate /= n_trials; printf("*****************************************\n"); printf("SNR %f, (false positive %f)\n", SNR, @@ -1109,7 +1114,7 @@ int main(int argc, char **argv) printf("*****************************************\n"); printf("\n"); dump_pdsch_stats(gNB); - printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS); + printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, BLER %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],berStats[snrRun],blerStats[snrRun],effRate,effRate/TBS*100,TBS); printf("\n"); if (print_perf==1) { @@ -1174,15 +1179,19 @@ int main(int argc, char **argv) break; } - //if ((float)n_errors/(float)n_trials <= target_error_rate) { if (effRate > (eff_tp_check*TBS)) { printf("PDSCH test OK\n"); break; } + snrStats[snrRun] = SNR; snrRun++; } // NSR + LOG_M("dlsimStats.m","SNR",snrStats,snrRun,1,7); + LOG_MM("dlsimStats.m","BLER",blerStats,snrRun,1,7); + LOG_MM("dlsimStats.m","BER",berStats,snrRun,1,7); + LOG_MM("dlsimStats.m","rounds",roundStats,snrRun,1,7); /*if (n_trials>1) { printf("HARQ stats:\nSNR\tRounds\n"); psnr = snr0; From 7c86b9c28990fbdbb8e83aa2ba29128ab3426b7a Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 16 Feb 2021 12:07:27 +0100 Subject: [PATCH 58/91] Ulsch coding fix Do encoding only if NDI toggles instead of doing on first round. Both are same but we now remove the dependancy on rv_round_mapping. --- openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 2 ++ openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 7 ++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 464bcfcfba..aa32ecc8c9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -105,6 +105,8 @@ typedef struct { uint8_t O_ACK; /// Index of current HARQ round for this ULSCH uint8_t round; + /// Last Ndi for this harq process + uint8_t ndi; /// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8) unsigned char *a; /// Pointer to the payload + CRC diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index d9bea8a3ac..1a39def26b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -202,7 +202,6 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, for (i=0; iharq_processes[i]->round=0; } - return(ulsch); } } @@ -257,7 +256,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Ilbrm = 0; Tbslbrm = 950984; //max tbs Coderate = 0.0; - harq_process->round = nr_rv_round_map_ue[harq_process->pusch_pdu.pusch_data.rv_index]; /////////// ///////////////////////////////////////////////////////////////////////////////////////// @@ -267,8 +265,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, LOG_D(PHY,"ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers); LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order); - // if (harq_process->Ndi == 1) { // this is a new packet - if (harq_process->round == 0) { // this is a new packet + if (harq_process->ndi != harq_process->pusch_pdu.pusch_data.new_data_indicator) { // this is a new packet #ifdef DEBUG_ULSCH_CODING printf("encoding thinks this is a new packet \n"); #endif @@ -415,7 +412,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, /////////// /////////////////////////////////////////////////////////////////////////////// - + harq_process->ndi = harq_process->pusch_pdu.pusch_data.new_data_indicator; } F = harq_process->F; Kr = harq_process->K; From c89d3493004b3913d69e60f8cf749279a25ca091 Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 16 Feb 2021 14:57:04 +0100 Subject: [PATCH 59/91] Bugfix in nr_ue_prach_scheduler - scheduled_response was called regardless of the UL config in the PRACH slot this was leading to wrong behaviour since it was interfering with the UL config of PUSCH --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 041d78d0e3..66b5c7a697 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1684,13 +1684,11 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s format0 = format & 0xff; // single PRACH format format1 = (format >> 8) & 0xff; // dual PRACH format - ul_config->sfn = frameP; - ul_config->slot = slotP; - - ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH; prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); - ul_config->number_pdus += 1; + + fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); + LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus); ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); @@ -1768,11 +1766,10 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s AssertFatal(1 == 0, "Invalid PRACH format"); } } // if format1 + fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) + mac->if_module->scheduled_response(&scheduled_response); } // is_nr_prach_slot - - fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) - mac->if_module->scheduled_response(&scheduled_response); } // if is_nr_UL_slot } From e023f67ed8717f78d2e0a5d5d16749064881b9e9 Mon Sep 17 00:00:00 2001 From: cig Date: Wed, 17 Feb 2021 13:50:25 +0100 Subject: [PATCH 60/91] Compute and apply symbol rotation for DL and UL - now done according to the proper DL/UL frequency - this makes it compatible with FDD mode --- executables/nr-uesoftmodem.c | 3 +- openair1/PHY/INIT/nr_init.c | 2 +- openair1/PHY/MODULATION/nr_modulation.c | 65 +++++++++++++++------- openair1/PHY/MODULATION/nr_modulation.h | 2 +- openair1/PHY/MODULATION/ofdm_mod.c | 22 +++++--- openair1/PHY/MODULATION/slot_fep_nr.c | 6 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 20 ++++--- openair1/PHY/defs_nr_common.h | 3 +- openair1/SIMULATION/NR_PHY/pbchsim.c | 2 +- 9 files changed, 84 insertions(+), 41 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 87cd157948..03bc7e14a5 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -531,7 +531,8 @@ int main( int argc, char **argv ) { fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config; nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]); - init_symbol_rotation(&UE[CC_id]->frame_parms, UE[CC_id]->frame_parms.dl_CarrierFreq); + + init_symbol_rotation(&UE[CC_id]->frame_parms); init_nr_ue_vars(UE[CC_id], 0, abstraction_flag); #ifdef FR2_TEST diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index bd6b944fef..cb14e12024 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -494,7 +494,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { // } RC.gNB[Mod_id]->configured = 1; - init_symbol_rotation(fp,fp->dl_CarrierFreq); + init_symbol_rotation(fp); LOG_I(PHY,"gNB %d configured\n",Mod_id); } diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 0a7088ba39..e0f087c808 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -502,35 +502,62 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) } -void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) { +void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { + + uint64_t dl_CarrierFreq = fp->dl_CarrierFreq; + uint64_t ul_CarrierFreq = fp->ul_CarrierFreq; + double f[2] = {(double)dl_CarrierFreq, (double)ul_CarrierFreq}; const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10; const double Tc=(1/480e3/4096); const double Nu=2048*64*(1/(float)(1<numerology_index)); - const double f0= (double)CarrierFreq; const double Ncp0=16*64 + (144*64*(1/(float)(1<numerology_index))); const double Ncp1=(144*64*(1/(float)(1<numerology_index))); double tl=0,poff,exp_re,exp_im; double Ncp,Ncpm1=Ncp0; - poff = 2*M_PI*((Ncp0*Tc))*f0; - exp_re = cos(poff); - exp_im = sin(-poff); - fp->symbol_rotation[0]=(int16_t)floor(exp_re*32767); - fp->symbol_rotation[1]=(int16_t)floor(exp_im*32767); - LOG_I(PHY,"Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n",f0,nsymb); - LOG_I(PHY,"Symbol rotation %d/%d => (%d,%d)\n",0,nsymb,fp->symbol_rotation[0],fp->symbol_rotation[1]); - for (int l=1;lnumerology_index))) Ncp=Ncp0; - else Ncp=Ncp1; - tl += (Nu+Ncpm1)*Tc; - poff = 2*M_PI*(tl + (Ncp*Tc))*f0; + for (uint8_t ll = 0; ll < 2; ll++){ + + double f0 = f[ll]; + int16_t *symbol_rotation = fp->symbol_rotation[ll]; + + poff = 2 * M_PI * ((Ncp0 * Tc)) * f0; exp_re = cos(poff); exp_im = sin(-poff); - fp->symbol_rotation[l<<1]=(int16_t)floor(exp_re*32767); - fp->symbol_rotation[1+(l<<1)]=(int16_t)floor(exp_im*32767); - LOG_I(PHY,"Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",l,nsymb,tl,fp->symbol_rotation[l<<1],fp->symbol_rotation[1+(l<<1)], - (poff/2/M_PI)-floor(poff/2/M_PI)); - Ncpm1=Ncp; + symbol_rotation[0] = (int16_t)floor(exp_re * 32767); + symbol_rotation[1] = (int16_t)floor(exp_im * 32767); + LOG_I(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb); + LOG_I(PHY, "Symbol rotation %d/%d => (%d,%d)\n", + 0, + nsymb, + symbol_rotation[0], + symbol_rotation[1]); + + for (int l = 1; l < nsymb; l++) { + + if (l == (7 * (1 << fp->numerology_index))) { + Ncp = Ncp0; + } else { + Ncp = Ncp1; + } + + tl += (Nu + Ncpm1) * Tc; + poff = 2 * M_PI * (tl + (Ncp * Tc)) * f0; + exp_re = cos(poff); + exp_im = sin(-poff); + symbol_rotation[l<<1] = (int16_t)floor(exp_re * 32767); + symbol_rotation[1 + (l<<1)] = (int16_t)floor(exp_im * 32767); + + LOG_I(PHY, "Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n", + l, + nsymb, + tl, + symbol_rotation[l<<1], + symbol_rotation[1 + (l<<1)], + (poff / 2 / M_PI) - floor(poff / 2 / M_PI)); + + Ncpm1 = Ncp; + + } } } diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 3d2be905ac..c6c9718f7e 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -110,7 +110,7 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, int nsymb, int length); -void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq); +void init_symbol_rotation(NR_DL_FRAME_PARMS *fp); void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdataF, diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 2d86b46742..8cf9f05b9b 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -306,15 +306,23 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, int length) { int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot; + int16_t *symbol_rotation = fp->symbol_rotation[0]; + for (int sidx=0;sidxsymbol_rotation[2*(sidx+first_symbol+symb_offset)],fp->symbol_rotation[1+2*(sidx+first_symbol+symb_offset)]); - rotate_cpx_vector(trxdata+(sidx*length*2), - &fp->symbol_rotation[2*(sidx+first_symbol+symb_offset)], - trxdata+(sidx*length*2), - length, - 15); + first_symbol + sidx, + slot, + sidx + first_symbol + symb_offset, + length, + symbol_rotation[2 * (sidx + first_symbol + symb_offset)], + symbol_rotation[1 + 2 * (sidx + first_symbol + symb_offset)]); + + rotate_cpx_vector(trxdata + (sidx * length * 2), + &symbol_rotation[2 * (sidx + first_symbol + symb_offset)], + trxdata + (sidx * length * 2), + length, + 15); } } diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 60b28d4ad1..7b5ddb230a 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -205,7 +205,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, #endif int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset]; + int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset]; ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], (int16_t*)&rot2, @@ -386,7 +386,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, } int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset]; + int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset]; ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; #ifdef DEBUG_FEP @@ -513,7 +513,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, for (int symbol=0;symbolsymbol_rotation)[symbol+symb_offset]; + uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset]; ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 208901f289..3d8c975a5c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -496,13 +496,19 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; for(ap = 0; ap < Nl; ap++) { for (int s=0;s (%d.%d)\n", - s,s+symb_offset,frame_parms->symbol_rotation[2*(s+symb_offset)],frame_parms->symbol_rotation[1+(2*(s+symb_offset))]); - rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s], - &frame_parms->symbol_rotation[2*(s+symb_offset)], - (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s], - frame_parms->ofdm_symbol_size, - 15); + + LOG_D(PHY,"In %s: rotating txdataF symbol %d (%d) => (%d.%d)\n", + __FUNCTION__, + s, + s + symb_offset, + frame_parms->symbol_rotation[1][2 * (s + symb_offset)], + frame_parms->symbol_rotation[1][1 + (2 * (s + symb_offset))]); + + rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], + &frame_parms->symbol_rotation[1][2 * (s + symb_offset)], + (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], + frame_parms->ofdm_symbol_size, + 15); } } diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 18c7dd413b..9458833427 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -327,7 +327,8 @@ struct NR_DL_FRAME_PARMS { /// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP) lte_prefix_type_t Ncp; /// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211 - int16_t symbol_rotation[224*2]; + /// First dimension is for the direction of the link (0 DL, 1 UL) + int16_t symbol_rotation[2][224*2]; /// shift of pilot position in one RB uint8_t nushift; /// SRS configuration from TS 38.331 RRC diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 2ff89364d3..a6c51468d2 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -111,7 +111,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, nr_init_frame_parms(gNB_config, fp); - init_symbol_rotation(fp,fp->dl_CarrierFreq); + init_symbol_rotation(fp); gNB->configured = 1; LOG_I(PHY,"gNB configured\n"); From 30aaa0dc44d3c8691c4653998247ce9679118e5b Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 19 Feb 2021 11:47:25 +0100 Subject: [PATCH 61/91] reducing UL target power for Benetel 5G RRU and adding missing parameter for PUSCH multi thread processing --- .../PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 940d619a51..504d5e7b34 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -104,9 +104,9 @@ gNBs = prach_msg1_FDM = 0; prach_msg1_FrequencyStart = 74; zeroCorrelationZoneConfig = 13; - #preambleReceivedTargetPower = -118; + preambleReceivedTargetPower = -118; #preambleReceivedTargetPower = -104; - preambleReceivedTargetPower = -108; + #preambleReceivedTargetPower = -108; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) preambleTransMax = 6; #powerRampingStep @@ -153,7 +153,7 @@ gNBs = msg3_DeltaPreamble = 1; #p0_NominalWithGrant =-90; - p0_NominalWithGrant =-108; + p0_NominalWithGrant =-118; # pucch-ConfigCommon setup : # pucchGroupHopping @@ -161,7 +161,7 @@ gNBs = pucchGroupHopping = 0; hoppingId = 40; #p0_nominal = -90; - p0_nominal = -108; + p0_nominal = -118; # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; @@ -234,9 +234,9 @@ gNBs = { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.195/24"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.187/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.195/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.187/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 GNB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; GNB_PORT_FOR_X2C = 36422; # Spec 36422 @@ -256,6 +256,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; + pusch_proc_threads = 8; } ); From a51e3defa834bd34781555a83b1dd5085ab49fa1 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 19 Feb 2021 11:01:03 +0100 Subject: [PATCH 62/91] when PRACH config 4 is used (Benetel RRU) we only schedule UL slots 8 and 9 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index d5dbbe5ddf..cf361f9342 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -370,7 +370,13 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, #define BIT(x) (1 << (x)) const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16); - const uint64_t ulsch_in_slot_bitmap = BIT( 8) | BIT(18); + + uint8_t prach_config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + uint64_t ulsch_in_slot_bitmap; + if (prach_config_index==4) //this is the PRACH config used in the Benetel RRU. TODO: make this generic for any PRACH config. + ulsch_in_slot_bitmap = BIT( 8) | BIT( 9); + else + ulsch_in_slot_bitmap = BIT( 8) | BIT(18); memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0 memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1 From 2651cd0cd3697f63919143b33061501cda21386f Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 19 Feb 2021 11:16:29 +0100 Subject: [PATCH 63/91] removing dead code --- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 4 ---- openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index d2baa40451..713e71674b 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -67,10 +67,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates; int **rxdataF = gNB->common_vars.rxdataF; -#if 0 -printf("nr_pusch_channel_estimation rxdataF %p\n", &rxdataF[0][0]); -#endif - nushift = (p>>1)&1; gNB->frame_parms.nushift = nushift; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 25c9fee832..7e6becb4a8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -250,10 +250,6 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, uint8_t is_dmrs_re; start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size; -#if 0 -printf("frame_parms->first_carrier_offset in nr_ulsch_extract_rbs_single %d\n", frame_parms->first_carrier_offset); -printf("rxdataF in nr_ulsch_extract_rbs_single %p\n", &rxdataF[0][0]); -#endif nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size; #ifdef __AVX2__ int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); From b6ab1eb9e1492d4666173a2cedee66b56716a92d Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 22 Feb 2021 15:34:15 +0000 Subject: [PATCH 64/91] Fix RA preamble shift at gNB --- openair1/PHY/NR_TRANSPORT/nr_prach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index b5a3c061e9..0fc2de2d0a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -681,7 +681,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, preamble_shift -= NCS; if (preamble_shift < 0) - preamble_shift+=N_ZC; + preamble_shift+=((N_ZC/NCS)*NCS); } } else { // This is the high-speed case new_dft = 0; From 4ea560f291a4cbead780228cfb1b8d5177d2ca92 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 22 Feb 2021 16:01:05 +0000 Subject: [PATCH 65/91] Address review comments --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 3 ++- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- openair2/RRC/NR_UE/rrc_defs.h | 16 ++++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 61b5efe39c..8f234cb585 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -515,7 +515,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, uint8_t sdu_lcids[NB_RB_MAX] = {0}; uint16_t sdu_lengths[NB_RB_MAX] = {0}; - int num_sdus, offset = 0; + int num_sdus = 0; + int offset = 0; // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side if (!prach_resources->init_msg1) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 592086e2ba..06aa4e5699 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -465,7 +465,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, // random access pusch with TC-RNTI if (ra->rnti != current_rnti) { - LOG_W(MAC, + LOG_W(NR_MAC, "expected TC-RNTI %04x to match current RNTI %04x\n", ra->rnti, current_rnti); diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index fabc77399f..f4ce474657 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -78,14 +78,14 @@ typedef struct OAI_NR_UECapability_s { } OAI_NR_UECapability_t; typedef enum requested_SI_List_e { - SIB2 = 0x1, - SIB3 = 0x2, - SIB4 = 0x4, - SIB5 = 0x8, - SIB6 = 0x16, - SIB7 = 0x32, - SIB8 = 0x64, - SIB9 = 0x128 + SIB2 = 1, + SIB3 = 2, + SIB4 = 4, + SIB5 = 8, + SIB6 = 16, + SIB7 = 32, + SIB8 = 64, + SIB9 = 128 } requested_SI_List_t; // 3GPP TS 38.300 Section 9.2.6 From bed43a2a79fbe6dc476f12a47d5e41f9b5192cde Mon Sep 17 00:00:00 2001 From: rmagueta Date: Mon, 22 Feb 2021 16:31:13 +0000 Subject: [PATCH 66/91] Address review comments --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 214abbce79..82855365c8 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1368,9 +1368,9 @@ uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) { rrcSetupRequest->rrcSetupRequest.spare.size=1; rrcSetupRequest->rrcSetupRequest.spare.bits_unused = 7; - //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg); - //} + } enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message, NULL, From 37a2ce7d3da0e5f5c2df31a48a48b43c4931af8b Mon Sep 17 00:00:00 2001 From: Saankhya Date: Sat, 20 Feb 2021 14:55:10 +0530 Subject: [PATCH 67/91] following coding guideline fixing the RE offset for each Rx antenna in pusch channel estimation --- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 713e71674b..38b35dcf6d 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -158,6 +158,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + re_offset = k; /* Initializing the Resource element offset for each Rx antenna */ + pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; From 95b659ab449373d2be8a46ccccee70c1411b7dfe Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 24 Feb 2021 16:21:36 +0100 Subject: [PATCH 68/91] T tracer: add gnb tracer Minimalist gnb tracer to trace (for the moment) rxdataF when some decoding for PUCCH or PUSCH has been done. Important: T_BUFFER_MAX and T_CACHE_SIZE have been changed. T_BUFFER_MAX is twice as big as before. T_CACHE_SIZE has been devided by two. Globally, the memory usage of the T tracer is the same, but since we divided by two the number of buffers in the cache, we may hit some realtime problems if all the buffers are busy at some point. The simple solution would be to use 8192*2 for T_CACHE_SIZE as it was, but then we double the memory usage of the T tracer. This, or another solution, to be defined. --- common/utils/T/.gitignore | 1 + common/utils/T/T_messages.txt | 8 +- common/utils/T/tracer/Makefile | 10 +- common/utils/T/tracer/gnb.c | 172 ++++++++++++++++++++++ common/utils/T/tracer/logger/iqlog.c | 78 ++++++++++ common/utils/T/tracer/logger/logger.h | 2 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 11 +- 7 files changed, 275 insertions(+), 7 deletions(-) create mode 100644 common/utils/T/tracer/gnb.c diff --git a/common/utils/T/.gitignore b/common/utils/T/.gitignore index d754ff7c38..6a6e5817c5 100644 --- a/common/utils/T/.gitignore +++ b/common/utils/T/.gitignore @@ -4,6 +4,7 @@ T_IDs.h T_messages.txt.h genids tracer/enb +tracer/gnb tracer/extract_config tracer/record tracer/replay diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index bad6444e13..fedc50cf5d 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1,7 +1,3 @@ -ID = BENETEL - GROUP = ALL - FORMAT = int,frame : int,slot : buffer,rxdataF - #general logs ID = ENB_MASTER_TICK DESC = eNodeB master tick - one tick per ms, to be used as "reference clock", mostly for ticktime view @@ -93,6 +89,10 @@ ID = GNB_PHY_MIB DESC = NR MIB data GROUP = ALL:PHY:GNB:WIRESHARK FORMAT = int,gNB_ID : int,frame : int,slot : buffer,data +ID = GNB_PHY_PUCCH_PUSCH_IQ + DESC = gNodeB input data in the frequency domain for a slot where some PUCCH or PUSCH detection was done + GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB + FORMAT = int,frame : int,slot : buffer,rxdataF #MAC logs ID = ENB_MAC_UE_DL_SDU diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 792c2a407c..0713d9a3df 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -7,7 +7,8 @@ LIBS=-lm XLIBS=-lX11 -lpng -lXft all: record replay extract_config textlog enb ue vcd macpdu2wireshark \ - extract_input_subframe extract_output_subframe to_vcd extract multi + extract_input_subframe extract_output_subframe to_vcd extract multi \ + gnb record: utils.o record.o database.o config.o $(CC) $(CFLAGS) -o record $^ $(LIBS) @@ -60,6 +61,11 @@ macpdu2wireshark: macpdu2wireshark.o database.o utils.o handler.o event.o \ multi: multi.o utils.o database.o config.o $(CC) $(CFLAGS) -o multi $^ $(LIBS) +gnb: utils.o gnb.o database.o event.o handler.o config.o \ + view/view.a gui/gui.a logger/logger.a \ + filter/filter.a + $(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS) + multi.o: ../T_IDs.h ../T_IDs.h: @@ -85,7 +91,7 @@ filter/filter.a: clean: rm -f *.o core tracer_remote textlog enb ue vcd record replay rm -f extract_config macpdu2wireshark extract_input_subframe - rm -f extract_output_subframe to_vcd extract multi + rm -f extract_output_subframe to_vcd extract multi gnb cd gui && $(MAKE) clean cd view && $(MAKE) clean cd logger && $(MAKE) clean diff --git a/common/utils/T/tracer/gnb.c b/common/utils/T/tracer/gnb.c new file mode 100644 index 0000000000..4aaa4898a1 --- /dev/null +++ b/common/utils/T/tracer/gnb.c @@ -0,0 +1,172 @@ +#include +#include +#include +#include +#include +#include "database.h" +#include "handler.h" +#include "config.h" +#include "logger/logger.h" +#include "view/view.h" +#include "gui/gui.h" + +typedef struct { + widget *pucch_pusch_iq_plot; + logger *pucch_pusch_iq_logger; +} gnb_gui; + +typedef struct { + int socket; + int *is_on; + int nevents; + pthread_mutex_t lock; + gnb_gui *e; + void *database; +} gnb_data; + +void is_on_changed(void *_d) +{ + gnb_data *d = _d; + char t; + + if (pthread_mutex_lock(&d->lock)) abort(); + + if (d->socket == -1) goto no_connection; + + t = 1; + if (socket_send(d->socket, &t, 1) == -1 || + socket_send(d->socket, &d->nevents, sizeof(int)) == -1 || + socket_send(d->socket, d->is_on, d->nevents * sizeof(int)) == -1) + goto connection_dies; + +no_connection: + if (pthread_mutex_unlock(&d->lock)) abort(); + return; + +connection_dies: + close(d->socket); + d->socket = -1; + if (pthread_mutex_unlock(&d->lock)) abort(); +} + +void usage(void) +{ + printf( +"options:\n" +" -d this option is mandatory\n" +" -ip connect to given IP address (default %s)\n" +" -p connect to given port (default %d)\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +static void *gui_thread(void *_g) +{ + gui *g = _g; + gui_loop(g); + return NULL; +} + +static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database, + gnb_data *ed) +{ + widget *main_window; + widget *top_container; + widget *line; + widget *w; + logger *l; + view *v; + + main_window = new_toplevel_window(g, 500, 300, "gNB tracer"); + + top_container = new_container(g, VERTICAL); + widget_add_child(g, main_window, top_container, -1); + + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + + /* PUCCH/PUSCH IQ data */ + w = new_xy_plot(g, 55, 55, "", 50); + e->pucch_pusch_iq_plot = w; + widget_add_child(g, line, w, -1); + xy_plot_set_range(g, w, -1000, 1000, -1000, 1000); + xy_plot_set_title(g, w, "rxdataF"); + l = new_iqlog_full(h, database, "GNB_PHY_PUCCH_PUSCH_IQ", "rxdataF"); + v = new_view_xy(300*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE); + logger_add_view(l, v); + e->pucch_pusch_iq_logger = l; +} + +int main(int n, char **v) +{ + char *database_filename = NULL; + void *database; + char *ip = DEFAULT_REMOTE_IP; + int port = DEFAULT_REMOTE_PORT; + int *is_on; + int number_of_events; + int i; + event_handler *h; + gnb_data gnb_data; + gui *g; + gnb_gui eg; + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) + { if (i > n-2) usage(); database_filename = v[++i]; continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(database_filename); + + load_config_file(database_filename); + + number_of_events = number_of_ids(database); + is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); + + h = new_handler(database); + + on_off(database, "GNB_PHY_PUCCH_PUSCH_IQ", is_on, 1); + + gnb_data.database = database; + gnb_data.socket = -1; + gnb_data.is_on = is_on; + gnb_data.nevents = number_of_events; + if (pthread_mutex_init(&gnb_data.lock, NULL)) abort(); + + g = gui_init(); + new_thread(gui_thread, g); + + gnb_main_gui(&eg, g, h, database, &gnb_data); + + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + +restart: + clear_remote_config(); + if (gnb_data.socket != -1) close(gnb_data.socket); + gnb_data.socket = connect_to(ip, port); + + /* send the first message - activate selected traces */ + is_on_changed(&gnb_data); + + /* read messages */ + while (1) { + event e; + e = get_event(gnb_data.socket, &ebuf, database); + if (e.type == -1) goto restart; + if (pthread_mutex_lock(&gnb_data.lock)) abort(); + handle_event(h, e); + if (pthread_mutex_unlock(&gnb_data.lock)) abort(); + } + + return 0; +} diff --git a/common/utils/T/tracer/logger/iqlog.c b/common/utils/T/tracer/logger/iqlog.c index 168c50e39b..1947de2bca 100644 --- a/common/utils/T/tracer/logger/iqlog.c +++ b/common/utils/T/tracer/logger/iqlog.c @@ -74,6 +74,44 @@ static void _event(void *p, event e) l->common.v[i]->append(l->common.v[i], l->i, l->q, count); } +static void _event_full(void *p, event e) +{ + struct iqlog *l = p; + int i; + void *buffer; + int bsize; + int nsamples; + float *idst, *qdst; + + if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) + return; + + buffer = e.e[l->buffer_arg].b; + bsize = e.e[l->buffer_arg].bsize; + + nsamples = bsize / 4; + + if (nsamples > l->max_length) { + l->i = realloc(l->i, nsamples * sizeof(float)); + if (l->i == NULL) abort(); + l->q = realloc(l->q, nsamples * sizeof(float)); + if (l->q == NULL) abort(); + l->max_length = nsamples; + } + + idst = l->i; + qdst = l->q; + for (i = 0; i < nsamples; i++) { + *idst = ((int16_t *)buffer)[i * 2]; + *qdst = ((int16_t *)buffer)[i * 2 + 1]; + idst++; + qdst++; + } + + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->append(l->common.v[i], l->i, l->q, nsamples); +} + logger *new_iqlog(event_handler *h, void *database, char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti, char *buffer_varname) @@ -149,3 +187,43 @@ logger *new_iqlog(event_handler *h, void *database, return ret; } + +logger *new_iqlog_full(event_handler *h, void *database, char *event_name, + char *buffer_varname) +{ + struct iqlog *ret; + int event_id; + database_event_format f; + int i; + + ret = calloc(1, sizeof(struct iqlog)); if (ret == NULL) abort(); + + ret->common.event_name = strdup(event_name); + if (ret->common.event_name == NULL) abort(); + ret->database = database; + + event_id = event_id_from_name(database, event_name); + + ret->common.handler_id = register_handler_function(h, event_id, _event_full, + ret); + + f = get_format(database, event_id); + + /* look for args */ + ret->buffer_arg = -1; + for (i = 0; i < f.count; i++) { + if (!strcmp(f.name[i], buffer_varname)) ret->buffer_arg = i; + } + if (ret->buffer_arg == -1) { + printf("%s:%d: buffer argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, buffer_varname, event_name); + abort(); + } + if (strcmp(f.type[ret->buffer_arg], "buffer") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'buffer')\n", + __FILE__, __LINE__, buffer_varname); + abort(); + } + + return ret; +} diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index 7c019b4797..d746161e70 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -23,6 +23,8 @@ logger *new_ticklog(void *event_handler, void *database, logger *new_iqlog(void *event_handler, void *database, char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti, char *buffer_varname); +logger *new_iqlog_full(void *event_handler, void *database, char *event_name, + char *buffer_varname); logger *new_iqdotlog(void *event_handler, void *database, char *event_name, char *I, char *Q); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 9d7422745e..b26c95fc4d 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -542,6 +542,9 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { + /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */ + int pucch_decode_done = 0; + int pusch_decode_done = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1); LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx); @@ -563,6 +566,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) (pucch->frame == frame_rx) && (pucch->slot == slot_rx) ) { + pucch_decode_done = 1; + nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu; uint16_t num_ucis; switch (pucch_pdu->format_type) { @@ -651,7 +656,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } #endif -T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], 2048*4*14)); + pusch_decode_done = 1; uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index; uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols; @@ -680,5 +685,9 @@ T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF // figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS if ((frame_rx&127) == 0 && slot_rx==19) dump_pusch_stats(gNB); + if (pucch_decode_done || pusch_decode_done) { + T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4)); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0); } From fdc818bc0684025f269a8aa65262e47c1f49aaa9 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 2 Mar 2021 21:39:19 +0100 Subject: [PATCH 69/91] Update TESTING_GNB_W_COTS_UE.md --- doc/TESTING_GNB_W_COTS_UE.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index 610cc5bdd4..73ae18351f 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -30,8 +30,6 @@ http://www.saelig.com/MFR00066/ste2300.htm ## Configuration Overview * Non Standalone (NSA) configuration : initial Control Plane established between UE and RAN eNB, then User Plane established between UE and gNB, Core network is 4G based supporting rel 15 - -* Commercial UE: Oppo Reno 5G * OAI Software Defined gNB and eNB * eNB RF front end: USRP (ETTUS) B200 Mini or B210 * gNB RF front end: USRP (ETTUS) B200 Mini or B210 (N310 will be needed for MIMO and wider BW's) @@ -40,6 +38,17 @@ http://www.saelig.com/MFR00066/ste2300.htm * BW: 40MHz * Antenna scheme: SISO +## COTS UEs + +Our code might not work with all 5G phones yet, but we are constantly improving it. Here is a list of COTS UEs that we know that work with OAI. + +* Oppo Reno 5G +* Samsung A90 5G +* Google Pixel 5G +* Simcom SIMCOM8200EA +* Quectel RM500Q-GL + + ## Repository https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop From 9edc8cce0ab9e61babec8b9263831a4df57bc82e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 3 Mar 2021 13:41:10 +0100 Subject: [PATCH 70/91] nr pdcp: improvements Implement data transfer (38.331 5.2): - transmit operation (in nr_pdcp_entity_recv_sdu) - receive operation (in nr_pdcp_entity_recv_pdu) - t-Reordering expiration To keep track of time the function nr_pdcp_wakeup_timer_thread has been added and is called by the gNB's MAC scheduler via nr_pdcp_tick. (The UE has not been modified.) A thread has been introduced to set time of all the existing PDCP entities in the system. This probably does not scale well with many PDCP entities (many UEs connected to the gNB). To be changed at some point when needed. Hopefully, with a few UEs this mechanism won't be too problematic (ie. won't cause realtime problems). The problem with time in PDCP is that SDUs are kept if some are missing, to do reordering. A timer is started and when it expires we have to transmit the SDUs even if some are still missing. We want to do that as soon as possible. So we have to check timers often (every millisecond). In RLC the time is set when there is some activity (SDU or PDU received). In PDCP we cannot wait for this kind of activity. We would keep packets longer than necessary, which may disturb upper layers (think: TCP). That is why we introduced the thread, as a simple mechanism to keep packets no longer than necessary. The locking done by this thread may create realtime issues. The whole logic of time keeping can be changed later if it turns out that it is not efficient. The functions dealing with DRB AM have been removed. All the types of PDCP entities (DRB AM, DRB UM, SRB) use the same mechanism for transmit and receive operations. So the code has been made common for all those types. We don't deal with: - entity re-establishment, entity release or entity suspend - SDU discard (the timer is present but not used) - status reporting - data recovery - data volume calculation - header compression / decompression There is no plan to implement those features in a near future. Integrity protection is not done yet, and will be implemented soon. --- cmake_targets/CMakeLists.txt | 3 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 2 + openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c | 262 ++++++++++++++++-- openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h | 57 +++- .../LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c | 90 ------ openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 29 +- openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c | 78 ++++++ ...{nr_pdcp_entity_drb_am.h => nr_pdcp_sdu.h} | 30 +- .../LAYER2/nr_pdcp/nr_pdcp_timer_thread.c | 87 ++++++ .../LAYER2/nr_pdcp/nr_pdcp_timer_thread.h | 32 +++ openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c | 14 + openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h | 3 + 12 files changed, 530 insertions(+), 157 deletions(-) delete mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c rename openair2/LAYER2/nr_pdcp/{nr_pdcp_entity_drb_am.h => nr_pdcp_sdu.h} (58%) create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index e11c850b8e..58530a5ae4 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1967,7 +1967,8 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c - ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_sdu.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index ede68b11ef..3c300c5f9d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -364,7 +364,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, /* send tick to RLC and RRC every ms */ if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) { void nr_rlc_tick(int frame, int subframe); + void nr_pdcp_tick(int frame, int subframe); nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing); + nr_pdcp_tick(frame, slot >> *scc->ssbSubcarrierSpacing); nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index ffc669a461..eda6888ecd 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -21,24 +21,222 @@ #include "nr_pdcp_entity.h" -#include "nr_pdcp_entity_drb_am.h" +#include +#include +#include + #include "nr_pdcp_security_nea2.h" +#include "nr_pdcp_sdu.h" #include "LOG/log.h" -nr_pdcp_entity_t *new_nr_pdcp_entity_srb( - int is_gnb, int rb_id, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size, int sdu_id), - void *deliver_pdu_data) +static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, + char *_buffer, int size) { - abort(); + unsigned char *buffer = (unsigned char *)_buffer; + nr_pdcp_sdu_t *sdu; + int rcvd_sn; + uint32_t rcvd_hfn; + uint32_t rcvd_count; + int header_size; + int integrity_size; + int rx_deliv_sn; + uint32_t rx_deliv_hfn; + + if (size < 1) { + LOG_E(PDCP, "bad PDU received (size = %d)\n", size); + return; + } + + if (!(buffer[0] & 0x80)) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (entity->sn_size == 12) { + rcvd_sn = (((unsigned char)buffer[0] & 0xf) << 8) | + (unsigned char)buffer[1]; + header_size = 2; + } else { + rcvd_sn = (((unsigned char)buffer[0] & 0x3) << 16) | + ((unsigned char)buffer[1] << 8) | + (unsigned char)buffer[2]; + header_size = 3; + } + + integrity_size = 0; + + if (size < header_size + integrity_size + 1) { + LOG_E(PDCP, "bad PDU received (size = %d)\n", size); + return; + } + + rx_deliv_sn = entity->rx_deliv & entity->sn_max; + rx_deliv_hfn = (entity->rx_deliv >> entity->sn_size) & ~entity->sn_max; + + if (rcvd_sn < rx_deliv_sn - entity->window_size) { + rcvd_hfn = rx_deliv_hfn + 1; + } else if (rcvd_sn >= rx_deliv_sn + entity->window_size) { + rcvd_hfn = rx_deliv_hfn - 1; + } else { + rcvd_hfn = rx_deliv_hfn; + } + + rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn; + + if (entity->has_ciphering) + entity->cipher(entity->security_context, + (unsigned char *)buffer+header_size, size-header_size, + entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1); + + if (rcvd_count < entity->rx_deliv + || nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) { + LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count); + return; + } + + sdu = nr_pdcp_new_sdu(rcvd_count, + (char *)buffer + header_size, + size - header_size - integrity_size); + entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu); + entity->rx_size += size-header_size; + + if (rcvd_count >= entity->rx_next) { + entity->rx_next = rcvd_count + 1; + } + + /* TODO(?): out of order delivery */ + + if (rcvd_count == entity->rx_deliv) { + /* deliver all SDUs starting from rx_deliv up to discontinuity or end of list */ + uint32_t count = entity->rx_deliv; + while (entity->rx_list != NULL && count == entity->rx_list->count) { + nr_pdcp_sdu_t *cur = entity->rx_list; + entity->deliver_sdu(entity->deliver_sdu_data, entity, + cur->buffer, cur->size); + entity->rx_list = cur->next; + entity->rx_size -= cur->size; + nr_pdcp_free_sdu(cur); + count++; + } + entity->rx_deliv = count; + } + + if (entity->t_reordering_start != 0 && entity->rx_deliv > entity->rx_reord) { + /* stop and reset t-Reordering */ + entity->t_reordering_start = 0; + } + + if (entity->t_reordering_start == 0 && entity->rx_deliv < entity->rx_next) { + entity->rx_reord = entity->rx_next; + entity->t_reordering_start = entity->t_current; + } } -nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( +static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity, + char *buffer, int size, int sdu_id) +{ + uint32_t count; + int sn; + int header_size; + char buf[size+3+4]; + + count = entity->tx_next; + sn = entity->tx_next & entity->sn_max; + + if (entity->sn_size == 12) { + buf[0] = 0x80 | ((sn >> 8) & 0xf); + buf[1] = sn & 0xff; + header_size = 2; + } else { + buf[0] = 0x80 | ((sn >> 16) & 0x3); + buf[1] = (sn >> 8) & 0xff; + buf[2] = sn & 0xff; + header_size = 3; + } + + memcpy(buf+header_size, buffer, size); + + if (entity->has_ciphering) + entity->cipher(entity->security_context, + (unsigned char *)buf+header_size, size, + entity->rb_id, count, entity->is_gnb ? 1 : 0); + + entity->tx_next++; + + entity->deliver_pdu(entity->deliver_pdu_data, entity, buf, + size+header_size, sdu_id); +} + +static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity, + char *key) +{ + memcpy(entity->integrity_key, key, 16); +} + +static void check_t_reordering(nr_pdcp_entity_t *entity) +{ + uint32_t count; + + if (entity->t_reordering_start == 0 + || entity->t_current <= entity->t_reordering_start + entity->t_reordering) + return; + + /* stop timer */ + entity->t_reordering_start = 0; + + /* deliver all SDUs with count < rx_reord */ + while (entity->rx_list != NULL && entity->rx_list->count < entity->rx_reord) { + nr_pdcp_sdu_t *cur = entity->rx_list; + entity->deliver_sdu(entity->deliver_sdu_data, entity, + cur->buffer, cur->size); + entity->rx_list = cur->next; + entity->rx_size -= cur->size; + nr_pdcp_free_sdu(cur); + } + + /* deliver all SDUs starting from rx_reord up to discontinuity or end of list */ + count = entity->rx_reord; + while (entity->rx_list != NULL && count == entity->rx_list->count) { + nr_pdcp_sdu_t *cur = entity->rx_list; + entity->deliver_sdu(entity->deliver_sdu_data, entity, + cur->buffer, cur->size); + entity->rx_list = cur->next; + entity->rx_size -= cur->size; + nr_pdcp_free_sdu(cur); + count++; + } + + entity->rx_deliv = count; + + if (entity->rx_deliv < entity->rx_next) { + entity->rx_reord = entity->rx_next; + entity->t_reordering_start = entity->t_current; + } +} + +void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now) +{ + entity->t_current = now; + + check_t_reordering(entity); +} + +void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity) +{ + nr_pdcp_sdu_t *cur = entity->rx_list; + while (cur != NULL) { + nr_pdcp_sdu_t *next = cur->next; + nr_pdcp_free_sdu(cur); + cur = next; + } + if (entity->free_security != NULL) + entity->free_security(entity->security_context); + free(entity); +} + +nr_pdcp_entity_t *new_nr_pdcp_entity( + nr_pdcp_entity_type_t type, int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), @@ -54,52 +252,56 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( unsigned char *ciphering_key, unsigned char *integrity_key) { - nr_pdcp_entity_drb_am_t *ret; + nr_pdcp_entity_t *ret; - ret = calloc(1, sizeof(nr_pdcp_entity_drb_am_t)); + ret = calloc(1, sizeof(nr_pdcp_entity_t)); if (ret == NULL) { LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - ret->common.recv_pdu = nr_pdcp_entity_drb_am_recv_pdu; - ret->common.recv_sdu = nr_pdcp_entity_drb_am_recv_sdu; - ret->common.set_integrity_key = nr_pdcp_entity_drb_am_set_integrity_key; + ret->type = type; - ret->common.delete = nr_pdcp_entity_drb_am_delete; + ret->recv_pdu = nr_pdcp_entity_recv_pdu; + ret->recv_sdu = nr_pdcp_entity_recv_sdu; + ret->set_integrity_key = nr_pdcp_entity_set_integrity_key; + ret->set_time = nr_pdcp_entity_set_time; - ret->common.deliver_sdu = deliver_sdu; - ret->common.deliver_sdu_data = deliver_sdu_data; + ret->delete = nr_pdcp_entity_delete; - ret->common.deliver_pdu = deliver_pdu; - ret->common.deliver_pdu_data = deliver_pdu_data; + ret->deliver_sdu = deliver_sdu; + ret->deliver_sdu_data = deliver_sdu_data; + + ret->deliver_pdu = deliver_pdu; + ret->deliver_pdu_data = deliver_pdu_data; ret->rb_id = rb_id; ret->sn_size = sn_size; ret->t_reordering = t_reordering; ret->discard_timer = discard_timer; - ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1; + ret->sn_max = (1 << sn_size) - 1; + ret->window_size = 1 << (sn_size - 1); if (ciphering_key != NULL && ciphering_algorithm != 0) { if (ciphering_algorithm != 2) { LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n"); exit(1); } - ret->common.has_ciphering = 1; - ret->common.ciphering_algorithm = ciphering_algorithm; - memcpy(ret->common.ciphering_key, ciphering_key, 16); + ret->has_ciphering = 1; + ret->ciphering_algorithm = ciphering_algorithm; + memcpy(ret->ciphering_key, ciphering_key, 16); - ret->common.security_context = nr_pdcp_security_nea2_init(ciphering_key); - ret->common.cipher = nr_pdcp_security_nea2_cipher; - ret->common.free_security = nr_pdcp_security_nea2_free_security; + ret->security_context = nr_pdcp_security_nea2_init(ciphering_key); + ret->cipher = nr_pdcp_security_nea2_cipher; + ret->free_security = nr_pdcp_security_nea2_free_security; } - ret->common.is_gnb = is_gnb; + ret->is_gnb = is_gnb; if (integrity_key != NULL) { printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - return (nr_pdcp_entity_t *)ret; + return ret; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 58d79835ec..36e7a540c4 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -19,18 +19,29 @@ * contact@openairinterface.org */ -#include - #ifndef _NR_PDCP_ENTITY_H_ #define _NR_PDCP_ENTITY_H_ +#include + +#include "nr_pdcp_sdu.h" + +typedef enum { + NR_PDCP_DRB_AM, + NR_PDCP_DRB_UM, + NR_PDCP_SRB +} nr_pdcp_entity_type_t; + typedef struct nr_pdcp_entity_t { + nr_pdcp_entity_type_t type; + /* functions provided by the PDCP module */ void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size); void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size, int sdu_id); void (*delete)(struct nr_pdcp_entity_t *entity); void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key); + void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now); /* callbacks provided to the PDCP module */ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, @@ -39,9 +50,28 @@ typedef struct nr_pdcp_entity_t { void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size, int sdu_id); void *deliver_pdu_data; - int tx_hfn; - int next_nr_pdcp_tx_sn; - int maximum_nr_pdcp_sn; + + /* configuration variables */ + int rb_id; + + int sn_size; /* SN size, in bits */ + int t_reordering; /* unit: ms */ + int discard_timer; /* unit: ms */ + + int sn_max; /* (2^SN_size) - 1 */ + int window_size; /* 2^(SN_size - 1) */ + + /* state variables */ + uint32_t tx_next; + uint32_t rx_next; + uint32_t rx_deliv; + uint32_t rx_reord; + + /* set to the latest know time by the user of the module. Unit: ms */ + uint64_t t_current; + + /* timers (stores the ms of activation, 0 means not active) */ + int t_reordering_start; /* security */ int has_ciphering; @@ -60,18 +90,15 @@ typedef struct nr_pdcp_entity_t { * pdcp entity is for a gnb or an ue */ int is_gnb; + + /* rx management */ + nr_pdcp_sdu_t *rx_list; + int rx_size; + int rx_maxsize; } nr_pdcp_entity_t; -nr_pdcp_entity_t *new_nr_pdcp_entity_srb( - int is_gnb, int rb_id, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size, int sdu_id), - void *deliver_pdu_data); - -nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( +nr_pdcp_entity_t *new_nr_pdcp_entity( + nr_pdcp_entity_type_t type, int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c deleted file mode 100644 index 62881c184e..0000000000 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "nr_pdcp_entity_drb_am.h" - -#include -#include -#include -#include "common/utils/LOG/log.h" - -void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size) -{ - nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; - int sn; - - if (size < 3) abort(); - - if (!(buffer[0] & 0x80)) - LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - - sn = (((unsigned char)buffer[0] & 0x3) << 16) | - ((unsigned char)buffer[1] << 8) | - (unsigned char)buffer[2]; - - if (entity->common.has_ciphering) - entity->common.cipher(entity->common.security_context, (unsigned char *)buffer+3, size-3, - entity->rb_id, sn, entity->common.is_gnb ? 0 : 1); - - entity->common.deliver_sdu(entity->common.deliver_sdu_data, - (nr_pdcp_entity_t *)entity, buffer+3, size-3); -} - -void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size, - int sdu_id) -{ - nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; - int sn; - char buf[size+3]; - - sn = entity->common.next_nr_pdcp_tx_sn; - - entity->common.next_nr_pdcp_tx_sn++; - if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) { - entity->common.next_nr_pdcp_tx_sn = 0; - entity->common.tx_hfn++; - } - - buf[0] = 0x80 | ((sn >> 16) & 0x3); - buf[1] = (sn >> 8) & 0xff; - buf[2] = sn & 0xff; - memcpy(buf+3, buffer, size); - - if (entity->common.has_ciphering) - entity->common.cipher(entity->common.security_context, (unsigned char *)buf+3, size, - entity->rb_id, sn, entity->common.is_gnb ? 1 : 0); - - entity->common.deliver_pdu(entity->common.deliver_pdu_data, - (nr_pdcp_entity_t *)entity, buf, size+3, sdu_id); -} - -void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key) -{ - /* nothing to do */ -} - -void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity) -{ - nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; - if (entity->common.free_security != NULL) - entity->common.free_security(entity->common.security_context); - free(entity); -} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index f14d25b145..597cba7bf5 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -24,6 +24,7 @@ #endif #include "asn1_utils.h" #include "nr_pdcp_ue_manager.h" +#include "nr_pdcp_timer_thread.h" #include "NR_RadioBearerConfig.h" #include "NR_RLC-BearerConfig.h" #include "NR_RLC-Config.h" @@ -41,6 +42,11 @@ static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager; +/* TODO: handle time a bit more properly */ +static uint64_t nr_pdcp_current_time; +static int nr_pdcp_current_time_last_frame; +static int nr_pdcp_current_time_last_subframe; + /* necessary globals for OAI, not used internally */ hash_table_t *pdcp_coll_p; static uint64_t pdcp_optmask; @@ -339,6 +345,8 @@ void pdcp_layer_init(void) nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1); init_nr_rlc_data_req_queue(); + + nr_pdcp_init_timer_thread(nr_pdcp_ue_manager); } #include "nfapi/oai_integration/vendor_ext.h" @@ -625,11 +633,11 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - pdcp_drb = new_nr_pdcp_entity_drb_am(is_gnb, drb_id, - deliver_sdu_drb, ue, deliver_pdu_drb, ue, - sn_size_dl, t_reordering, discard_timer, - ciphering_algorithm, integrity_algorithm, - ciphering_key, integrity_key); + pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id, + deliver_sdu_drb, ue, deliver_pdu_drb, ue, + sn_size_dl, t_reordering, discard_timer, + ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); @@ -976,3 +984,14 @@ void pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){ /* nothing to do */ } + +void nr_pdcp_tick(int frame, int subframe) +{ + if (frame != nr_pdcp_current_time_last_frame || + subframe != nr_pdcp_current_time_last_subframe) { + nr_pdcp_current_time_last_frame = frame; + nr_pdcp_current_time_last_subframe = subframe; + nr_pdcp_current_time++; + nr_pdcp_wakeup_timer_thread(nr_pdcp_current_time); + } +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c new file mode 100644 index 0000000000..47d95156e3 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c @@ -0,0 +1,78 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_sdu.h" + +#include +#include + +nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size) +{ + nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t)); + if (ret == NULL) + exit(1); + ret->count = count; + ret->buffer = malloc(size); + if (ret->buffer == NULL) + exit(1); + memcpy(ret->buffer, buffer, size); + ret->size = size; + return ret; +} + +nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu) +{ + nr_pdcp_sdu_t head; + nr_pdcp_sdu_t *cur; + nr_pdcp_sdu_t *prev; + + head.next = l; + cur = l; + prev = &head; + + /* order is by 'count' */ + while (cur != NULL) { + /* check if 'sdu' is before 'cur' in the list */ + if (sdu->count < cur->count) + break; + prev = cur; + cur = cur->next; + } + prev->next = sdu; + sdu->next = cur; + return head.next; +} + +int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count) +{ + while (l != NULL) { + if (l->count == count) + return 1; + l = l->next; + } + return 0; +} + +void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu) +{ + free(sdu->buffer); + free(sdu); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h similarity index 58% rename from openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h rename to openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h index d7c42e6a62..3d4e50a4ce 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h @@ -19,23 +19,21 @@ * contact@openairinterface.org */ -#ifndef _NR_PDCP_ENTITY_DRB_AM_H_ -#define _NR_PDCP_ENTITY_DRB_AM_H_ +#ifndef _NR_PDCP_SDU_H_ +#define _NR_PDCP_SDU_H_ -#include "nr_pdcp_entity.h" +#include -typedef struct { - nr_pdcp_entity_t common; - int rb_id; - int sn_size; /* unit: bits */ - int t_reordering; /* unit: ms */ - int discard_timer; /* unit: ms, -1 means infinity */ -} nr_pdcp_entity_drb_am_t; +typedef struct nr_pdcp_sdu_t { + uint32_t count; + char *buffer; + int size; + struct nr_pdcp_sdu_t *next; +} nr_pdcp_sdu_t; -void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size); -void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *entity, char *buffer, int size, - int sdu_id); -void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *entity, char *key); -void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *entity); +nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size); +nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu); +int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count); +void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu); -#endif /* _NR_PDCP_ENTITY_DRB_AM_H_ */ +#endif /* _NR_PDCP_SDU_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c new file mode 100644 index 0000000000..36e9b16024 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c @@ -0,0 +1,87 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_timer_thread.h" + +#include +#include +#include + +#include "LOG/log.h" + +static pthread_mutex_t timer_thread_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t timer_thread_cond = PTHREAD_COND_INITIALIZER; +static volatile uint64_t timer_thread_curtime = 0; + +static void *nr_pdcp_timer_thread(void *_nr_pdcp_ue_manager) +{ + nr_pdcp_ue_manager_t *nr_pdcp_ue_manager = (nr_pdcp_ue_manager_t *)_nr_pdcp_ue_manager; + nr_pdcp_ue_t **ue_list; + int ue_count; + int i; + int j; + uint64_t curtime = 0; + + while (1) { + if (pthread_mutex_lock(&timer_thread_mutex) != 0) abort(); + while (curtime == timer_thread_curtime) + if (pthread_cond_wait(&timer_thread_cond, &timer_thread_mutex) != 0) abort(); + curtime = timer_thread_curtime; + if (pthread_mutex_unlock(&timer_thread_mutex) != 0) abort(); + + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + + ue_list = nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager); + ue_count = nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager); + for (i = 0; i < ue_count; i++) { + for (j = 0; j < 2; j++) { + if (ue_list[i]->srb[j] != NULL) + ue_list[i]->srb[j]->set_time(ue_list[i]->srb[j], curtime); + } + for (j = 0; j < 5; j++) { + if (ue_list[i]->drb[j] != NULL) + ue_list[i]->drb[j]->set_time(ue_list[i]->drb[j], curtime); + } + } + + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + } + + return NULL; +} + +void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager) +{ + pthread_t t; + + if (pthread_create(&t, NULL, nr_pdcp_timer_thread, nr_pdcp_ue_manager) != 0) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +void nr_pdcp_wakeup_timer_thread(uint64_t time) +{ + if (pthread_mutex_lock(&timer_thread_mutex)) abort(); + timer_thread_curtime = time; + if (pthread_cond_broadcast(&timer_thread_cond)) abort(); + if (pthread_mutex_unlock(&timer_thread_mutex)) abort(); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h new file mode 100644 index 0000000000..db8282f940 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h @@ -0,0 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_PDCP_TIMER_THREAD_H_ +#define _NR_PDCP_TIMER_THREAD_H_ + +#include "nr_pdcp_ue_manager.h" + +#include + +void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager); +void nr_pdcp_wakeup_timer_thread(uint64_t time); + +#endif /* _NR_PDCP_TIMER_THREAD_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c index ca51da3d5f..f89a18f94e 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c @@ -189,6 +189,20 @@ void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, nr_pdcp_entity ue->drb[drb_id] = entity; } +/* must be called with lock acquired */ +nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m) +{ + nr_pdcp_ue_manager_internal_t *m = _m; + return m->ue_list; +} + +/* must be called with lock acquired */ +int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m) +{ + nr_pdcp_ue_manager_internal_t *m = _m; + return m->ue_count; +} + int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m) { nr_pdcp_ue_manager_internal_t *m = _m; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h index 0de2f024b3..3329f856b7 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h @@ -46,6 +46,9 @@ void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *m); nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti); void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti); +nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m); +int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m); + /***********************************************************************/ /* ue functions */ /***********************************************************************/ From 01645168f0ebaaa0374a0d62740e17e5b23e4de5 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 18 Feb 2021 13:17:38 +0100 Subject: [PATCH 71/91] NR_UE: handle initial TA the same way as TA updates, independent of the UE_mode In FDD mode, the UE_mode switches to PUSCH mode before the initial TA value was applied. Because of this, the ta_command was misinterpreted. Fix this by adding 31 to the initial TA comamnd and handle it the same as TA updates. --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 34 +++++--------------- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f516ad8639..9843a7e174 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -238,33 +238,15 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){ int factor_mu = 1 << numerology; uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB); - LOG_D(PHY, "In %s: applying timing advance -- frame %d -- slot %d -- UE_mode %d\n", __FUNCTION__, frame_tx, slot_tx, ue->UE_mode[gNB_id]); + ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling / factor_mu; - if (ue->UE_mode[gNB_id] == RA_RESPONSE){ - - ue->timing_advance = ul_time_alignment->ta_command * bw_scaling / factor_mu; - - LOG_D(PHY, "In %s: [UE %d] [%d.%d] Received (RAR) timing advance command %d new value is %u \n", - __FUNCTION__, - ue->Mod_id, - frame_tx, - slot_tx, - ul_time_alignment->ta_command, - ue->timing_advance); - - } else if (ue->UE_mode[gNB_id] == PUSCH){ - - ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling / factor_mu; - - LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", - __FUNCTION__, - ue->Mod_id, - frame_tx, - slot_tx, - ul_time_alignment->ta_command, - ue->timing_advance); - - } + LOG_I(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", + __FUNCTION__, + ue->Mod_id, + frame_tx, + slot_tx, + ul_time_alignment->ta_command, + ue->timing_advance); ul_time_alignment->ta_frame = -1; ul_time_alignment->ta_slot = -1; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 64067e9d60..0f347204a0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2230,7 +2230,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t // TA command ul_time_alignment->apply_ta = 1; - ul_time_alignment->ta_command = rar->TA2 + (rar->TA1 << 5); + ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5); #ifdef DEBUG_RAR // CSI From f2bc1012be43ae2f630877ab2b1d28bc478758ac Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 18 Feb 2021 08:56:54 +0100 Subject: [PATCH 72/91] Minor cleanup UE - removed commented out code - improved logging in UL channel estimation - minor fixes according to OAI coding guidelines - moving fetching TDD configuration parameters in nr-ue.c only in TDD case --- executables/nr-ue.c | 10 ++- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 90 ++++++++++++++----- 2 files changed, 73 insertions(+), 27 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 0c97552c15..dd11071682 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -703,12 +703,14 @@ void *UE_thread(void *arg) { int flags = 0; int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - RX_NB_TH; - uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots; - uint8_t num_UL_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots + - (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0); - uint8_t first_tx_slot = tdd_period - num_UL_slots; if (openair0_cfg[0].duplex_mode == duplex_mode_TDD) { + + uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots; + int nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSlots != 0); + uint8_t first_tx_slot = tdd_period - num_UL_slots; + if (slot_tx_usrp % tdd_period == first_tx_slot) flags = 2; else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 713e71674b..6617fabbb4 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -61,8 +61,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, debug_ch_est = fopen("debug_ch_est.txt","w"); #endif - //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1]; - uint8_t nushift; int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates; int **rxdataF = gNB->common_vars.rxdataF; @@ -79,12 +77,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, uint16_t nb_rb_pusch = pusch_pdu->rb_size; -/* #ifdef DEBUG_CH - printf("PUSCH Channel Estimation : ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", ,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size, - gNB->frame_parms.Ncp,l,Ns,k, symbol); + LOG_I(PHY, "In %s: ch_offset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n", + __FUNCTION__, + ch_offset, + symbol_offset, + gNB->frame_parms.ofdm_symbol_size, + Ns, + k, + symbol); #endif -*/ + switch (nushift) { case 0: fl = filt8_l0; @@ -124,9 +127,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------generate DMRS------------------// - if (pusch_pdu->transform_precoding == transform_precoder_disabled) + if (pusch_pdu->transform_precoding == transform_precoder_disabled) { nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); - + } else { // if transform precoding or SC-FDMA is enabled in Uplink // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible @@ -151,11 +154,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------------------------------------// - #ifdef DEBUG_PUSCH - for (int i=0;i<(6*nb_rb_pusch);i++) - printf("%d+j*(%d)\n",((int16_t*)pilot)[2*i],((int16_t*)pilot)[1+(2*i)]); + for (int i = 0; i < (6 * nb_rb_pusch); i++) { + LOG_I(PHY, "In %s: %d + j*(%d)\n", + __FUNCTION__, + ((int16_t*)pilot)[2 * i], + ((int16_t*)pilot)[1 + (2 * i)]); + } #endif + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { pil = (int16_t *)&pilot[0]; @@ -165,11 +172,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); #ifdef DEBUG_PUSCH - printf("symbol_offset %d, nushift %d\n",symbol_offset,nushift); - printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL); - printf("bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n",bwp_start_subcarrier,k,gNB->frame_parms.first_carrier_offset,nb_rb_pusch); - printf("rxF addr %p p %d\n", rxF,p); - printf("ul_ch addr %p nushift %d\n",ul_ch,nushift); + LOG_I(PHY, "In %s symbol_offset %d, nushift %d\n", __FUNCTION__, symbol_offset, nushift); + LOG_I(PHY, "In %s ch est pilot addr %p, N_RB_UL %d\n", __FUNCTION__, &pilot[0], gNB->frame_parms.N_RB_UL); + LOG_I(PHY, "In %s bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n", __FUNCTION__, bwp_start_subcarrier, k, gNB->frame_parms.first_carrier_offset, nb_rb_pusch); + LOG_I(PHY, "In %s rxF addr %p p %d\n", __FUNCTION__, rxF, p); + LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift); #endif //if ((gNB->frame_parms.N_RB_UL&1)==0) { @@ -180,9 +187,18 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data 0 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3])); + LOG_I(PHY, "In %s ch 0 %d\n", __FUNCTION__, ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); + LOG_I(PHY, "In %s pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n", + __FUNCTION__, + rxF[0], + rxF[1], + dBc(rxF[0],rxF[1]), + ch[0], + ch[1], + dBc(ch[0],ch[1]), + pil[0], + pil[1]); + LOG_I(PHY, "In %s data 0 : rxF - > (%d,%d) (%d)\n", __FUNCTION__, rxF[2], rxF[3], dBc(rxF[2],rxF[3])); #endif multadd_real_vector_complex_scalar(fl, @@ -199,9 +215,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data 1 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3])); + LOG_I(PHY, "In %s pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n", + __FUNCTION__, + rxF[0], + rxF[1], + dBc(rxF[0],rxF[1]), + ch[0], + ch[1], + dBc(ch[0],ch[1]), + pil[0], + pil[1]); + LOG_I(PHY, "In %s data 1 : rxF - > (%d,%d) (%d)\n", + __FUNCTION__, + rxF[2], + rxF[3], + dBc(rxF[2],rxF[3])); #endif + multadd_real_vector_complex_scalar(fml, ch, ul_ch, @@ -215,9 +245,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data 2 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3])); + LOG_I(PHY, "In %s pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n", + __FUNCTION__, + rxF[0], + rxF[1], + dBc(rxF[0],rxF[1]), + ch[0], + ch[1], + dBc(ch[0],ch[1]), + pil[0], + pil[1]); + LOG_I(PHY, "In %s data 2 : rxF - > (%d,%d) (%d)\n", + __FUNCTION__, + rxF[2], + rxF[3], + dBc(rxF[2],rxF[3])); #endif + multadd_real_vector_complex_scalar(fmm, ch, ul_ch, From 222933a59ba1eb4894377d73edf50cc525edbe11 Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 23 Feb 2021 09:40:04 +0100 Subject: [PATCH 73/91] Updated arbitrary frequencies section in RUNMODEM.md file --- doc/RUNMODEM.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index d13b193ff9..ffe963da8f 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -168,7 +168,7 @@ With the RF simulator (on the same machine): ## IF setup with OAI -The -C and -CO flags can be used together at UE side to set custom downlink and uplink FR1 intermediate frequencies for the IF equipment. +The -C and --CO flags can be used together at UE side to set custom downlink and uplink FR1 arbitrary frequencies for the IF equipment. In order to run this setup, the following flags are needed at the UE side: @@ -182,9 +182,11 @@ and the following parameters must be configured in the RUs section of the gNB co `if_offset` -### Run OAI with custom DL/UL intermediate frequencies +The values must be given in Hz. -The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 at gNB side. +### Run OAI with custom DL/UL arbitrary frequencies + +The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 (FDD) at gNB side. From the `cmake_targets/ran_build/build` folder: From 62612feebf710ee97542d4ddfb7d518d0d4c83bb Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 3 Mar 2021 18:00:08 +0100 Subject: [PATCH 74/91] change get_band() to take the duplex spacing into account --- openair1/PHY/INIT/nr_init.c | 12 +- openair1/PHY/INIT/nr_parms.c | 5 +- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 115 ++++++++---------- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 7 +- openair2/LAYER2/NR_MAC_UE/config_ue.c | 3 +- openair2/LAYER2/NR_MAC_gNB/config.c | 3 +- 6 files changed, 63 insertions(+), 82 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 52a6b49cbb..a8faf2bba7 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -455,7 +455,6 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion; NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms; nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config; - int32_t dlul_offset = 0; memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg)); RC.gNB[Mod_id]->mac_enabled = 1; @@ -466,16 +465,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { uint64_t ul_bw_khz = (12*gNB_config->carrier_config.ul_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<ssb_config.scs_common.value); fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ; - //fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - lte_frame_type_t frame_type = 0; // FDD - - get_band(fp->dl_CarrierFreq,&fp->nr_band,&dlul_offset,&frame_type); //RC.nrmac[Mod_id] cannot be accessed in NFAPI + int32_t dlul_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq; + fp->nr_band = get_band(fp->dl_CarrierFreq, dlul_offset); - get_delta_duplex(fp->nr_band, gNB_config->ssb_config.scs_common.value, &dlul_offset); - dlul_offset *= 1000; - - AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + dlul_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + dlul_offset); - LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset); fp->threequarter_fs = openair0_cfg[0].threequarter_fs; diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index ba4147e5cd..c5904a7da5 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -352,9 +352,8 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->N_RB_UL = config->carrier_config.ul_grid_size[fp->numerology_index]; fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index]; - int32_t uplink_frequency_offset = 0; - get_delta_duplex(fp->nr_band, fp->numerology_index, &uplink_frequency_offset); - get_frame_type(fp->nr_band, fp->numerology_index, &fp->frame_type); + fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index); + int32_t uplink_frequency_offset = get_delta_duplex(fp->nr_band, fp->numerology_index); uplink_frequency_offset *= 1000; LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 1ebf83e9a3..5c0c97f566 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1692,9 +1692,45 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = { #define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t)) -// Returns the corresponding row index of the NR table -int get_nr_table_idx(int nr_bandP, uint8_t scs_index){ +uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex) +{ + const uint64_t dl_freq_khz = downlink_frequency / 1000; + const int32_t delta_duplex_khz = delta_duplex / 1000; + uint64_t center_freq_diff_khz = 999999999999999999; // 2^64 + uint16_t current_band = 0; + + for (int ind = 0; ind < NR_BANDTABLE_SIZE; ind++) { + + LOG_D(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min, nr_bandtable[ind].ul_min); + + if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max) + continue; + + int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min; + + if (current_offset_khz != delta_duplex_khz) + continue; + + uint64_t center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min) / 2; + + if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){ + current_band = nr_bandtable[ind].band; + center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz); + } + } + + LOG_I(PHY, "DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n", + downlink_frequency, current_band, downlink_frequency+delta_duplex); + + AssertFatal(current_band != 0, "Can't find EUTRA band for frequency %"PRIu64" and duplex_spacing %u\n", downlink_frequency, delta_duplex); + + return current_band; +} + +// Returns the corresponding row index of the NR table +int get_nr_table_idx(int nr_bandP, uint8_t scs_index) +{ int i, j; int scs_khz = 15 << scs_index; int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95}; @@ -1715,35 +1751,33 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index){ LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min); return i; - } // Computes the duplex spacing (either positive or negative) in KHz -void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex){ - +int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index) +{ int nr_table_idx = get_nr_table_idx(nr_bandP, scs_index); - *delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min); + int32_t delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min); - LOG_D(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", *delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band); + LOG_I(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band); + return delta_duplex; } -void get_frame_type(uint16_t current_band, - uint8_t scs_index, - lte_frame_type_t *current_type){ +lte_frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index) +{ + lte_frame_type_t current_type; + int32_t delta_duplex = get_delta_duplex(current_band, scs_index); - int32_t current_offset; - get_delta_duplex(current_band, scs_index, ¤t_offset); - - current_offset *= 1000; - if (current_offset == 0) - *current_type = TDD; + if (delta_duplex == 0) + current_type = TDD; else - *current_type = FDD; + current_type = FDD; - LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[*current_type], current_offset); + LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex); + return current_type; } uint16_t config_bandwidth(int mu, int nb_rb, int nr_band) @@ -1921,7 +1955,6 @@ uint64_t from_nrarfcn(int nr_bandP, int deltaFglobal = 5; uint32_t N_REF_Offs = 0; uint64_t F_REF_Offs_khz = 0; - int32_t delta_duplex; uint64_t N_OFFs, frequency, freq_min; int i = get_nr_table_idx(nr_bandP, scs_index); @@ -1936,7 +1969,7 @@ uint64_t from_nrarfcn(int nr_bandP, F_REF_Offs_khz = 24250080; } - get_delta_duplex(nr_bandP, scs_index, &delta_duplex); + int32_t delta_duplex = get_delta_duplex(nr_bandP, scs_index); if (delta_duplex <= 0){ // DL band >= UL band if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL @@ -3081,48 +3114,6 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config, //printf("[MAC] PTRS is set K= %u L= %u\n", *K_ptrs,1<<*L_ptrs); return valid; } -void get_band(uint64_t downlink_frequency, - uint16_t *current_band, - int32_t *current_offset, - lte_frame_type_t *current_type) -{ - int ind; - uint64_t center_frequency_khz; - uint64_t center_freq_diff_khz; - uint64_t dl_freq_khz = downlink_frequency/1000; - - center_freq_diff_khz = 999999999999999999; // 2^64 - *current_band = 0; - - for ( ind=0; - ind < sizeof(nr_bandtable) / sizeof(nr_bandtable[0]); - ind++) { - - LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min); - - if ( nr_bandtable[ind].dl_min <= dl_freq_khz && nr_bandtable[ind].dl_max >= dl_freq_khz ) { - - center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min)/2; - if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){ - *current_band = nr_bandtable[ind].band; - *current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000; - center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz); - - if (*current_offset == 0) - *current_type = TDD; - else - *current_type = FDD; - } - } - } - - LOG_I( PHY, "DL frequency %"PRIu64": band %d, frame_type %d, UL frequency %"PRIu64"\n", - downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset); - - AssertFatal(*current_band != 0, - "Can't find EUTRA band for frequency %lu\n", downlink_frequency); -} - uint32_t get_ssb_slot(uint32_t ssb_index){ // this function now only support f <= 3GHz diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index a94a79fe37..380b5b9067 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -39,9 +39,11 @@ uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); -void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type); +uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex); -void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex); +lte_frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index); + +int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index); uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); @@ -140,7 +142,6 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config, uint8_t *K_ptrs, uint8_t *L_ptrs,uint8_t *portIndex, uint8_t *nERatio,uint8_t *reOffset, uint8_t NrOfSymbols); -void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type); uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index f6bd5436bc..4910588ab3 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -203,8 +203,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; frequency_range_t frequency_range = band<100?FR1:FR2; - lte_frame_type_t frame_type; - get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type); + lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); // cell config diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index bce0719556..1640ba25a6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -127,8 +127,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; frequency_range_t frequency_range = band<100?FR1:FR2; - lte_frame_type_t frame_type; - get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type); + lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type; // Cell configuration From 06b368914beb86e6a8e0729276364284a3fe73c4 Mon Sep 17 00:00:00 2001 From: Rohan Patil Date: Thu, 4 Mar 2021 15:19:22 +0530 Subject: [PATCH 75/91] PBCH test case support for non-zero bchpyload --- openair1/SIMULATION/NR_PHY/pbchsim.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 2512988371..86029a4e79 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -540,7 +540,7 @@ int main(int argc, char **argv) if (input_fd==NULL) { gNB->pbch_configured = 1; - gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0; + gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33; for (int slot=0;slotslots_per_frame;slot++) { for (aa=0; aaframe_parms.nb_antennas_tx; aa++) @@ -718,9 +718,9 @@ int main(int argc, char **argv) payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte); for (i=0;i<3;i++){ - payload_ret += (UE->pbch_vars[0]->decoded_output[i] == (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i))); + payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff)); } - //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->rx_ind.rx_indication_body->mib_pdu.additional_bits); + //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte); //printf("ret %d\n", payload_ret); if (payload_ret!=4) n_errors_payload++; From a0922cef2fda367034a994bebd7118ee1ae4592a Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 4 Mar 2021 14:49:38 +0100 Subject: [PATCH 76/91] merge develop --- executables/nr-gnb.c | 28 +-------------------------- executables/softmodem-common.h | 3 +++ openair1/PHY/TOOLS/nr_phy_scope.c | 24 ----------------------- openair1/SIMULATION/NR_PHY/dlsim.c | 4 ++-- openair1/SIMULATION/NR_PHY/prachsim.c | 2 +- openair1/SIMULATION/NR_PHY/ulsim.c | 4 ++-- 6 files changed, 9 insertions(+), 56 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 0d2ffbc2c3..fce01f04fd 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -85,6 +85,7 @@ #include "T.h" #include "nfapi/oai_integration/vendor_ext.h" +#include //#define DEBUG_THREADS 1 //#define USRP_DEBUG 1 @@ -92,17 +93,6 @@ // extern openair0_device openair0; -extern volatile int start_gNB; -extern volatile int start_UE; -extern volatile int oai_exit; - -extern openair0_config_t openair0_cfg[MAX_CARDS]; - -extern int transmission_mode; - -extern uint16_t sf_ahead; -extern uint16_t sl_ahead; - //pthread_t main_gNB_thread; time_stats_t softmodem_stats_mt; // main thread @@ -111,25 +101,13 @@ time_stats_t softmodem_stats_rxtx_sf; // total tx time time_stats_t nfapi_meas; // total tx time time_stats_t softmodem_stats_rx_sf; // total rx time -extern double cpuf; - -void init_gNB(int,int); -void stop_gNB(int nb_inst); #include "executables/thread-common.h" -//extern PARALLEL_CONF_t get_thread_parallel_conf(void); -//extern WORKER_CONF_t get_thread_worker_conf(void); -extern uint8_t nfapi_mode; -extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); -extern void oai_slot_ind(uint16_t sfn, uint16_t slot); -extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); //#define TICK_TO_US(ts) (ts.diff) #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) -extern void init_td_thread(PHY_VARS_gNB *); -extern void init_te_thread(PHY_VARS_gNB *); void tx_func(void *param) { @@ -411,9 +389,6 @@ void kill_gNB_proc(int inst) { } - - - void reset_opp_meas(void) { int sfn; reset_meas(&softmodem_stats_mt); @@ -481,7 +456,6 @@ printf("after %p\n", gNB->common_vars.rxdataF[aa]); * (not tested in other modes). */ //init_precoding_weights(RC.gNB[inst]); - //init_gNB_proc(inst); init_gNB_Tpool(inst); } diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 6dd798ff36..7a7be1de96 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -244,6 +244,9 @@ extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr); extern void set_softmodem_sighandler(void); extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +extern uint16_t sl_ahead; +extern uint16_t sf_ahead; +extern volatile int oai_exit; void tx_func(void *param); void rx_func(void *param); diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index cb61523852..b45c1abf0b 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -282,30 +282,6 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in graph->iteration++; } -static void genericLogPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) { - float *values, *time; - oai_xygraph_getbuff(graph, &time, &values, len, 0); - - for (int ant=0; ant Date: Thu, 4 Mar 2021 22:15:56 +0100 Subject: [PATCH 77/91] Adding thread count parameter to ci-scripts config file --- ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index aeba400cad..17bc3507f8 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -234,6 +234,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; + pusch_proc_threads = 8; } ); From 7cb8acf6cadf8aa7efcf95cec2471b9fdd204bdb Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 5 Mar 2021 10:50:53 +0100 Subject: [PATCH 78/91] CI: removing 1 VM in the pipeline Signed-off-by: Raphael Defosseux --- ci-scripts/buildOnVM.sh | 6 ++ ci-scripts/createVM.sh | 6 ++ ci-scripts/oai-ci-vm-tool | 8 +-- ci-scripts/reportBuildLocally.sh | 100 ++++++++++++++++--------------- ci-scripts/waitBuildOnVM.sh | 6 ++ 5 files changed, 74 insertions(+), 52 deletions(-) diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 861cab0782..2bc4e6ee92 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -62,6 +62,12 @@ function build_on_vm { echo "ARCHIVES_LOC = $ARCHIVES_LOC" echo "BUILD_OPTIONS = $BUILD_OPTIONS" + if [[ "$VM_NAME" == *"-enb-usrp"* ]] + then + echo "This VM type is no longer supported in the pipeline framework" + return + fi + IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME` if [ $IS_VM_ALIVE -eq 0 ] diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index 237a1a5d5e..b67668f0bc 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -87,6 +87,12 @@ function create_vm { echo "VM_CPU = $VM_CPU" echo "VM_DISK = $VM_DISK GBytes" + if [[ "$VM_NAME" == *"-enb-usrp"* ]] + then + echo "This VM type is no longer supported in the pipeline framework" + return + fi + echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 9b9fe462f1..297e8e61b6 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -213,15 +213,15 @@ function variant__v6__nr_ue_usrp { function variant__v7__enb_ethernet { VM_MEMORY=4096 ARCHIVES_LOC=enb_eth - NB_PATTERN_FILES=8 - BUILD_OPTIONS="--eNB" + NB_PATTERN_FILES=9 + BUILD_OPTIONS="--eNB -w USRP --mu" } function variant__v8__ue_ethernet { VM_MEMORY=4096 ARCHIVES_LOC=ue_eth - NB_PATTERN_FILES=12 - BUILD_OPTIONS="--UE" + NB_PATTERN_FILES=13 + BUILD_OPTIONS="--UE -w USRP" } function variant__v10__flexran_rtc { diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index 44d200c3b6..19a486303f 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -580,16 +580,42 @@ function report_build { sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder sca_summary_table_footer ./archives/cppcheck/cppcheck.xml - summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp - summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html - summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html - summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html - summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html - summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_usrp_row5.html - summary_table_row "NASMESH - Release 15" ./archives/enb_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./enb_usrp_row6.html - summary_table_row "RB Tool - Release 15" ./archives/enb_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./enb_usrp_row7.html - summary_table_row "RF Simulator - Release 15" ./archives/enb_usrp/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_usrp_row8.html - summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html +# summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp +# summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html +# summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html +# summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html +# summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html +# summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_usrp_row5.html +# summary_table_row "NASMESH - Release 15" ./archives/enb_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./enb_usrp_row6.html +# summary_table_row "RB Tool - Release 15" ./archives/enb_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./enb_usrp_row7.html +# summary_table_row "RF Simulator - Release 15" ./archives/enb_usrp/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_usrp_row8.html +# summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html +# summary_table_footer +# + summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_eth + summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html + summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html + summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html + summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_eth_row4.html + summary_table_row "RF Simulator - Release 15" ./archives/enb_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_eth_row5.html + summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html + summary_table_row "OAI USRP device if - Release 15" ./archives/enb_eth/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_eth_row7.html + summary_table_row "NASMESH - Release 15" ./archives/enb_eth/nasmesh.Rel15.txt "Built target nasmesh" ./enb_eth_row8.html + summary_table_row "RB Tool - Release 15" ./archives/enb_eth/rb_tool.Rel15.txt "Built target rb_tool" ./enb_eth_row9.html + summary_table_footer + + summary_table_header "OAI Build: 4G LTE UE -- USRP option" ./archives/ue_eth + summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html + summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html + summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html + summary_table_row "Parameters Lib Config - Release 15" ./archives/ue_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./ue_eth_row4.html + summary_table_row "RF Simulator - Release 15" ./archives/ue_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./ue_eth_row5.html + summary_table_row "TCP OAI Bridge - Release 15" ./archives/ue_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./ue_eth_row6.html + summary_table_row "Conf 2 UE Data - Release 15" ./archives/ue_eth/conf2uedata.Rel15.txt "Built target conf2uedata" ./ue_eth_row7.html + summary_table_row "NVRAM - Release 15" ./archives/ue_eth/nvram.Rel15.txt "Built target nvram" ./ue_eth_row8.html + summary_table_row "UE IP - Release 15" ./archives/ue_eth/ue_ip.Rel15.txt "Built target ue_ip" ./ue_eth_row9.html + summary_table_row "USIM - Release 15" ./archives/ue_eth/usim.Rel15.txt "Built target usim" ./ue_eth_row9a.html + summary_table_row "OAI USRP device if - Release 15" ./archives/ue_eth/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./ue_eth_row9b.html summary_table_footer summary_table_header "OAI Build: 4G LTE basic simulator option" ./archives/basic_sim @@ -676,28 +702,6 @@ function report_build { summary_table_footer fi - summary_table_header "OAI Build: 4G LTE eNB -- ETHERNET transport option" ./archives/enb_eth - summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html - summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html - summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html - summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_eth_row4.html - summary_table_row "RF Simulator - Release 15" ./archives/enb_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_eth_row5.html - summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html - summary_table_footer - - summary_table_header "OAI Build: 4G LTE UE -- ETHERNET transport option" ./archives/ue_eth - summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html - summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html - summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html - summary_table_row "Parameters Lib Config - Release 15" ./archives/ue_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./ue_eth_row4.html - summary_table_row "RF Simulator - Release 15" ./archives/ue_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./ue_eth_row5.html - summary_table_row "TCP OAI Bridge - Release 15" ./archives/ue_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./ue_eth_row6.html - summary_table_row "Conf 2 UE Data - Release 15" ./archives/ue_eth/conf2uedata.Rel15.txt "Built target conf2uedata" ./ue_eth_row7.html - summary_table_row "NVRAM - Release 15" ./archives/ue_eth/nvram.Rel15.txt "Built target nvram" ./ue_eth_row8.html - summary_table_row "UE IP - Release 15" ./archives/ue_eth/ue_ip.Rel15.txt "Built target ue_ip" ./ue_eth_row9.html - summary_table_row "USIM - Release 15" ./archives/ue_eth/usim.Rel15.txt "Built target usim" ./ue_eth_row9a.html - summary_table_footer - if [ -e ./archives/red_hat ] then echo "

Red Hat Enterprise Linux Server release 7.6) -- Summary

" >> ./build_results.html @@ -714,9 +718,23 @@ function report_build { echo " " >> ./build_results.html echo "
" >> ./build_results.html - if [ -f ./enb_usrp_row1.html ] || [ -f ./enb_usrp_row2.html ] || [ -f ./enb_usrp_row3.html ] || [ -f ./enb_usrp_row4.html ] +# if [ -f ./enb_usrp_row1.html ] || [ -f ./enb_usrp_row2.html ] || [ -f ./enb_usrp_row3.html ] || [ -f ./enb_usrp_row4.html ] +# then +# for DETAILS_TABLE in `ls ./enb_usrp_row*.html` +# do +# cat $DETAILS_TABLE >> ./build_results.html +# done +# fi + if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] || [ -f ./enb_eth_row7.html ] || [ -f ./enb_eth_row8.html ] || [ -f ./enb_eth_row9.html ] then - for DETAILS_TABLE in `ls ./enb_usrp_row*.html` + for DETAILS_TABLE in `ls ./enb_eth_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ] || [ -f ./ue_eth_row7.html ] || [ -f ./ue_eth_row8.html ] || [ -f ./ue_eth_row9.html ] || [ -f ./ue_eth_row9a.html ] || [ -f ./ue_eth_row9b.html ] + then + for DETAILS_TABLE in `ls ./ue_eth_row*.html` do cat $DETAILS_TABLE >> ./build_results.html done @@ -749,20 +767,6 @@ function report_build { cat $DETAILS_TABLE >> ./build_results.html done fi - if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] - then - for DETAILS_TABLE in `ls ./enb_eth_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - fi - if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ] - then - for DETAILS_TABLE in `ls ./ue_eth_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - fi if [ -f ./enb_usrp_rh_row1.html ] || [ -f ./enb_usrp_rh_row2.html ] || [ -f ./enb_usrp_rh_row3.html ] || [ -f ./enb_usrp_rh_row4.html ] then for DETAILS_TABLE in `ls ./enb_usrp_rh_row*.html` diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index f066dacd81..8b426b9798 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -47,6 +47,12 @@ function wait_on_vm_build { echo "ARCHIVES_LOC = $ARCHIVES_LOC" echo "BUILD_OPTIONS = $BUILD_OPTIONS" + if [[ "$VM_NAME" == *"-enb-usrp"* ]] + then + echo "This VM type is no longer supported in the pipeline framework" + return + fi + IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME` if [ $IS_VM_ALIVE -eq 0 ] From 2f23751a8805b99586c544cc6a7a4252c4fdc953 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 5 Mar 2021 13:57:57 +0100 Subject: [PATCH 79/91] CI: try some sleeps Signed-off-by: Raphael Defosseux --- ci-scripts/buildOnVM.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 2bc4e6ee92..7dab96d35b 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -214,7 +214,15 @@ function build_on_vm { echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS else - echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + if [[ "$VM_NAME" == *"-enb-ethernet"* ]] + then + echo "echo \"sleep 200 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + elif [[ "$VM_NAME" == *"-enb-ethernet"* ]] + then + echo "echo \"sleep 100 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + else + echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + fi echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS echo "echo \"sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh\"" >> $VM_CMDS echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS From 7c6213ba47198ef83375999cca741bd98e0bef74 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 5 Mar 2021 14:47:26 +0100 Subject: [PATCH 80/91] CI: increase timeout for wait stages and fix wait on v1 Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 33 +++++++-------------------------- ci-scripts/buildOnVM.sh | 6 +++--- ci-scripts/waitBuildOnVM.sh | 6 ++++++ 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index ff661543c0..de49275b7e 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -196,16 +196,6 @@ pipeline { } } - stage ("Start VM -- enb-usrp") { - steps { - lock (vmResource) { - timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" - } - } - } - } - stage ("Start VM -- phy-sim") { steps { lock (vmResource) { @@ -251,7 +241,7 @@ pipeline { stage ("Analysis with cppcheck") { steps { gitlabCommitStatus(name: "Analysis with cppcheck") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } @@ -260,7 +250,7 @@ pipeline { stage ("Build basic simulator") { steps { gitlabCommitStatus(name: "Build basic-sim") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -269,7 +259,7 @@ pipeline { stage ("Build 5G gNB-USRP") { steps { gitlabCommitStatus(name: "Build gNB-USRP") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -278,25 +268,16 @@ pipeline { stage ("Build 5G NR-UE-USRP") { steps { gitlabCommitStatus(name: "Build nr-UE-USRP") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } } - stage ("Build eNB-USRP") { - steps { - gitlabCommitStatus(name: "Build eNB-USRP") { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - } stage ("Build physical simulators") { steps { gitlabCommitStatus(name: "Build phy-sim") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -305,7 +286,7 @@ pipeline { stage ("Build eNB-ethernet") { steps { gitlabCommitStatus(name: "Build eNB-ethernet") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -316,7 +297,7 @@ pipeline { // This is typically the last one to finish. lock (vmResource) { gitlabCommitStatus(name: "Build UE-ethernet") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 7dab96d35b..90591d67d5 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -216,10 +216,10 @@ function build_on_vm { else if [[ "$VM_NAME" == *"-enb-ethernet"* ]] then - echo "echo \"sleep 200 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS - elif [[ "$VM_NAME" == *"-enb-ethernet"* ]] + echo "echo \"sleep 170 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + elif [[ "$VM_NAME" == *"-ue-ethernet"* ]] then - echo "echo \"sleep 100 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + echo "echo \"sleep 60 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS else echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS fi diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index 8b426b9798..ff2129a187 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -90,6 +90,12 @@ function wait_on_vm_build { } function check_on_vm_build { + if [[ "$VM_NAME" == *"-enb-usrp"* ]] + then + echo "This VM type is no longer supported in the pipeline framework" + return + fi + echo "############################################################" echo "Creating a tmp folder to store results and artifacts" echo "############################################################" From 2411743f4438548626cecf89d2468dbbcf08e055 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Fri, 5 Mar 2021 17:27:45 +0100 Subject: [PATCH 81/91] gNB: move get_band() to its only user in nr_init.c --- openair1/PHY/INIT/nr_init.c | 40 +++++++++++++++++-- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 40 +------------------ openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 6 ++- 3 files changed, 42 insertions(+), 44 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index a8faf2bba7..d5e0da5c70 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -45,10 +45,42 @@ #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" -/* -extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn); -extern openair0_config_t openair0_cfg[MAX_CARDS]; -*/ +static +uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex) +{ + const uint64_t dl_freq_khz = downlink_frequency / 1000; + const int32_t delta_duplex_khz = delta_duplex / 1000; + + uint64_t center_freq_diff_khz = 999999999999999999; // 2^64 + uint16_t current_band = 0; + + for (int ind = 0; ind < nr_bandtable_size; ind++) { + + LOG_D(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min, nr_bandtable[ind].ul_min); + + if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max) + continue; + + int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min; + + if (current_offset_khz != delta_duplex_khz) + continue; + + uint64_t center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min) / 2; + + if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){ + current_band = nr_bandtable[ind].band; + center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz); + } + } + + LOG_I(PHY, "DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n", + downlink_frequency, current_band, downlink_frequency+delta_duplex); + + AssertFatal(current_band != 0, "Can't find EUTRA band for frequency %"PRIu64" and duplex_spacing %u\n", downlink_frequency, delta_duplex); + + return current_band; +} int l1_north_init_gNB() { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 5c0c97f566..72c113e86e 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1649,6 +1649,8 @@ nr_bandentry_t nr_bandtable[] = { {261,27500040,28350000,27500040,28350000, 2,2070833, 120} }; +#define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t)) +const size_t nr_bandtable_size = NR_BANDTABLE_SIZE; // TS 38.211 Table 6.4.1.1.3-3: PUSCH DMRS positions l' within a slot for single-symbol DMRS and intra-slot frequency hopping disabled. // The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B. @@ -1690,44 +1692,6 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = { {1, 1025, -1, -1, 1, 513, -1, -1}, //14 // (DMRS l' position) }; -#define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t)) - -uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex) -{ - const uint64_t dl_freq_khz = downlink_frequency / 1000; - const int32_t delta_duplex_khz = delta_duplex / 1000; - - uint64_t center_freq_diff_khz = 999999999999999999; // 2^64 - uint16_t current_band = 0; - - for (int ind = 0; ind < NR_BANDTABLE_SIZE; ind++) { - - LOG_D(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min, nr_bandtable[ind].ul_min); - - if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max) - continue; - - int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min; - - if (current_offset_khz != delta_duplex_khz) - continue; - - uint64_t center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min) / 2; - - if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){ - current_band = nr_bandtable[ind].band; - center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz); - } - } - - LOG_I(PHY, "DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n", - downlink_frequency, current_band, downlink_frequency+delta_duplex); - - AssertFatal(current_band != 0, "Can't find EUTRA band for frequency %"PRIu64" and duplex_spacing %u\n", downlink_frequency, delta_duplex); - - return current_band; -} - // Returns the corresponding row index of the NR table int get_nr_table_idx(int nr_bandP, uint8_t scs_index) { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 380b5b9067..bc41bdabc8 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -36,11 +36,13 @@ #include "NR_CellGroupConfig.h" #include "nr_mac.h" #include "openair1/PHY/impl_defs_nr.h" +#include "openair1/PHY/defs_nr_common.h" + +extern const size_t nr_bandtable_size; +extern nr_bandentry_t nr_bandtable[]; uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); -uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex); - lte_frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index); int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index); From 11755fc4739f1ffa7af8d1f4cde216187c55c69d Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Sat, 6 Mar 2021 10:50:49 +0100 Subject: [PATCH 82/91] CI: remove --mu option Signed-off-by: Raphael Defosseux --- ci-scripts/oai-ci-vm-tool | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 297e8e61b6..1f5fa8eff6 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -214,7 +214,7 @@ function variant__v7__enb_ethernet { VM_MEMORY=4096 ARCHIVES_LOC=enb_eth NB_PATTERN_FILES=9 - BUILD_OPTIONS="--eNB -w USRP --mu" + BUILD_OPTIONS="--eNB -w USRP" } function variant__v8__ue_ethernet { From 681c03667dd58a339c06be559b0da2ce1f0c70c5 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 8 Mar 2021 16:23:20 +0100 Subject: [PATCH 83/91] NR: fix init_symbol_rotation() for UL --- openair1/PHY/MODULATION/nr_modulation.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index b1b07c88e3..f12dcfc01b 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -602,17 +602,17 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { const double Nu=2048*64*(1/(float)(1<numerology_index)); const double Ncp0=16*64 + (144*64*(1/(float)(1<numerology_index))); const double Ncp1=(144*64*(1/(float)(1<numerology_index))); - double tl=0,poff,exp_re,exp_im; - double Ncp,Ncpm1=Ncp0; for (uint8_t ll = 0; ll < 2; ll++){ double f0 = f[ll]; + double Ncpm1 = Ncp0; int16_t *symbol_rotation = fp->symbol_rotation[ll]; - poff = 2 * M_PI * ((Ncp0 * Tc)) * f0; - exp_re = cos(poff); - exp_im = sin(-poff); + double tl = 0; + double poff = 2 * M_PI * ((Ncp0 * Tc)) * f0; + double exp_re = cos(poff); + double exp_im = sin(-poff); symbol_rotation[0] = (int16_t)floor(exp_re * 32767); symbol_rotation[1] = (int16_t)floor(exp_im * 32767); LOG_I(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb); @@ -624,6 +624,7 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { for (int l = 1; l < nsymb; l++) { + double Ncp; if (l == (7 * (1 << fp->numerology_index))) { Ncp = Ncp0; } else { From 969425f6a8a5cec22d8b70e26683cc2a3954c4f0 Mon Sep 17 00:00:00 2001 From: "masayuki.harada" Date: Tue, 9 Mar 2021 03:25:00 +0900 Subject: [PATCH 84/91] Replace to itti timer. Fix nnsf selection. Fix indentation and opening brace. --- openair3/S1AP/s1ap_eNB.c | 327 ++++++++---------- openair3/S1AP/s1ap_eNB_handlers.c | 52 +-- .../S1AP/s1ap_eNB_management_procedures.c | 29 +- openair3/S1AP/s1ap_eNB_nas_procedures.c | 9 +- openair3/S1AP/s1ap_eNB_nnsf.c | 102 +++--- openair3/S1AP/s1ap_eNB_nnsf.h | 3 +- openair3/S1AP/s1ap_eNB_timer.c | 260 +------------- 7 files changed, 226 insertions(+), 556 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index c40cc7cea9..6cb82de8d3 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -78,7 +78,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p); void s1ap_eNB_timer_expired(instance_t instance, - s1ap_timer_has_expired_t *msg_p); + timer_has_expired_t *msg_p); uint32_t s1ap_generate_eNB_id(void) { char *out; @@ -157,7 +157,6 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * uint8_t index; DevAssert(s1ap_register_eNB != NULL); /* Look if the provided instance already exists */ - s1ap_timer_init(); new_instance = s1ap_eNB_get_instance(instance); if (new_instance != NULL) { @@ -268,45 +267,36 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa sctp_new_association_resp->ulp_cnx_id); DevAssert(s1ap_mme_data_p != NULL); memset(enb_s1ap_id, 0, sizeof(enb_s1ap_id) ); - if( s1ap_mme_data_p->timer_id != S1AP_TIMERID_INIT ) - { + if( s1ap_mme_data_p->timer_id != S1AP_TIMERID_INIT ) { s1ap_timer_remove( s1ap_mme_data_p->timer_id ); s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT; } - if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) - { - RB_FOREACH(ue_p, s1ap_ue_map, &instance_p->s1ap_ue_head) - { - if( ue_p->mme_ref == s1ap_mme_data_p ) - { - if(cnt < NUMBER_OF_UE_MAX){ + if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) { + RB_FOREACH(ue_p, s1ap_ue_map, &instance_p->s1ap_ue_head) { + if( ue_p->mme_ref == s1ap_mme_data_p ) { + if(cnt < NUMBER_OF_UE_MAX) { enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id; cnt++; message_p = NULL; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND); - if( message_p != NULL ) - { + if( message_p != NULL ) { S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = ue_p->eNB_ue_s1ap_id; - if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) - { + if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) { S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); } - } - else - { + } else { S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); } }else{ - S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt); + S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt); } } } - for( ; cnt > 0 ; ) - { + for( ; cnt > 0 ; ) { cnt--; struct s1ap_eNB_ue_context_s *ue_context_p = NULL; struct s1ap_eNB_ue_context_s *s1ap_ue_context_p = NULL; @@ -323,25 +313,21 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa s1ap_mme_data_p->out_streams = 0; s1ap_mme_data_p->assoc_id = -1; - while (!STAILQ_EMPTY(&s1ap_mme_data_p->served_gummei)) - { + while (!STAILQ_EMPTY(&s1ap_mme_data_p->served_gummei)) { gummeiInfo = STAILQ_FIRST(&s1ap_mme_data_p->served_gummei); STAILQ_REMOVE_HEAD(&s1ap_mme_data_p->served_gummei, next); - while (!STAILQ_EMPTY(&gummeiInfo->served_plmns)) - { + 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)) - { + 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)) - { + while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) { mmeCode = STAILQ_FIRST(&gummeiInfo->mme_codes); STAILQ_REMOVE_HEAD(&gummeiInfo->mme_codes, next); free(mmeCode); @@ -351,45 +337,33 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa STAILQ_INIT(&s1ap_mme_data_p->served_gummei); - if( s1ap_mme_data_p->state == S1AP_ENB_STATE_DISCONNECTED ) - { + if( s1ap_mme_data_p->state == S1AP_ENB_STATE_DISCONNECTED ) { if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) || - (instance_p->sctp_req_count == 0xffff) ) - { + (instance_p->sctp_req_count == 0xffff) ) { timer_kind = s1ap_mme_data_p->cnx_id; timer_kind = timer_kind | S1AP_MMEIND; timer_kind = timer_kind | SCTP_REQ_WAIT; if( s1ap_timer_setup( instance_p->sctp_req_timer, 0, TASK_S1AP, instance_p->instance, - timer_kind, S1AP_TIMER_ONE_SHOT, NULL, &s1ap_mme_data_p->timer_id) < 0 ) - { + timer_kind, S1AP_TIMER_ONE_SHOT, NULL, &s1ap_mme_data_p->timer_id) < 0 ) { S1AP_ERROR("Timer Start NG(SCTP retransmission wait timer) : MME=%d\n",s1ap_mme_data_p->cnx_id); s1ap_sctp_req( instance_p, s1ap_mme_data_p ); } - } - else - { + } else { S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id); } - } - else - { + } else { S1AP_ERROR("SCTP disconnection reception : MME = %d\n",s1ap_mme_data_p->cnx_id); if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) || - (instance_p->sctp_req_count == 0xffff) ) - { + (instance_p->sctp_req_count == 0xffff) ) { s1ap_sctp_req( instance_p, s1ap_mme_data_p ); - } - else - { + } else { S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id); } s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED; } - } - else - { + } else { /* Update parameters */ s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; @@ -422,101 +396,81 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { } void s1ap_eNB_timer_expired( - instance_t instance, - s1ap_timer_has_expired_t *msg_p) + instance_t instance, + timer_has_expired_t *msg_p) { - uint32_t timer_kind = 0; - int16_t line_ind = 0; - s1ap_eNB_mme_data_t *mme_desc_p = NULL; - uint32_t timer_ind = 0; - s1ap_eNB_instance_t *instance_p = NULL; - long timer_id = S1AP_TIMERID_INIT; - - instance_p = s1ap_eNB_get_instance(instance); - timer_kind = msg_p->timer_kind; - line_ind = (int16_t)(timer_kind & S1AP_LINEIND); - timer_id = msg_p->timer_id; - - if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) - { - mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind); - if(mme_desc_p != NULL) + uint32_t timer_kind = 0; + int16_t line_ind = 0; + s1ap_eNB_mme_data_t *mme_desc_p = NULL; + uint32_t timer_ind = 0; + s1ap_eNB_instance_t *instance_p = NULL; + long timer_id = S1AP_TIMERID_INIT; + + instance_p = s1ap_eNB_get_instance(instance); + timer_kind = *((uint32_t*)msg_p->arg); + line_ind = (int16_t)(timer_kind & S1AP_LINEIND); + timer_id = msg_p->timer_id; + + if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) { + mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind); + if(mme_desc_p != NULL) { + if( timer_id == mme_desc_p->timer_id ) { + mme_desc_p->timer_id = S1AP_TIMERID_INIT; + timer_ind = timer_kind & S1AP_TIMERIND; + + switch(timer_ind) { - if( timer_id == mme_desc_p->timer_id ) - { - mme_desc_p->timer_id = S1AP_TIMERID_INIT; - timer_ind = timer_kind & S1AP_TIMERIND; - - switch(timer_ind) - { - case S1_SETRSP_WAIT: - { - if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || - (instance_p->s1_setupreq_count == 0xffff) ) - { - s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); - } - else - { - S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); - } - break; - } - case S1_SETREQ_WAIT: - { - if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || - (instance_p->s1_setupreq_count == 0xffff) ) - { - s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); - } - else - { - S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); - } - break; - } - case SCTP_REQ_WAIT: - { - if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) || - (instance_p->sctp_req_count == 0xffff) ) - { - s1ap_sctp_req( instance_p, mme_desc_p ); - } - else - { - S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind); - } - break; - } - default: - { - S1AP_WARN("Invalid Timer indication\n"); - break; - } - } + case S1_SETRSP_WAIT: + { + if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + (instance_p->s1_setupreq_count == 0xffff) ) { + s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); } - else - { - S1AP_DEBUG("Unmatch timer id\n"); - return; + break; + } + case S1_SETREQ_WAIT: + { + if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + (instance_p->s1_setupreq_count == 0xffff) ) { + s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); } + break; + } + case SCTP_REQ_WAIT: + { + if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) || + (instance_p->sctp_req_count == 0xffff) ) { + s1ap_sctp_req( instance_p, mme_desc_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind); + } + break; + } + default: + { + S1AP_WARN("Invalid Timer indication\n"); + break; + } } - else - { - S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind); - return; - } + } else { + S1AP_DEBUG("Unmatch timer id\n"); + return; + } + } else { + S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind); + return; } - else - { - } - return; + } + return; } void s1ap_eNB_init(void) { S1AP_DEBUG("Starting S1AP layer\n"); s1ap_eNB_prepare_internal_data(); - s1ap_timer_init(); itti_mark_task_ready(TASK_S1AP); MSC_START_USE(); } @@ -639,8 +593,8 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { case TIMER_HAS_EXPIRED: { - s1ap_eNB_timer_expired(ITTI_MESSAGE_GET_INSTANCE(received_msg), - (s1ap_timer_has_expired_t *) &TIMER_HAS_EXPIRED(received_msg)); + s1ap_eNB_timer_expired(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &received_msg->ittiMsg.timer_has_expired); } break; @@ -781,61 +735,52 @@ static int s1ap_eNB_generate_s1_setup_request( static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p) { - MessageDef *message_p = NULL; - sctp_new_association_req_t *sctp_new_association_req_p = NULL; - - if( instance_p == NULL ) - { - S1AP_ERROR("Invalid instance_p\n"); - return -1; + MessageDef *message_p = NULL; + sctp_new_association_req_t *sctp_new_association_req_p = NULL; + + if( instance_p == NULL ) + { + S1AP_ERROR("Invalid instance_p\n"); + return -1; + } + + message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_NEW_ASSOCIATION_REQ); + sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; + sctp_new_association_req_p->port = S1AP_PORT_NUMBER; + sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; + sctp_new_association_req_p->in_streams = instance_p->sctp_in_streams; + sctp_new_association_req_p->out_streams = instance_p->sctp_out_streams; + sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; + + if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) { + memcpy(&sctp_new_association_req_p->remote_address, + &s1ap_mme_data_p->mme_ip_address, + sizeof(net_ip_address_t)); + if( instance_p->enb_ip_address.ipv4 != 0 ) { + memcpy(&sctp_new_association_req_p->local_address, + &instance_p->enb_ip_address, + sizeof(net_ip_address_t)); + } else { + S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n"); + return -1; } - - message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); - sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; - sctp_new_association_req_p->port = S1AP_PORT_NUMBER; - sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; - sctp_new_association_req_p->in_streams = instance_p->sctp_in_streams; - sctp_new_association_req_p->out_streams = instance_p->sctp_out_streams; - sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; - - if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) - { - memcpy(&sctp_new_association_req_p->remote_address, - &s1ap_mme_data_p->mme_ip_address, - sizeof(net_ip_address_t)); - if( instance_p->enb_ip_address.ipv4 != 0 ) - { - memcpy(&sctp_new_association_req_p->local_address, - &instance_p->enb_ip_address, - sizeof(net_ip_address_t)); - } - else - { - S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n"); - return -1; - } + } else { + memcpy(&sctp_new_association_req_p->remote_address, + &s1ap_mme_data_p->mme_ip_address, + sizeof(net_ip_address_t)); + if( instance_p->enb_ip_address.ipv6 != 0 ) { + memcpy(&sctp_new_association_req_p->local_address, + &instance_p->enb_ip_address, + sizeof(net_ip_address_t)); + } else { + S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n"); + return -1; } - else - { - memcpy(&sctp_new_association_req_p->remote_address, - &s1ap_mme_data_p->mme_ip_address, - sizeof(net_ip_address_t)); - if( instance_p->enb_ip_address.ipv6 != 0 ) - { - memcpy(&sctp_new_association_req_p->local_address, - &instance_p->enb_ip_address, - sizeof(net_ip_address_t)); - } - else - { - S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n"); - return -1; - } - } - - itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); - - s1ap_mme_data_p->sctp_req_cnt++; - - return 0; + } + + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); + + s1ap_mme_data_p->sctp_req_cnt++; + + return 0; } diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index ce9e2ce302..7c611b0fbf 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -290,8 +290,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container, S1AP_ProtocolIE_ID_id_Cause,true); - if(ie == NULL) - { + if(ie == NULL) { return -1; } @@ -302,19 +301,16 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n"); } - if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) - { + if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) { s1ap_timer_remove( mme_desc_p->timer_id ); mme_desc_p->timer_id = S1AP_TIMERID_INIT; } instance_p = mme_desc_p->s1ap_eNB_instance; if( ( instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || - ( instance_p->s1_setupreq_count == 0xffff) ) - { + ( instance_p->s1_setupreq_count == 0xffff) ) { S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container, S1AP_ProtocolIE_ID_id_TimeToWait, false); - if( ie != NULL ) - { + if( ie != NULL ) { switch(ie->value.choice.TimeToWait) { case S1AP_TimeToWait_v1s: @@ -339,9 +335,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, interval_sec = instance_p->s1_setupreq_wait_timer; break; } - } - else - { + } else { interval_sec = instance_p->s1_setupreq_wait_timer; } @@ -350,16 +344,12 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, timer_kind = timer_kind | S1_SETREQ_WAIT; if( s1ap_timer_setup(interval_sec, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT, - NULL, &mme_desc_p->timer_id) < 0 ) - { + NULL, &mme_desc_p->timer_id) < 0 ) { S1AP_ERROR("Timer Start NG(S1 Setup Request) : MME=%d\n",mme_desc_p->cnx_id); - s1ap_eNB_snd_s1_setup_request( instance_p, mme_desc_p ); } - } - else - { - S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id); + } else { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id); } return 0; } @@ -391,16 +381,14 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, /* Set the capacity of this MME */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); - if(ie == NULL) - { + if(ie == NULL) { return -1; } mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_ServedGUMMEIs, true); - if(ie == NULL) - { + if(ie == NULL) { return -1; } @@ -462,13 +450,7 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next); } - - /* Set the capacity of this MME */ -// S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, -// S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); -// -// mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; -// + /* Optionaly set the mme name */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MMEname, false); @@ -486,7 +468,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, */ mme_desc_p->state = S1AP_ENB_STATE_CONNECTED; mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++; -// s1ap_handle_s1_setup_message(mme_desc_p, 0); return 0; } @@ -819,8 +800,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false); if (ie) { - if( ie->value.choice.CriticalityDiagnostics.procedureCode ) - { + if( ie->value.choice.CriticalityDiagnostics.procedureCode ) { S1AP_WARN("Received S1 Error indication CriticalityDiagnostics procedureCode = %ld\n", *ie->value.choice.CriticalityDiagnostics.procedureCode); } // TODO continue @@ -1023,8 +1003,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_Cause, true); - if( ie == NULL ) - { + if( ie == NULL ) { S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(Cause)\n" ); return -1; } @@ -1076,9 +1055,6 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, //#warning "TODO mapping mme_ue_s1ap_id enb_ue_s1ap_id?" case S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID: -// mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; -// S1AP_ERROR("TO DO mapping mme_ue_s1ap_id enb_ue_s1ap_id"); -// (void)mme_ue_s1ap_id; /* TODO: remove - it's to remove gcc warning about unused var */ mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.mME_UE_S1AP_ID; RB_FOREACH(ue_desc_p, s1ap_ue_map, &mme_desc_p->s1ap_eNB_instance->s1ap_ue_head) @@ -1087,7 +1063,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, { enb_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND); S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); diff --git a/openair3/S1AP/s1ap_eNB_management_procedures.c b/openair3/S1AP/s1ap_eNB_management_procedures.c index 1fdc09664b..a870e975a2 100644 --- a/openair3/S1AP/s1ap_eNB_management_procedures.c +++ b/openair3/S1AP/s1ap_eNB_management_procedures.c @@ -102,8 +102,7 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME( temp.assoc_id = assoc_id; temp.cnx_id = cnx_id; - if( cnx_id != 0 ) - { + if( cnx_id != 0 ) { if (instance_p == NULL) { STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, s1ap_eNB_entries) { @@ -116,29 +115,19 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME( } else { return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); } - } - else - { - if (instance_p == NULL) - { + } else { + if (instance_p == NULL) { STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, - s1ap_eNB_entries) - { - RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) - { - if( mme_p->assoc_id == assoc_id ) - { + s1ap_eNB_entries) { + RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + if( mme_p->assoc_id == assoc_id ) { return mme_p; } } } - } - else - { - RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) - { - if( mme_p->assoc_id == assoc_id ) - { + } else { + RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + if( mme_p->assoc_id == assoc_id ) { return mme_p; } } diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index 206201089d..b55bc06e11 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -139,8 +139,7 @@ int s1ap_eNB_handle_nas_first_req( */ mme_desc_p = s1ap_eNB_nnsf_select_mme( instance_p, - s1ap_nas_first_req_p->establishment_cause, - s1ap_nas_first_req_p->selected_plmn_identity); + s1ap_nas_first_req_p->establishment_cause); if (mme_desc_p) { S1AP_INFO("[eNB %ld] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", @@ -233,9 +232,9 @@ int s1ap_eNB_handle_nas_first_req( MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id, 0, // Cell ID &ie->value.choice.EUTRAN_CGI.cell_ID); - MCC_MNC_TO_TBCD(instance_p->mcc[mme_desc_p->broadcast_plmn_index[0]], - instance_p->mnc[mme_desc_p->broadcast_plmn_index[0]], - instance_p->mnc_digit_length[mme_desc_p->broadcast_plmn_index[0]], + MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], &ie->value.choice.EUTRAN_CGI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* Set the establishment cause according to those provided by RRC */ diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c index 6577b8f10b..a5a4e74734 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.c +++ b/openair3/S1AP/s1ap_eNB_nnsf.c @@ -36,17 +36,18 @@ #include "s1ap_eNB_defs.h" #include "s1ap_eNB_nnsf.h" + +typedef struct MME_nnsf_inf { + struct s1ap_eNB_mme_data_s *mme_p; + uint64_t weight; +} MME_nnsf_inf_t; + struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, - rrc_establishment_cause_t cause, - uint32_t plmn_id) + rrc_establishment_cause_t cause) { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; - typedef struct MME_nnsf_inf { - struct s1ap_eNB_mme_data_s *mme_p; - uint64_t weight; - } MME_nnsf_inf_t; uint16_t capacity_sum = 0; MME_nnsf_inf_t mme_inf[10]; @@ -55,9 +56,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, uint64_t weight = 0; memset(mme_inf, 0, sizeof(mme_inf)); - + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { - struct served_gummei_s *gummei_p = NULL; capacity_sum = capacity_sum + mme_data_p->relative_mme_capacity; if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) { /* The association between MME and eNB is not ready for the moment, @@ -83,7 +83,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) { continue; } - + mme_inf[nb_mme].mme_p = mme_data_p; + nb_mme++; /* At this point, the RRC establishment can be handled by the MME * even if it is in overload state. */ @@ -92,58 +93,27 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, continue; } } - - gummei_p = mme_data_p->served_gummei.stqh_first; - if( gummei_p != NULL ) - { - struct plmn_identity_s *served_plmns_p = NULL; - - served_plmns_p = gummei_p->served_plmns.stqh_first; - if( served_plmns_p != 0 ) - for( cnt = 0 ; cnt < 8 ; cnt++) - { - if ( (served_plmns_p->mcc == instance_p->mcc[plmn_id]) && - (served_plmns_p->mnc == instance_p->mnc[plmn_id]) ) - { - mme_inf[nb_mme].mme_p = mme_data_p; - nb_mme++; - break; - } - if( served_plmns_p->next.stqe_next == 0 ) - { - break; - } - served_plmns_p = served_plmns_p->next.stqe_next; - } - } } - if( nb_mme != 0 ) - { - for( cnt = 0 ; cnt < nb_mme ; cnt++ ) - { + + if( nb_mme != 0 ) { + for( cnt = 0 ; cnt < nb_mme ; cnt++ ) { mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity; mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1); } mme_highest_capacity_p = mme_inf[0].mme_p; weight = mme_inf[0].weight; - for( cnt = 1 ; cnt < nb_mme ; cnt++ ) - { - if( weight > mme_inf[cnt].weight ) - { + for( cnt = 1 ; cnt < nb_mme ; cnt++ ) { + if( weight > mme_inf[cnt].weight ) { mme_highest_capacity_p = mme_inf[cnt].mme_p; weight = mme_inf[cnt].weight; } } - } - else - { + } else { mme_highest_capacity_p = NULL; } - if( mme_highest_capacity_p != NULL ) - { + if( mme_highest_capacity_p != NULL ) { mme_highest_capacity_p->nb_calls++; } - return mme_highest_capacity_p; } @@ -154,8 +124,15 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; - uint8_t current_capacity = 0; - + + uint16_t capacity_sum = 0; + MME_nnsf_inf_t mme_inf[10]; + int cnt; + int nb_mme = 0; + uint64_t weight = 0; + + memset(mme_inf, 0, sizeof(mme_inf)); + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { struct served_gummei_s *gummei_p = NULL; struct plmn_identity_s *served_plmn_p = NULL; @@ -198,6 +175,8 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) { if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { + mme_inf[nb_mme].mme_p = mme_data_p; + nb_mme++; break; } } @@ -206,14 +185,27 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, } /* if we didn't find such a served PLMN, go on with the next MME */ if (!served_plmn_p) continue; - - if (current_capacity < mme_data_p->relative_mme_capacity) { - /* We find a better MME, keep a reference to it */ - current_capacity = mme_data_p->relative_mme_capacity; - mme_highest_capacity_p = mme_data_p; - } } + if( nb_mme != 0 ) { + for( cnt = 0 ; cnt < nb_mme ; cnt++ ) { + mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity; + mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1); + } + mme_highest_capacity_p = mme_inf[0].mme_p; + weight = mme_inf[0].weight; + for( cnt = 1 ; cnt < nb_mme ; cnt++ ) { + if( weight > mme_inf[cnt].weight ) { + mme_highest_capacity_p = mme_inf[cnt].mme_p; + weight = mme_inf[cnt].weight; + } + } + } else { + mme_highest_capacity_p = NULL; + } + if( mme_highest_capacity_p != NULL ) { + mme_highest_capacity_p->nb_calls++; + } return mme_highest_capacity_p; } diff --git a/openair3/S1AP/s1ap_eNB_nnsf.h b/openair3/S1AP/s1ap_eNB_nnsf.h index de039b7d30..d5f080649b 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.h +++ b/openair3/S1AP/s1ap_eNB_nnsf.h @@ -24,8 +24,7 @@ struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, - rrc_establishment_cause_t cause, - uint32_t plmn_id); + rrc_establishment_cause_t cause); struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, diff --git a/openair3/S1AP/s1ap_eNB_timer.c b/openair3/S1AP/s1ap_eNB_timer.c index ccb294cb54..3014f961a9 100644 --- a/openair3/S1AP/s1ap_eNB_timer.c +++ b/openair3/S1AP/s1ap_eNB_timer.c @@ -36,91 +36,6 @@ #include "queue.h" #include "s1ap_common.h" -struct s1ap_timer_elm_s { - task_id_t task_id; ///< Task ID which has requested the timer - int32_t instance; ///< Instance of the task which has requested the timer - uint32_t timer_kind; ///< Instance of the task which has requested the timer - timer_t timer; ///< Unique timer id - timer_type_t type; ///< Timer type - void *timer_arg; ///< Optional argument that will be passed when timer expires - STAILQ_ENTRY(s1ap_timer_elm_s) entries; ///< Pointer to next element -}; - -typedef struct timer_desc_s { - STAILQ_HEAD(timer_list_head, s1ap_timer_elm_s) timer_queue; - pthread_mutex_t timer_list_mutex; - struct timespec timeout; -} timer_desc_t; - -static timer_desc_t timer_desc; - -#define TIMER_SEARCH(vAR, tIMERfIELD, tIMERvALUE, tIMERqUEUE) \ -do { \ - STAILQ_FOREACH(vAR, tIMERqUEUE, entries) { \ - if (((vAR)->tIMERfIELD == tIMERvALUE)) \ - break; \ - } \ -} while(0) - -int s1ap_timer_timeout(sigval_t info) -{ - struct s1ap_timer_elm_s *timer_p; - MessageDef *message_p; - s1ap_timer_has_expired_t *timer_expired_p; - task_id_t task_id; - int32_t instance; - uint32_t timer_kind; - - timer_kind = info.sival_int; - if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 ) - { - S1AP_ERROR("Failed to mutex lock timeout=%x\n", timer_kind); - - return -1; - } - TIMER_SEARCH(timer_p, timer_kind, timer_kind, &timer_desc.timer_queue); - - if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 ) - { - S1AP_ERROR("Failed to mutex unlock timeout=0x%x\n", timer_kind); - } - if (timer_p == NULL) - { - S1AP_ERROR("Didn't find timer 0x%x in list\n", timer_kind); - - return -1; - } - S1AP_DEBUG("Timer kind 0x%x has expired\n", timer_kind); - - task_id = timer_p->task_id; - instance = timer_p->instance; - message_p = itti_alloc_new_message(TASK_UNKNOWN, TIMER_HAS_EXPIRED); - - timer_expired_p = (s1ap_timer_has_expired_t *)(&message_p->ittiMsg.timer_has_expired); - - timer_expired_p->timer_id = (long)timer_p->timer; - timer_expired_p->timer_kind = timer_p->timer_kind; - timer_expired_p->arg = timer_p->timer_arg; - - /* Timer is a one shot timer, remove it */ - if( (int)timer_p->type == (int)S1AP_TIMER_ONE_SHOT ) - { - if( s1ap_timer_remove((long)timer_p->timer) != 0 ) - { - S1AP_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer); - } - } - - /* Notify task of timer expiry */ - if( itti_send_msg_to_task(task_id, instance, message_p) < 0 ) - { - S1AP_ERROR("Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id); - free(message_p); - return -1; - } - - return 0; -} int s1ap_timer_setup( uint32_t interval_sec, @@ -132,169 +47,24 @@ int s1ap_timer_setup( void *timer_arg, long *timer_id) { - struct sigevent evp; - struct itimerspec its; - struct s1ap_timer_elm_s *timer_p; - timer_t timer; - - if( timer_id == NULL ) - { - S1AP_ERROR("Invalid timer_id\n"); - return -1; - } - - if( (int)type >= (int)S1AP_TIMER_TYPE_MAX ) - { - S1AP_ERROR("Invalid timer type (%d/%d)!\n", type, TIMER_TYPE_MAX); - return -1; - } - - if( *timer_id != S1AP_TIMERID_INIT ) - { - if( s1ap_timer_remove(*timer_id) != 0 ) - { - S1AP_ERROR("Failed to delete timer when the timer start 0x%lx\n", *timer_id); - } - } - - /* Allocate new timer list element */ - timer_p = malloc(sizeof(struct s1ap_timer_elm_s)); - - if( timer_p == NULL ) - { - S1AP_ERROR("Failed to create new timer element\n"); - return -1; - } - - memset(&timer, 0, sizeof(timer_t)); - memset(&evp, 0, sizeof(evp)); - - timer_p->task_id = task_id; - timer_p->instance = instance; - timer_p->timer_kind = timer_kind; - timer_p->type = type; - timer_p->timer_arg = timer_arg; - - evp.sigev_notify = (int)SIGEV_THREAD; - evp.sigev_notify_function = (void *)s1ap_timer_timeout; - evp.sigev_signo = SIGRTMIN; - evp.sigev_notify_attributes = NULL; - evp.sigev_value.sival_int = timer_kind; - - /* At the timer creation, the timer structure will be filled in with timer_id, - * which is unique for this process. This id is allocated by kernel and the - * value might be used to distinguish timers. - */ - if( timer_create(CLOCK_REALTIME, &evp, &timer) < 0 ) - { - S1AP_ERROR("Failed to create timer: (%s:%d)\n", strerror(errno), errno); - free(timer_p); - return -1; - } - - /* Fill in the first expiration value. */ - its.it_value.tv_sec = interval_sec; - its.it_value.tv_nsec = interval_us * 1000; - - if( (int)type == (int)S1AP_TIMER_PERIODIC ) - { - /* Asked for periodic timer. We set the interval time */ - its.it_interval.tv_sec = interval_sec; - its.it_interval.tv_nsec = interval_us * 1000; - } - else - { - /* Asked for one-shot timer. Do not set the interval field */ - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - } - - if( timer_settime(timer, 0, &its, NULL) ) - { - S1AP_ERROR("Failed to Settimer: (%s:%d)\n", strerror(errno), errno); - free(timer_p); - return -1; - } - - /* Simply set the timer_id argument. so it can be used by caller */ - *timer_id = (long)timer; - - timer_p->timer = timer; - - /* Lock the queue and insert the timer at the tail */ - if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 ) - { - S1AP_ERROR("Failed to mutex lock\n"); - if( timer_delete(timer_p->timer) < 0 ) - { - S1AP_ERROR("Failed to delete timer 0x%lx\n", (long)timer_p->timer); - } - free(timer_p); - timer_p = NULL; - - return -1; - } - - STAILQ_INSERT_TAIL(&timer_desc.timer_queue, timer_p, entries); - if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 ) - { - S1AP_ERROR("Failed to mutex unlock\n"); - } - - return 0; + uint32_t *timeoutArg=NULL; + int ret=0; + timeoutArg=malloc(sizeof(uint32_t)); + *timeoutArg=timer_kind; + ret=timer_setup(interval_sec, + interval_us, + task_id, + instance, + type, + (void*)timeoutArg, + timer_id); + return ret; } int s1ap_timer_remove(long timer_id) { - int rc = 0; - struct s1ap_timer_elm_s *timer_p; - - - if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 ) - { - S1AP_ERROR("Failed to mutex lock\n"); - if( timer_delete((timer_t)timer_id) < 0 ) - { - S1AP_ERROR("Failed to delete timer 0x%lx\n", (long)timer_id); - } - - return -1; - } - - TIMER_SEARCH(timer_p, timer, ((timer_t)timer_id), &timer_desc.timer_queue); - - /* We didn't find the timer in list */ - if (timer_p == NULL) - { - S1AP_ERROR("Didn't find timer 0x%lx in list\n", timer_id); - if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 ) - { - S1AP_ERROR("Failed to mutex unlock\n"); - } - - return -1; - } - - timer_delete(timer_p->timer); - - STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, s1ap_timer_elm_s, entries); - - if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 ) - { - S1AP_ERROR("Failed to mutex unlock\n"); - } - - free(timer_p); - timer_p = NULL; - return rc; + int ret; + ret=timer_remove(timer_id); + return ret; } -int s1ap_timer_init(void) -{ - memset(&timer_desc, 0, sizeof(timer_desc_t)); - - STAILQ_INIT(&timer_desc.timer_queue); - pthread_mutex_init(&timer_desc.timer_list_mutex, NULL); - - return 0; -} From a2e2968244bb389927cf58b1552a0e423aa3dacd Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 9 Mar 2021 10:06:33 +0100 Subject: [PATCH 85/91] Fix after review MR 1039 - use LOG_D for debug logging --- openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 7f1ad13c8e..10ac23bef0 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -78,7 +78,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, uint16_t nb_rb_pusch = pusch_pdu->rb_size; #ifdef DEBUG_CH - LOG_I(PHY, "In %s: ch_offset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n", + LOG_D(PHY, "In %s: ch_offset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n", __FUNCTION__, ch_offset, symbol_offset, From 443a44911996d4facbb785b17eabf8d4e2d4aa45 Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 9 Mar 2021 10:20:58 +0100 Subject: [PATCH 86/91] Fix after review MR 1039 - FAPI structures not to be used as config_req at MAC since that FAPI is just for communication between MAC and PHY - additional frame_type member added to the FAPI struct --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 6 +++--- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 2 ++ openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 4 ++-- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 4910588ab3..fee2efc4a8 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -203,12 +203,12 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; frequency_range_t frequency_range = band<100?FR1:FR2; - lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); + mac->frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); // cell config cfg->cell_config.phy_cell_id = *scc->physCellId; - cfg->cell_config.frame_duplex_type = frame_type; + cfg->cell_config.frame_duplex_type = mac->frame_type; // SSB config cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower; @@ -312,7 +312,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart; cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig; - cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type,frequency_range); + cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, mac->frame_type, frequency_range); //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ??? } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index dd0aa15c52..3e299d291e 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -325,6 +325,8 @@ typedef struct { NR_ControlResourceSet_t *coreset[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP]; NR_SearchSpace_t *SSpace[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP][FAPI_NR_MAX_SS_PER_CORESET]; + lte_frame_type_t frame_type; + /*BWP*/ // dedicated active DL BWP NR_BWP_Id_t DL_BWP_Id; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 66b5c7a697..dc3c84d326 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -121,7 +121,7 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) { //Check if request to access ul_config is for a UL slot - if (is_nr_UL_slot(mac->scc, slot, mac->phy_config.config_req.cell_config.frame_duplex_type) == 0) { + if (is_nr_UL_slot(mac->scc, slot, mac->frame_type) == 0) { LOG_W(MAC, "Slot %d is not a UL slot. %s called for wrong slot!!!\n", slot, __FUNCTION__); return NULL; } @@ -1663,7 +1663,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s ra->RA_offset = 2; // to compensate the rx frame offset at the gNB ra->generate_nr_prach = 0; // Reset flag for PRACH generation - if (is_nr_UL_slot(scc, slotP, mac->phy_config.config_req.cell_config.frame_duplex_type)) { + if (is_nr_UL_slot(scc, slotP, mac->frame_type)) { // WIP Need to get the proper selected ssb_idx // Initial beam selection functionality is not available yet diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 4956f955b9..653bba0c0a 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -90,7 +90,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ ret = nr_ue_scheduler(NULL, ul_info); - if (is_nr_UL_slot(mac->scc, ul_info->slot_tx, mac->phy_config.config_req.cell_config.frame_duplex_type) && get_softmodem_params()->do_ra) + if (is_nr_UL_slot(mac->scc, ul_info->slot_tx, mac->frame_type) && get_softmodem_params()->do_ra) nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id); switch(ret){ From 2cf4daefa827b3d875c6afe7acc108c838f4d61f Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Mar 2021 11:56:06 +0100 Subject: [PATCH 87/91] NR: move nr_bandtable from nr_mac_common.c to nr_common.c so PHY can use it, too --- common/utils/nr/nr_common.c | 75 +++++++++++++++++ common/utils/nr/nr_common.h | 14 ++++ openair1/PHY/INIT/nr_init.c | 1 + openair1/PHY/defs_nr_common.h | 16 ---- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 80 +------------------ openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 4 - 6 files changed, 93 insertions(+), 97 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 5f07fc00aa..0671aed813 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -32,6 +32,81 @@ #include #include "assertions.h" +#include "nr_common.h" + +// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) +// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101) +// Notes: +// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL +// - Frequencies are expressed in KHz +// - col: NR_band ul_min ul_max dl_min dl_max step N_OFFs_DL deltaf_raster +nr_bandentry_t nr_bandtable[] = { + {1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100}, + {2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100}, + {3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100}, + {5, 824000, 849000, 869000, 894000, 20, 173800, 100}, + {7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100}, + {8, 880000, 915000, 925000, 960000, 20, 185000, 100}, + {12, 698000, 716000, 729000, 746000, 20, 145800, 100}, + {14, 788000, 798000, 758000, 768000, 20, 151600, 100}, + {18, 815000, 830000, 860000, 875000, 20, 172000, 100}, + {20, 832000, 862000, 791000, 821000, 20, 158200, 100}, + {25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100}, + {26, 814000, 849000, 859000, 894000, 20, 171800, 100}, + {28, 703000, 758000, 758000, 813000, 20, 151600, 100}, + {29, 000, 000, 717000, 728000, 20, 143400, 100}, + {30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100}, + {34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100}, + {38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100}, + {39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100}, + {40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100}, + {41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, + {41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, + {47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15}, + //{48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15}, + //{48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30}, + {50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100}, + {51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100}, + {53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100}, + {65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100}, + {66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100}, + {70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100}, + {71, 663000, 698000, 617000, 652000, 20, 123400, 100}, + {74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100}, + {75, 000, 000, 1432000, 1517000, 20, 286400, 100}, + {76, 000, 000, 1427000, 1432000, 20, 285400, 100}, + {77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15}, + {77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30}, + {78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15}, + {78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30}, + {79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15}, + {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30}, + {80, 1710000, 1785000, 000, 000, 20, 342000, 100}, + {81, 880000, 915000, 000, 000, 20, 176000, 100}, + {82, 832000, 862000, 000, 000, 20, 166400, 100}, + {83, 703000, 748000, 000, 000, 20, 140600, 100}, + {84, 1920000, 1980000, 000, 000, 20, 384000, 100}, + {86, 1710000, 1785000, 000, 000, 20, 342000, 100}, + {89, 824000, 849000, 000, 000, 20, 342000, 100}, + {90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, + {90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, + {90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100}, + {91, 832000, 862000, 1427000, 1432000, 20, 285400, 100}, + {92, 832000, 862000, 1432000, 1517000, 20, 286400, 100}, + {93, 880000, 915000, 1427000, 1432000, 20, 285400, 100}, + {94, 880000, 915000, 1432000, 1517000, 20, 286400, 100}, + {95, 2010000, 2025000, 000, 000, 20, 402000, 100}, + {257,26500020,29500000,26500020,29500000, 1,2054166, 60}, + {257,26500080,29500000,26500080,29500000, 2,2054167, 120}, + {258,24250080,27500000,24250080,27500000, 1,2016667, 60}, + {258,24250080,27500000,24250080,27500000, 2,2016667, 120}, + {260,37000020,40000000,37000020,40000000, 1,2229166, 60}, + {260,37000080,40000000,37000080,40000000, 2,2229167, 120}, + {261,27500040,28350000,27500040,28350000, 1,2070833, 60}, + {261,27500040,28350000,27500040,28350000, 2,2070833, 120} +}; + +const size_t nr_bandtable_size = sizeof(nr_bandtable) / sizeof(nr_bandentry_t); int NRRIV2BW(int locationAndBandwidth,int N_RB) { int tmp = locationAndBandwidth/N_RB; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 5601c0fcbf..6389c2c094 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -36,6 +36,20 @@ #include #include "assertions.h" +typedef struct nr_bandentry_s { + int16_t band; + uint64_t ul_min; + uint64_t ul_max; + uint64_t dl_min; + uint64_t dl_max; + uint64_t step_size; + uint64_t N_OFFs_DL; + uint8_t deltaf_raster; +} nr_bandentry_t; + +extern const size_t nr_bandtable_size; +extern nr_bandentry_t nr_bandtable[]; + int NRRIV2BW(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize); diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index d5e0da5c70..ab363fcae4 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -20,6 +20,7 @@ */ #include "executables/nr-softmodem-common.h" +#include "common/utils/nr/nr_common.h" #include "PHY/defs_gNB.h" #include "PHY/phy_extern.h" #include "PHY/NR_REFSIG/nr_refsig.h" diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 9458833427..398252c37b 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -369,20 +369,4 @@ struct NR_DL_FRAME_PARMS { #define KHz (1000UL) #define MHz (1000*KHz) -typedef struct nr_bandentry_s { - int16_t band; - uint64_t ul_min; - uint64_t ul_max; - uint64_t dl_min; - uint64_t dl_max; - uint64_t step_size; - uint64_t N_OFFs_DL; - uint8_t deltaf_raster; -} nr_bandentry_t; - -typedef struct nr_band_info_s { - int nbands; - nr_bandentry_t band_info[100]; -} nr_band_info_t; - #endif diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 72c113e86e..ce4e0f81f3 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -31,6 +31,7 @@ */ #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "common/utils/nr/nr_common.h" #include #define reserved 0xffff @@ -1577,81 +1578,6 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, } } -// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) -// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101) -// Notes: -// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL -// - Frequencies are expressed in KHz -// - col: NR_band ul_min ul_max dl_min dl_max step N_OFFs_DL deltaf_raster -nr_bandentry_t nr_bandtable[] = { - {1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100}, - {2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100}, - {3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100}, - {5, 824000, 849000, 869000, 894000, 20, 173800, 100}, - {7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100}, - {8, 880000, 915000, 925000, 960000, 20, 185000, 100}, - {12, 698000, 716000, 729000, 746000, 20, 145800, 100}, - {14, 788000, 798000, 758000, 768000, 20, 151600, 100}, - {18, 815000, 830000, 860000, 875000, 20, 172000, 100}, - {20, 832000, 862000, 791000, 821000, 20, 158200, 100}, - {25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100}, - {26, 814000, 849000, 859000, 894000, 20, 171800, 100}, - {28, 703000, 758000, 758000, 813000, 20, 151600, 100}, - {29, 000, 000, 717000, 728000, 20, 143400, 100}, - {30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100}, - {34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100}, - {38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100}, - {39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100}, - {40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100}, - {41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, - {41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, - {47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15}, - //{48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15}, - //{48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30}, - {50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100}, - {51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100}, - {53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100}, - {65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100}, - {66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100}, - {70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100}, - {71, 663000, 698000, 617000, 652000, 20, 123400, 100}, - {74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100}, - {75, 000, 000, 1432000, 1517000, 20, 286400, 100}, - {76, 000, 000, 1427000, 1432000, 20, 285400, 100}, - {77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15}, - {77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30}, - {78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15}, - {78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30}, - {79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15}, - {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30}, - {80, 1710000, 1785000, 000, 000, 20, 342000, 100}, - {81, 880000, 915000, 000, 000, 20, 176000, 100}, - {82, 832000, 862000, 000, 000, 20, 166400, 100}, - {83, 703000, 748000, 000, 000, 20, 140600, 100}, - {84, 1920000, 1980000, 000, 000, 20, 384000, 100}, - {86, 1710000, 1785000, 000, 000, 20, 342000, 100}, - {89, 824000, 849000, 000, 000, 20, 342000, 100}, - {90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, - {90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, - {90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100}, - {91, 832000, 862000, 1427000, 1432000, 20, 285400, 100}, - {92, 832000, 862000, 1432000, 1517000, 20, 286400, 100}, - {93, 880000, 915000, 1427000, 1432000, 20, 285400, 100}, - {94, 880000, 915000, 1432000, 1517000, 20, 286400, 100}, - {95, 2010000, 2025000, 000, 000, 20, 402000, 100}, - {257,26500020,29500000,26500020,29500000, 1,2054166, 60}, - {257,26500080,29500000,26500080,29500000, 2,2054167, 120}, - {258,24250080,27500000,24250080,27500000, 1,2016667, 60}, - {258,24250080,27500000,24250080,27500000, 2,2016667, 120}, - {260,37000020,40000000,37000020,40000000, 1,2229166, 60}, - {260,37000080,40000000,37000080,40000000, 2,2229167, 120}, - {261,27500040,28350000,27500040,28350000, 1,2070833, 60}, - {261,27500040,28350000,27500040,28350000, 2,2070833, 120} -}; - -#define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t)) -const size_t nr_bandtable_size = NR_BANDTABLE_SIZE; - // TS 38.211 Table 6.4.1.1.3-3: PUSCH DMRS positions l' within a slot for single-symbol DMRS and intra-slot frequency hopping disabled. // The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B. // When l' = l0, it is represented by 1 @@ -1705,8 +1631,8 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index) AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]); } - AssertFatal(nr_bandP <= nr_bandtable[NR_BANDTABLE_SIZE-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[NR_BANDTABLE_SIZE-1].band); - for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); + AssertFatal(nr_bandP <= nr_bandtable[nr_bandtable_size-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[nr_bandtable_size-1].band); + for (i = 0; i < nr_bandtable_size && nr_bandtable[i].band != nr_bandP; i++); // selection of correct Deltaf raster according to SCS if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index bc41bdabc8..ffb36963a7 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -36,10 +36,6 @@ #include "NR_CellGroupConfig.h" #include "nr_mac.h" #include "openair1/PHY/impl_defs_nr.h" -#include "openair1/PHY/defs_nr_common.h" - -extern const size_t nr_bandtable_size; -extern nr_bandentry_t nr_bandtable[]; uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); From 4e87bc3c96429d7dbb5d5624ddede35c4de577bc Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 10 Mar 2021 10:45:31 +0100 Subject: [PATCH 88/91] add missing parameter 'pusch_proc_threads' to configuration files also harmonize configuration files some more --- .../gnb.band66.tm1.106PRB.usrpn300.conf | 18 +++++++++---- .../gnb.band78.tm1.106PRB.usrpn300.conf | 21 ++++++++++----- .../CONF/gnb.band66.tm1.106PRB.usrpn300.conf | 18 +++++++++---- .../CONF/gnb.band66.tm1.106PRB.usrpx300.conf | 18 +++++++++---- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 8 +++--- .../CONF/gnb.band78.tm1.106PRB.usrpx300.conf | 27 ++++++++++++------- 6 files changed, 74 insertions(+), 36 deletions(-) diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf index 9e13d493a8..32de0aa4f5 100644 --- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf @@ -225,14 +225,15 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( @@ -246,8 +247,15 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 75; eNB_instances = [0]; - #beamforming 1x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; # if_freq = 3700000000L; diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index 17bc3507f8..decaa392d7 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -23,7 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; - + servingCellConfigCommon = ( { #spCellConfigCommon @@ -227,15 +227,15 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - pusch_proc_threads = 8; - } + pusch_proc_threads = 8; + } ); RUs = ( @@ -249,8 +249,15 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 75; eNB_instances = [0]; - #beamforming 1x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf index 9e13d493a8..32de0aa4f5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf @@ -225,14 +225,15 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( @@ -246,8 +247,15 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 75; eNB_instances = [0]; - #beamforming 1x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; # if_freq = 3700000000L; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf index 831f9c7978..307cf52cb3 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf @@ -225,14 +225,15 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( @@ -246,8 +247,15 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - #beamforming 1x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + sdr_addrs = "type=x300"; clock_src = "external"; # if_freq = 3700000000L; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 760689f653..c77497dedd 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -226,15 +226,15 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - pusch_proc_threads = 8; - } + pusch_proc_threads = 8; + } ); RUs = ( diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index d38fff4241..b3fdd79475 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -23,7 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; - + servingCellConfigCommon = ( { #spCellConfigCommon @@ -135,18 +135,17 @@ gNBs = initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 6; + + initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; initialULBWPmappingType_2 = 1; # this is SS=10 L=4 initialULBWPstartSymbolAndLength_2 = 52; - msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -227,14 +226,15 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( @@ -248,8 +248,15 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - #beamforming 1x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + sdr_addrs = "type=x300"; clock_src = "external"; } From 535efa0fd265671afbe021f6f41ee7844349be46 Mon Sep 17 00:00:00 2001 From: "masayuki.harada" Date: Wed, 10 Mar 2021 23:16:12 +0900 Subject: [PATCH 89/91] Remove s1ap_eNB_timer.c and s1ap_eNB_timer.h --- cmake_targets/CMakeLists.txt | 1 - openair3/S1AP/s1ap_eNB.c | 41 +++++++++++++-- openair3/S1AP/s1ap_eNB.h | 17 ++++++ openair3/S1AP/s1ap_eNB_handlers.c | 11 +++- openair3/S1AP/s1ap_eNB_timer.c | 70 ------------------------- openair3/S1AP/s1ap_eNB_timer.h | 86 ------------------------------- 6 files changed, 65 insertions(+), 161 deletions(-) delete mode 100644 openair3/S1AP/s1ap_eNB_timer.c delete mode 100644 openair3/S1AP/s1ap_eNB_timer.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index fecb69939f..e11c850b8e 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -539,7 +539,6 @@ add_library(S1AP_ENB ${S1AP_DIR}/s1ap_eNB_overload.c ${S1AP_DIR}/s1ap_eNB_trace.c ${S1AP_DIR}/s1ap_eNB_ue_context.c - ${S1AP_DIR}/s1ap_eNB_timer.c ) add_dependencies(S1AP_ENB rrc_flag s1ap_flag) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 6cb82de8d3..e528c9e53e 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -58,8 +58,6 @@ #include "s1ap_eNB_ue_context.h" // test, to be removed #include "msc.h" -#include "s1ap_eNB_timer.h" - #include "assertions.h" #include "conversions.h" #if defined(TEST_S1C_MME) @@ -80,6 +78,37 @@ static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, void s1ap_eNB_timer_expired(instance_t instance, timer_has_expired_t *msg_p); +int s1ap_timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + uint32_t timer_kind, + timer_type_t type, + void *timer_arg, + long *timer_id) +{ + uint32_t *timeoutArg=NULL; + int ret=0; + timeoutArg=malloc(sizeof(uint32_t)); + *timeoutArg=timer_kind; + ret=timer_setup(interval_sec, + interval_us, + task_id, + instance, + type, + (void*)timeoutArg, + timer_id); + return ret; +} + +int s1ap_timer_remove(long timer_id) +{ + int ret; + ret=timer_remove(timer_id); + return ret; +} + uint32_t s1ap_generate_eNB_id(void) { char *out; char hostname[50]; @@ -407,7 +436,13 @@ void s1ap_eNB_timer_expired( long timer_id = S1AP_TIMERID_INIT; instance_p = s1ap_eNB_get_instance(instance); - timer_kind = *((uint32_t*)msg_p->arg); + if(msg_p->arg!=NULL){ + timer_kind = *((uint32_t*)msg_p->arg); + free(msg_p->arg); + }else{ + S1AP_ERROR("s1 timer timer_kind is NULL\n"); + return; + } line_ind = (int16_t)(timer_kind & S1AP_LINEIND); timer_id = msg_p->timer_id; diff --git a/openair3/S1AP/s1ap_eNB.h b/openair3/S1AP/s1ap_eNB.h index 2abbc53ec9..2183587214 100644 --- a/openair3/S1AP/s1ap_eNB.h +++ b/openair3/S1AP/s1ap_eNB.h @@ -30,6 +30,22 @@ #ifndef S1AP_ENB_H_ #define S1AP_ENB_H_ +#define S1AP_MMEIND 0x80000000 +#define S1AP_UEIND 0x00000000 +#define S1_SETRSP_WAIT 0x00010000 +#define S1_SETREQ_WAIT 0x00020000 +#define SCTP_REQ_WAIT 0x00030000 +#define S1AP_LINEIND 0x0000ffff +#define S1AP_TIMERIND 0x00ff0000 + +#define S1AP_TIMERID_INIT 0xffffffffffffffff + +typedef enum s1ap_timer_type_s { + S1AP_TIMER_PERIODIC, + S1AP_TIMER_ONE_SHOT, + S1AP_TIMER_TYPE_MAX, +} s1ap_timer_type_t; + typedef struct s1ap_eNB_config_s { // MME related params unsigned char mme_enabled; ///< MME enabled ? @@ -43,6 +59,7 @@ void *s1ap_eNB_process_itti_msg(void*); void s1ap_eNB_init(void); void *s1ap_eNB_task(void *arg); +int s1ap_timer_remove(long timer_id); uint32_t s1ap_generate_eNB_id(void); #endif /* S1AP_ENB_H_ */ diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 7c611b0fbf..9ee3287b94 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -52,7 +52,6 @@ #include "assertions.h" #include "conversions.h" #include "msc.h" -#include "s1ap_eNB_timer.h" static int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, @@ -117,6 +116,16 @@ static int s1ap_eNB_snd_s1_setup_request( s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p); +int s1ap_timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + uint32_t timer_kind, + timer_type_t type, + void *timer_arg, + long *timer_id); + /* Handlers matrix. Only eNB related procedure present here */ s1ap_message_decoded_callback messages_callback[][3] = { { 0, 0, 0 }, /* HandoverPreparation */ diff --git a/openair3/S1AP/s1ap_eNB_timer.c b/openair3/S1AP/s1ap_eNB_timer.c deleted file mode 100644 index 3014f961a9..0000000000 --- a/openair3/S1AP/s1ap_eNB_timer.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "assertions.h" -#include "intertask_interface.h" -#include "s1ap_eNB_timer.h" -#include "common/utils/LOG/log.h" -#include "queue.h" -#include "s1ap_common.h" - - -int s1ap_timer_setup( - uint32_t interval_sec, - uint32_t interval_us, - task_id_t task_id, - int32_t instance, - uint32_t timer_kind, - timer_type_t type, - void *timer_arg, - long *timer_id) -{ - uint32_t *timeoutArg=NULL; - int ret=0; - timeoutArg=malloc(sizeof(uint32_t)); - *timeoutArg=timer_kind; - ret=timer_setup(interval_sec, - interval_us, - task_id, - instance, - type, - (void*)timeoutArg, - timer_id); - return ret; -} - -int s1ap_timer_remove(long timer_id) -{ - int ret; - ret=timer_remove(timer_id); - return ret; -} - diff --git a/openair3/S1AP/s1ap_eNB_timer.h b/openair3/S1AP/s1ap_eNB_timer.h deleted file mode 100644 index 7af80eb806..0000000000 --- a/openair3/S1AP/s1ap_eNB_timer.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef TIMER_H_ -#define TIMER_H_ - -#include - -#define SIGTIMER SIGRTMIN - -typedef enum s1ap_timer_type_s { - S1AP_TIMER_PERIODIC, - S1AP_TIMER_ONE_SHOT, - S1AP_TIMER_TYPE_MAX, -} s1ap_timer_type_t; - -typedef struct { - void *arg; - long timer_id; - int32_t timer_kind; -} s1ap_timer_has_expired_t; - - -int s1ap_timer_timeout(sigval_t info); - -/** \brief Request a new timer - * \param interval_sec timer interval in seconds - * \param interval_us timer interval in micro seconds - * \param task_id task id of the task requesting the timer - * \param instance instance of the task requesting the timer - * \param type timer type - * \param timer_id unique timer identifier - * @returns -1 on failure, 0 otherwise - **/ -int s1ap_timer_setup( - uint32_t interval_sec, - uint32_t interval_us, - task_id_t task_id, - int32_t instance, - uint32_t timer_kind, - timer_type_t type, - void *timer_arg, - long *timer_id); - -/** \brief Remove the timer from list - * \param timer_id unique timer id - * @returns -1 on failure, 0 otherwise - **/ - -int s1ap_timer_remove(long timer_id); - -/** \brief Initialize timer task and its API - * \param mme_config MME common configuration - * @returns -1 on failure, 0 otherwise - **/ -int s1ap_timer_init(void); - -#define S1AP_MMEIND 0x80000000 -#define S1AP_UEIND 0x00000000 -#define S1_SETRSP_WAIT 0x00010000 -#define S1_SETREQ_WAIT 0x00020000 -#define SCTP_REQ_WAIT 0x00030000 -#define S1AP_LINEIND 0x0000ffff -#define S1AP_TIMERIND 0x00ff0000 - -#define S1AP_TIMERID_INIT 0xffffffffffffffff - -#endif From 8cec7f717123d6431813d40c12b3fd167879d1b3 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Wed, 10 Mar 2021 20:04:14 +0000 Subject: [PATCH 90/91] Revert commit b6ab1eb9 --- openair1/PHY/NR_TRANSPORT/nr_prach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 0fc2de2d0a..b5a3c061e9 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -681,7 +681,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, preamble_shift -= NCS; if (preamble_shift < 0) - preamble_shift+=((N_ZC/NCS)*NCS); + preamble_shift+=N_ZC; } } else { // This is the high-speed case new_dft = 0; From 3f6df6b9adcbf912709c71d1d1813c93970cab94 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 26 Jan 2021 15:33:22 +0100 Subject: [PATCH 91/91] CI: try to optimize the file system usage when building in the CI VM env. Increased the VM memory of one to allow linking Signed-off-by: Raphael Defosseux --- ci-scripts/buildOnVM.sh | 3 +++ ci-scripts/oai-ci-vm-tool | 1 + cmake_targets/tools/build_helper | 11 +++++++++++ 3 files changed, 15 insertions(+) diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 90591d67d5..2b1a5e0c71 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -164,6 +164,9 @@ function build_on_vm { echo "cd tmp" >> $VM_CMDS echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $VM_CMDS echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS + # Trying to make some room on filesystem before building + echo "rm ../localZip.zip" >> $VM_CMDS + echo "export CI_ENV=True" >> $VM_CMDS if [[ "$VM_NAME" == *"-cppcheck"* ]] then echo "mkdir cmake_targets/log" >> $VM_CMDS diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 1f5fa8eff6..d8f088b707 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -172,6 +172,7 @@ function setvar_usage { function variant__v1__enb_usrp { NB_PATTERN_FILES=9 BUILD_OPTIONS="--eNB -w USRP --mu" + VM_MEMORY=3072 } function variant__v2__basic_sim { diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 674d4a0cac..977827b0c9 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -273,6 +273,10 @@ install_protobuf_from_source(){ make -j`nproc` $SUDO make install $SUDO ldconfig + if [[ -v CI_ENV ]]; then + cd /tmp + $SUDO rm -rf protobuf* + fi ) >& $protobuf_install_log } @@ -295,6 +299,10 @@ install_protobuf_c_from_source(){ make -j`nproc` $SUDO make install $SUDO ldconfig + if [[ -v CI_ENV ]]; then + cd /tmp + $SUDO rm -rf protobuf* + fi ) >& $protobuf_c_install_log } @@ -831,6 +839,9 @@ install_asn1c_from_source(){ $SUDO make install cd - $SUDO ldconfig + if [[ -v CI_ENV ]]; then + $SUDO rm -rf /tmp/asn1c + fi ) > $asn1_install_log 2>&1 }