nfapi work around (missing malloc)
This commit is contained in:
@@ -195,21 +195,13 @@ typedef uint8_t mme_code_t;
|
||||
typedef uint32_t m_tmsi_t;
|
||||
|
||||
//Random UE identity length = 40 bits
|
||||
#if ! defined(NOT_A_RANDOM_UE_IDENTITY)
|
||||
#define NOT_A_RANDOM_UE_IDENTITY (uint64_t)0xFFFFFFFF
|
||||
#endif
|
||||
#if ! defined(NOT_A_RNTI)
|
||||
#define NOT_A_RNTI (rnti_t)0
|
||||
#endif
|
||||
#if ! defined(M_RNTI)
|
||||
#define M_RNTI (rnti_t)0xFFFD
|
||||
#endif
|
||||
#if ! defined(P_RNTI)
|
||||
#define P_RNTI (rnti_t)0xFFFE
|
||||
#endif
|
||||
#if ! defined(SI_RNTI)
|
||||
#define SI_RNTI (rnti_t)0xFFFF
|
||||
#endif
|
||||
#define CBA_RNTI (rnti_t)0xfff4
|
||||
#define OAI_C_RNTI (rnti_t)0x1234
|
||||
typedef enum config_action_e {
|
||||
CONFIG_ACTION_NULL = 0,
|
||||
CONFIG_ACTION_ADD = 1,
|
||||
|
||||
@@ -405,6 +405,7 @@ typedef struct NRRrcConfigurationReq_s {
|
||||
uint16_t mcc[PLMN_LIST_MAX_SIZE];
|
||||
uint16_t mnc[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t num_plmn;
|
||||
NR_ServingCellConfigCommon_t *scc;
|
||||
NR_ServingCellConfig_t *scd;
|
||||
int ssb_SubcarrierOffset;
|
||||
|
||||
@@ -98,6 +98,7 @@ typedef enum {
|
||||
#define CONFIG_STRING_RU_BF_WEIGHTS_LIST "bf_weights"
|
||||
#define CONFIG_STRING_RU_IF_FREQUENCY "if_freq"
|
||||
#define CONFIG_STRING_RU_IF_FREQ_OFFSET "if_offset"
|
||||
#define CONFIG_STRING_RU_DO_PRECODING "do_precoding"
|
||||
|
||||
#define RU_LOCAL_IF_NAME_IDX 0
|
||||
#define RU_LOCAL_ADDRESS_IDX 1
|
||||
@@ -127,7 +128,7 @@ typedef enum {
|
||||
#define RU_BF_WEIGHTS_LIST_IDX 25
|
||||
#define RU_IF_FREQUENCY 26
|
||||
#define RU_IF_FREQ_OFFSET 27
|
||||
|
||||
#define RU_DO_PRECODING 28
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* RU configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
@@ -160,7 +161,8 @@ typedef enum {
|
||||
{CONFIG_STRING_RU_OTA_SYNC_ENABLE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
|
||||
{CONFIG_STRING_RU_BF_WEIGHTS_LIST, NULL, 0, iptr:NULL, defintarrayval:DEFBFW, TYPE_INTARRAY, 0}, \
|
||||
{CONFIG_STRING_RU_IF_FREQUENCY, NULL, 0, u64ptr:NULL, defuintval:0, TYPE_UINT64, 0}, \
|
||||
{CONFIG_STRING_RU_IF_FREQ_OFFSET, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_RU_IF_FREQ_OFFSET, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_RU_DO_PRECODING, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -20,42 +20,15 @@
|
||||
*/
|
||||
|
||||
#include "COMMON/platform_types.h"
|
||||
#include "COMMON/platform_constants.h"
|
||||
#include "common/ran_context.h"
|
||||
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
#include "NR_BCCH-BCH-Message.h"
|
||||
#include "NR_ServingCellConfigCommon.h"
|
||||
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "SCHED_NR/phy_frame_config_nr.h"
|
||||
|
||||
#include "NR_MIB.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
#include "../../../../nfapi/oai_integration/vendor_ext.h"
|
||||
/* Softmodem params */
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP ) {
|
||||
abort();
|
||||
}
|
||||
|
||||
int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
int ssb_SubcarrierOffset,
|
||||
int pdsch_AntennaPorts,
|
||||
int pusch_AntennaPorts,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
int add_ue,
|
||||
uint32_t rnti,
|
||||
NR_CellGroupConfig_t *CellGroup){
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
|
||||
const NR_SRB_ToAddModList_t * const srb2add_listP,
|
||||
const NR_DRB_ToAddModList_t * const drb2add_listP,
|
||||
const NR_DRB_ToReleaseList_t * const drb2release_listP,
|
||||
const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list){
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,13 +38,6 @@
|
||||
#include "common/ran_context.h"
|
||||
#include "openair3/UTILS/conversions.h"
|
||||
|
||||
// undefine C_RNTI from
|
||||
// openair1/PHY/LTE_TRANSPORT/transport_common.h which
|
||||
// replaces in ie->value.choice.C_RNTI, causing
|
||||
// a compile error
|
||||
#undef C_RNTI
|
||||
|
||||
|
||||
// Bing Kai: create CU and DU context, and put all the information there.
|
||||
uint64_t du_ue_f1ap_id = 0;
|
||||
uint32_t f1ap_assoc_id = 0;
|
||||
|
||||
@@ -39,8 +39,10 @@
|
||||
|
||||
#include "rrc_extern.h"
|
||||
#include "rrc_eNB_UE_context.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
#include "rrc_eNB_S1AP.h"
|
||||
#include "rrc_eNB_GTPV1U.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
|
||||
|
||||
extern f1ap_setup_req_t *f1ap_du_data_from_du;
|
||||
extern f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB];
|
||||
@@ -1029,35 +1031,55 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
// F1AP_CriticalityDiagnostics_IE_List
|
||||
}
|
||||
|
||||
struct rrc_eNB_ue_context_s *ue_context_p =
|
||||
rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
|
||||
protocol_ctxt_t ctxt;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, ENB_FLAG_YES, rnti, 0, 0, instance);
|
||||
|
||||
if (ue_context_p) {
|
||||
/* The following is normally done in the function rrc_rx_tx() */
|
||||
rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance,
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
if (RC.nrrrc[instance]->node_type == ngran_gNB_CU) {
|
||||
struct rrc_gNB_ue_context_s *ue_context_p =
|
||||
rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
|
||||
|
||||
rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p);
|
||||
// erase data of GTP tunnels in UE context
|
||||
for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
|
||||
memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
|
||||
0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
|
||||
if (ue_context_p) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id;
|
||||
itti_send_msg_to_task(TASK_NGAP, instance, msg);
|
||||
|
||||
rrc_gNB_remove_ue_context(&ctxt, RC.nrrrc[instance], ue_context_p);
|
||||
} else {
|
||||
LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
|
||||
}
|
||||
#ifdef ITTI_SIM
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids =
|
||||
rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0,
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
if (rrc_ue_s1ap_ids)
|
||||
rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
|
||||
|
||||
/* trigger UE release in RRC */
|
||||
rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p);
|
||||
} else {
|
||||
LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
|
||||
struct rrc_eNB_ue_context_s *ue_context_p =
|
||||
rrc_eNB_get_ue_context(RC.rrc[instance], rnti);
|
||||
|
||||
if (ue_context_p) {
|
||||
/* The following is normally done in the function rrc_rx_tx() */
|
||||
rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance,
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
|
||||
rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p);
|
||||
// erase data of GTP tunnels in UE context
|
||||
for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
|
||||
memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
|
||||
0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
|
||||
}
|
||||
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids =
|
||||
rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0,
|
||||
ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
if (rrc_ue_s1ap_ids)
|
||||
rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids);
|
||||
|
||||
/* trigger UE release in RRC */
|
||||
rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p);
|
||||
} else {
|
||||
LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
|
||||
}
|
||||
}
|
||||
|
||||
pdcp_remove_UE(&ctxt);
|
||||
|
||||
@@ -56,13 +56,6 @@
|
||||
#include "intertask_interface.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
|
||||
// undefine C_RNTI from
|
||||
// openair1/PHY/LTE_TRANSPORT/transport_common.h which
|
||||
// replaces in ie->value.choice.C_RNTI, causing
|
||||
// a compile error
|
||||
|
||||
#undef C_RNTI
|
||||
|
||||
extern f1ap_setup_req_t *f1ap_du_data;
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
|
||||
@@ -990,135 +983,6 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
msg->rrc_container_length);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (msg->srb_id == 1 || msg->srb_id == 2) {
|
||||
struct rrc_gNB_ue_context_s* ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
|
||||
|
||||
|
||||
NR_UL_DCCH_Message_t* ul_dcch_msg=NULL;
|
||||
asn_dec_rval_t dec_rval;
|
||||
dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_NR_UL_DCCH_Message,
|
||||
(void**)&ul_dcch_msg,
|
||||
&ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header
|
||||
msg->rrc_container_length, 0, 0);
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
LOG_E(F1AP, " Failed to decode UL-DCCH (%zu bytes)\n",dec_rval.consumed);
|
||||
/* for rfsim, because UE send RRCSetupRequest in SRB1 */
|
||||
// NR_UL_CCCH_Message_t *ul_ccch_msg;
|
||||
// dec_rval = uper_decode(NULL,
|
||||
// &asn_DEF_NR_UL_CCCH_Message,
|
||||
// (void**)&ul_ccch_msg,
|
||||
// &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header
|
||||
// msg->rrc_container_length, 0, 0);
|
||||
// if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
// LOG_E(F1AP, " Failed to decode UL-CCCH (%zu bytes)\n",dec_rval.consumed);
|
||||
// } else {
|
||||
// LOG_I(F1AP, "decode UL-CCCH success \n");
|
||||
// LOG_I(F1AP, "Received message: present %d and c1 present %d\n",
|
||||
// ul_ccch_msg->message.present, ul_ccch_msg->message.choice.c1->present);
|
||||
|
||||
// if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) {
|
||||
// if (ul_ccch_msg->message.choice.c1->present == NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest) {
|
||||
// LOG_I(F1AP, "[MSG] RRC Setup Request\n");
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
else
|
||||
LOG_I(F1AP, "Received message: present %d and c1 present %d\n",
|
||||
ul_dcch_msg->message.present, ul_dcch_msg->message.choice.c1->present);
|
||||
|
||||
if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) {
|
||||
|
||||
switch (ul_dcch_msg->message.choice.c1->present) {
|
||||
case NR_UL_DCCH_MessageType__c1_PR_NOTHING: /* No components present */
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_measurementReport:
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete:
|
||||
LOG_I(F1AP, "[MSG] RRC UL rrcReconfigurationComplete\n");
|
||||
|
||||
/* CDRX: activated when RRC Connection Reconfiguration Complete is received */
|
||||
#if(0)
|
||||
int UE_id_mac = find_nr_UE_id(instance, rnti);
|
||||
|
||||
if (UE_id_mac == -1) {
|
||||
LOG_E(F1AP, "Can't find UE_id(MAC) of UE rnti %x\n", rnti);
|
||||
break;
|
||||
}
|
||||
|
||||
UE_sched_ctrl_t *UE_scheduling_control = &(RC.nrmac[instance]->UE_info.UE_sched_ctrl[UE_id_mac]);
|
||||
|
||||
if (UE_scheduling_control->cdrx_waiting_ack == TRUE) {
|
||||
UE_scheduling_control->cdrx_waiting_ack = FALSE;
|
||||
UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration Complete is received
|
||||
LOG_I(F1AP, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n");
|
||||
}
|
||||
/* End of CDRX processing */
|
||||
#endif
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete:
|
||||
LOG_I(F1AP, "[MSG] RRC UL rrcSetupComplete \n");
|
||||
|
||||
if(!ue_context_p){
|
||||
LOG_E(F1AP, "Did not find the UE context associated with UE RNTOI %x, ue_context_p is NULL\n", rnti);
|
||||
|
||||
} else {
|
||||
LOG_I(F1AP, "Processing RRCSetupComplete UE %x\n", rnti);
|
||||
ue_context_p->ue_context.StatusRrc = NR_RRC_CONNECTED;
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
|
||||
LOG_I(F1AP, "[MSG] RRC ReestablishmentComplete \n");
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_rrcResumeComplete:
|
||||
LOG_I(F1AP, "[MSG] RRC ResumeComplete \n");
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete:
|
||||
LOG_I(F1AP, "[MSG] RRC securityModeComplete \n");
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure:
|
||||
LOG_I(F1AP, "[MSG] RRC securityModeFailure \n");
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
|
||||
LOG_I(F1AP, "[MSG] RRC UL Information Transfer \n");
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_locationMeasurementIndication:
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
|
||||
LOG_I(F1AP, "[MSG] RRC ueCapabilityInformation \n");
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_ueAssistanceInformation:
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_failureInformation:
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_scgFailureInformation:
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_scgFailureInformationEUTRA:
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(NR_RRC, "Unknown UL DCCH message type, present %d \n", ul_dcch_msg->message.choice.c1->present);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER \n");
|
||||
@@ -1252,6 +1116,7 @@ int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
RC.nrrrc[ctxt.module_id],
|
||||
ctxt.rnti);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
if (srb_id == 0) {
|
||||
NR_DL_CCCH_Message_t* dl_ccch_msg=NULL;
|
||||
asn_dec_rval_t dec_rval;
|
||||
@@ -1295,47 +1160,17 @@ int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance,
|
||||
rrcSetup_ies->masterCellGroup.size,0,0);
|
||||
AssertFatal(dec_rval.code == RC_OK, "could not decode masterCellGroup\n");
|
||||
|
||||
// configure MAC
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
rrc_mac_config_req_gNB(ctxt.module_id,
|
||||
rrc->carrier.ssb_SubcarrierOffset,
|
||||
rrc->carrier.pdsch_AntennaPorts,
|
||||
rrc->carrier.pusch_AntennaPorts,
|
||||
NULL,
|
||||
0,
|
||||
ue_context_p->ue_context.rnti,
|
||||
ue_context_p->ue_context.masterCellGroup
|
||||
);
|
||||
apply_macrlc_config(rrc,ue_context_p,&ctxt);
|
||||
|
||||
// rrc_rlc_config_asn1_req
|
||||
nr_rrc_rlc_config_asn1_req(&ctxt,
|
||||
ue_context_p->ue_context.SRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
|
||||
AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n");
|
||||
|
||||
// This should be somewhere in the f1ap_cudu_ue_inst_t
|
||||
/*int macrlc_instance = 0;
|
||||
memcpy((void*)ue_p->Srb0.Tx_buffer.Payload,
|
||||
(void*)ie->value.choice.RRCContainer.buf,
|
||||
rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size
|
||||
|
||||
rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_inst[0], du_ue_f1ap_id);
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[macrlc_instance],rnti);
|
||||
*/
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
|
||||
AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n");
|
||||
ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len;
|
||||
|
||||
memcpy((void*)ue_p->Srb0.Tx_buffer.Payload,
|
||||
(void*)ie->value.choice.RRCContainer.buf,
|
||||
rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size
|
||||
|
||||
ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len;
|
||||
|
||||
// NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = NULL;
|
||||
// if (cellGroupConfig->mac_CellGroupConfig)
|
||||
// mac_CellGroupConfig = cellGroupConfig->mac_CellGroupConfig;
|
||||
|
||||
// rrc_mac_config_req_gNB
|
||||
break;
|
||||
} // case
|
||||
|
||||
|
||||
@@ -38,13 +38,8 @@
|
||||
|
||||
#include "rrc_extern.h"
|
||||
#include "rrc_eNB_UE_context.h"
|
||||
|
||||
// undefine C_RNTI from
|
||||
// openair1/PHY/LTE_TRANSPORT/transport_common.h which
|
||||
// replaces in ie->value.choice.C_RNTI, causing
|
||||
// a compile error
|
||||
|
||||
#undef C_RNTI
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
|
||||
extern f1ap_setup_req_t *f1ap_du_data;
|
||||
extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB];
|
||||
@@ -664,11 +659,21 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
rnti, ctxt.rnti);
|
||||
int UE_out_of_sync = 0;
|
||||
|
||||
for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
|
||||
if (RC.mac[instance]->UE_info.active[n] == TRUE
|
||||
&& rnti == UE_RNTI(instance, n)) {
|
||||
UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync;
|
||||
break;
|
||||
if (RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
|
||||
for (int n = 0; n < MAX_MOBILES_PER_GNB; ++n) {
|
||||
if (RC.nrmac[instance]->UE_info.active[n] == TRUE
|
||||
&& rnti == RC.nrmac[instance]->UE_info.rnti[n]) {
|
||||
UE_out_of_sync = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
|
||||
if (RC.mac[instance]->UE_info.active[n] == TRUE
|
||||
&& rnti == UE_RNTI(instance, n)) {
|
||||
UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,6 +723,15 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
}
|
||||
}
|
||||
|
||||
if (RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
|
||||
// struct rrc_gNB_ue_context_s *ue_context_p;
|
||||
|
||||
f1ap_ue_context_release_cplt_t cplt;
|
||||
cplt.rnti = ctxt.rnti;
|
||||
DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rrc_eNB_ue_context_s *ue_context_p;
|
||||
|
||||
ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id], ctxt.rnti);
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:100, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:150, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0} \
|
||||
}
|
||||
#define L1_CC_IDX 0
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "f1ap_cu_task.h"
|
||||
#include "f1ap_du_task.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include <openair2/LAYER2/nr_pdcp/nr_pdcp.h>
|
||||
extern unsigned char NB_gNB_INST;
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
@@ -1028,7 +1028,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
|
||||
PLMNParamList.numelt);
|
||||
|
||||
RRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt;
|
||||
NRRRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt;
|
||||
|
||||
for (int l = 0; l < PLMNParamList.numelt; ++l) {
|
||||
|
||||
|
||||
@@ -169,4 +169,9 @@ uint8_t get_transformPrecoding(const NR_BWP_UplinkCommon_t *initialUplinkBWP,
|
||||
int rnti_type,
|
||||
uint8_t configuredGrant);
|
||||
|
||||
void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP,
|
||||
const int CC_idP,
|
||||
const frame_t frameP,
|
||||
const sub_frame_t subframeP,
|
||||
const rnti_t rntiP) ;
|
||||
#endif
|
||||
|
||||
@@ -2167,22 +2167,19 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
|
||||
uint16_t buflen) {
|
||||
|
||||
NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu;
|
||||
unsigned char last_size = 0, i, mac_header_control_elements[16], *ce_ptr, bsr = 0;
|
||||
int mac_ce_size;
|
||||
uint16_t offset = 0;
|
||||
|
||||
LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus);
|
||||
|
||||
#ifdef DEBUG_HEADER_PARSING
|
||||
|
||||
for (i = 0; i < num_sdus; i++)
|
||||
for (int i = 0; i < num_sdus; i++)
|
||||
LOG_D(MAC, "[UE] MAC subPDU %d (lcid %d length %d bytes \n", i, sdu_lcids[i], sdu_lengths[i]);
|
||||
|
||||
#endif
|
||||
|
||||
// Generating UL MAC subPDUs including MAC SDU and subheader
|
||||
|
||||
for (i = 0; i < num_sdus; i++) {
|
||||
for (int i = 0; i < num_sdus; i++) {
|
||||
LOG_D(MAC, "[UE] Generating UL MAC subPDUs for SDU with lenght %d ( num_sdus %d )\n", sdu_lengths[i], num_sdus);
|
||||
|
||||
if (sdu_lcids[i] != UL_SCH_LCID_CCCH){
|
||||
@@ -2191,23 +2188,21 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i];
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i];
|
||||
last_size = 2;
|
||||
mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_SHORT);
|
||||
} else {
|
||||
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0;
|
||||
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1;
|
||||
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i];
|
||||
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
|
||||
((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff;
|
||||
last_size = 3;
|
||||
mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
}
|
||||
} else { // UL CCCH SDU
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = sdu_lcids[i];
|
||||
last_size = 1;
|
||||
mac_pdu_ptr->R = 0;
|
||||
mac_pdu_ptr->LCID = sdu_lcids[i];
|
||||
mac_pdu_ptr ++;
|
||||
}
|
||||
|
||||
mac_pdu_ptr += last_size;
|
||||
|
||||
// cycle through SDUs, compute each relevant and place ulsch_buffer in
|
||||
memcpy((void *) mac_pdu_ptr, (void *) sdus_payload, sdu_lengths[i]);
|
||||
sdus_payload += sdu_lengths[i];
|
||||
@@ -2216,8 +2211,6 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
|
||||
|
||||
// Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader)
|
||||
|
||||
ce_ptr = &mac_header_control_elements[0];
|
||||
|
||||
if (power_headroom) {
|
||||
// MAC CE fixed subheader
|
||||
mac_pdu_ptr->R = 0;
|
||||
@@ -2225,17 +2218,11 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
|
||||
mac_pdu_ptr++;
|
||||
|
||||
// PHR MAC CE (1 octet)
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PH = power_headroom;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R1 = 0;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PCMAX = 0; // todo
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R2 = 0;
|
||||
|
||||
mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
|
||||
|
||||
// Copying bytes for PHR MAC CEs to the mac pdu pointer
|
||||
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
|
||||
ce_ptr += mac_ce_size;
|
||||
mac_pdu_ptr += (unsigned char) mac_ce_size;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PH = power_headroom;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R1 = 0;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PCMAX = 0; // todo
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R2 = 0;
|
||||
mac_pdu_ptr += sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
|
||||
}
|
||||
|
||||
if (crnti) {
|
||||
@@ -2245,13 +2232,8 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
|
||||
mac_pdu_ptr++;
|
||||
|
||||
// C-RNTI MAC CE (2 octets)
|
||||
* (uint16_t *) ce_ptr = crnti;
|
||||
mac_ce_size = sizeof(uint16_t);
|
||||
|
||||
// Copying bytes for CRNTI MAC CE to the mac pdu pointer
|
||||
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
|
||||
ce_ptr += mac_ce_size;
|
||||
mac_pdu_ptr += (unsigned char) mac_ce_size;
|
||||
* (uint16_t *) mac_pdu_ptr = crnti;
|
||||
mac_pdu_ptr += sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if (truncated_bsr) {
|
||||
@@ -2261,11 +2243,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
|
||||
mac_pdu_ptr++;
|
||||
|
||||
// Short truncated BSR MAC CE (1 octet)
|
||||
((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> Buffer_size = truncated_bsr;
|
||||
((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> LcgID = 0; // todo
|
||||
mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
|
||||
|
||||
bsr = 1 ;
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> Buffer_size = truncated_bsr;
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> LcgID = 0; // todo
|
||||
mac_pdu_ptr+= sizeof(NR_BSR_SHORT_TRUNCATED);
|
||||
} else if (short_bsr) {
|
||||
// MAC CE fixed subheader
|
||||
mac_pdu_ptr->R = 0;
|
||||
@@ -2273,11 +2253,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
|
||||
mac_pdu_ptr++;
|
||||
|
||||
// Short truncated BSR MAC CE (1 octet)
|
||||
((NR_BSR_SHORT *) ce_ptr)->Buffer_size = short_bsr;
|
||||
((NR_BSR_SHORT *) ce_ptr)->LcgID = 0; // todo
|
||||
mac_ce_size = sizeof(NR_BSR_SHORT);
|
||||
|
||||
bsr = 1 ;
|
||||
((NR_BSR_SHORT *) mac_pdu_ptr)->Buffer_size = short_bsr;
|
||||
((NR_BSR_SHORT *) mac_pdu_ptr)->LcgID = 0; // todo
|
||||
mac_pdu_ptr+= sizeof(NR_BSR_SHORT);
|
||||
} else if (long_bsr) {
|
||||
// MAC CE variable subheader
|
||||
// todo ch 6.1.3.1. TS 38.321
|
||||
@@ -2293,36 +2271,21 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
|
||||
// ((NR_BSR_LONG *) ce_ptr)->LCGID0 = 0;
|
||||
// mac_ce_size = sizeof(NR_BSR_LONG); // size is variable
|
||||
}
|
||||
|
||||
if (bsr){
|
||||
// Copying bytes for BSR MAC CE to the mac pdu pointer
|
||||
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
|
||||
ce_ptr += mac_ce_size;
|
||||
mac_pdu_ptr += (unsigned char) mac_ce_size;
|
||||
}
|
||||
|
||||
// compute offset before adding padding (if necessary)
|
||||
offset = ((unsigned char *) mac_pdu_ptr - pdu);
|
||||
uint16_t padding_bytes = 0;
|
||||
// compute offset before adding padding (if necessary)
|
||||
int padding_bytes = 0;
|
||||
|
||||
if(buflen > 0) // If the buflen is provided
|
||||
padding_bytes = buflen - offset;
|
||||
padding_bytes = buflen + pdu - (unsigned char *) mac_pdu_ptr;
|
||||
|
||||
AssertFatal(padding_bytes>=0,"");
|
||||
|
||||
// Compute final offset for padding
|
||||
if (post_padding > 0 || padding_bytes>0) {
|
||||
if (post_padding || padding_bytes>0) {
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING;
|
||||
mac_pdu_ptr++;
|
||||
} else {
|
||||
// no MAC subPDU with padding
|
||||
}
|
||||
|
||||
// compute final offset
|
||||
offset = ((unsigned char *) mac_pdu_ptr - pdu);
|
||||
|
||||
//printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - pdu));
|
||||
|
||||
return offset;
|
||||
}
|
||||
return (uint8_t *)mac_pdu_ptr-pdu;
|
||||
}
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
@@ -2013,7 +2013,9 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
||||
ENB_FLAG_NO,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
buflen_remain,
|
||||
buflen_remain-MAX_RLC_SDU_SUBHEADER_SIZE,
|
||||
//Fixme: Laurent I removed MAX_RLC_SDU_SUBHEADER_SIZE because else we get out the buffer silently
|
||||
// the interface with nr_generate_ulsch_pdu() looks over complex and not CPU optimized
|
||||
(char *)&ulsch_sdus[sdu_length_total],0,
|
||||
0);
|
||||
|
||||
@@ -2033,8 +2035,7 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
||||
|
||||
/* Get updated BO after multiplexing this PDU */
|
||||
lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP,mac->crnti,eNB_index,frameP, subframe, ENB_FLAG_NO, lcid);
|
||||
buflen_remain =
|
||||
buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE);
|
||||
buflen_remain = buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,12 +489,12 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
/* FIXME: it seems there is a problem with slot 0/10/slots right after UL:
|
||||
* we just get retransmissions. Thus, do not schedule such slots in DL */
|
||||
if (slot % nr_slots_period != 0)
|
||||
RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64);
|
||||
RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
|
||||
RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64);
|
||||
RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
|
||||
LOG_D(NR_MAC, "slot %d DL %d UL %d\n",
|
||||
slot,
|
||||
(RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0,
|
||||
(RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0);
|
||||
(RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0,
|
||||
(RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0);
|
||||
}
|
||||
|
||||
if (get_softmodem_params()->phy_test) {
|
||||
|
||||
@@ -55,33 +55,58 @@
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "executables/nr-softmodem.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
|
||||
|
||||
void clear_mac_stats(gNB_MAC_INST *gNB) {
|
||||
memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
|
||||
}
|
||||
|
||||
#define MACSTATSSTRLEN 16384
|
||||
void dump_mac_stats(gNB_MAC_INST *gNB)
|
||||
{
|
||||
NR_UE_info_t *UE_info = &gNB->UE_info;
|
||||
int num = 1;
|
||||
FILE *fd=fopen("nrMAC_stats.log","w");
|
||||
AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno));
|
||||
char output[MACSTATSSTRLEN];
|
||||
memset(output,0,MACSTATSSTRLEN);
|
||||
int stroff=0;
|
||||
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
stroff = sprintf(output,"UE ID %d RNTI %04x (%d/%d)\n", UE_id, UE_info->rnti[UE_id], num++, UE_info->num_UEs);
|
||||
LOG_I(NR_MAC, "UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n",
|
||||
UE_id,
|
||||
UE_info->rnti[UE_id],
|
||||
num++,
|
||||
UE_info->num_UEs,
|
||||
UE_info->UE_sched_ctrl[UE_id].ph,
|
||||
UE_info->UE_sched_ctrl[UE_id].pcmax);
|
||||
UE_id,
|
||||
UE_info->rnti[UE_id],
|
||||
num++,
|
||||
UE_info->num_UEs,
|
||||
UE_info->UE_sched_ctrl[UE_id].ph,
|
||||
UE_info->UE_sched_ctrl[UE_id].pcmax);
|
||||
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
|
||||
const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0;
|
||||
LOG_I(NR_MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n",
|
||||
stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n",
|
||||
UE_id,
|
||||
stats->dlsch_rounds[0], stats->dlsch_rounds[1],
|
||||
stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors,
|
||||
avg_rsrp, stats->num_rsrp_meas);
|
||||
LOG_I(NR_MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n",
|
||||
UE_id,
|
||||
stats->dlsch_rounds[0], stats->dlsch_rounds[1],
|
||||
stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors,
|
||||
avg_rsrp, stats->num_rsrp_meas);
|
||||
stats->num_rsrp_meas = 0;
|
||||
stats->cumul_rsrp = 0 ;
|
||||
stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
|
||||
stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n",
|
||||
UE_id,
|
||||
stats->ulsch_rounds[0], stats->ulsch_rounds[1],
|
||||
stats->ulsch_rounds[2], stats->ulsch_rounds[3],
|
||||
stats->ulsch_DTX,
|
||||
stats->ulsch_errors);
|
||||
stroff+=sprintf(output+stroff,
|
||||
"UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",
|
||||
UE_id,
|
||||
stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx);
|
||||
LOG_I(NR_MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
|
||||
LOG_I(NR_MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n",
|
||||
UE_id,
|
||||
@@ -95,12 +120,16 @@ void dump_mac_stats(gNB_MAC_INST *gNB)
|
||||
stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx);
|
||||
for (int lc_id = 0; lc_id < 63; lc_id++) {
|
||||
if (stats->lc_bytes_tx[lc_id] > 0)
|
||||
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
|
||||
LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
|
||||
if (stats->lc_bytes_rx[lc_id] > 0)
|
||||
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
|
||||
LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
|
||||
}
|
||||
}
|
||||
print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL);
|
||||
if (stroff>0) fprintf(fd,"%s",output);
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
@@ -311,7 +340,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
|
||||
|
||||
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
|
||||
if (slot>64) return false; //quickfix for FR2 where there are more than 64 slots (bitmap to be removed)
|
||||
if (slot>=64) return false; //quickfix for FR2 where there are more than 64 slots (bitmap to be removed)
|
||||
return (bitmap >> slot) & 0x01;
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
|
||||
}
|
||||
|
||||
cc->total_prach_occasions_per_config_period = total_RA_occasions;
|
||||
for(int i=1; (1 << (i-1)) < max_association_period; i++) {
|
||||
for(int i=1; (1 << (i-1)) <= max_association_period; i++) {
|
||||
cc->max_association_period = (1 <<(i-1));
|
||||
total_RA_occasions = total_RA_occasions * cc->max_association_period;
|
||||
if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) {
|
||||
@@ -697,28 +697,34 @@ void nr_get_Msg3alloc(module_id_t module_id,
|
||||
int mu = ubwp ?
|
||||
ubwp->bwp_Common->genericParameters.subcarrierSpacing :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||
int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
|
||||
int StartSymbolIndex = 0;
|
||||
int NrOfSymbols = 0;
|
||||
int startSymbolAndLength = 0;
|
||||
int temp_slot = 0;
|
||||
ra->Msg3_tda_id = 16; // initialization to a value above limit
|
||||
|
||||
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ?
|
||||
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
|
||||
uint8_t k2 = 0;
|
||||
for (int i=0; i<pusch_TimeDomainAllocationList->list.count; i++) {
|
||||
startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
|
||||
// we want to transmit in the uplink symbols of mixed slot
|
||||
if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
|
||||
ra->Msg3_tda_id = i;
|
||||
break;
|
||||
k2 = *pusch_TimeDomainAllocationList->list.array[i]->k2;
|
||||
temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
|
||||
ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
|
||||
if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot)) {
|
||||
ra->Msg3_tda_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
|
||||
|
||||
uint8_t k2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
|
||||
|
||||
temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
|
||||
ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
|
||||
if (nr_slots_per_frame[mu]>temp_slot)
|
||||
ra->Msg3_frame = current_frame;
|
||||
else
|
||||
|
||||
@@ -573,6 +573,7 @@ void pf_dl(module_id_t module_id,
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
if (UE_info->Msg4_ACKed[UE_id] != true) continue;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
|
||||
@@ -691,8 +692,7 @@ void pf_dl(module_id_t module_id,
|
||||
sched_pdsch->pucch_allocation = alloc;
|
||||
uint32_t TBS = 0;
|
||||
uint16_t rbSize;
|
||||
const int oh = 2 + (sched_ctrl->num_total_bytes >= 256)
|
||||
+ 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
|
||||
const int oh = 3 + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
|
||||
nr_find_nb_rb(sched_pdsch->Qm,
|
||||
sched_pdsch->R,
|
||||
ps->nrOfSymbols,
|
||||
|
||||
@@ -393,6 +393,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||
vrb_map[rb + sched_pdsch->rbStart] = 1;
|
||||
|
||||
if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize);
|
||||
}
|
||||
|
||||
uint32_t target_ul_mcs = 9;
|
||||
|
||||
@@ -144,7 +144,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
|
||||
if ((symb_pucch & symb_tda_mi) == 0 && (symb_ulMixed & symb_tda_mi) == symb_tda_mi) {
|
||||
tdaMi = 1;
|
||||
} else {
|
||||
LOG_E(MAC,
|
||||
LOG_E(NR_MAC,
|
||||
"TDA index 1 UL overlaps with PUCCH or is not entirely in mixed slot (symb_pucch %x symb_ulMixed %x symb_tda_mi %x), won't schedule UL mixed slot\n",
|
||||
symb_pucch,
|
||||
symb_ulMixed,
|
||||
@@ -168,7 +168,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
|
||||
}
|
||||
|
||||
if (k2 < tdd->nrofUplinkSlots)
|
||||
LOG_W(MAC,
|
||||
LOG_W(NR_MAC,
|
||||
"k2 %d < tdd->nrofUplinkSlots %ld: not all UL slots can be scheduled\n",
|
||||
k2,
|
||||
tdd->nrofUplinkSlots);
|
||||
@@ -192,6 +192,10 @@ void nr_process_mac_pdu(module_id_t module_idP,
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
if ( pduP[0] != UL_SCH_LCID_PADDING )
|
||||
trace_NRpdu(DIRECTION_UPLINK, pduP, mac_pdu_len ,UE_id, WS_C_RNTI, UE_info->rnti[UE_id], frameP, 0, 0, 0);
|
||||
|
||||
// For both DL/UL-SCH
|
||||
// Except:
|
||||
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
|
||||
@@ -327,7 +331,7 @@ void nr_process_mac_pdu(module_id_t module_idP,
|
||||
sched_ctrl->ph = PH - 32 + (PH - 54);
|
||||
/* 38.133 Table10.1.18.1-1 */
|
||||
sched_ctrl->pcmax = PCMAX - 29;
|
||||
LOG_D(MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
|
||||
LOG_D(NR_MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
|
||||
phr->R1, PH, sched_ctrl->ph, phr->R2, PCMAX, sched_ctrl->pcmax);
|
||||
break;
|
||||
|
||||
@@ -371,7 +375,7 @@ void nr_process_mac_pdu(module_id_t module_idP,
|
||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: %d \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, *UE_info->rnti);
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: %d \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, UE_info->rnti[UE_id]);
|
||||
mac_rlc_data_ind(module_idP,
|
||||
UE_info->rnti[UE_id],
|
||||
module_idP,
|
||||
@@ -664,6 +668,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
if (UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt >= pusch_failure_thres) {
|
||||
LOG_D(NR_MAC,"Detected UL Failure on PUSCH, stopping scheduling\n");
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure = 1;
|
||||
nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP);
|
||||
}
|
||||
}
|
||||
} else if(sduP) {
|
||||
@@ -812,7 +817,7 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
|
||||
* (3) or we did not schedule it in more than 10 frames */
|
||||
const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes;
|
||||
const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity;
|
||||
LOG_D(MAC,
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
|
||||
frame,
|
||||
slot,
|
||||
@@ -842,29 +847,20 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
|
||||
// frame/slot in sched_pusch has been set previously. In the following, we
|
||||
// overwrite the information in the retransmission information before storing
|
||||
// as the new scheduling instruction
|
||||
retInfo->frame = sched_ctrl->sched_pusch.frame;
|
||||
retInfo->slot = sched_ctrl->sched_pusch.slot;
|
||||
|
||||
// Get previous PUSCH filed info
|
||||
sched_ctrl->sched_pusch = *retInfo;
|
||||
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_bwp ? 1 : 2;
|
||||
const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
|
||||
const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda);
|
||||
if (tda == retInfo->time_domain_allocation) {
|
||||
/* Check the resource is enough for retransmission */
|
||||
while (rbStart < bwpSize && !rballoc_mask[rbStart])
|
||||
rbStart++;
|
||||
if (rbStart + retInfo->rbSize >= bwpSize) {
|
||||
LOG_D(MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
|
||||
if (rbStart + retInfo->rbSize > bwpSize) {
|
||||
LOG_W(NR_MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d\n", UE_id, UE_info->rnti[UE_id], rbStart, retInfo->rbSize, bwpSize);
|
||||
return false;
|
||||
}
|
||||
/* check whether we need to switch the TDA allocation since tha last
|
||||
@@ -876,7 +872,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
LOG_D(MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
|
||||
LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
|
||||
} else {
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
* that we have enough resources */
|
||||
@@ -900,10 +896,10 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
&new_tbs,
|
||||
&new_rbSize);
|
||||
if (!success || new_tbs != retInfo->tb_size) {
|
||||
LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
|
||||
LOG_D(NR_MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
|
||||
return false; /* the maximum TBsize we might have is smaller than what we need */
|
||||
}
|
||||
LOG_D(MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs);
|
||||
LOG_D(NR_MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs);
|
||||
/* we can allocate it. Overwrite the time_domain_allocation, the number
|
||||
* of RBs, and the new TB size. The rest is done below */
|
||||
retInfo->tb_size = new_tbs;
|
||||
@@ -915,11 +911,20 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
/* Find free CCE */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
if (!freeCCE) {
|
||||
LOG_D(MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_D(MAC,
|
||||
/* frame/slot in sched_pusch has been set previously. In the following, we
|
||||
* overwrite the information in the retransmission information before storing
|
||||
* as the new scheduling instruction */
|
||||
retInfo->frame = sched_ctrl->sched_pusch.frame;
|
||||
retInfo->slot = sched_ctrl->sched_pusch.slot;
|
||||
/* Get previous PSUCH field info */
|
||||
sched_ctrl->sched_pusch = *retInfo;
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n",
|
||||
frame,
|
||||
slot,
|
||||
@@ -995,7 +1000,7 @@ void pf_ul(module_id_t module_id,
|
||||
bool r = allocate_ul_retransmission(
|
||||
module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pusch->ul_harq_pid);
|
||||
if (!r) {
|
||||
LOG_D(MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
LOG_D(NR_MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
continue;
|
||||
}
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
@@ -1026,7 +1031,7 @@ void pf_ul(module_id_t module_id,
|
||||
if (max_num_ue < 0)
|
||||
return;
|
||||
|
||||
LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb,rbStart);
|
||||
LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb, rbStart);
|
||||
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
|
||||
if (rbStart + min_rb >= bwpSize) {
|
||||
LOG_W(NR_MAC, "cannot allocate continuous UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n",
|
||||
@@ -1041,7 +1046,7 @@ void pf_ul(module_id_t module_id,
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_ubwp ? 1 : 2;
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0;
|
||||
const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
|
||||
const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
@@ -1137,7 +1142,7 @@ void pf_ul(module_id_t module_id,
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_ubwp ? 1 : 2;
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0;
|
||||
const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
|
||||
const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
@@ -1158,7 +1163,7 @@ void pf_ul(module_id_t module_id,
|
||||
&rbSize);
|
||||
sched_pusch->rbSize = rbSize;
|
||||
sched_pusch->tb_size = TBS;
|
||||
LOG_D(MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n",
|
||||
LOG_D(NR_MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n",
|
||||
rbSize, sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B);
|
||||
|
||||
/* Mark the corresponding RBs as used */
|
||||
@@ -1187,15 +1192,23 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
* schedule now (slot + k2 is not UL slot) */
|
||||
int UE_id = UE_info->list.head;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
|
||||
const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
if (tda < 0)
|
||||
return false;
|
||||
int K2 = get_K2(scc, sched_ctrl->active_ubwp, tda, mu);
|
||||
const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
|
||||
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
|
||||
|
||||
if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
|
||||
return false;
|
||||
|
||||
bool is_mixed_slot = is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[sched_slot / 64], sched_slot) &&
|
||||
is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot);
|
||||
|
||||
// FIXME: Avoid mixed slots for initialUplinkBWP
|
||||
if (sched_ctrl->active_ubwp==NULL && is_mixed_slot)
|
||||
return false;
|
||||
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
|
||||
@@ -445,7 +445,8 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
int rb_id;
|
||||
int i;
|
||||
|
||||
if(IS_SOFTMODEM_NOS1){
|
||||
if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){
|
||||
LOG_D(PDCP, "IP packet received, to be sent to TUN interface");
|
||||
len = write(nas_sock_fd[0], buf, size);
|
||||
if (len != size) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
@@ -534,7 +535,7 @@ static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
int srb_id;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (i = 0; i < sizeofArray(ue->srb) ; i++) {
|
||||
if (entity == ue->srb[i]) {
|
||||
srb_id = i+1;
|
||||
goto srb_found;
|
||||
@@ -577,7 +578,7 @@ static void deliver_pdu_srb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
int i;
|
||||
mem_block_t *memblock;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (i = 0; i < sizeofArray(ue->srb) ; i++) {
|
||||
if (entity == ue->srb[i]) {
|
||||
srb_id = i+1;
|
||||
goto srb_found;
|
||||
@@ -896,13 +897,14 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
//ctxt_pP->configured != 2 ||
|
||||
//srb2add_list == NULL ||
|
||||
//drb2add_list != NULL ||
|
||||
drb2release_list != NULL ||
|
||||
//drb2release_list != NULL ||
|
||||
//security_modeP != 255 ||
|
||||
//kRRCenc != NULL ||
|
||||
//kRRCint != NULL ||
|
||||
//kUPenc != NULL ||
|
||||
pmch_InfoList_r9 != NULL /*||
|
||||
defaultDRB != NULL */) {
|
||||
LOG_I(PDCP,"Releasing DRBs, oops\n");
|
||||
TODO;
|
||||
}
|
||||
|
||||
@@ -926,6 +928,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
/* todo */
|
||||
}
|
||||
|
||||
if (drb2release_list != NULL) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
free(kRRCenc);
|
||||
free(kRRCint);
|
||||
free(kUPenc);
|
||||
@@ -1189,6 +1195,7 @@ static boolean_t pdcp_data_req_drb(
|
||||
if (rb == NULL) {
|
||||
LOG_E(PDCP, "%s:%d:%s: no DRB found (rnti %d, rb_id %ld)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ typedef void nr_pdcp_ue_manager_t;
|
||||
|
||||
typedef struct nr_pdcp_ue_t {
|
||||
int rnti;
|
||||
nr_pdcp_entity_t *srb[2];
|
||||
nr_pdcp_entity_t *srb[3];
|
||||
nr_pdcp_entity_t *drb[5];
|
||||
} nr_pdcp_ue_t;
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "common/ran_context.h"
|
||||
#include "NR_UL-CCCH-Message.h"
|
||||
|
||||
#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace
|
||||
#include "openair2/F1AP/f1ap_du_rrc_message_transfer.h"
|
||||
|
||||
#include "openair2/LAYER2/PROTO_AGENT/proto_agent.h"
|
||||
@@ -47,6 +46,8 @@ extern RAN_CONTEXT_t RC;
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <executables/softmodem-common.h>
|
||||
|
||||
static nr_rlc_ue_manager_t *nr_rlc_ue_manager;
|
||||
|
||||
/* TODO: handle time a bit more properly */
|
||||
@@ -324,7 +325,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
|
||||
* reports '> 81338368' (table 6.1.3.1-2). Passing 100000000 is thus
|
||||
* more than enough.
|
||||
*/
|
||||
buf_stat = rb->buffer_status(rb, 100000000);
|
||||
// Fixme : Laurent reduced size for CPU saving
|
||||
buf_stat = rb->buffer_status(rb, 10000000);
|
||||
ret = buf_stat.status_size
|
||||
+ buf_stat.retx_size
|
||||
+ buf_stat.tx_size;
|
||||
@@ -426,7 +428,7 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
|
||||
int is_enb;
|
||||
|
||||
/* is it SRB? */
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (i = 0; i < sizeofArray(ue->srb); i++) {
|
||||
if (entity == ue->srb[i]) {
|
||||
is_srb = 1;
|
||||
rb_id = i+1;
|
||||
@@ -435,7 +437,7 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
|
||||
}
|
||||
|
||||
/* maybe DRB? */
|
||||
for (i = 0; i < 5; i++) {
|
||||
for (i = 0; i < sizeofArray(ue->drb) ; i++) {
|
||||
if (entity == ue->drb[i]) {
|
||||
is_srb = 0;
|
||||
rb_id = i+1;
|
||||
@@ -918,7 +920,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt
|
||||
|
||||
if (drb2release_listP != NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
if (srb2add_listP != NULL) {
|
||||
|
||||
@@ -49,8 +49,6 @@
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "flexran_agent_extern.h"
|
||||
#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace
|
||||
//#include "f1ap_du_rrc_message_transfer.h"
|
||||
#include "openair2/F1AP/f1ap_du_rrc_message_transfer.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
#include "NR_MIB.h"
|
||||
#include "NR_BCCH-BCH-Message.h"
|
||||
#include "rrc_gNB_UE_context.h"
|
||||
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
|
||||
#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
|
||||
#include <openair2/F1AP/f1ap_du_rrc_message_transfer.h>
|
||||
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
@@ -361,4 +363,23 @@ int8_t nr_mac_rrc_data_ind(const module_id_t module_idP,
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP,
|
||||
const int CC_idP,
|
||||
const frame_t frameP,
|
||||
const sub_frame_t subframeP,
|
||||
const rnti_t rntiP) {
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
ue_context_p = rrc_gNB_get_ue_context(
|
||||
RC.nrrrc[Mod_instP],
|
||||
rntiP);
|
||||
|
||||
if (ue_context_p != NULL) {
|
||||
LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
|
||||
if(ue_context_p->ue_context.ul_failure_timer == 0)
|
||||
ue_context_p->ue_context.ul_failure_timer=1;
|
||||
} else {
|
||||
LOG_D(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1220,47 +1220,6 @@ void fill_initial_cellGroupConfig(rnti_t rnti,
|
||||
logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
|
||||
rlc_BearerConfig->mac_LogicalChannelConfig = logicalChannelConfig;
|
||||
ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
|
||||
|
||||
/*
|
||||
// SRB2
|
||||
NR_RLC_BearerConfig_t *rlc_BearerConfig2 = NULL;
|
||||
NR_RLC_Config_t *rlc_Config2 = NULL;
|
||||
NR_LogicalChannelConfig_t *logicalChannelConfig2= NULL;
|
||||
long *logicalChannelGroup2 = NULL;
|
||||
rlc_BearerConfig2 = calloc(1, sizeof(NR_RLC_BearerConfig_t));
|
||||
rlc_BearerConfig2->logicalChannelIdentity = 2;
|
||||
rlc_BearerConfig2->servedRadioBearer = calloc(1, sizeof(*rlc_BearerConfig2->servedRadioBearer));
|
||||
rlc_BearerConfig2->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity;
|
||||
rlc_BearerConfig2->servedRadioBearer->choice.srb_Identity = 2;
|
||||
rlc_BearerConfig2->reestablishRLC = NULL;
|
||||
rlc_Config2 = calloc(1, sizeof(NR_RLC_Config_t));
|
||||
rlc_Config2->present = NR_RLC_Config_PR_am;
|
||||
rlc_Config2->choice.am = calloc(1, sizeof(*rlc_Config2->choice.am));
|
||||
rlc_Config2->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
|
||||
*(rlc_Config2->choice.am->dl_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12;
|
||||
rlc_Config2->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms35;
|
||||
rlc_Config2->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms0;
|
||||
rlc_Config2->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
|
||||
*(rlc_Config2->choice.am->ul_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12;
|
||||
rlc_Config2->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45;
|
||||
rlc_Config2->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_infinity;
|
||||
rlc_Config2->choice.am->ul_AM_RLC.pollByte = NR_PollByte_infinity;
|
||||
rlc_Config2->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t8;
|
||||
rlc_BearerConfig2->rlc_Config = rlc_Config2;
|
||||
logicalChannelConfig2 = calloc(1, sizeof(NR_LogicalChannelConfig_t));
|
||||
logicalChannelConfig2->ul_SpecificParameters = calloc(1, sizeof(*logicalChannelConfig2->ul_SpecificParameters));
|
||||
logicalChannelConfig2->ul_SpecificParameters->priority = 1;
|
||||
logicalChannelConfig2->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
|
||||
logicalChannelGroup2 = CALLOC(1, sizeof(long));
|
||||
*logicalChannelGroup2 = 0;
|
||||
logicalChannelConfig2->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup2;
|
||||
logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID));
|
||||
*logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID = 0;
|
||||
logicalChannelConfig2->ul_SpecificParameters->logicalChannelSR_Mask = 0;
|
||||
logicalChannelConfig2->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
|
||||
rlc_BearerConfig2->mac_LogicalChannelConfig = logicalChannelConfig2;
|
||||
ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig2);
|
||||
*/
|
||||
|
||||
cellGroupConfig->rlc_BearerToReleaseList = NULL;
|
||||
|
||||
@@ -1653,13 +1612,14 @@ int16_t do_RRCReconfiguration(
|
||||
// *security_config->keyToUse = NR_SecurityConfig__keyToUse_master;
|
||||
|
||||
ie = calloc(1, sizeof(NR_RRCReconfiguration_IEs_t));
|
||||
ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t));
|
||||
ie->radioBearerConfig->srb_ToAddModList = SRB_configList;
|
||||
ie->radioBearerConfig->drb_ToAddModList = DRB_configList;
|
||||
ie->radioBearerConfig->securityConfig = security_config;
|
||||
ie->radioBearerConfig->srb3_ToRelease = NULL;
|
||||
ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
|
||||
|
||||
if (SRB_configList || DRB_configList) {
|
||||
ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t));
|
||||
ie->radioBearerConfig->srb_ToAddModList = SRB_configList;
|
||||
ie->radioBearerConfig->drb_ToAddModList = DRB_configList;
|
||||
ie->radioBearerConfig->securityConfig = security_config;
|
||||
ie->radioBearerConfig->srb3_ToRelease = NULL;
|
||||
ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
|
||||
}
|
||||
/******************** Secondary Cell Group ********************/
|
||||
// rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier);
|
||||
// fill_default_secondaryCellGroup( carrier->servingcellconfigcommon,
|
||||
|
||||
@@ -356,7 +356,7 @@ typedef struct gNB_RRC_UE_s {
|
||||
/* list of e_rab to be setup by RRC layers */
|
||||
/* list of pdu session to be setup by RRC layers */
|
||||
e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
|
||||
pdu_session_param_t pdusession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION];
|
||||
pdu_session_param_t pduSession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION];
|
||||
//release e_rabs
|
||||
uint8_t nb_release_of_e_rabs;
|
||||
e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB];
|
||||
@@ -381,6 +381,7 @@ typedef struct gNB_RRC_UE_s {
|
||||
uint32_t ue_reestablishment_timer_thres;
|
||||
uint8_t e_rab_release_command_flag;
|
||||
uint8_t pdu_session_release_command_flag;
|
||||
uint8_t established_pdu_sessions_flag;
|
||||
uint32_t ue_rrc_inactivity_timer;
|
||||
int8_t reestablishment_xid;
|
||||
//------------------------------------------------------------------------------//
|
||||
|
||||
@@ -106,6 +106,13 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
|
||||
NR_RRCReconfiguration_t *reconfig,
|
||||
NR_RadioBearerConfig_t *rbconfig);
|
||||
|
||||
void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP );
|
||||
|
||||
void apply_pdcp_config(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP );
|
||||
|
||||
void
|
||||
rrc_gNB_generate_RRCSetup(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
|
||||
+421
-80
@@ -378,6 +378,46 @@ rrc_gNB_get_next_transaction_identifier(
|
||||
return nr_rrc_transaction_identifier[gnb_mod_idP];
|
||||
}
|
||||
|
||||
void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP ) {
|
||||
|
||||
rrc_mac_config_req_gNB(rrc->module_id,
|
||||
rrc->carrier.ssb_SubcarrierOffset,
|
||||
rrc->carrier.pdsch_AntennaPorts,
|
||||
rrc->carrier.pusch_AntennaPorts,
|
||||
NULL,
|
||||
0,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : (NR_CellGroupConfig_t *)NULL);
|
||||
|
||||
nr_rrc_rlc_config_asn1_req(ctxt_pP,
|
||||
ue_context_pP->ue_context.SRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
|
||||
}
|
||||
|
||||
void apply_pdcp_config(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP ) {
|
||||
|
||||
nr_rrc_pdcp_config_asn1_req(ctxt_pP,
|
||||
ue_context_pP->ue_context.SRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
0xff,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
rrc_gNB_generate_RRCSetup(
|
||||
@@ -487,34 +527,9 @@ rrc_gNB_generate_RRCSetup(
|
||||
// ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
|
||||
|
||||
// configure MAC
|
||||
rrc_mac_config_req_gNB(rrc->module_id,
|
||||
rrc->carrier.ssb_SubcarrierOffset,
|
||||
rrc->carrier.pdsch_AntennaPorts,
|
||||
rrc->carrier.pusch_AntennaPorts,
|
||||
NULL,
|
||||
0,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : (NR_CellGroupConfig_t *)NULL);
|
||||
apply_macrlc_config(rrc,ue_context_pP,ctxt_pP);
|
||||
|
||||
nr_rrc_rlc_config_asn1_req(ctxt_pP,
|
||||
ue_context_pP->ue_context.SRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
|
||||
nr_rrc_pdcp_config_asn1_req(ctxt_pP,
|
||||
ue_context_pP->ue_context.SRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
0xff,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
apply_pdcp_config(ue_context_pP,ctxt_pP);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@@ -784,6 +799,22 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
|
||||
dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
|
||||
|
||||
/* Add all NAS PDUs to the list */
|
||||
for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
|
||||
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
|
||||
memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
|
||||
OCTET_STRING_fromBuf(dedicatedNAS_Message,
|
||||
(char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer,
|
||||
ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length);
|
||||
ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
|
||||
}
|
||||
|
||||
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
|
||||
i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE");
|
||||
}
|
||||
|
||||
if (ue_context_pP->ue_context.nas_pdu_flag == 1) {
|
||||
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
|
||||
memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
|
||||
@@ -815,6 +846,15 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
free(ue_context_pP->ue_context.nas_pdu.buffer);
|
||||
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n");
|
||||
|
||||
/* Free all NAS PDUs */
|
||||
for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
|
||||
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
|
||||
ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame,
|
||||
@@ -916,15 +956,14 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
|
||||
/* Configure SRB2 */
|
||||
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
|
||||
if (*SRB_configList2) {
|
||||
free(*SRB_configList2);
|
||||
if (*SRB_configList2 == NULL) {
|
||||
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
|
||||
memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
|
||||
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
SRB2_config->srb_Identity = 2;
|
||||
ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
|
||||
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
|
||||
}
|
||||
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
|
||||
memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
|
||||
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
SRB2_config->srb_Identity = 2;
|
||||
ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
|
||||
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
|
||||
|
||||
DRB_configList = &ue_context_pP->ue_context.DRB_configList;
|
||||
if (*DRB_configList) {
|
||||
@@ -947,7 +986,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
break;
|
||||
}
|
||||
|
||||
if (ue_context_pP->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE) {
|
||||
if (ue_context_pP->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -958,15 +997,15 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
// sdap_Config
|
||||
sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
|
||||
sdap_config->pdu_Session = ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
|
||||
sdap_config->pdu_Session = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
|
||||
sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||
sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
|
||||
sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||
sdap_config->defaultDRB = TRUE;
|
||||
sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
|
||||
memset(sdap_config->mappedQoS_FlowsToAdd, 0, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
|
||||
|
||||
for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pdusession[i].param.nb_qos; qos_flow_index++) {
|
||||
qfi = ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].qfi;
|
||||
for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[i].param.nb_qos; qos_flow_index++) {
|
||||
qfi = ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].qfi;
|
||||
ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, &qfi);
|
||||
}
|
||||
sdap_config->mappedQoS_FlowsToRelease = NULL;
|
||||
@@ -996,8 +1035,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
DRB_config->pdcp_Config->ext1 = NULL;
|
||||
|
||||
// Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
|
||||
for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pdusession[i].param.nb_qos; qos_flow_index++) {
|
||||
switch (ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].fiveQI) {
|
||||
for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[i].param.nb_qos; qos_flow_index++) {
|
||||
switch (ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].fiveQI) {
|
||||
case 1: //100ms
|
||||
case 2: //150ms
|
||||
case 3: //50ms
|
||||
@@ -1011,9 +1050,9 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].fiveQI);
|
||||
ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_FAILED;
|
||||
ue_context_pP->ue_context.pdusession[i].xid = xid;
|
||||
LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].fiveQI);
|
||||
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_FAILED;
|
||||
ue_context_pP->ue_context.pduSession[i].xid = xid;
|
||||
pdu_sessions_done++;
|
||||
free(DRB_config);
|
||||
continue;
|
||||
@@ -1023,18 +1062,18 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
|
||||
ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
|
||||
|
||||
ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
ue_context_pP->ue_context.pdusession[i].xid = xid;
|
||||
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
ue_context_pP->ue_context.pduSession[i].xid = xid;
|
||||
|
||||
if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
|
||||
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
|
||||
memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
|
||||
OCTET_STRING_fromBuf(dedicatedNAS_Message,
|
||||
(char *)ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer,
|
||||
ue_context_pP->ue_context.pdusession[i].param.nas_pdu.length);
|
||||
(char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer,
|
||||
ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length);
|
||||
ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
|
||||
|
||||
LOG_I(NR_RRC,"add NAS info with size %d (pdusession id %d)\n",ue_context_pP->ue_context.pdusession[i].param.nas_pdu.length, i);
|
||||
LOG_I(NR_RRC,"add NAS info with size %d (pdusession id %d)\n",ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length, i);
|
||||
} else {
|
||||
// TODO
|
||||
LOG_E(NR_RRC,"no NAS info (pdusession id %d)\n", i);
|
||||
@@ -1065,10 +1104,10 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
|
||||
/* Free all NAS PDUs */
|
||||
for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
|
||||
if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
|
||||
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
/* Free the NAS PDU buffer and invalidate it */
|
||||
free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer);
|
||||
ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL;
|
||||
free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
|
||||
ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1137,7 +1176,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
||||
|
||||
*DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2));
|
||||
for(i = 0; i < NB_RB_MAX; i++) {
|
||||
if((ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pdusession[i].xid == xid) {
|
||||
if((ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pduSession[i].xid == xid) {
|
||||
DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t));
|
||||
*DRB_release = i+1;
|
||||
ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release);
|
||||
@@ -1238,6 +1277,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
||||
NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
|
||||
NR_DRB_Identity_t *drb_id_p = NULL;
|
||||
// uint8_t nr_DRB2LCHAN[8];
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
|
||||
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
|
||||
|
||||
@@ -1268,7 +1308,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
||||
SRB_configList, // NULL,
|
||||
DRB_configList,
|
||||
DRB_Release_configList2,
|
||||
0xff, // already configured during the securitymodecommand
|
||||
0, // already configured during the securitymodecommand
|
||||
kRRCenc,
|
||||
kRRCint,
|
||||
kUPenc,
|
||||
@@ -1278,6 +1318,15 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
||||
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
/* Refresh SRBs/DRBs */
|
||||
if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||
rrc_mac_config_req_gNB(rrc->module_id,
|
||||
rrc->carrier.ssb_SubcarrierOffset,
|
||||
rrc->carrier.pdsch_AntennaPorts,
|
||||
rrc->carrier.pusch_AntennaPorts,
|
||||
NULL,
|
||||
0,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
ue_context_pP->ue_context.masterCellGroup
|
||||
);
|
||||
LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
|
||||
nr_rrc_rlc_config_asn1_req(ctxt_pP,
|
||||
SRB_configList, // NULL,
|
||||
@@ -1592,13 +1641,13 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
|
||||
|
||||
for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
|
||||
if (ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_DONE) {
|
||||
create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
|
||||
create_tunnel_req.upf_NGu_teid[j] = ue_context_pP->ue_context.pdusession[i].param.gtp_teid;
|
||||
if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) {
|
||||
create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
|
||||
create_tunnel_req.upf_NGu_teid[j] = ue_context_pP->ue_context.pduSession[i].param.gtp_teid;
|
||||
memcpy(create_tunnel_req.upf_addr[j].buffer,
|
||||
ue_context_pP->ue_context.pdusession[i].param.upf_addr.buffer,
|
||||
ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer,
|
||||
sizeof(uint8_t)*20);
|
||||
create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pdusession[i].param.upf_addr.length;
|
||||
create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pduSession[i].param.upf_addr.length;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@@ -1658,10 +1707,10 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
|
||||
/* TODO parameters yet to process ... */
|
||||
/* TODO should test if pdu session are Ok before! */
|
||||
ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
ue_context_pP->ue_context.pdusession[i].xid = xid;
|
||||
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
ue_context_pP->ue_context.pduSession[i].xid = xid;
|
||||
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
|
||||
i, ue_context_pP->ue_context.pdusession[i].status, "PDU_SESSION_STATUS_DONE");
|
||||
i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE");
|
||||
}
|
||||
|
||||
memset(buffer, 0, RRC_BUF_SIZE);
|
||||
@@ -1682,10 +1731,10 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
|
||||
/* Free all NAS PDUs */
|
||||
for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
|
||||
if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
|
||||
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
/* Free the NAS PDU buffer and invalidate it */
|
||||
free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer);
|
||||
ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL;
|
||||
free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
|
||||
ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2015,10 +2064,10 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
|
||||
ue_context_p->ue_context.reestablishment_xid);
|
||||
|
||||
for (uint8_t pdusessionid = 0; pdusessionid < ue_context_p->ue_context.nb_of_pdusessions; pdusessionid++) {
|
||||
if (ue_context_p->ue_context.pdusession[pdusessionid].status == PDU_SESSION_STATUS_DONE) {
|
||||
ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED;
|
||||
if (ue_context_p->ue_context.pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) {
|
||||
ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED;
|
||||
} else {
|
||||
ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_FAILED;
|
||||
ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2264,7 +2313,7 @@ rrc_gNB_decode_dcch(
|
||||
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||
|
||||
for(i = 0; i < NB_RB_MAX; i++) {
|
||||
if(xid == ue_context_p->ue_context.pdusession[i].xid) {
|
||||
if(xid == ue_context_p->ue_context.pduSession[i].xid) {
|
||||
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] =
|
||||
ue_context_p->ue_context.gnb_gtp_psi[i];
|
||||
ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
|
||||
@@ -2276,13 +2325,14 @@ rrc_gNB_decode_dcch(
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p);
|
||||
//NGAP_PDUSESSION_RELEASE_RESPONSE
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid);
|
||||
} else {
|
||||
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP,
|
||||
ue_context_p,
|
||||
ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
|
||||
} else if (ue_context_p->ue_context.established_pdu_sessions_flag != 1) {
|
||||
if (ue_context_p->ue_context.setup_pdu_sessions > 0) {
|
||||
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP,
|
||||
ue_context_p,
|
||||
ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (first_rrcreconfiguration == 0){
|
||||
first_rrcreconfiguration = 1;
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
|
||||
@@ -2563,7 +2613,13 @@ rrc_gNB_decode_dcch(
|
||||
ue_context_p,
|
||||
ul_dcch_msg);
|
||||
}
|
||||
rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
|
||||
|
||||
if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) {
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p);
|
||||
} else {
|
||||
rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
|
||||
@@ -2771,8 +2827,290 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC
|
||||
rrc_remove_nsa_user(rrc, m->rnti);
|
||||
}
|
||||
|
||||
unsigned int mask_flip(unsigned int x) {
|
||||
return((((x>>8) + (x<<8))&0xffff)>>6);
|
||||
}
|
||||
|
||||
unsigned int get_dl_bw_mask(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
|
||||
|
||||
int common_band = *rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
|
||||
NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
|
||||
if (bandNRinfo->bandNR == common_band) {
|
||||
if (common_band < 257) { // FR1
|
||||
switch (common_scs) {
|
||||
case NR_SubcarrierSpacing_kHz15 :
|
||||
if (bandNRinfo->channelBWs_DL &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr1 &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz->buf));
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz30 :
|
||||
if (bandNRinfo->channelBWs_DL &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr1 &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz->buf));
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz60 :
|
||||
if (bandNRinfo->channelBWs_DL &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr1 &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz->buf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (common_scs) {
|
||||
case NR_SubcarrierSpacing_kHz60 :
|
||||
if (bandNRinfo->channelBWs_DL &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr2 &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz->buf));
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz120 :
|
||||
if (bandNRinfo->channelBWs_DL &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr2 &&
|
||||
bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz->buf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
unsigned int get_ul_bw_mask(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
|
||||
|
||||
int common_band = *rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
|
||||
NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
|
||||
if (bandNRinfo->bandNR == common_band) {
|
||||
if (common_band < 257) { // FR1
|
||||
switch (common_scs) {
|
||||
case NR_SubcarrierSpacing_kHz15 :
|
||||
if (bandNRinfo->channelBWs_UL &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr1 &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz->buf));
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz30 :
|
||||
if (bandNRinfo->channelBWs_UL &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr1 &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz->buf));
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz60 :
|
||||
if (bandNRinfo->channelBWs_UL &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr1 &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz->buf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (common_scs) {
|
||||
case NR_SubcarrierSpacing_kHz60 :
|
||||
if (bandNRinfo->channelBWs_UL &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr2 &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz->buf));
|
||||
break;
|
||||
case NR_SubcarrierSpacing_kHz120 :
|
||||
if (bandNRinfo->channelBWs_UL &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr2 &&
|
||||
bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz)
|
||||
return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz->buf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int is_dl_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
int common_band = *rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
if (common_band>256) {
|
||||
for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
|
||||
NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
|
||||
if (bandNRinfo->bandNR == common_band && !bandNRinfo->pdsch_256QAM_FR2) return (0);
|
||||
}
|
||||
}
|
||||
else if (cap->phy_Parameters.phy_ParametersFR1 && !cap->phy_Parameters.phy_ParametersFR1->pdsch_256QAM_FR1) return(0);
|
||||
|
||||
// check featureSet
|
||||
NR_FeatureSets_t *fs=cap->featureSets;
|
||||
if (fs) {
|
||||
// go through DL feature sets and look for one with current SCS
|
||||
for (int i=0;i<fs->featureSetsDownlinkPerCC->list.count;i++) {
|
||||
if (fs->featureSetsDownlinkPerCC->list.array[i]->supportedSubcarrierSpacingDL == common_scs &&
|
||||
fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL &&
|
||||
*fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL == NR_ModulationOrder_qam256) return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int is_ul_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
int common_band = *rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
|
||||
NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
|
||||
if (bandNRinfo->bandNR == common_band && !bandNRinfo->pusch_256QAM) return (0);
|
||||
}
|
||||
|
||||
// check featureSet
|
||||
NR_FeatureSets_t *fs=cap->featureSets;
|
||||
if (fs) {
|
||||
// go through UL feature sets and look for one with current SCS
|
||||
for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
|
||||
if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
|
||||
fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL &&
|
||||
*fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL == NR_ModulationOrder_qam256) return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int get_ul_mimo_layersCB(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
|
||||
// check featureSet
|
||||
NR_FeatureSets_t *fs=cap->featureSets;
|
||||
if (fs) {
|
||||
// go through UL feature sets and look for one with current SCS
|
||||
for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
|
||||
if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
|
||||
fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH &&
|
||||
fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH)
|
||||
return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
int get_ul_mimo_layers(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
|
||||
// check featureSet
|
||||
NR_FeatureSets_t *fs=cap->featureSets;
|
||||
if (fs) {
|
||||
// go through UL feature sets and look for one with current SCS
|
||||
for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
|
||||
if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
|
||||
fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH)
|
||||
return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
int get_dl_mimo_layers(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
|
||||
// check featureSet
|
||||
NR_FeatureSets_t *fs=cap->featureSets;
|
||||
if (fs) {
|
||||
// go through UL feature sets and look for one with current SCS
|
||||
for (int i=0;i<fs->featureSetsDownlinkPerCC->list.count;i++) {
|
||||
if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
|
||||
fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH)
|
||||
return(2<<*fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
|
||||
MessageDef *msg;
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
FILE *fd=NULL;//fopen("nrRRCstats.log","w");
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head)) {
|
||||
ctxt_pP->rnti = ue_context_p->ue_id_rnti;
|
||||
|
||||
if (fd) {
|
||||
if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) {
|
||||
fprintf(fd,"NR RRC UE rnti %x: S-TMSI %x failure timer %d/8\n",
|
||||
ue_context_p->ue_id_rnti,
|
||||
ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi,
|
||||
ue_context_p->ue_context.ul_failure_timer);
|
||||
} else {
|
||||
fprintf(fd,"NR RRC UE rnti %x failure timer %d/8\n",
|
||||
ue_context_p->ue_id_rnti,
|
||||
ue_context_p->ue_context.ul_failure_timer);
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.UE_Capability_nr) {
|
||||
fprintf(fd,"NR RRC UE cap: BW DL %x. BW UL %x, 256 QAM DL %s, 256 QAM UL %s, DL MIMO Layers %d UL MIMO Layers (CB) %d UL MIMO Layers (nonCB) %d\n",
|
||||
get_dl_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
|
||||
get_ul_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
|
||||
is_dl_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no",
|
||||
is_ul_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no",
|
||||
get_dl_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
|
||||
get_ul_mimo_layersCB(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
|
||||
get_ul_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr));
|
||||
}
|
||||
}
|
||||
if (ue_context_p->ue_context.ul_failure_timer > 0) {
|
||||
ue_context_p->ue_context.ul_failure_timer++;
|
||||
|
||||
if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
|
||||
// remove UE after 20 seconds after MAC (or else) has indicated UL failure
|
||||
LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n",
|
||||
ue_context_p->ue_context.rnti);
|
||||
if(ue_context_p->ue_context.StatusRrc >= NR_RRC_CONNECTED){
|
||||
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(
|
||||
ctxt_pP->module_id,
|
||||
ue_context_p,
|
||||
NGAP_CAUSE_RADIO_NETWORK,
|
||||
30);
|
||||
}else{
|
||||
mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti);
|
||||
rrc_rlc_remove_ue(ctxt_pP);
|
||||
pdcp_remove_UE(ctxt_pP);
|
||||
|
||||
/* remove RRC UE Context */
|
||||
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti);
|
||||
if (ue_context_p) {
|
||||
rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p);
|
||||
LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti);
|
||||
}
|
||||
}
|
||||
break; // break RB_FOREACH
|
||||
}
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer_rrc > 0) {
|
||||
ue_context_p->ue_context.ue_release_timer_rrc++;
|
||||
|
||||
if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) {
|
||||
LOG_I(NR_RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n",
|
||||
ue_context_p->ue_context.rnti);
|
||||
ue_context_p->ue_context.ue_release_timer_rrc = 0;
|
||||
|
||||
mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti);
|
||||
rrc_rlc_remove_ue(ctxt_pP);
|
||||
pdcp_remove_UE(ctxt_pP);
|
||||
|
||||
/* remove RRC UE Context */
|
||||
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti);
|
||||
if (ue_context_p) {
|
||||
rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p);
|
||||
LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti);
|
||||
}
|
||||
|
||||
break; // break RB_FOREACH
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd) fclose(fd);
|
||||
|
||||
/* send a tick to x2ap */
|
||||
if (is_x2ap_enabled()){
|
||||
@@ -2790,7 +3128,6 @@ void *rrc_gnb_task(void *args_p) {
|
||||
int result;
|
||||
//SRB_INFO *srb_info_p;
|
||||
//int CC_id;
|
||||
|
||||
protocol_ctxt_t ctxt={.module_id=0,
|
||||
.enb_flag=1,
|
||||
.instance=0,
|
||||
@@ -2801,7 +3138,6 @@ void *rrc_gnb_task(void *args_p) {
|
||||
.configured=true,
|
||||
.brOption=false
|
||||
};
|
||||
|
||||
itti_mark_task_ready(TASK_RRC_GNB);
|
||||
LOG_I(NR_RRC,"Entering main loop of NR_RRC message task\n");
|
||||
|
||||
@@ -3242,11 +3578,13 @@ rrc_gNB_generate_RRCRelease(
|
||||
itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
|
||||
#else
|
||||
if (NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||
uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size);
|
||||
memcpy (message_buffer, buffer, size);
|
||||
MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
|
||||
F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti;
|
||||
F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK;
|
||||
F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release
|
||||
F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = buffer;
|
||||
F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = message_buffer;
|
||||
F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size;
|
||||
itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m);
|
||||
} else {
|
||||
@@ -3257,6 +3595,9 @@ rrc_gNB_generate_RRCRelease(
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
|
||||
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id);
|
||||
ue_context_pP->ue_context.ue_release_timer_rrc = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+126
-61
@@ -57,6 +57,8 @@
|
||||
#include "RRC/NR/MESSAGES/asn1_msg.h"
|
||||
#include "NR_UERadioAccessCapabilityInformation.h"
|
||||
#include "NR_UE-CapabilityRAT-ContainerList.h"
|
||||
#include "NGAP_Cause.h"
|
||||
#include "NGAP_CauseRadioNetwork.h"
|
||||
#include "f1ap_messages_types.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
@@ -352,8 +354,8 @@ nr_rrc_pdcp_config_security(
|
||||
if (print_keys == 1 ) {
|
||||
print_keys =0;
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kgnb, 32,"\nKgNB:" );
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 32,"\nKRRCenc:" );
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 32,"\nKRRCint:" );
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 16,"\nKRRCenc:" );
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 16,"\nKRRCint:" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,6 +506,10 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
protocol_ctxt_t ctxt;
|
||||
uint8_t pdu_sessions_done = 0;
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp;
|
||||
uint8_t inde_list[NR_NB_RB_MAX - 3]= {0};
|
||||
int ret = 0;
|
||||
|
||||
ue_initial_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id;
|
||||
gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).gNB_ue_ngap_id;
|
||||
@@ -527,28 +533,64 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id;
|
||||
ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag;
|
||||
|
||||
if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions != 0) {
|
||||
ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions;
|
||||
uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
|
||||
if (nb_pdusessions_tosetup != 0) {
|
||||
memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t));
|
||||
for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
|
||||
if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE)
|
||||
continue;
|
||||
ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW;
|
||||
ue_context_p->ue_context.pdusession[i].param = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done];
|
||||
pdu_sessions_done++;
|
||||
if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
|
||||
continue;
|
||||
ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_NEW;
|
||||
ue_context_p->ue_context.pduSession[i].param = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done];
|
||||
create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].pdusession_id;
|
||||
create_tunnel_req.upf_NGu_teid[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid;
|
||||
create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length;
|
||||
memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer,
|
||||
NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.buffer,
|
||||
sizeof(uint8_t)*20);
|
||||
LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n",
|
||||
i,
|
||||
create_tunnel_req.upf_NGu_teid[pdu_sessions_done],
|
||||
create_tunnel_req.pdusession_id[pdu_sessions_done]);
|
||||
inde_list[pdu_sessions_done] = i;
|
||||
pdu_sessions_done++;
|
||||
|
||||
// TODO establish PDU SESSION
|
||||
|
||||
if(pdu_sessions_done >= NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions) {
|
||||
break;
|
||||
}
|
||||
if(pdu_sessions_done >= nb_pdusessions_tosetup) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
|
||||
create_tunnel_req.rnti = ue_context_p->ue_context.rnti;
|
||||
create_tunnel_req.num_tunnels = pdu_sessions_done;
|
||||
|
||||
ret = gtpv1u_create_ngu_tunnel(
|
||||
instance,
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp);
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC,"rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti);
|
||||
ue_context_p->ue_context.ue_release_timer_ng = 1;
|
||||
ue_context_p->ue_context.ue_release_timer_thres_ng = 100;
|
||||
ue_context_p->ue_context.ue_release_timer = 0;
|
||||
ue_context_p->ue_context.ue_reestablishment_timer = 0;
|
||||
ue_context_p->ue_context.ul_failure_timer = 20000;
|
||||
ue_context_p->ue_context.ul_failure_timer = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
&ctxt,
|
||||
&create_tunnel_resp,
|
||||
&inde_list[0]);
|
||||
ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup;
|
||||
ue_context_p->ue_context.established_pdu_sessions_flag = 1;
|
||||
}
|
||||
|
||||
/* NAS PDU */
|
||||
ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag;
|
||||
if (ue_context_p->ue_context.nas_pdu_flag == 1) {
|
||||
ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length;
|
||||
ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer;
|
||||
if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag == 1) {
|
||||
ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag;
|
||||
ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length;
|
||||
ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer;
|
||||
}
|
||||
|
||||
/* security */
|
||||
@@ -598,25 +640,34 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
|
||||
{
|
||||
MessageDef *msg_p = NULL;
|
||||
int pdusession;
|
||||
int e_rabs_done = 0;
|
||||
int e_rabs_failed = 0;
|
||||
int pdu_sessions_done = 0;
|
||||
int pdu_sessions_failed = 0;
|
||||
int qos_flow_index = 0;
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, NGAP_INITIAL_CONTEXT_SETUP_RESP);
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
|
||||
|
||||
for (pdusession = 0; pdusession < ue_context_pP->ue_context.nb_of_pdusessions; pdusession++) {
|
||||
if (ue_context_pP->ue_context.pdusession[pdusession].status == E_RAB_STATUS_DONE) {
|
||||
e_rabs_done++;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
|
||||
if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) {
|
||||
pdu_sessions_done++;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
|
||||
// TODO add other information from S1-U when it will be integrated
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession];
|
||||
memcpy(NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.buffer , ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, 20);
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.length = 4;
|
||||
ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_ESTABLISHED;
|
||||
ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos;
|
||||
for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos; qos_flow_index++) {
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi =
|
||||
ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
|
||||
}
|
||||
} else {
|
||||
e_rabs_failed++;
|
||||
ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_FAILED;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
|
||||
pdu_sessions_failed++;
|
||||
ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
|
||||
// TODO add cause when it will be integrated
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause = NGAP_Cause_PR_radioNetwork;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,9 +680,9 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
|
||||
MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
ue_context_pP->ue_id_rnti,
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id,
|
||||
e_rabs_done, e_rabs_failed);
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = e_rabs_done;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = e_rabs_failed;
|
||||
pdu_sessions_done, pdu_sessions_failed);
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = pdu_sessions_done;
|
||||
NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = pdu_sessions_failed;
|
||||
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
|
||||
}
|
||||
|
||||
@@ -902,10 +953,10 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
|
||||
for (pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) {
|
||||
// if (xid == ue_context_pP->ue_context.pdusession[pdusession].xid) {
|
||||
if (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_DONE) {
|
||||
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
|
||||
if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) {
|
||||
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
|
||||
// NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = 1;
|
||||
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pdusession[pdusession].param.nb_qos;
|
||||
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos;
|
||||
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession];
|
||||
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.pdu_session_type = PDUSessionType_ipv4;
|
||||
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.length = ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].length;
|
||||
@@ -913,13 +964,13 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, sizeof(uint8_t)*20);
|
||||
for (qos_flow_index = 0; qos_flow_index < NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow; qos_flow_index++) {
|
||||
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi =
|
||||
ue_context_pP->ue_context.pdusession[pdusession].param.qos[qos_flow_index].qfi;
|
||||
ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi;
|
||||
NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
|
||||
}
|
||||
|
||||
ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
|
||||
ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED;
|
||||
LOG_I (NR_RRC,"gnb_gtp_addr (msg index %d, pdu_sessions index %d, status %d, xid %d): nb_of_pdusessions %d, pdusession_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
|
||||
pdu_sessions_done, pdusession, ue_context_pP->ue_context.pdusession[pdusession].status, xid,
|
||||
pdu_sessions_done, pdusession, ue_context_pP->ue_context.pduSession[pdusession].status, xid,
|
||||
ue_context_pP->ue_context.nb_of_pdusessions,
|
||||
NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].pdusession_id,
|
||||
NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gtp_teid,
|
||||
@@ -928,12 +979,12 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[2],
|
||||
NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[3]);
|
||||
pdu_sessions_done++;
|
||||
} else if ((ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_NEW) ||
|
||||
(ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) {
|
||||
} else if ((ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_NEW) ||
|
||||
(ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) {
|
||||
LOG_D (NR_RRC,"PDU-SESSION is NEW or already ESTABLISHED\n");
|
||||
} else { /* to be improved */
|
||||
ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_FAILED;
|
||||
NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
|
||||
ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED;
|
||||
NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
|
||||
pdu_sessions_failed++;
|
||||
// TODO add cause when it will be integrated
|
||||
}
|
||||
@@ -962,7 +1013,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
}
|
||||
|
||||
for(int i = 0; i < NB_RB_MAX; i++) {
|
||||
ue_context_pP->ue_context.pdusession[i].xid = -1;
|
||||
ue_context_pP->ue_context.pduSession[i].xid = -1;
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1008,20 +1059,20 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
||||
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
|
||||
for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
|
||||
if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE)
|
||||
if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
|
||||
continue;
|
||||
ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW;
|
||||
ue_context_p->ue_context.pdusession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
|
||||
ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_NEW;
|
||||
ue_context_p->ue_context.pduSession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done];
|
||||
create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id;
|
||||
create_tunnel_req.upf_NGu_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid;
|
||||
memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer,
|
||||
NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.buffer,
|
||||
NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer,
|
||||
sizeof(uint8_t)*20);
|
||||
create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.length;
|
||||
create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length;
|
||||
LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n",
|
||||
i,
|
||||
create_tunnel_req.upf_NGu_teid[i],
|
||||
create_tunnel_req.pdusession_id[i]);
|
||||
create_tunnel_req.upf_NGu_teid[pdu_sessions_done],
|
||||
create_tunnel_req.pdusession_id[pdu_sessions_done]);
|
||||
inde_list[pdu_sessions_done] = i;
|
||||
pdu_sessions_done++;
|
||||
|
||||
@@ -1089,7 +1140,7 @@ rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(
|
||||
NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value = cause_valueP;
|
||||
NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).nb_of_pdusessions = ue_context_pP->ue_context.setup_pdu_sessions;
|
||||
for (int pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) {
|
||||
NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id;
|
||||
NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
|
||||
}
|
||||
itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg_context_release_req_p);
|
||||
}
|
||||
@@ -1174,11 +1225,25 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(
|
||||
return -1;
|
||||
} else {
|
||||
ue_context_p->ue_context.ue_release_timer_ng = 0;
|
||||
ue_context_p->ue_context.ue_release_timer_thres_rrc = 1000;
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
|
||||
ctxt.eNB_index = 0;
|
||||
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
|
||||
instance_t instance,
|
||||
uint32_t gNB_ue_ngap_id) {
|
||||
MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_NGAP_GNB, NULL, 0,
|
||||
"0 NGAP_UE_CONTEXT_RELEASE_COMPLETE gNB_ue_ngap_id 0x%06"PRIX32" ",
|
||||
gNB_ue_ngap_id);
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = gNB_ue_ngap_id;
|
||||
itti_send_msg_to_task(TASK_NGAP, instance, msg);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Remove UE ids (ue_initial_id and ng_id) from hashtables.
|
||||
@@ -1288,12 +1353,12 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
|
||||
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
|
||||
|
||||
for (int i = 0; i < NB_RB_MAX; i++) {
|
||||
if (xid == ue_context_pP->ue_context.pdusession[i].xid) {
|
||||
if (xid == ue_context_pP->ue_context.pduSession[i].xid) {
|
||||
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusession_release[pdu_sessions_released].pdusession_id =
|
||||
ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
|
||||
ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
|
||||
pdu_sessions_released++;
|
||||
//clear
|
||||
memset(&ue_context_pP->ue_context.pdusession[i], 0, sizeof(pdu_session_param_t));
|
||||
memset(&ue_context_pP->ue_context.pduSession[i], 0, sizeof(pdu_session_param_t));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,7 +1374,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
|
||||
|
||||
//clear xid
|
||||
for(int i = 0; i < NB_RB_MAX; i++) {
|
||||
ue_context_pP->ue_context.pdusession[i].xid = -1;
|
||||
ue_context_pP->ue_context.pduSession[i].xid = -1;
|
||||
}
|
||||
|
||||
//clear release pdusessions
|
||||
@@ -1370,7 +1435,7 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
|
||||
}
|
||||
|
||||
for (i = 0; i < NR_NB_RB_MAX; i++) {
|
||||
if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pdusession[i].param.pdusession_id) {
|
||||
if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pduSession[i].param.pdusession_id) {
|
||||
b_existed = 1;
|
||||
break;
|
||||
}
|
||||
@@ -1384,13 +1449,13 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
|
||||
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 30;
|
||||
ue_context_p->ue_context.nb_release_of_pdusessions++;
|
||||
} else {
|
||||
if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_FAILED) {
|
||||
ue_context_p->ue_context.pdusession[i].xid = xid;
|
||||
if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_FAILED) {
|
||||
ue_context_p->ue_context.pduSession[i].xid = xid;
|
||||
continue;
|
||||
} else if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
|
||||
LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pdusession[i].param.pdusession_id);
|
||||
ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_TORELEASE;
|
||||
ue_context_p->ue_context.pdusession[i].xid = xid;
|
||||
} else if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
|
||||
LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pduSession[i].param.pdusession_id);
|
||||
ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_TORELEASE;
|
||||
ue_context_p->ue_context.pduSession[i].xid = xid;
|
||||
pdusession_release_drb++;
|
||||
} else {
|
||||
// pdusession_id status NG
|
||||
@@ -1414,7 +1479,7 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
|
||||
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||
|
||||
for(i = 0; i < NB_RB_MAX; i++) {
|
||||
if(xid == ue_context_p->ue_context.pdusession[i].xid) {
|
||||
if(xid == ue_context_p->ue_context.pduSession[i].xid) {
|
||||
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i];
|
||||
ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
|
||||
memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i]));
|
||||
|
||||
@@ -129,6 +129,10 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(
|
||||
instance_t instance
|
||||
);
|
||||
|
||||
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
|
||||
instance_t instance,
|
||||
uint32_t gNB_ue_ngap_id);
|
||||
|
||||
void
|
||||
rrc_gNB_NGAP_remove_ue_ids(
|
||||
gNB_RRC_INST *const rrc_instance_pP,
|
||||
|
||||
@@ -135,7 +135,7 @@ rrc_gNB_allocate_new_UE_context(
|
||||
|
||||
for(int i = 0; i < NB_RB_MAX; i++) {
|
||||
new_p->ue_context.e_rab[i].xid = -1;
|
||||
new_p->ue_context.pdusession[i].xid = -1;
|
||||
new_p->ue_context.pduSession[i].xid = -1;
|
||||
new_p->ue_context.modify_e_rab[i].xid = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,8 +61,15 @@ void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellC
|
||||
|
||||
// frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B,
|
||||
if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6);
|
||||
coreset0->frequencyDomainResources.buf[0] = 0xff;
|
||||
coreset0->frequencyDomainResources.buf[1] = 0;
|
||||
int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
|
||||
if (curr_bwp < 48)
|
||||
coreset0->frequencyDomainResources.buf[0] = 0xf0;
|
||||
else
|
||||
coreset0->frequencyDomainResources.buf[0] = 0xff;
|
||||
if (curr_bwp < 96)
|
||||
coreset0->frequencyDomainResources.buf[1] = 0;
|
||||
else
|
||||
coreset0->frequencyDomainResources.buf[1] = 0xff;
|
||||
coreset0->frequencyDomainResources.buf[2] = 0;
|
||||
coreset0->frequencyDomainResources.buf[3] = 0;
|
||||
coreset0->frequencyDomainResources.buf[4] = 0;
|
||||
|
||||
+58
-30
@@ -69,9 +69,7 @@
|
||||
#include "SIMULATION/TOOLS/sim.h" // for taus
|
||||
#include <executables/softmodem-common.h>
|
||||
|
||||
#if defined(ITTI_SIM) || defined(RFSIM_NAS)
|
||||
#include "nr_nas_msg_sim.h"
|
||||
#endif
|
||||
|
||||
NR_UE_RRC_INST_t *NR_UE_rrc_inst;
|
||||
/* NAS Attach request with IMSI */
|
||||
@@ -1267,16 +1265,34 @@ nr_rrc_ue_process_masterCellGroup(
|
||||
// NSA procedures
|
||||
}
|
||||
|
||||
if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config == NULL){
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
|
||||
}
|
||||
|
||||
if( cellGroupConfig->rlc_BearerToReleaseList != NULL){
|
||||
//TODO (perform RLC bearer release as specified in 5.3.5.5.3)
|
||||
}
|
||||
|
||||
if( cellGroupConfig->rlc_BearerToAddModList != NULL){
|
||||
//TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4)
|
||||
if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList != NULL){
|
||||
free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
|
||||
}
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
|
||||
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList,
|
||||
sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
|
||||
}
|
||||
|
||||
if( cellGroupConfig->mac_CellGroupConfig != NULL){
|
||||
//TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
|
||||
LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n");
|
||||
if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig != NULL){
|
||||
LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n");
|
||||
free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig);
|
||||
}
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig));
|
||||
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig,
|
||||
sizeof(struct NR_MAC_CellGroupConfig));
|
||||
}
|
||||
|
||||
if( cellGroupConfig->sCellToReleaseList != NULL){
|
||||
@@ -1332,14 +1348,21 @@ static void rrc_ue_generate_RRCSetupComplete(
|
||||
AssertFatal(1==0,"2 > csi_MeasConfig is not null\n");
|
||||
|
||||
if (AMF_MODE_ENABLED) {
|
||||
#if defined(ITTI_SIM) || defined(RFSIM_NAS)
|
||||
#if defined(ITTI_SIM)
|
||||
as_nas_info_t initialNasMsg;
|
||||
generateRegistrationRequest(&initialNasMsg);
|
||||
generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
|
||||
nas_msg = (char*)initialNasMsg.data;
|
||||
nas_msg_length = initialNasMsg.length;
|
||||
#else
|
||||
nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
|
||||
nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
|
||||
if (get_softmodem_params()->sa) {
|
||||
as_nas_info_t initialNasMsg;
|
||||
generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
|
||||
nas_msg = (char*)initialNasMsg.data;
|
||||
nas_msg_length = initialNasMsg.length;
|
||||
} else {
|
||||
nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
|
||||
nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
nas_msg = nr_nas_attach_req_imsi;
|
||||
@@ -2115,28 +2138,27 @@ nr_rrc_ue_establish_srb2(
|
||||
(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4));
|
||||
|
||||
// Refresh DRBs
|
||||
// nr_rrc_pdcp_config_asn1_req(ctxt_pP,
|
||||
// NULL,
|
||||
// radioBearerConfig->drb_ToAddModList,
|
||||
// NULL,
|
||||
// NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
|
||||
// (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
|
||||
// NULL,
|
||||
// NULL,
|
||||
// kUPenc,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
|
||||
// NULL);
|
||||
nr_rrc_pdcp_config_asn1_req(ctxt_pP,
|
||||
NULL,
|
||||
radioBearerConfig->drb_ToAddModList,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
kUPenc,
|
||||
NULL,
|
||||
NULL,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
|
||||
// Refresh DRBs
|
||||
// nr_rrc_rlc_config_asn1_req(ctxt_pP,
|
||||
// NULL,
|
||||
// radioBearerConfig->drb_ToAddModList,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL
|
||||
// );
|
||||
} // drb_ToAddModList
|
||||
nr_rrc_rlc_config_asn1_req(ctxt_pP,
|
||||
NULL,
|
||||
radioBearerConfig->drb_ToAddModList,
|
||||
NULL,
|
||||
NULL,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList
|
||||
);
|
||||
} // drb_ToAddModList //
|
||||
|
||||
if (radioBearerConfig->drb_ToReleaseList != NULL) {
|
||||
for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) {
|
||||
@@ -2171,9 +2193,16 @@ nr_rrc_ue_establish_srb2(
|
||||
// nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig);
|
||||
}
|
||||
|
||||
if(ie->nonCriticalExtension->masterCellGroup!=NULL) {
|
||||
nr_rrc_ue_process_masterCellGroup(
|
||||
ctxt_pP,
|
||||
gNB_index,
|
||||
ie->nonCriticalExtension->masterCellGroup);
|
||||
}
|
||||
|
||||
if (ie->radioBearerConfig != NULL) {
|
||||
LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
|
||||
// nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
|
||||
nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
|
||||
}
|
||||
|
||||
/* Check if there is dedicated NAS information to forward to NAS */
|
||||
@@ -2255,8 +2284,7 @@ nr_rrc_ue_establish_srb2(
|
||||
|
||||
if (Srb_id != 1) {
|
||||
LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n",
|
||||
ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
|
||||
return -1;
|
||||
ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
|
||||
} else {
|
||||
LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
|
||||
How to configure wireshark for dissecting LTE protocols:
|
||||
How to configure wireshark for dissecting LTE/NR protocols:
|
||||
- start the wireshark as a sudoers
|
||||
- goto analyze->enabled prototols
|
||||
=> enable mac_lte_udp and rlc_lte_udp
|
||||
=> enable mac_xxx_udp and rlc_xxx_udp (xxx is lte or nr)
|
||||
- goto edit/preferences and expand Protocols
|
||||
- select UDP and check "try heuristic sub-dissectors first"
|
||||
- select MAC-LTE, and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info"
|
||||
- select RLC-LTE, and check all the options except the "May see RLC headers only", and
|
||||
- select MAC-LTE (or MAC-NR), and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info"
|
||||
- select RLC-LTE (or NR), and check all the options except the "May see RLC headers only", and
|
||||
set the "call PDCP dissector for DRB PDUs" to "12-bit SN". Optionally you may select the sequence analysis for RLC AM/UM.
|
||||
- select PDCP-LTE (or NR)
|
||||
|
||||
How to use
|
||||
- start eNB or UE with option --opt.type wireshark
|
||||
|
||||
@@ -59,7 +59,8 @@ typedef uint16_t guint16;
|
||||
typedef uint32_t guint32;
|
||||
typedef guint8 gboolean;
|
||||
|
||||
#include "packet-mac-lte.h"
|
||||
#include <openair2/UTIL/OPT/wireshark_headers.h>
|
||||
|
||||
#include "mac_pcap.h"
|
||||
|
||||
/* OPT parameters definitions */
|
||||
@@ -107,9 +108,10 @@ typedef enum radio_type_e {
|
||||
*/
|
||||
|
||||
extern int opt_enabled;
|
||||
#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(x)
|
||||
#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(0, x)
|
||||
#define trace_NRpdu(x...) if (opt_enabled) trace_pdu_implementation(1, x)
|
||||
|
||||
void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
|
||||
int oob_event, int oob_event_value);
|
||||
|
||||
|
||||
@@ -1,382 +0,0 @@
|
||||
/* packet-mac-lte.h
|
||||
*
|
||||
* Martin Mathieson
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* This header file may also be distributed under
|
||||
* the terms of the BSD Licence as follows:
|
||||
*
|
||||
* Copyright (C) 2009 Martin Mathieson. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
this is wireshark, commit: commit eda834b6e29c36e05a63a6056afa98390ff79357
|
||||
Date: Wed Aug 22 14:36:20 2018 +0200
|
||||
modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_OPT_PACKET_MAC_LTE__H__
|
||||
#define __UTIL_OPT_PACKET_MAC_LTE__H__
|
||||
|
||||
#include "ws_symbol_export.h"
|
||||
|
||||
/** data structure to hold time values with nanosecond resolution*/
|
||||
typedef struct {
|
||||
time_t secs;
|
||||
int nsecs;
|
||||
} nstime_t;
|
||||
|
||||
|
||||
/* radioType */
|
||||
#define FDD_RADIO 1
|
||||
#define TDD_RADIO 2
|
||||
|
||||
/* Direction */
|
||||
#define DIRECTION_UPLINK 0
|
||||
#define DIRECTION_DOWNLINK 1
|
||||
|
||||
/* rntiType */
|
||||
#define WS_NO_RNTI 0
|
||||
#define WS_P_RNTI 1
|
||||
#define WS_RA_RNTI 2
|
||||
#define WS_C_RNTI 3
|
||||
#define WS_SI_RNTI 4
|
||||
#define WS_SPS_RNTI 5
|
||||
#define WS_M_RNTI 6
|
||||
#define WS_SL_BCH_RNTI 7
|
||||
#define WS_SL_RNTI 8
|
||||
#define WS_SC_RNTI 9
|
||||
#define WS_G_RNTI 10
|
||||
|
||||
typedef enum mac_lte_oob_event {
|
||||
ltemac_send_preamble,
|
||||
ltemac_send_sr,
|
||||
ltemac_sr_failure
|
||||
} mac_lte_oob_event;
|
||||
|
||||
typedef enum mac_lte_dl_retx {
|
||||
dl_retx_no,
|
||||
dl_retx_yes,
|
||||
dl_retx_unknown
|
||||
} mac_lte_dl_retx;
|
||||
|
||||
typedef enum mac_lte_crc_status {
|
||||
crc_fail = 0,
|
||||
crc_success = 1,
|
||||
crc_high_code_rate = 2,
|
||||
crc_pdsch_lost = 3,
|
||||
crc_duplicate_nonzero_rv = 4,
|
||||
crc_false_dci = 5
|
||||
} mac_lte_crc_status;
|
||||
|
||||
/* N.B. for SCellIndex-r13 extends to 31 */
|
||||
typedef enum mac_lte_carrier_id {
|
||||
carrier_id_primary,
|
||||
carrier_id_secondary_1,
|
||||
carrier_id_secondary_2,
|
||||
carrier_id_secondary_3,
|
||||
carrier_id_secondary_4,
|
||||
carrier_id_secondary_5,
|
||||
carrier_id_secondary_6,
|
||||
carrier_id_secondary_7
|
||||
} mac_lte_carrier_id;
|
||||
|
||||
typedef enum mac_lte_ce_mode {
|
||||
no_ce_mode = 0,
|
||||
ce_mode_a = 1,
|
||||
ce_mode_b = 2
|
||||
} mac_lte_ce_mode;
|
||||
|
||||
typedef enum mac_lte_nb_mode {
|
||||
no_nb_mode = 0,
|
||||
nb_mode = 1
|
||||
} mac_lte_nb_mode;
|
||||
|
||||
/* Context info attached to each LTE MAC frame */
|
||||
typedef struct mac_lte_info
|
||||
{
|
||||
/* Needed for decode */
|
||||
guint8 radioType;
|
||||
guint8 direction;
|
||||
guint8 rntiType;
|
||||
|
||||
/* Extra info to display */
|
||||
guint16 rnti;
|
||||
guint16 ueid;
|
||||
|
||||
/* Timing info */
|
||||
guint16 sysframeNumber;
|
||||
guint16 subframeNumber;
|
||||
|
||||
/* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */
|
||||
gboolean subframeNumberOfGrantPresent;
|
||||
guint16 subframeNumberOfGrant;
|
||||
|
||||
/* Flag set only if doing PHY-level data test - i.e. there may not be a
|
||||
well-formed MAC PDU so just show as raw data */
|
||||
gboolean isPredefinedData;
|
||||
|
||||
/* Length of DL PDU or UL grant size in bytes */
|
||||
guint16 length;
|
||||
|
||||
/* 0=newTx, 1=first-retx, etc */
|
||||
guint8 reTxCount;
|
||||
guint8 isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */
|
||||
|
||||
/* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set */
|
||||
gboolean isExtendedBSRSizes;
|
||||
|
||||
/* UL only. Indicates if the R10 simultaneousPUCCH-PUSCH parameter is set for PCell */
|
||||
gboolean isSimultPUCCHPUSCHPCell;
|
||||
|
||||
/* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set for PSCell */
|
||||
gboolean isSimultPUCCHPUSCHPSCell;
|
||||
|
||||
/* Status of CRC check. For UE it is DL only. For eNodeB it is UL
|
||||
only. For an analyzer, it is present for both DL and UL. */
|
||||
gboolean crcStatusValid;
|
||||
mac_lte_crc_status crcStatus;
|
||||
|
||||
/* Carrier ID */
|
||||
mac_lte_carrier_id carrierId;
|
||||
|
||||
/* DL only. Is this known to be a retransmission? */
|
||||
mac_lte_dl_retx dl_retx;
|
||||
|
||||
/* DL only. CE mode to be used for RAR decoding */
|
||||
mac_lte_ce_mode ceMode;
|
||||
|
||||
/* DL and UL. NB-IoT mode of the UE */
|
||||
mac_lte_nb_mode nbMode;
|
||||
|
||||
/* UL only, for now used for CE mode A RAR decoding */
|
||||
guint8 nUlRb;
|
||||
|
||||
/* More Physical layer info (see direction above for which side of union to use) */
|
||||
union {
|
||||
struct mac_lte_ul_phy_info
|
||||
{
|
||||
guint8 present; /* Remaining UL fields are present and should be displayed */
|
||||
guint8 modulation_type;
|
||||
guint8 tbs_index;
|
||||
guint8 resource_block_length;
|
||||
guint8 resource_block_start;
|
||||
guint8 harq_id;
|
||||
gboolean ndi;
|
||||
} ul_info;
|
||||
struct mac_lte_dl_phy_info
|
||||
{
|
||||
guint8 present; /* Remaining DL fields are present and should be displayed */
|
||||
guint8 dci_format;
|
||||
guint8 resource_allocation_type;
|
||||
guint8 aggregation_level;
|
||||
guint8 mcs_index;
|
||||
guint8 redundancy_version_index;
|
||||
guint8 resource_block_length;
|
||||
guint8 harq_id;
|
||||
gboolean ndi;
|
||||
guint8 transport_block; /* 0..1 */
|
||||
} dl_info;
|
||||
} detailed_phy_info;
|
||||
|
||||
/* Relating to out-of-band events */
|
||||
/* N.B. dissector will only look to these fields if length is 0... */
|
||||
mac_lte_oob_event oob_event;
|
||||
guint8 rapid;
|
||||
guint8 rach_attempt_number;
|
||||
#define MAX_SRs 20
|
||||
guint16 number_of_srs;
|
||||
guint16 oob_ueid[MAX_SRs];
|
||||
guint16 oob_rnti[MAX_SRs];
|
||||
} mac_lte_info;
|
||||
|
||||
|
||||
typedef struct mac_lte_tap_info {
|
||||
/* Info from context */
|
||||
guint16 rnti;
|
||||
guint16 ueid;
|
||||
guint8 rntiType;
|
||||
guint8 isPredefinedData;
|
||||
gboolean crcStatusValid;
|
||||
mac_lte_crc_status crcStatus;
|
||||
guint8 direction;
|
||||
|
||||
guint8 isPHYRetx;
|
||||
guint16 ueInTTI;
|
||||
|
||||
nstime_t mac_lte_time;
|
||||
|
||||
/* Number of bytes (which part is used depends upon context settings) */
|
||||
guint32 single_number_of_bytes;
|
||||
guint32 bytes_for_lcid[11];
|
||||
guint32 sdus_for_lcid[11];
|
||||
guint8 number_of_rars;
|
||||
guint8 number_of_paging_ids;
|
||||
|
||||
/* Number of padding bytes includes padding subheaders and trailing padding */
|
||||
guint16 padding_bytes;
|
||||
guint16 raw_length;
|
||||
} mac_lte_tap_info;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
/* UDP framing format */
|
||||
/* ----------------------- */
|
||||
/* Several people have asked about dissecting MAC by framing */
|
||||
/* PDUs over IP. A suggested format over UDP has been created */
|
||||
/* and implemented by this dissector, using the definitions */
|
||||
/* below. A link to an example program showing you how to encode */
|
||||
/* these headers and send LTE MAC PDUs on a UDP socket is */
|
||||
/* provided at https://wiki.wireshark.org/MAC-LTE */
|
||||
/* */
|
||||
/* A heuristic dissector (enabled by a preference) will */
|
||||
/* recognise a signature at the beginning of these frames. */
|
||||
/*****************************************************************/
|
||||
|
||||
|
||||
/* Signature. Rather than try to define a port for this, or make the
|
||||
port number a preference, frames will start with this string (with no
|
||||
terminating NULL */
|
||||
#define MAC_LTE_START_STRING "mac-lte"
|
||||
|
||||
/* Fixed fields. This is followed by the following 3 mandatory fields:
|
||||
- radioType (1 byte)
|
||||
- direction (1 byte)
|
||||
- rntiType (1 byte)
|
||||
(where the allowed values are defined above */
|
||||
|
||||
/* Optional fields. Attaching this info to frames will allow you
|
||||
to show you display/filter/plot/add-custom-columns on these fields, so should
|
||||
be added if available.
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag) */
|
||||
|
||||
#define MAC_LTE_RNTI_TAG 0x02
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define MAC_LTE_UEID_TAG 0x03
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define MAC_LTE_FRAME_SUBFRAME_TAG 0x04
|
||||
/* 2 bytes, network order, SFN is stored in 12 MSB and SF in 4 LSB */
|
||||
|
||||
#define MAC_LTE_PREDEFINED_DATA_TAG 0x05
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_RETX_TAG 0x06
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_CRC_STATUS_TAG 0x07
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_EXT_BSR_SIZES_TAG 0x08
|
||||
/* 0 byte */
|
||||
|
||||
#define MAC_LTE_SEND_PREAMBLE_TAG 0x09
|
||||
/* 2 bytes, RAPID value (1 byte) followed by RACH attempt number (1 byte) */
|
||||
|
||||
#define MAC_LTE_CARRIER_ID_TAG 0x0A
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_PHY_TAG 0x0B
|
||||
/* variable length, length (1 byte) then depending on direction
|
||||
in UL: modulation type (1 byte), TBS index (1 byte), RB length (1 byte),
|
||||
RB start (1 byte), HARQ id (1 byte), NDI (1 byte)
|
||||
in DL: DCI format (1 byte), resource allocation type (1 byte), aggregation level (1 byte),
|
||||
MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte),
|
||||
HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */
|
||||
|
||||
#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG 0x0C
|
||||
/* 0 byte */
|
||||
|
||||
#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D
|
||||
/* 0 byte */
|
||||
|
||||
#define MAC_LTE_CE_MODE_TAG 0x0E
|
||||
/* 1 byte containing mac_lte_ce_mode enum value */
|
||||
|
||||
#define MAC_LTE_NB_MODE_TAG 0x0F
|
||||
/* 1 byte containing mac_lte_nb_mode enum value */
|
||||
|
||||
#define MAC_LTE_N_UL_RB_TAG 0x10
|
||||
/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */
|
||||
|
||||
#define MAC_LTE_SR_TAG 0x11
|
||||
/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */
|
||||
|
||||
|
||||
/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
|
||||
continues until the end of the frame) */
|
||||
#define MAC_LTE_PAYLOAD_TAG 0x01
|
||||
|
||||
|
||||
/* Type to store parameters for configuring LCID->RLC channel settings for DRB */
|
||||
/* Some are optional, and may not be seen (e.g. on reestablishment) */
|
||||
typedef struct drb_mapping_t
|
||||
{
|
||||
guint16 ueid; /* Mandatory */
|
||||
guint8 drbid; /* Mandatory */
|
||||
gboolean lcid_present;
|
||||
guint8 lcid; /* Part of LogicalChannelConfig - optional */
|
||||
gboolean rlcMode_present;
|
||||
guint8 rlcMode; /* Part of RLC config - optional */
|
||||
gboolean rlc_ul_ext_li_field; /* Part of RLC config - optional */
|
||||
gboolean rlc_dl_ext_li_field; /* Part of RLC config - optional */
|
||||
gboolean rlc_ul_ext_am_sn; /* Part of RLC config - optional */
|
||||
gboolean rlc_dl_ext_am_sn; /* Part of RLC config - optional */
|
||||
gboolean um_sn_length_present;
|
||||
guint8 um_sn_length; /* Part of RLC config - optional */
|
||||
gboolean ul_priority_present;
|
||||
guint8 ul_priority; /* Part of LogicalChannelConfig - optional */
|
||||
gboolean pdcp_sn_size_present;
|
||||
guint8 pdcp_sn_size; /* Part of pdcp-Config - optional */
|
||||
} drb_mapping_t;
|
||||
|
||||
|
||||
|
||||
/* Dedicated DRX config. Used to verify that a sensible config is given.
|
||||
Also, beginning to configure MAC with this config and (optionally) show
|
||||
DRX config and state (cycles/timers) attached to each UL/DL PDU! */
|
||||
typedef struct drx_config_t {
|
||||
gboolean configured;
|
||||
guint32 frameNum;
|
||||
guint32 previousFrameNum;
|
||||
|
||||
guint32 onDurationTimer;
|
||||
guint32 inactivityTimer;
|
||||
guint32 retransmissionTimer;
|
||||
guint32 longCycle;
|
||||
guint32 cycleOffset;
|
||||
/* Optional Short cycle */
|
||||
gboolean shortCycleConfigured;
|
||||
guint32 shortCycle;
|
||||
guint32 shortCycleTimer;
|
||||
} drx_config_t;
|
||||
|
||||
/* RRC can indicate whether simultaneous PUCCH/PUSCH is used */
|
||||
typedef enum {
|
||||
SIMULT_PUCCH_PUSCH_PCELL = 0,
|
||||
SIMULT_PUCCH_PUSCH_PSCELL
|
||||
} simult_pucch_pusch_cell_type;
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/* packet-rohc.h
|
||||
* Routines for RObust Header Compression (ROHC) dissection.
|
||||
*
|
||||
* Copyright 2011, Anders Broman <anders.broman[at]ericsson.com>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* Ref:
|
||||
* http://www.ietf.org/rfc/rfc3095.txt RObust Header Compression (ROHC): Framework and four profiles: RTP, UDP, ESP, and uncompressed
|
||||
* http://datatracker.ietf.org/doc/rfc4815/ RObust Header Compression (ROHC): Corrections and Clarifications to RFC 3095
|
||||
* http://datatracker.ietf.org/doc/rfc5225/ RObust Header Compression Version 2 (ROHCv2): Profiles for RTP, UDP, IP, ESP and UDP-Lite
|
||||
*/
|
||||
|
||||
#ifndef PACKET_ROHC_H
|
||||
#define PACKET_ROHC_H
|
||||
|
||||
#define MAX_CID 15
|
||||
|
||||
/* ROHC Profiles */
|
||||
#define ROHC_PROFILE_UNCOMPRESSED 0
|
||||
#define ROHC_PROFILE_RTP 1
|
||||
#define ROHC_PROFILE_UDP 2
|
||||
#define ROHC_PROFILE_IP 4
|
||||
#define ROHC_PROFILE_UNKNOWN 0xFFFF
|
||||
|
||||
enum rohc_mode
|
||||
{
|
||||
MODE_NOT_SET = 0,
|
||||
UNIDIRECTIONAL = 1,
|
||||
OPTIMISTIC_BIDIRECTIONAL = 2,
|
||||
RELIABLE_BIDIRECTIONAL = 3
|
||||
};
|
||||
|
||||
enum rohc_d_mode
|
||||
{
|
||||
NO_CONTEXT = 1,
|
||||
STATIC_CONTEXT = 2,
|
||||
FULL_CONTEXT = 3
|
||||
};
|
||||
typedef struct rohc_info
|
||||
{
|
||||
gboolean rohc_compression;
|
||||
guint8 rohc_ip_version;
|
||||
gboolean cid_inclusion_info;
|
||||
gboolean large_cid_present;
|
||||
enum rohc_mode mode;
|
||||
gboolean rnd;
|
||||
gboolean udp_checksum_present;
|
||||
guint16 profile;
|
||||
proto_item *last_created_item;
|
||||
} rohc_info;
|
||||
|
||||
|
||||
typedef struct rohc_context
|
||||
{
|
||||
guint8 rohc_ip_version[MAX_CID+1];
|
||||
gboolean large_cid_present[MAX_CID+1];
|
||||
enum rohc_mode mode[MAX_CID+1];
|
||||
enum rohc_d_mode d_mode[MAX_CID+1];
|
||||
gboolean rnd[MAX_CID+1];
|
||||
gboolean udp_checkum_present[MAX_CID+1];
|
||||
guint16 profile[MAX_CID+1];
|
||||
gboolean rohc_context_init[MAX_CID+1];
|
||||
gint ir_frame_number[MAX_CID+1]; /* The frame number of the last IR packet seen */
|
||||
|
||||
} rohc_context;
|
||||
|
||||
#endif /* PACKET_ROHC_H */
|
||||
+94
-20
@@ -128,12 +128,6 @@ typedef struct {
|
||||
|
||||
opt_listener_t opt_listener;
|
||||
|
||||
static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
guint16 rnti, guint16 ueid, guint16 sysframeNumber,
|
||||
guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
|
||||
guint8 oob_event, guint8 oob_event_value,
|
||||
uint8_t *pdu_buffer, unsigned int pdu_buffer_size);
|
||||
|
||||
unsigned short checksum(unsigned short *ptr, int length) {
|
||||
int sum = 0;
|
||||
u_short answer = 0;
|
||||
@@ -152,7 +146,7 @@ unsigned short checksum(unsigned short *ptr, int length) {
|
||||
}
|
||||
|
||||
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
|
||||
static int MAC_LTE_PCAP_WritePDU(const uint8_t *PDU,
|
||||
static int PCAP_WritePDU(const uint8_t *PDU,
|
||||
unsigned int length) {
|
||||
pcaprec_hdr_t packet_header;
|
||||
// IPv4 header
|
||||
@@ -288,7 +282,7 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) {
|
||||
*/
|
||||
/* Add framing header to MAC PDU and send. */
|
||||
static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
guint16 rnti, guint16 ueid, guint16 sfnSf,
|
||||
guint16 rnti, guint16 ueid, guint16 frame, guint16 subframe,
|
||||
guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
|
||||
guint8 oob_event, guint8 oob_event_value,
|
||||
uint8_t *pdu_buffer, unsigned int pdu_buffer_size) {
|
||||
@@ -317,9 +311,9 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
tmp16 = htons(ueid);
|
||||
memcpy(frameBuffer+frameOffset, &tmp16, 2);
|
||||
frameOffset += 2;
|
||||
/* Subframe number */
|
||||
/* Subframe number */
|
||||
frameBuffer[frameOffset++] = MAC_LTE_FRAME_SUBFRAME_TAG;
|
||||
tmp16 = htons(sfnSf); // frame counter : this will give an expert info as wireshark expects SF and not F
|
||||
tmp16 = htons((frame<<4)+subframe); // frame counter : this will give an expert info as wireshark expects SF and not F
|
||||
memcpy(frameBuffer+frameOffset, &tmp16, 2);
|
||||
frameOffset += 2;
|
||||
frameBuffer[frameOffset++] = MAC_LTE_CRC_STATUS_TAG;
|
||||
@@ -400,7 +394,76 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0,
|
||||
(const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr));
|
||||
else
|
||||
bytesSent = MAC_LTE_PCAP_WritePDU(frameBuffer, frameOffset);
|
||||
bytesSent = PCAP_WritePDU(frameBuffer, frameOffset);
|
||||
|
||||
if (bytesSent != frameOffset) {
|
||||
LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n",
|
||||
frameOffset, bytesSent, errno);
|
||||
//exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void SendFrameNR(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
guint16 rnti, guint16 ueid, guint16 frame, guint16 subframe,
|
||||
guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
|
||||
guint8 oob_event, guint8 oob_event_value,
|
||||
uint8_t *pdu_buffer, unsigned int pdu_buffer_size) {
|
||||
unsigned char frameBuffer[9000];
|
||||
unsigned int frameOffset;
|
||||
ssize_t bytesSent;
|
||||
frameOffset = 0;
|
||||
uint16_t tmp16;
|
||||
memcpy(frameBuffer+frameOffset, MAC_NR_START_STRING,
|
||||
strlen(MAC_NR_START_STRING));
|
||||
frameOffset += strlen(MAC_NR_START_STRING);
|
||||
/******************************************************************************/
|
||||
/* Now write out fixed fields (the mandatory elements of struct mac_lte_info) */
|
||||
frameBuffer[frameOffset++] = radioType;
|
||||
frameBuffer[frameOffset++] = direction;
|
||||
frameBuffer[frameOffset++] = rntiType;
|
||||
/*************************************/
|
||||
/* Now optional fields */
|
||||
/* RNTI */
|
||||
frameBuffer[frameOffset++] = MAC_NR_RNTI_TAG;
|
||||
tmp16 = htons(rnti);
|
||||
memcpy(frameBuffer+frameOffset, &tmp16, 2);
|
||||
frameOffset += 2;
|
||||
/* UEId */
|
||||
frameBuffer[frameOffset++] = MAC_NR_UEID_TAG;
|
||||
tmp16 = htons(ueid);
|
||||
memcpy(frameBuffer+frameOffset, &tmp16, 2);
|
||||
frameOffset += 2;
|
||||
/* Subframe number */
|
||||
frameBuffer[frameOffset++] = MAC_NR_FRAME_SLOT_TAG;
|
||||
tmp16 = htons(frame); // frame counter : this will give an expert info as wireshark expects SF and not F
|
||||
memcpy(frameBuffer+frameOffset, &tmp16, 2);
|
||||
frameOffset += 2;
|
||||
tmp16 = htons(subframe); // frame counter : this will give an expert info as wireshark expects SF and not F
|
||||
memcpy(frameBuffer+frameOffset, &tmp16, 2);
|
||||
frameOffset += 2;
|
||||
if (direction == 0 ) { //ulink
|
||||
frameBuffer[frameOffset++] = MAC_NR_PHR_TYPE2_OTHERCELL_TAG;
|
||||
frameBuffer[frameOffset++] = 0;
|
||||
}
|
||||
|
||||
/***************************************/
|
||||
/* Now write the MAC PDU */
|
||||
frameBuffer[frameOffset++] = MAC_NR_PAYLOAD_TAG;
|
||||
|
||||
/* Append actual PDU */
|
||||
//memcpy(frameBuffer+frameOffset, g_PDUBuffer, g_PDUOffset);
|
||||
//frameOffset += g_PDUOffset;
|
||||
if (pdu_buffer != NULL) {
|
||||
memcpy(frameBuffer+frameOffset, (void *)pdu_buffer, pdu_buffer_size);
|
||||
frameOffset += pdu_buffer_size;
|
||||
}
|
||||
|
||||
if ( opt_type == OPT_WIRESHARK )
|
||||
/* Send out the data over the UDP socket */
|
||||
bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0,
|
||||
(const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr));
|
||||
else
|
||||
bytesSent = PCAP_WritePDU(frameBuffer, frameOffset);
|
||||
|
||||
if (bytesSent != frameOffset) {
|
||||
LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n",
|
||||
@@ -413,20 +476,23 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
extern RAN_CONTEXT_t RC;
|
||||
#include <openair1/PHY/phy_extern_ue.h>
|
||||
/* Remote serveraddress (where Wireshark is running) */
|
||||
void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
|
||||
int oob_event_value) {
|
||||
int radioType=FDD_RADIO;
|
||||
LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n",
|
||||
direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber);
|
||||
|
||||
if (RC.eNB && RC.eNB[0][0]!=NULL)
|
||||
radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
|
||||
else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL)
|
||||
radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
|
||||
else {
|
||||
LOG_E(OPT,"not a eNB neither a UE!!! \n");
|
||||
return;
|
||||
if (nr) {
|
||||
radioType=TDD_RADIO;
|
||||
} else {
|
||||
if (RC.eNB && RC.eNB[0][0]!=NULL)
|
||||
radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
|
||||
else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL)
|
||||
radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO;
|
||||
else {
|
||||
LOG_E(OPT,"not a 4G eNB neither a 4G UE!!! \n");
|
||||
}
|
||||
}
|
||||
|
||||
switch (opt_type) {
|
||||
@@ -448,9 +514,17 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p
|
||||
break;
|
||||
}
|
||||
|
||||
if (nr)
|
||||
SendFrameNR( radioType,
|
||||
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
|
||||
rntiType, rnti, ueid, sysFrameNumber, subFrameNumber,
|
||||
1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
|
||||
oob_event,oob_event_value,
|
||||
pdu_buffer, pdu_buffer_size);
|
||||
else
|
||||
SendFrame( radioType,
|
||||
(direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
|
||||
rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
|
||||
rntiType, rnti, ueid, sysFrameNumber, subFrameNumber,
|
||||
1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
|
||||
oob_event,oob_event_value,
|
||||
pdu_buffer, pdu_buffer_size);
|
||||
|
||||
@@ -0,0 +1,895 @@
|
||||
/* packet-mac-lte.h
|
||||
*
|
||||
* Martin Mathieson
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* Copyright (C) 2009 Martin Mathieson. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
this is wireshark, commit: commit eda834b6e29c36e05a63a6056afa98390ff79357
|
||||
Date: Wed Aug 22 14:36:20 2018 +0200
|
||||
modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_OPT_PACKET_MAC_LTE__H__
|
||||
#define __UTIL_OPT_PACKET_MAC_LTE__H__
|
||||
|
||||
/** data structure to hold time values with nanosecond resolution*/
|
||||
typedef struct {
|
||||
time_t secs;
|
||||
int nsecs;
|
||||
} nstime_t;
|
||||
|
||||
|
||||
/* radioType */
|
||||
#define FDD_RADIO 1
|
||||
#define TDD_RADIO 2
|
||||
|
||||
/* Direction */
|
||||
#define DIRECTION_UPLINK 0
|
||||
#define DIRECTION_DOWNLINK 1
|
||||
|
||||
/* rntiType */
|
||||
#define WS_NO_RNTI 0
|
||||
#define WS_P_RNTI 1
|
||||
#define WS_RA_RNTI 2
|
||||
#define WS_C_RNTI 3
|
||||
#define WS_SI_RNTI 4
|
||||
#define WS_SPS_RNTI 5
|
||||
#define WS_M_RNTI 6
|
||||
#define WS_SL_BCH_RNTI 7
|
||||
#define WS_SL_RNTI 8
|
||||
#define WS_SC_RNTI 9
|
||||
#define WS_G_RNTI 10
|
||||
|
||||
#define WS_CS_RNTI 5
|
||||
|
||||
typedef enum mac_lte_oob_event {
|
||||
ltemac_send_preamble,
|
||||
ltemac_send_sr,
|
||||
ltemac_sr_failure
|
||||
} mac_lte_oob_event;
|
||||
|
||||
typedef enum mac_lte_dl_retx {
|
||||
dl_retx_no,
|
||||
dl_retx_yes,
|
||||
dl_retx_unknown
|
||||
} mac_lte_dl_retx;
|
||||
|
||||
typedef enum mac_lte_crc_status {
|
||||
crc_fail = 0,
|
||||
crc_success = 1,
|
||||
crc_high_code_rate = 2,
|
||||
crc_pdsch_lost = 3,
|
||||
crc_duplicate_nonzero_rv = 4,
|
||||
crc_false_dci = 5
|
||||
} mac_lte_crc_status;
|
||||
|
||||
/* N.B. for SCellIndex-r13 extends to 31 */
|
||||
typedef enum mac_lte_carrier_id {
|
||||
carrier_id_primary,
|
||||
carrier_id_secondary_1,
|
||||
carrier_id_secondary_2,
|
||||
carrier_id_secondary_3,
|
||||
carrier_id_secondary_4,
|
||||
carrier_id_secondary_5,
|
||||
carrier_id_secondary_6,
|
||||
carrier_id_secondary_7
|
||||
} mac_lte_carrier_id;
|
||||
|
||||
typedef enum mac_lte_ce_mode {
|
||||
no_ce_mode = 0,
|
||||
ce_mode_a = 1,
|
||||
ce_mode_b = 2
|
||||
} mac_lte_ce_mode;
|
||||
|
||||
typedef enum mac_lte_nb_mode {
|
||||
no_nb_mode = 0,
|
||||
nb_mode = 1
|
||||
} mac_lte_nb_mode;
|
||||
|
||||
/* Context info attached to each LTE MAC frame */
|
||||
typedef struct mac_lte_info
|
||||
{
|
||||
/* Needed for decode */
|
||||
guint8 radioType;
|
||||
guint8 direction;
|
||||
guint8 rntiType;
|
||||
|
||||
/* Extra info to display */
|
||||
guint16 rnti;
|
||||
guint16 ueid;
|
||||
|
||||
/* Timing info */
|
||||
guint16 sysframeNumber;
|
||||
guint16 subframeNumber;
|
||||
gboolean sfnSfInfoPresent;
|
||||
|
||||
/* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */
|
||||
gboolean subframeNumberOfGrantPresent;
|
||||
guint16 subframeNumberOfGrant;
|
||||
|
||||
/* Flag set only if doing PHY-level data test - i.e. there may not be a
|
||||
well-formed MAC PDU so just show as raw data */
|
||||
gboolean isPredefinedData;
|
||||
|
||||
/* Length of DL PDU or UL grant size in bytes */
|
||||
guint16 length;
|
||||
|
||||
/* 0=newTx, 1=first-retx, etc */
|
||||
guint8 reTxCount;
|
||||
guint8 isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */
|
||||
|
||||
/* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set */
|
||||
gboolean isExtendedBSRSizes;
|
||||
|
||||
/* UL only. Indicates if the R10 simultaneousPUCCH-PUSCH parameter is set for PCell */
|
||||
gboolean isSimultPUCCHPUSCHPCell;
|
||||
|
||||
/* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set for PSCell */
|
||||
gboolean isSimultPUCCHPUSCHPSCell;
|
||||
|
||||
/* Status of CRC check. For UE it is DL only. For eNodeB it is UL
|
||||
only. For an analyzer, it is present for both DL and UL. */
|
||||
gboolean crcStatusValid;
|
||||
mac_lte_crc_status crcStatus;
|
||||
|
||||
/* Carrier ID */
|
||||
mac_lte_carrier_id carrierId;
|
||||
|
||||
/* DL only. Is this known to be a retransmission? */
|
||||
mac_lte_dl_retx dl_retx;
|
||||
|
||||
/* DL only. CE mode to be used for RAR decoding */
|
||||
mac_lte_ce_mode ceMode;
|
||||
|
||||
/* DL and UL. NB-IoT mode of the UE */
|
||||
mac_lte_nb_mode nbMode;
|
||||
|
||||
/* UL only, for now used for CE mode A RAR decoding */
|
||||
guint8 nUlRb;
|
||||
|
||||
/* More Physical layer info (see direction above for which side of union to use) */
|
||||
union {
|
||||
struct mac_lte_ul_phy_info
|
||||
{
|
||||
guint8 present; /* Remaining UL fields are present and should be displayed */
|
||||
guint8 modulation_type;
|
||||
guint8 tbs_index;
|
||||
guint8 resource_block_length;
|
||||
guint8 resource_block_start;
|
||||
guint8 harq_id;
|
||||
gboolean ndi;
|
||||
} ul_info;
|
||||
struct mac_lte_dl_phy_info
|
||||
{
|
||||
guint8 present; /* Remaining DL fields are present and should be displayed */
|
||||
guint8 dci_format;
|
||||
guint8 resource_allocation_type;
|
||||
guint8 aggregation_level;
|
||||
guint8 mcs_index;
|
||||
guint8 redundancy_version_index;
|
||||
guint8 resource_block_length;
|
||||
guint8 harq_id;
|
||||
gboolean ndi;
|
||||
guint8 transport_block; /* 0..1 */
|
||||
} dl_info;
|
||||
} detailed_phy_info;
|
||||
|
||||
/* Relating to out-of-band events */
|
||||
/* N.B. dissector will only look to these fields if length is 0... */
|
||||
mac_lte_oob_event oob_event;
|
||||
guint8 rapid;
|
||||
guint8 rach_attempt_number;
|
||||
#define MAX_SRs 20
|
||||
guint16 number_of_srs;
|
||||
guint16 oob_ueid[MAX_SRs];
|
||||
guint16 oob_rnti[MAX_SRs];
|
||||
} mac_lte_info;
|
||||
|
||||
/* 0 to 10 and 32 to 38 */
|
||||
#define MAC_LTE_DATA_LCID_COUNT_MAX 18
|
||||
#define MAC_LTE_START_STRING "mac-lte"
|
||||
|
||||
/* Fixed fields. This is followed by the following 3 mandatory fields:
|
||||
- radioType (1 byte)
|
||||
- direction (1 byte)
|
||||
- rntiType (1 byte)
|
||||
(where the allowed values are defined above */
|
||||
|
||||
/* Optional fields. Attaching this info to frames will allow you
|
||||
to show you display/filter/plot/add-custom-columns on these fields, so should
|
||||
be added if available.
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag) */
|
||||
|
||||
#define MAC_LTE_RNTI_TAG 0x02
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define MAC_LTE_UEID_TAG 0x03
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define MAC_LTE_FRAME_SUBFRAME_TAG 0x04
|
||||
/* 2 bytes, network order, SFN is stored in 12 MSB and SF in 4 LSB */
|
||||
|
||||
#define MAC_LTE_PREDEFINED_DATA_TAG 0x05
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_RETX_TAG 0x06
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_CRC_STATUS_TAG 0x07
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_EXT_BSR_SIZES_TAG 0x08
|
||||
/* 0 byte */
|
||||
|
||||
#define MAC_LTE_SEND_PREAMBLE_TAG 0x09
|
||||
/* 2 bytes, RAPID value (1 byte) followed by RACH attempt number (1 byte) */
|
||||
|
||||
#define MAC_LTE_CARRIER_ID_TAG 0x0A
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_PHY_TAG 0x0B
|
||||
/* variable length, length (1 byte) then depending on direction
|
||||
in UL: modulation type (1 byte), TBS index (1 byte), RB length (1 byte),
|
||||
RB start (1 byte), HARQ id (1 byte), NDI (1 byte)
|
||||
in DL: DCI format (1 byte), resource allocation type (1 byte), aggregation level (1 byte),
|
||||
MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte),
|
||||
HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */
|
||||
|
||||
#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG 0x0C
|
||||
/* 0 byte */
|
||||
|
||||
#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D
|
||||
/* 0 byte */
|
||||
|
||||
#define MAC_LTE_CE_MODE_TAG 0x0E
|
||||
/* 1 byte containing mac_lte_ce_mode enum value */
|
||||
|
||||
#define MAC_LTE_NB_MODE_TAG 0x0F
|
||||
/* 1 byte containing mac_lte_nb_mode enum value */
|
||||
|
||||
#define MAC_LTE_N_UL_RB_TAG 0x10
|
||||
/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */
|
||||
|
||||
#define MAC_LTE_SR_TAG 0x11
|
||||
/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */
|
||||
|
||||
|
||||
/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
|
||||
continues until the end of the frame) */
|
||||
#define MAC_LTE_PAYLOAD_TAG 0x01
|
||||
|
||||
/* rlcMode */
|
||||
#define RLC_TM_MODE 1
|
||||
#define RLC_UM_MODE 2
|
||||
#define RLC_AM_MODE 4
|
||||
#define RLC_PREDEF 8
|
||||
|
||||
/* priority ? */
|
||||
|
||||
/* channelType */
|
||||
#define CHANNEL_TYPE_CCCH 1
|
||||
#define CHANNEL_TYPE_BCCH_BCH 2
|
||||
#define CHANNEL_TYPE_PCCH 3
|
||||
#define CHANNEL_TYPE_SRB 4
|
||||
#define CHANNEL_TYPE_DRB 5
|
||||
#define CHANNEL_TYPE_BCCH_DL_SCH 6
|
||||
#define CHANNEL_TYPE_MCCH 7
|
||||
#define CHANNEL_TYPE_MTCH 8
|
||||
|
||||
/* sequenceNumberLength */
|
||||
#define UM_SN_LENGTH_5_BITS 5
|
||||
#define UM_SN_LENGTH_10_BITS 10
|
||||
#define AM_SN_LENGTH_10_BITS 10
|
||||
#define AM_SN_LENGTH_16_BITS 16
|
||||
|
||||
|
||||
typedef enum rlc_lte_nb_mode {
|
||||
rlc_no_nb_mode = 0,
|
||||
rlc_nb_mode = 1
|
||||
} rlc_lte_nb_mode;
|
||||
|
||||
|
||||
/* Info attached to each LTE RLC frame */
|
||||
typedef struct rlc_lte_info
|
||||
{
|
||||
guint8 rlcMode;
|
||||
guint8 direction;
|
||||
guint8 priority;
|
||||
guint8 sequenceNumberLength;
|
||||
guint16 ueid;
|
||||
guint16 channelType;
|
||||
guint16 channelId; /* for SRB: 1=SRB1, 2=SRB2, 3=SRB1bis; for DRB: DRB ID */
|
||||
guint16 pduLength;
|
||||
gboolean extendedLiField;
|
||||
rlc_lte_nb_mode nbMode;
|
||||
} rlc_lte_info;
|
||||
|
||||
|
||||
typedef struct rlc_lte_tap_info {
|
||||
/* Info from context */
|
||||
guint8 rlcMode;
|
||||
guint8 direction;
|
||||
guint8 priority;
|
||||
guint16 ueid;
|
||||
guint16 channelType;
|
||||
guint16 channelId;
|
||||
guint16 pduLength;
|
||||
guint8 sequenceNumberLength;
|
||||
|
||||
nstime_t rlc_lte_time;
|
||||
guint8 loggedInMACFrame;
|
||||
guint16 sequenceNumber;
|
||||
guint8 isResegmented;
|
||||
guint8 isControlPDU;
|
||||
guint16 ACKNo;
|
||||
#define MAX_NACKs 128
|
||||
guint16 noOfNACKs;
|
||||
guint16 NACKs[MAX_NACKs];
|
||||
|
||||
guint16 missingSNs;
|
||||
} rlc_lte_tap_info;
|
||||
|
||||
|
||||
/* Signature. Rather than try to define a port for this, or make the
|
||||
port number a preference, frames will start with this string (with no
|
||||
terminating NULL */
|
||||
#define RLC_LTE_START_STRING "rlc-lte"
|
||||
|
||||
/* Fixed field. This is followed by the following 1 mandatory field:
|
||||
- rlcMode (1 byte)
|
||||
(where the allowed values are defined above */
|
||||
|
||||
/* Conditional field. This field is mandatory in case of RLC Unacknowledged mode.
|
||||
In case of RLC Acknowledged mode, the field is optional (assume 10 bits by default).
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag). The allowed values are defined above. */
|
||||
|
||||
#define RLC_LTE_SN_LENGTH_TAG 0x02
|
||||
/* 1 byte */
|
||||
|
||||
/* Optional fields. Attaching this info to frames will allow you
|
||||
to show you display/filter/plot/add-custom-columns on these fields, so should
|
||||
be added if available.
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag) */
|
||||
|
||||
#define RLC_LTE_DIRECTION_TAG 0x03
|
||||
/* 1 byte */
|
||||
|
||||
#define RLC_LTE_PRIORITY_TAG 0x04
|
||||
/* 1 byte */
|
||||
|
||||
#define RLC_LTE_UEID_TAG 0x05
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define RLC_LTE_CHANNEL_TYPE_TAG 0x06
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define RLC_LTE_CHANNEL_ID_TAG 0x07
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define RLC_LTE_EXT_LI_FIELD_TAG 0x08
|
||||
/* 0 byte, tag presence indicates that AM DRB PDU is using an extended LI field of 15 bits */
|
||||
|
||||
#define RLC_LTE_NB_MODE_TAG 0x09
|
||||
/* 1 byte containing rlc_lte_nb_mode enum value */
|
||||
|
||||
/* RLC PDU. Following this tag comes the actual RLC PDU (there is no length, the PDU
|
||||
continues until the end of the frame) */
|
||||
#define RLC_LTE_PAYLOAD_TAG 0x01
|
||||
|
||||
enum pdcp_plane
|
||||
{
|
||||
SIGNALING_PLANE = 1,
|
||||
USER_PLANE = 2
|
||||
};
|
||||
|
||||
typedef enum LogicalChannelType
|
||||
{
|
||||
Channel_DCCH=1,
|
||||
Channel_BCCH=2,
|
||||
Channel_CCCH=3,
|
||||
Channel_PCCH=4,
|
||||
Channel_DCCH_NB=5,
|
||||
Channel_BCCH_NB=6,
|
||||
Channel_CCCH_NB=7,
|
||||
Channel_PCCH_NB=8
|
||||
} LogicalChannelType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BCH_TRANSPORT=1,
|
||||
DLSCH_TRANSPORT=2
|
||||
} BCCHTransportType;
|
||||
|
||||
#define PDCP_SN_LENGTH_5_BITS 5
|
||||
#define PDCP_SN_LENGTH_7_BITS 7
|
||||
#define PDCP_SN_LENGTH_12_BITS 12
|
||||
#define PDCP_SN_LENGTH_15_BITS 15
|
||||
#define PDCP_SN_LENGTH_18_BITS 18
|
||||
|
||||
enum lte_security_integrity_algorithm_e { eia0, eia1, eia2, eia3 };
|
||||
enum lte_security_ciphering_algorithm_e { eea0, eea1, eea2, eea3 };
|
||||
|
||||
typedef struct pdcp_lte_security_info_t
|
||||
{
|
||||
guint32 configuration_frame;
|
||||
gboolean seen_next_ul_pdu; /* i.e. have we seen SecurityModeResponse */
|
||||
enum lte_security_integrity_algorithm_e integrity;
|
||||
enum lte_security_ciphering_algorithm_e ciphering;
|
||||
|
||||
/* Store previous settings so can revert if get SecurityModeFailure */
|
||||
guint32 previous_configuration_frame;
|
||||
enum lte_security_integrity_algorithm_e previous_integrity;
|
||||
enum lte_security_ciphering_algorithm_e previous_ciphering;
|
||||
} pdcp_lte_security_info_t;
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/* UDP framing format */
|
||||
/* ----------------------- */
|
||||
/* Several people have asked about dissecting PDCP by framing */
|
||||
/* PDUs over IP. A suggested format over UDP has been defined */
|
||||
/* and implemented by this dissector, using the definitions */
|
||||
/* below. A link to an example program showing you how to encode */
|
||||
/* these headers and send LTE PDCP PDUs on a UDP socket is */
|
||||
/* provided at https://gitlab.com/wireshark/wireshark/-/wikis/PDCP-LTE */
|
||||
/* */
|
||||
/* A heuristic dissecter (enabled by a preference) will */
|
||||
/* recognise a signature at the beginning of these frames. */
|
||||
/* Until someone is using this format, suggestions for changes */
|
||||
/* are welcome. */
|
||||
/***********************************************************************/
|
||||
|
||||
|
||||
/* Signature. Rather than try to define a port for this, or make the
|
||||
port number a preference, frames will start with this string (with no
|
||||
terminating NULL */
|
||||
#define PDCP_LTE_START_STRING "pdcp-lte"
|
||||
|
||||
/* Fixed fields. This is followed by the following 3 mandatory fields:
|
||||
- no_header_pdu (1 byte)
|
||||
- plane (1 byte)
|
||||
- rohc_compression ( byte)
|
||||
(where the allowed values are defined above) */
|
||||
|
||||
/* Conditional field. This field is mandatory in case of User Plane PDCP PDU.
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag). The allowed values are defined above. */
|
||||
|
||||
#define PDCP_LTE_SEQNUM_LENGTH_TAG 0x02
|
||||
/* 1 byte */
|
||||
|
||||
/* Optional fields. Attaching this info to frames will allow you
|
||||
to show you display/filter/plot/add-custom-columns on these fields, so should
|
||||
be added if available.
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag) */
|
||||
|
||||
#define PDCP_LTE_DIRECTION_TAG 0x03
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_LTE_LOG_CHAN_TYPE_TAG 0x04
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_LTE_BCCH_TRANSPORT_TYPE_TAG 0x05
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_LTE_ROHC_IP_VERSION_TAG 0x06
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define PDCP_LTE_ROHC_CID_INC_INFO_TAG 0x07
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_LTE_ROHC_LARGE_CID_PRES_TAG 0x08
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_LTE_ROHC_MODE_TAG 0x09
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_LTE_ROHC_RND_TAG 0x0A
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_LTE_ROHC_UDP_CHECKSUM_PRES_TAG 0x0B
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_LTE_ROHC_PROFILE_TAG 0x0C
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define PDCP_LTE_CHANNEL_ID_TAG 0x0D
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define PDCP_LTE_UEID_TAG 0x0E
|
||||
/* 2 bytes, network order */
|
||||
|
||||
/* PDCP PDU. Following this tag comes the actual PDCP PDU (there is no length, the PDU
|
||||
continues until the end of the frame) */
|
||||
#define PDCP_LTE_PAYLOAD_TAG 0x01
|
||||
|
||||
|
||||
|
||||
/* Called by RRC, or other configuration protocols */
|
||||
|
||||
/* Function to configure ciphering & integrity algorithms */
|
||||
void set_pdcp_lte_security_algorithms(guint16 ueid, pdcp_lte_security_info_t *security_info);
|
||||
|
||||
/* Function to indicate securityModeCommand did not complete */
|
||||
void set_pdcp_lte_security_algorithms_failed(guint16 ueid);
|
||||
|
||||
|
||||
/* Called by external dissectors */
|
||||
void set_pdcp_lte_rrc_ciphering_key(guint16 ueid, const char *key);
|
||||
void set_pdcp_lte_rrc_integrity_key(guint16 ueid, const char *key);
|
||||
void set_pdcp_lte_up_ciphering_key(guint16 ueid, const char *key);
|
||||
|
||||
|
||||
|
||||
/* Context info attached to each NR MAC frame */
|
||||
typedef struct mac_nr_info
|
||||
{
|
||||
/* Needed for decode */
|
||||
guint8 radioType;
|
||||
guint8 direction;
|
||||
guint8 rntiType;
|
||||
|
||||
/* Extra info to display */
|
||||
guint16 rnti;
|
||||
guint16 ueid;
|
||||
guint8 harqid;
|
||||
|
||||
/* Will these be included in the ME PHR report? */
|
||||
guint8 phr_type2_othercell;
|
||||
|
||||
/* Timing info */
|
||||
gboolean sfnSlotInfoPresent;
|
||||
guint16 sysframeNumber;
|
||||
guint16 slotNumber;
|
||||
|
||||
/* Length of DL PDU or UL grant size in bytes */
|
||||
guint16 length;
|
||||
|
||||
} mac_nr_info;
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
/* UDP framing format */
|
||||
/* ----------------------- */
|
||||
/* Several people have asked about dissecting MAC by framing */
|
||||
/* PDUs over IP. A suggested format over UDP has been created */
|
||||
/* and implemented by this dissector, using the definitions */
|
||||
/* below. */
|
||||
/* */
|
||||
/* A heuristic dissector (enabled by a preference) will */
|
||||
/* recognise a signature at the beginning of these frames. */
|
||||
/*****************************************************************/
|
||||
|
||||
|
||||
/* Signature. Rather than try to define a port for this, or make the
|
||||
port number a preference, frames will start with this string (with no
|
||||
terminating NULL */
|
||||
#define MAC_NR_START_STRING "mac-nr"
|
||||
|
||||
/* Fixed fields. This is followed by the following 3 mandatory fields:
|
||||
- radioType (1 byte)
|
||||
- direction (1 byte)
|
||||
- rntiType (1 byte)
|
||||
(where the allowed values are defined above */
|
||||
|
||||
/* Optional fields. Attaching this info to frames will allow you
|
||||
to show you display/filter/plot/add-custom-columns on these fields, so should
|
||||
be added if available.
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag) */
|
||||
|
||||
#define MAC_NR_RNTI_TAG 0x02
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define MAC_NR_UEID_TAG 0x03
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define MAC_NR_FRAME_SUBFRAME_TAG 0x04
|
||||
/* 2 bytes, deprecated, do not use it */
|
||||
|
||||
#define MAC_NR_PHR_TYPE2_OTHERCELL_TAG 0x05
|
||||
/* 1 byte, TRUE/FALSE */
|
||||
|
||||
#define MAC_NR_HARQID 0x06
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_NR_FRAME_SLOT_TAG 0x07
|
||||
/* 4 bytes, network order, SFN is stored in the 2 first bytes and slot number in the 2 last bytes */
|
||||
|
||||
/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
|
||||
continues until the end of the frame) */
|
||||
#define MAC_NR_PAYLOAD_TAG 0x01
|
||||
|
||||
|
||||
/* Type to store parameters for configuring LCID->RLC channel settings for DRB */
|
||||
/* Some are optional, and may not be seen (e.g. on reestablishment) */
|
||||
typedef struct nr_drb_mac_rlc_mapping_t
|
||||
{
|
||||
gboolean active;
|
||||
guint16 ueid; /* Mandatory */
|
||||
guint8 drbid; /* Mandatory */
|
||||
|
||||
gboolean lcid_present;
|
||||
guint8 lcid; /* Part of LogicalChannelConfig - optional */
|
||||
gboolean rlcMode_present;
|
||||
guint8 rlcMode; /* Part of RLC config - optional */
|
||||
|
||||
guint8 tempDirection; /* So know direction of next SN length... */
|
||||
|
||||
gboolean rlcUlSnLength_present;
|
||||
guint8 rlcUlSnLength; /* Part of RLC config - optional */
|
||||
gboolean rlcDlSnLength_present;
|
||||
guint8 rlcDlSnLength; /* Part of RLC config - optional */
|
||||
} nr_drb_mac_rlc_mapping_t;
|
||||
|
||||
/* rlcMode */
|
||||
#define RLC_TM_MODE 1
|
||||
#define RLC_UM_MODE 2
|
||||
#define RLC_AM_MODE 4
|
||||
|
||||
/* bearerType */
|
||||
#define BEARER_TYPE_CCCH 1
|
||||
#define BEARER_TYPE_BCCH_BCH 2
|
||||
#define BEARER_TYPE_PCCH 3
|
||||
#define BEARER_TYPE_SRB 4
|
||||
#define BEARER_TYPE_DRB 5
|
||||
#define BEARER_TYPE_BCCH_DL_SCH 6
|
||||
|
||||
/* sequenceNumberLength */
|
||||
#define TM_SN_LENGTH_0_BITS 0
|
||||
#define UM_SN_LENGTH_6_BITS 6
|
||||
#define UM_SN_LENGTH_12_BITS 12
|
||||
#define AM_SN_LENGTH_12_BITS 12
|
||||
#define AM_SN_LENGTH_18_BITS 18
|
||||
|
||||
/* Info attached to each NR RLC frame */
|
||||
typedef struct rlc_nr_info
|
||||
{
|
||||
guint8 rlcMode;
|
||||
guint8 direction;
|
||||
guint8 sequenceNumberLength;
|
||||
guint8 bearerType;
|
||||
guint8 bearerId;
|
||||
guint16 ueid;
|
||||
guint16 pduLength;
|
||||
} rlc_nr_info;
|
||||
|
||||
typedef struct nr_drb_rlc_pdcp_mapping_t
|
||||
{
|
||||
gboolean active;
|
||||
guint16 ueid; /* Mandatory */
|
||||
guint8 drbid; /* Mandatory */
|
||||
|
||||
gboolean pdcpUlSnLength_present;
|
||||
guint8 pdcpUlSnLength; /* Part of PDCP config - optional */
|
||||
gboolean pdcpDlSnLength_present;
|
||||
guint8 pdcpDlSnLength; /* Part of PDCP config - optional */
|
||||
gboolean pdcpUlSdap;
|
||||
gboolean pdcpDlSdap;
|
||||
gboolean pdcpIntegrityProtection;
|
||||
gboolean pdcpCipheringDisabled;
|
||||
|
||||
} nr_drb_rlc_pdcp_mapping_t;
|
||||
|
||||
/* TODO: could probably merge this struct with above */
|
||||
typedef struct pdcp_ue_parameters {
|
||||
guint32 id;
|
||||
guint8 pdcp_sn_bits_ul;
|
||||
guint8 pdcp_sn_bits_dl;
|
||||
gboolean pdcp_sdap_ul;
|
||||
gboolean pdcp_sdap_dl;
|
||||
gboolean pdcp_integrity;
|
||||
gboolean pdcp_ciphering_disabled;
|
||||
} pdcp_bearer_parameters;
|
||||
|
||||
/*****************************************************************/
|
||||
/* UDP framing format */
|
||||
/* ----------------------- */
|
||||
/* Several people have asked about dissecting RLC by framing */
|
||||
/* PDUs over IP. A suggested format over UDP has been defined */
|
||||
/* and implemented by this dissector, using the definitions */
|
||||
/* below. */
|
||||
/* */
|
||||
/* A heuristic dissector (enabled by a preference) will */
|
||||
/* recognise a signature at the beginning of these frames. */
|
||||
/*****************************************************************/
|
||||
|
||||
|
||||
/* Signature. Rather than try to define a port for this, or make the
|
||||
port number a preference, frames will start with this string (with no
|
||||
terminating NULL */
|
||||
#define RLC_NR_START_STRING "rlc-nr"
|
||||
|
||||
/* Fixed field. This is followed by the following 2 mandatory field:
|
||||
- rlcMode (1 byte)
|
||||
- sequenceNumberLength (1 byte)
|
||||
(where the allowed values are defined above) */
|
||||
|
||||
/* Optional fields. Attaching this info to frames will allow you
|
||||
to show you display/filter/plot/add-custom-columns on these fields, so should
|
||||
be added if available.
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag) */
|
||||
|
||||
#define RLC_NR_DIRECTION_TAG 0x02
|
||||
/* 1 byte */
|
||||
|
||||
#define RLC_NR_UEID_TAG 0x03
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define RLC_NR_BEARER_TYPE_TAG 0x04
|
||||
/* 1 byte */
|
||||
|
||||
#define RLC_NR_BEARER_ID_TAG 0x05
|
||||
/* 1 byte */
|
||||
|
||||
/* RLC PDU. Following this tag comes the actual RLC PDU (there is no length, the PDU
|
||||
continues until the end of the frame) */
|
||||
#define RLC_NR_PAYLOAD_TAG 0x01
|
||||
|
||||
enum pdcp_nr_plane
|
||||
{
|
||||
NR_SIGNALING_PLANE = 1,
|
||||
NR_USER_PLANE = 2
|
||||
};
|
||||
|
||||
typedef enum NRBearerType
|
||||
{
|
||||
Bearer_DCCH=1,
|
||||
Bearer_BCCH_BCH=2,
|
||||
Bearer_BCCH_DL_SCH=3,
|
||||
Bearer_CCCH=4,
|
||||
Bearer_PCCH=5,
|
||||
} NRBearerType;
|
||||
|
||||
|
||||
#define PDCP_NR_SN_LENGTH_12_BITS 12
|
||||
#define PDCP_NR_SN_LENGTH_18_BITS 18
|
||||
|
||||
#define PDCP_NR_UL_SDAP_HEADER_PRESENT 0x01
|
||||
#define PDCP_NR_DL_SDAP_HEADER_PRESENT 0x02
|
||||
|
||||
enum nr_security_integrity_algorithm_e { nia0, nia1, nia2, nia3 };
|
||||
enum nr_security_ciphering_algorithm_e { nea0, nea1, nea2, nea3, nea_disabled=999};
|
||||
|
||||
typedef struct pdcp_nr_security_info_t
|
||||
{
|
||||
guint32 configuration_frame;
|
||||
gboolean seen_next_ul_pdu; /* i.e. have we seen SecurityModeResponse */
|
||||
enum nr_security_integrity_algorithm_e integrity;
|
||||
enum nr_security_ciphering_algorithm_e ciphering;
|
||||
|
||||
/* Store previous settings so can revert if get SecurityModeFailure */
|
||||
guint32 previous_configuration_frame;
|
||||
enum nr_security_integrity_algorithm_e previous_integrity;
|
||||
enum nr_security_ciphering_algorithm_e previous_ciphering;
|
||||
} pdcp_nr_security_info_t;
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
/* UDP framing format */
|
||||
/* ----------------------- */
|
||||
/* Several people have asked about dissecting PDCP by framing */
|
||||
/* PDUs over IP. A suggested format over UDP has been defined */
|
||||
/* and implemented by this dissector, using the definitions */
|
||||
/* below. */
|
||||
/* */
|
||||
/* A heuristic dissector (enabled by a preference) will */
|
||||
/* recognise a signature at the beginning of these frames. */
|
||||
/* Until someone is using this format, suggestions for changes */
|
||||
/* are welcome. */
|
||||
/*****************************************************************/
|
||||
|
||||
|
||||
/* Signature. Rather than try to define a port for this, or make the
|
||||
port number a preference, frames will start with this string (with no
|
||||
terminating NULL */
|
||||
#define PDCP_NR_START_STRING "pdcp-nr"
|
||||
|
||||
/* Fixed fields:
|
||||
- plane (1 byte) */
|
||||
|
||||
/* Conditional field. This field is mandatory in case of User Plane PDCP PDU.
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag). The allowed values are defined above. */
|
||||
|
||||
#define PDCP_NR_SEQNUM_LENGTH_TAG 0x02
|
||||
/* 1 byte */
|
||||
|
||||
/* Optional fields. Attaching this info should be added if available.
|
||||
The format is to have the tag, followed by the value (there is no length field,
|
||||
it's implicit from the tag) */
|
||||
|
||||
#define PDCP_NR_DIRECTION_TAG 0x03
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_NR_BEARER_TYPE_TAG 0x04
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_NR_BEARER_ID_TAG 0x05
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_NR_UEID_TAG 0x06
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define PDCP_NR_ROHC_COMPRESSION_TAG 0x07
|
||||
/* 0 byte */
|
||||
|
||||
/* N.B. The following ROHC values only have significance if rohc_compression
|
||||
is in use for the current channel */
|
||||
|
||||
#define PDCP_NR_ROHC_IP_VERSION_TAG 0x08
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_NR_ROHC_CID_INC_INFO_TAG 0x09
|
||||
/* 0 byte */
|
||||
|
||||
#define PDCP_NR_ROHC_LARGE_CID_PRES_TAG 0x0A
|
||||
/* 0 byte */
|
||||
|
||||
#define PDCP_NR_ROHC_MODE_TAG 0x0B
|
||||
/* 1 byte */
|
||||
|
||||
#define PDCP_NR_ROHC_RND_TAG 0x0C
|
||||
/* 0 byte */
|
||||
|
||||
#define PDCP_NR_ROHC_UDP_CHECKSUM_PRES_TAG 0x0D
|
||||
/* 0 byte */
|
||||
|
||||
#define PDCP_NR_ROHC_PROFILE_TAG 0x0E
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define PDCP_NR_MACI_PRES_TAG 0x0F
|
||||
/* 0 byte */
|
||||
|
||||
#define PDCP_NR_SDAP_HEADER_TAG 0x10
|
||||
/* 1 byte, bitmask with PDCP_NR_UL_SDAP_HEADER_PRESENT and/or PDCP_NR_DL_SDAP_HEADER_PRESENT */
|
||||
|
||||
#define PDCP_NR_CIPHER_DISABLED_TAG 0x11
|
||||
/* 0 byte */
|
||||
|
||||
/* PDCP PDU. Following this tag comes the actual PDCP PDU (there is no length, the PDU
|
||||
continues until the end of the frame) */
|
||||
#define PDCP_NR_PAYLOAD_TAG 0x01
|
||||
|
||||
|
||||
/* Called by RRC, or other configuration protocols */
|
||||
|
||||
/* Function to configure ciphering & integrity algorithms */
|
||||
void set_pdcp_nr_security_algorithms(guint16 ueid, pdcp_nr_security_info_t *security_info);
|
||||
|
||||
/* Function to indicate securityModeCommand did not complete */
|
||||
void set_pdcp_nr_security_algorithms_failed(guint16 ueid);
|
||||
|
||||
|
||||
/* Called by external dissectors */
|
||||
void set_pdcp_nr_rrc_ciphering_key(guint16 ueid, const char *key);
|
||||
void set_pdcp_nr_rrc_integrity_key(guint16 ueid, const char *key);
|
||||
void set_pdcp_nr_up_ciphering_key(guint16 ueid, const char *key);
|
||||
void set_pdcp_nr_up_integrity_key(guint16 ueid, const char *key);
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
||||
#endif
|
||||
Reference in New Issue
Block a user