Merge remote-tracking branch 'origin/develop' into bler_txoptim
# Conflicts: # openair1/PHY/NR_TRANSPORT/pucch_rx.c # openair2/GNB_APP/gnb_config.c
This commit is contained in:
@@ -55,7 +55,7 @@
|
||||
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc"
|
||||
#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd"
|
||||
#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd"
|
||||
#define CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY "ulsch_max_slots_inactivity"
|
||||
#define CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY "ulsch_max_frame_inactivity"
|
||||
#define CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10 "pusch_TargetSNRx10"
|
||||
#define CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10 "pucch_TargetSNRx10"
|
||||
#define CONFIG_STRING_MACRLC_PUCCHFAILURETHRES "pucch_FailureThres"
|
||||
@@ -88,7 +88,7 @@
|
||||
{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY, "Maximum number of slots before a UE is scheduled ULSCH due to inactivity", 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY, NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
|
||||
@@ -115,7 +115,7 @@
|
||||
#define MACRLC_REMOTE_S_PORTC_IDX 14
|
||||
#define MACRLC_LOCAL_S_PORTD_IDX 15
|
||||
#define MACRLC_REMOTE_S_PORTD_IDX 16
|
||||
#define MACRLC_ULSCH_MAX_SLOTS_INACTIVITY 17
|
||||
#define MACRLC_ULSCH_MAX_FRAME_INACTIVITY 17
|
||||
#define MACRLC_PUSCHTARGETSNRX10_IDX 18
|
||||
#define MACRLC_PUCCHTARGETSNRX10_IDX 19
|
||||
#define MACRLC_PUCCHFAILURETHRES_IDX 20
|
||||
|
||||
@@ -754,7 +754,7 @@ void RCconfig_nr_macrlc() {
|
||||
}else { // other midhaul
|
||||
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
|
||||
}
|
||||
RC.nrmac[j]->ulsch_max_slots_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_SLOTS_INACTIVITY].uptr);
|
||||
RC.nrmac[j]->ulsch_max_frame_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_FRAME_INACTIVITY].uptr);
|
||||
RC.nrmac[j]->dl_bler_target_upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr);
|
||||
RC.nrmac[j]->dl_bler_target_lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr);
|
||||
RC.nrmac[j]->dl_rd2_bler_threshold = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_RD2_BLER_THRESHOLD_IDX].dblptr);
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
|
||||
#include "NR_SubcarrierSpacing.h"
|
||||
|
||||
#define NR_SHORT_BSR_TABLE_SIZE 32
|
||||
#define NR_LONG_BSR_TABLE_SIZE 256
|
||||
|
||||
#define TABLE_38213_13_1_NUM_INDEXES 15
|
||||
#define TABLE_38213_13_2_NUM_INDEXES 14
|
||||
#define TABLE_38213_13_3_NUM_INDEXES 9
|
||||
@@ -65,6 +68,11 @@ typedef enum frequency_range_e {
|
||||
FR2
|
||||
} frequency_range_t;
|
||||
|
||||
#define NR_BSR_TRIGGER_NONE (0) /* No BSR Trigger */
|
||||
#define NR_BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */
|
||||
#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */
|
||||
#define NR_BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */
|
||||
|
||||
// For both DL/UL-SCH
|
||||
// Except:
|
||||
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
|
||||
|
||||
@@ -48,6 +48,33 @@ void reverse_n_bits(uint8_t *value, uint16_t bitlen) {
|
||||
}
|
||||
}
|
||||
|
||||
//38.321 Table 6.1.3.1-1
|
||||
const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE] = {
|
||||
0, 10, 14, 20, 28, 38, 53, 74,
|
||||
102, 142, 198, 276, 384, 535, 745, 1038,
|
||||
1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726,
|
||||
20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000
|
||||
};
|
||||
|
||||
//38.321 Table 6.1.3.1-2
|
||||
const uint32_t NR_LONG_BSR_TABLE[NR_LONG_BSR_TABLE_SIZE] ={
|
||||
0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
|
||||
28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71,
|
||||
75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193,
|
||||
205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526,
|
||||
560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439,
|
||||
1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934,
|
||||
4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760,
|
||||
11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431,
|
||||
31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505,
|
||||
85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209,
|
||||
234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350,
|
||||
641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644,
|
||||
1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902,
|
||||
4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006,
|
||||
13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553,
|
||||
35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295
|
||||
};
|
||||
|
||||
// start symbols for SSB types A,B,C,D,E
|
||||
uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50};
|
||||
|
||||
@@ -76,6 +76,9 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
|
||||
extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||
#endif*/
|
||||
|
||||
extern const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE];
|
||||
extern const uint32_t NR_LONG_BSR_TABLE[NR_LONG_BSR_TABLE_SIZE];
|
||||
|
||||
// Type0-PDCCH search space
|
||||
extern const int32_t table_38213_13_1_c1[16];
|
||||
extern const int32_t table_38213_13_1_c2[16];
|
||||
|
||||
Executable → Regular
+23
@@ -615,6 +615,18 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){
|
||||
}
|
||||
}
|
||||
|
||||
// todo handle mac_LogicalChannelConfig
|
||||
int nr_rrc_mac_config_req_ue_logicalChannelBearer(
|
||||
module_id_t module_id,
|
||||
int cc_idP,
|
||||
uint8_t gNB_index,
|
||||
long logicalChannelIdentity,
|
||||
boolean_t status){
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
mac->logicalChannelBearer_exist[logicalChannelIdentity] = status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_rrc_mac_config_req_ue(
|
||||
module_id_t module_id,
|
||||
int cc_idP,
|
||||
@@ -678,6 +690,17 @@ int nr_rrc_mac_config_req_ue(
|
||||
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
|
||||
mac->cg = cell_group_config;
|
||||
mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
|
||||
|
||||
mac->scheduling_info.periodicBSR_SF =
|
||||
MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->scheduling_info.retxBSR_SF =
|
||||
MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE;
|
||||
LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
|
||||
module_id,
|
||||
mac->scheduling_info.periodicBSR_SF,
|
||||
mac->scheduling_info.retxBSR_SF);
|
||||
|
||||
config_control_ue(mac);
|
||||
//config_common_ue(mac,module_id,cc_idP);
|
||||
/*
|
||||
|
||||
Executable → Regular
+11
-12
@@ -182,9 +182,9 @@ typedef struct {
|
||||
uint16_t All_lcid_buffer_size_lastTTI;
|
||||
/// buffer status for each lcid
|
||||
uint8_t LCID_status[NR_MAX_NUM_LCID];
|
||||
/// SR pending as defined in 36.321
|
||||
/// SR pending as defined in 38.321
|
||||
uint8_t SR_pending;
|
||||
/// SR_COUNTER as defined in 36.321
|
||||
/// SR_COUNTER as defined in 38.321
|
||||
uint16_t SR_COUNTER;
|
||||
/// logical channel group ide for each LCID
|
||||
uint8_t LCGID[NR_MAX_NUM_LCID];
|
||||
@@ -328,15 +328,6 @@ typedef struct {
|
||||
|
||||
} RAR_grant_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
uint8_t phr_reporting;
|
||||
uint16_t truncated_bsr;
|
||||
uint16_t short_bsr;
|
||||
uint16_t long_bsr;
|
||||
|
||||
} NR_UE_MAC_CE_t;
|
||||
|
||||
typedef struct {
|
||||
int n_HARQ_ACK;
|
||||
uint32_t ack_payload;
|
||||
@@ -353,6 +344,7 @@ typedef struct {
|
||||
int8_t delta_pucch;
|
||||
} PUCCH_sched_t;
|
||||
|
||||
|
||||
/*!\brief Top level UE MAC structure */
|
||||
typedef struct {
|
||||
|
||||
@@ -419,8 +411,15 @@ typedef struct {
|
||||
nr_ue_if_module_t *if_module;
|
||||
nr_phy_config_t phy_config;
|
||||
|
||||
/// BSR report flag management
|
||||
uint8_t BSR_reporting_active;
|
||||
|
||||
/// LogicalChannelConfig has bearer.
|
||||
boolean_t logicalChannelBearer_exist[NR_MAX_NUM_LCID];
|
||||
NR_UE_SCHEDULING_INFO scheduling_info;
|
||||
NR_UE_MAC_CE_t nr_ue_mac_ce;
|
||||
|
||||
/// PHR
|
||||
uint8_t PHR_reporting_active;
|
||||
|
||||
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
|
||||
NR_SearchSpace_t *search_space_zero;
|
||||
|
||||
Executable → Regular
+73
-3
@@ -40,6 +40,10 @@
|
||||
#define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */
|
||||
#define NR_DL_MAX_NB_CW (2) /* number of downlink code word */
|
||||
|
||||
/**\brief initialize the field in nr_mac instance
|
||||
\param module_id module id */
|
||||
void nr_ue_init_mac(module_id_t module_idP);
|
||||
|
||||
/**\brief decode mib pdu in NR_UE, from if_module ul_ind with P7 tx_ind message
|
||||
\param module_id module id
|
||||
\param cc_id component carrier id
|
||||
@@ -74,6 +78,20 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
|
||||
uint8_t *pduP,
|
||||
uint32_t pdu_len);
|
||||
|
||||
/**\brief primitive from RRC layer to MAC layer to set if bearer exists for a logical channel. todo handle mac_LogicalChannelConfig
|
||||
\param module_id module id
|
||||
\param cc_id component carrier id
|
||||
\param gNB_index gNB index
|
||||
\param long logicalChannelIdentity
|
||||
\param boolean_t status*/
|
||||
int nr_rrc_mac_config_req_ue_logicalChannelBearer(
|
||||
module_id_t module_id,
|
||||
int cc_idP,
|
||||
uint8_t gNB_index,
|
||||
long logicalChannelIdentity,
|
||||
boolean_t status
|
||||
);
|
||||
|
||||
/**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config)
|
||||
\param module_id module id
|
||||
\param cc_id component carrier id
|
||||
@@ -125,7 +143,53 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
|
||||
int slot,
|
||||
int thread_id);
|
||||
|
||||
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP);
|
||||
/*! \fn int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
|
||||
\brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU.
|
||||
\param[in] Mod_id Instance id of UE in machine
|
||||
\param[in] frameP subframe number
|
||||
\param[in] slotP slot number
|
||||
*/
|
||||
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
|
||||
|
||||
/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index)
|
||||
\brief get the rlc stats and update the bsr level for each lcid
|
||||
\param[in] Mod_id instance of the UE
|
||||
\param[in] frameP Frame index
|
||||
\param[in] slot slotP number
|
||||
\param[in] uint8_t gNB_index
|
||||
*/
|
||||
boolean_t nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index);
|
||||
|
||||
/*! \fn nr_locate_BsrIndexByBufferSize (int *table, int size, int value)
|
||||
\brief locate the BSR level in the table as defined in 38.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table.
|
||||
\param[in] *table Pointer to BSR table
|
||||
\param[in] size Size of the table
|
||||
\param[in] value Value of the buffer
|
||||
\return the index in the BSR_LEVEL table
|
||||
*/
|
||||
uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size,
|
||||
int value);
|
||||
|
||||
/*! \fn int nr_get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
|
||||
\brief get the number of subframe from the periodic BSR timer configured by the higher layers
|
||||
\param[in] periodicBSR_Timer timer for periodic BSR
|
||||
\return the number of subframe
|
||||
*/
|
||||
int nr_get_sf_periodicBSRTimer(uint8_t bucketSize);
|
||||
|
||||
/*! \fn int nr_get_ms_bucketsizeduration(uint8_t bucketSize)
|
||||
\brief get the time in ms form the bucket size duration configured by the higher layer
|
||||
\param[in] bucketSize the bucket size duration
|
||||
\return the time in ms
|
||||
*/
|
||||
int nr_get_ms_bucketsizeduration(uint8_t bucketsizeduration);
|
||||
|
||||
/*! \fn int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer)
|
||||
\brief get the number of subframe form the bucket size duration configured by the higher layer
|
||||
\param[in] retxBSR_Timer timer for regular BSR
|
||||
\return the time in sf
|
||||
*/
|
||||
int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer);
|
||||
|
||||
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind);
|
||||
int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
|
||||
@@ -170,7 +234,13 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
int pdu_id);
|
||||
|
||||
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
NR_UE_MAC_INST_t *mac);
|
||||
NR_UE_MAC_INST_t *mac,
|
||||
uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom,
|
||||
uint16_t *crnti,
|
||||
NR_BSR_SHORT *truncated_bsr,
|
||||
NR_BSR_SHORT *short_bsr,
|
||||
NR_BSR_LONG *long_bsr
|
||||
);
|
||||
|
||||
void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
|
||||
|
||||
@@ -330,7 +400,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot);
|
||||
If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC
|
||||
attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB
|
||||
index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for
|
||||
andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321)
|
||||
andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 38.321)
|
||||
@param mod_id Index of UE instance
|
||||
@param CC_id Component Carrier Index
|
||||
@param frame
|
||||
|
||||
@@ -52,8 +52,9 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
|
||||
//init mac here
|
||||
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST);
|
||||
|
||||
for (int j=0;j<NB_NR_UE_MAC_INST;j++)
|
||||
for (int i=0;i<NR_MAX_HARQ_PROCESSES;i++) nr_ue_mac_inst[j].first_ul_tx[i]=1;
|
||||
for (int j=0;j<NB_NR_UE_MAC_INST;j++) {
|
||||
nr_ue_init_mac(j);
|
||||
}
|
||||
|
||||
|
||||
if (rrc_inst && rrc_inst->scell_group_config) {
|
||||
|
||||
@@ -740,7 +740,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
} else {
|
||||
|
||||
size_sdu = nr_write_ce_ulsch_pdu(pdu, mac);
|
||||
size_sdu = nr_write_ce_ulsch_pdu(pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL);
|
||||
pdu += size_sdu;
|
||||
ra->Msg3_size = size_sdu;
|
||||
|
||||
|
||||
@@ -134,6 +134,55 @@ const initial_pucch_resource_t initial_pucch_resource[16] = {
|
||||
};
|
||||
|
||||
|
||||
void nr_ue_init_mac(module_id_t module_idP) {
|
||||
int i;
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
// default values as deined in 38.331 sec 9.2.2
|
||||
LOG_I(NR_MAC, "[UE%d] Applying default macMainConfig\n", module_idP);
|
||||
//mac->scheduling_info.macConfig=NULL;
|
||||
mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf10240;
|
||||
mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_infinity;
|
||||
// mac->scheduling_info.periodicPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
|
||||
// mac->scheduling_info.prohibitPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
|
||||
// mac->scheduling_info.PathlossChange_db = NR_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;
|
||||
// mac->PHR_state = NR_MAC_MainConfig__phr_Config_PR_setup;
|
||||
mac->scheduling_info.SR_COUNTER = 0;
|
||||
mac->scheduling_info.sr_ProhibitTimer = 0;
|
||||
mac->scheduling_info.sr_ProhibitTimer_Running = 0;
|
||||
// mac->scheduling_info.maxHARQ_Tx = NR_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
|
||||
// mac->scheduling_info.ttiBundling = 0;
|
||||
// mac->scheduling_info.extendedBSR_Sizes_r10 = 0;
|
||||
// mac->scheduling_info.extendedPHR_r10 = 0;
|
||||
// mac->scheduling_info.drx_config = NULL;
|
||||
// mac->scheduling_info.phr_config = NULL;
|
||||
// set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW.
|
||||
mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
mac->BSR_reporting_active = BSR_TRIGGER_NONE;
|
||||
// mac->scheduling_info.periodicPHR_SF = nr_get_sf_perioidicPHR_Timer(mac->scheduling_info.periodicPHR_Timer);
|
||||
// mac->scheduling_info.prohibitPHR_SF = nr_get_sf_prohibitPHR_Timer(mac->scheduling_info.prohibitPHR_Timer);
|
||||
// mac->scheduling_info.PathlossChange_db = nr_get_db_dl_PathlossChange(mac->scheduling_info.PathlossChange);
|
||||
// mac->PHR_reporting_active = 0;
|
||||
|
||||
for (i = 0; i < NR_MAX_NUM_LCID; i++) {
|
||||
LOG_D(NR_MAC, "[UE%d] Applying default logical channel config for LCGID %d\n",
|
||||
module_idP, i);
|
||||
mac->scheduling_info.Bj[i] = -1;
|
||||
mac->scheduling_info.bucket_size[i] = -1;
|
||||
|
||||
if (i < UL_SCH_LCID_DTCH) { // initialize all control channels lcgid to 0
|
||||
mac->scheduling_info.LCGID[i] = 0;
|
||||
} else { // initialize all the data channels lcgid to 1
|
||||
mac->scheduling_info.LCGID[i] = 1;
|
||||
}
|
||||
|
||||
mac->scheduling_info.LCID_status[i] = LCID_EMPTY;
|
||||
mac->scheduling_info.LCID_buffer_remain[i] = 0;
|
||||
for (int i=0;i<NR_MAX_HARQ_PROCESSES;i++) mac->first_ul_tx[i]=1;
|
||||
}
|
||||
}
|
||||
|
||||
void get_bwp_info(NR_UE_MAC_INST_t *mac,
|
||||
int dl_bwp_id,
|
||||
int ul_bwp_id,
|
||||
@@ -2202,9 +2251,54 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
|
||||
return false;
|
||||
}
|
||||
|
||||
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot){
|
||||
// no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti
|
||||
DevCheck(module_idP < (int) NB_UE_INST, module_idP, NB_NR_UE_MAC_INST, 0);
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
DSR_TRANSMAX_t dsr_TransMax = sr_n64; // todo
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n",
|
||||
module_idP, frameP, slot,
|
||||
mac->scheduling_info.SR_COUNTER,
|
||||
(1 << (2 + dsr_TransMax)),
|
||||
mac->scheduling_info.SR_pending); // todo
|
||||
|
||||
int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP){
|
||||
return 0;
|
||||
if ((mac->scheduling_info.SR_pending == 1) &&
|
||||
(mac->scheduling_info.SR_COUNTER < (1 << (2 + dsr_TransMax)))) {
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d slot %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d, increment SR_COUNTER\n",
|
||||
module_idP, frameP, slot,
|
||||
mac->scheduling_info.SR_COUNTER,
|
||||
(1 << (2 + dsr_TransMax)),
|
||||
mac->scheduling_info.SR_pending); // todo
|
||||
mac->scheduling_info.SR_COUNTER++;
|
||||
|
||||
// start the sr-prohibittimer : rel 9 and above
|
||||
if (mac->scheduling_info.sr_ProhibitTimer > 0) { // timer configured
|
||||
mac->scheduling_info.sr_ProhibitTimer--;
|
||||
mac->scheduling_info.
|
||||
sr_ProhibitTimer_Running = 1;
|
||||
} else {
|
||||
mac->scheduling_info.
|
||||
sr_ProhibitTimer_Running = 0;
|
||||
}
|
||||
//mac->ul_active =1;
|
||||
return (1); //instruct phy to signal SR
|
||||
} else {
|
||||
// notify RRC to relase PUCCH/SRS
|
||||
// clear any configured dl/ul
|
||||
// initiate RA
|
||||
if (mac->scheduling_info.SR_pending) {
|
||||
// release all pucch resource
|
||||
//mac->physicalConfigDedicated = NULL; // todo
|
||||
//mac->ul_active = 0; // todo
|
||||
mac->BSR_reporting_active =
|
||||
NR_BSR_TRIGGER_NONE;
|
||||
LOG_I(NR_MAC, "[UE %d] Release all SRs \n", module_idP);
|
||||
}
|
||||
|
||||
mac->scheduling_info.SR_pending = 0;
|
||||
mac->scheduling_info.SR_COUNTER = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3466,13 +3560,17 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
* Return: number of written bytes
|
||||
*/
|
||||
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
NR_UE_MAC_INST_t *mac) {
|
||||
NR_UE_MAC_INST_t *mac,
|
||||
uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom,
|
||||
uint16_t *crnti,
|
||||
NR_BSR_SHORT *truncated_bsr,
|
||||
NR_BSR_SHORT *short_bsr,
|
||||
NR_BSR_LONG *long_bsr) {
|
||||
|
||||
int mac_ce_len = 0;
|
||||
uint8_t mac_ce_size = 0;
|
||||
NR_UE_MAC_CE_t *nr_ue_mac_ce = &mac->nr_ue_mac_ce;
|
||||
|
||||
if (nr_ue_mac_ce->phr_reporting && mac->phr_Config != NULL) {
|
||||
uint8_t *pdu = mac_ce;
|
||||
if (power_headroom) {
|
||||
|
||||
// MAC CE fixed subheader
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
|
||||
@@ -3480,21 +3578,22 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
mac_ce++;
|
||||
|
||||
// PHR MAC CE (1 octet)
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = 0;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = power_headroom;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0;
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; // todo
|
||||
((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0;
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : power_headroom pdu %p mac_ce %p b\n",
|
||||
pdu, mac_ce);
|
||||
}
|
||||
|
||||
if (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED) {
|
||||
if (crnti && (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED)) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, mac->crnti);
|
||||
LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, (*crnti));
|
||||
|
||||
// MAC CE fixed subheader
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
|
||||
@@ -3502,7 +3601,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
mac_ce++;
|
||||
|
||||
// C-RNTI MAC CE (2 octets)
|
||||
*(uint16_t *) mac_ce = mac->crnti;
|
||||
*(uint16_t *) mac_ce = (*crnti);
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(uint16_t);
|
||||
@@ -3511,55 +3610,110 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
|
||||
|
||||
}
|
||||
|
||||
if (nr_ue_mac_ce->truncated_bsr) {
|
||||
if (truncated_bsr) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s: generating short truncated BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->truncated_bsr);
|
||||
|
||||
// MAC CE fixed subheader
|
||||
// MAC CE fixed subheader
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_TRUNCATED_BSR;
|
||||
mac_ce++;
|
||||
|
||||
// Short truncated BSR MAC CE (1 octet)
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = 0;
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = 0;
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = truncated_bsr->Buffer_size;
|
||||
((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = truncated_bsr->LcgID;;
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : truncated_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
|
||||
truncated_bsr->Buffer_size, truncated_bsr->LcgID, pdu, mac_ce);
|
||||
|
||||
} else if (nr_ue_mac_ce->short_bsr) {
|
||||
} else if (short_bsr) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s: generating short BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->short_bsr);
|
||||
|
||||
// MAC CE fixed subheader
|
||||
// MAC CE fixed subheader
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_BSR;
|
||||
mac_ce++;
|
||||
|
||||
// Short truncated BSR MAC CE (1 octet)
|
||||
((NR_BSR_SHORT *) mac_ce)->Buffer_size = nr_ue_mac_ce->short_bsr;
|
||||
((NR_BSR_SHORT *) mac_ce)->LcgID = 0;
|
||||
((NR_BSR_SHORT *) mac_ce)->Buffer_size = short_bsr->Buffer_size;
|
||||
((NR_BSR_SHORT *) mac_ce)->LcgID = short_bsr->LcgID;
|
||||
|
||||
// update pointer and length
|
||||
mac_ce_size = sizeof(NR_BSR_SHORT);
|
||||
mac_ce += mac_ce_size;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : short_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n",
|
||||
short_bsr->Buffer_size, short_bsr->LcgID, pdu, mac_ce);
|
||||
} else if (long_bsr) {
|
||||
|
||||
} else if (nr_ue_mac_ce->long_bsr) {
|
||||
// MAC CE variable subheader
|
||||
// todo ch 6.1.3.1. TS 38.321
|
||||
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
|
||||
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
|
||||
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = UL_SCH_LCID_L_BSR;
|
||||
// ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = 0;
|
||||
// sh_size = 2;
|
||||
// MAC CE variable subheader
|
||||
// ch 6.1.3.1. TS 38.321
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->R = 0;
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->F = 0;
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_ce)->LCID = UL_SCH_LCID_L_BSR;
|
||||
|
||||
// Short truncated BSR MAC CE (1 octet)
|
||||
// ((NR_BSR_LONG *) mac_ce)->Buffer_size0 = short_bsr;
|
||||
// ((NR_BSR_LONG *) mac_ce)->LCGID0 = 0;
|
||||
// mac_ce_size = sizeof(NR_BSR_LONG); // size is variable
|
||||
NR_MAC_SUBHEADER_SHORT *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT *) mac_ce;
|
||||
mac_ce += 2;
|
||||
|
||||
// Could move to nr_get_sdu()
|
||||
uint8_t *Buffer_size_ptr= (uint8_t*) mac_ce + 1;
|
||||
//int NR_BSR_LONG_SIZE = 1;
|
||||
if (long_bsr->Buffer_size0 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID0 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID0 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size0;
|
||||
}
|
||||
if (long_bsr->Buffer_size1 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID1 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID1 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size1;
|
||||
}
|
||||
if (long_bsr->Buffer_size2 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID2 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID2 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size2;
|
||||
}
|
||||
if (long_bsr->Buffer_size3 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID3 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID3 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size3;
|
||||
}
|
||||
if (long_bsr->Buffer_size4 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID4 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID4 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size4;
|
||||
}
|
||||
if (long_bsr->Buffer_size5 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID5 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID5 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size5;
|
||||
}
|
||||
if (long_bsr->Buffer_size6 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID6 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID6 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size6;
|
||||
}
|
||||
if (long_bsr->Buffer_size7 == 0) {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID7 = 0;
|
||||
} else {
|
||||
((NR_BSR_LONG *) mac_ce)->LcgID7 = 1;
|
||||
*Buffer_size_ptr++ = long_bsr->Buffer_size7;
|
||||
}
|
||||
((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = mac_ce_size = (uint8_t*) Buffer_size_ptr - (uint8_t*) mac_ce;
|
||||
LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", mac_ce_size, *((uint8_t*) mac_ce),
|
||||
((NR_BSR_LONG *) mac_ce)->Buffer_size0, ((NR_BSR_LONG *) mac_ce)->Buffer_size1, ((NR_BSR_LONG *) mac_ce)->Buffer_size2, ((NR_BSR_LONG *) mac_ce)->Buffer_size3,
|
||||
((NR_BSR_LONG *) mac_ce)->Buffer_size4, ((NR_BSR_LONG *) mac_ce)->Buffer_size5, ((NR_BSR_LONG *) mac_ce)->Buffer_size6, ((NR_BSR_LONG *) mac_ce)->Buffer_size7);
|
||||
// update pointer and length
|
||||
mac_ce = Buffer_size_ptr;
|
||||
mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_SHORT);
|
||||
}
|
||||
|
||||
return mac_ce_len;
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
|
||||
#include <executables/softmodem-common.h>
|
||||
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
|
||||
static prach_association_pattern_t prach_assoc_pattern;
|
||||
static ssb_list_info_t ssb_list;
|
||||
|
||||
@@ -164,13 +166,26 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl
|
||||
void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) {
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
|
||||
NR_BWP_UplinkDedicated_t *ubwpd=NULL;
|
||||
|
||||
if (mac->cg &&
|
||||
mac->cg->spCellConfig &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)
|
||||
ubwpd = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP;
|
||||
|
||||
NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0] ?
|
||||
mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup :
|
||||
(ubwpd?
|
||||
ubwpd->pusch_Config->choice.setup:
|
||||
NULL);
|
||||
|
||||
long transformPrecoder;
|
||||
if (pusch_Config->transformPrecoder)
|
||||
if (pusch_Config && pusch_Config->transformPrecoder)
|
||||
transformPrecoder = *pusch_Config->transformPrecoder;
|
||||
else {
|
||||
if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder)
|
||||
if(scc && scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder)
|
||||
transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled;
|
||||
else
|
||||
transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
|
||||
@@ -1004,10 +1019,324 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
}
|
||||
}
|
||||
|
||||
if (dl_info) {
|
||||
return (CONNECTION_OK);
|
||||
}
|
||||
module_id_t mod_id = ul_info->module_id;
|
||||
frame_t txFrameP = ul_info->frame_tx;
|
||||
slot_t txSlotP = ul_info->slot_tx;
|
||||
|
||||
// Handle the SR/BSR procedures per subframe
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
||||
uint8_t gNB_indexP=0;
|
||||
|
||||
// Call BSR procedure as described in Section 5.4.5 in 38.321
|
||||
|
||||
// First check ReTxBSR Timer because it is always configured
|
||||
// Decrement ReTxBSR Timer if it is running and not null
|
||||
if ((mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.retxBSR_SF != 0)) {
|
||||
mac->scheduling_info.retxBSR_SF--;
|
||||
}
|
||||
|
||||
// Decrement Periodic Timer if it is running and not null
|
||||
if ((mac->scheduling_info.periodicBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.periodicBSR_SF != 0)) {
|
||||
mac->scheduling_info.periodicBSR_SF--;
|
||||
}
|
||||
|
||||
//Check whether Regular BSR is triggered
|
||||
if (nr_update_bsr(mod_id, txFrameP, txSlotP, gNB_indexP) == TRUE) {
|
||||
// call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures
|
||||
// outlined in Sections 5.4.4 an 5.4.5 of 38.321
|
||||
mac->scheduling_info.SR_pending = 1;
|
||||
// Regular BSR trigger
|
||||
mac->BSR_reporting_active |= NR_BSR_TRIGGER_REGULAR;
|
||||
LOG_D(NR_MAC, "[UE %d][BSR] Regular BSR Triggered Frame %d slot %d SR for PUSCH is pending\n",
|
||||
mod_id, txFrameP, txSlotP);
|
||||
}
|
||||
return UE_CONNECTION_OK;
|
||||
|
||||
}
|
||||
|
||||
boolean_t
|
||||
nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) {
|
||||
mac_rlc_status_resp_t rlc_status;
|
||||
boolean_t bsr_regular_triggered = FALSE;
|
||||
uint8_t lcid;
|
||||
uint8_t lcgid;
|
||||
uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined
|
||||
uint32_t lcgid_buffer_remain[NR_MAX_NUM_LCGID] = {0,0,0,0,0,0,0,0};
|
||||
int32_t lcid_bytes_in_buffer[NR_MAX_NUM_LCID];
|
||||
/* Array for ordering LCID with data per decreasing priority order */
|
||||
uint8_t lcid_reordered_array[NR_MAX_NUM_LCID]=
|
||||
{NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
|
||||
NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
|
||||
NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
|
||||
NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,
|
||||
};
|
||||
uint8_t pos_next = 0;
|
||||
//uint8_t highest_priority = 16;
|
||||
uint8_t array_index = 0;
|
||||
// Reset All BSR Infos
|
||||
lcid_bytes_in_buffer[0] = 0;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
|
||||
// Reset transmission status
|
||||
lcid_bytes_in_buffer[lcid] = 0;
|
||||
mac->scheduling_info.LCID_status[lcid]=LCID_EMPTY;
|
||||
}
|
||||
|
||||
for (lcgid=0; lcgid < NR_MAX_NUM_LCGID; lcgid++) {
|
||||
// Reset Buffer Info
|
||||
mac->scheduling_info.BSR[lcgid]=0;
|
||||
mac->scheduling_info.BSR_bytes[lcgid]=0;
|
||||
}
|
||||
|
||||
//Get Buffer Occupancy and fill lcid_reordered_array
|
||||
for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
|
||||
//if (mac->logicalChannelConfig[lcid]) {
|
||||
if (mac->logicalChannelBearer_exist[lcid] ) { // todo
|
||||
lcgid = mac->scheduling_info.LCGID[lcid];
|
||||
|
||||
// Store already available data to transmit per Group
|
||||
if (lcgid < NR_MAX_NUM_LCGID) {
|
||||
lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid];
|
||||
}
|
||||
|
||||
rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0);
|
||||
|
||||
lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer;
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n",
|
||||
module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,slotP);
|
||||
mac->scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY;
|
||||
|
||||
//Update BSR_bytes and position in lcid_reordered_array only if Group is defined
|
||||
if (lcgid < NR_MAX_NUM_LCGID) {
|
||||
num_lcid_with_data ++;
|
||||
// sum lcid buffer which has same lcgid
|
||||
mac->scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer;
|
||||
//Fill in the array
|
||||
array_index = 0;
|
||||
|
||||
do {
|
||||
//if (mac->logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) {
|
||||
if (1) { // todo
|
||||
//Insert if priority is higher or equal (lower or equal in value)
|
||||
for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--) {
|
||||
lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1];
|
||||
}
|
||||
|
||||
lcid_reordered_array[array_index] = lcid;
|
||||
break;
|
||||
}
|
||||
|
||||
array_index ++;
|
||||
} while ((array_index < num_lcid_with_data) && (array_index < NR_MAX_NUM_LCID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether a regular BSR can be triggered according to the first cases in 38.321
|
||||
if (num_lcid_with_data) {
|
||||
LOG_D(NR_MAC, "[UE %d] PDCCH Tick at frame %d slot %d: NumLCID with data=%d Reordered LCID0=%d LCID1=%d LCID2=%d\n",
|
||||
module_idP, frameP, slotP, num_lcid_with_data,
|
||||
lcid_reordered_array[0], lcid_reordered_array[1],
|
||||
lcid_reordered_array[2]);
|
||||
|
||||
for (array_index = 0; array_index < num_lcid_with_data; array_index++) {
|
||||
lcid = lcid_reordered_array[array_index];
|
||||
|
||||
/* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity
|
||||
either the data belongs to a logical channel with higher priority than the priorities of the logical channels
|
||||
which belong to any LCG and for which data is already available for transmission
|
||||
*/
|
||||
{
|
||||
bsr_regular_triggered = TRUE;
|
||||
LOG_D(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n",
|
||||
module_idP, lcid,
|
||||
mac->scheduling_info.LCGID[lcid],
|
||||
frameP, slotP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission
|
||||
if (mac->scheduling_info.retxBSR_SF == 0) {
|
||||
bsr_regular_triggered = TRUE;
|
||||
|
||||
if ((mac->BSR_reporting_active & NR_BSR_TRIGGER_REGULAR) == 0) {
|
||||
LOG_I(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d slot %d\n",
|
||||
module_idP, frameP, slotP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Store Buffer Occupancy in remain buffers for next TTI
|
||||
for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
|
||||
mac->scheduling_info.LCID_buffer_remain[lcid] = lcid_bytes_in_buffer[lcid];
|
||||
}
|
||||
|
||||
return bsr_regular_triggered;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size, int value) {
|
||||
uint8_t ju, jm, jl;
|
||||
int ascend;
|
||||
//DevAssert(size > 0);
|
||||
//DevAssert(size <= 256);
|
||||
|
||||
if (value == 0) {
|
||||
return 0; //elseif (value > 150000) return 63;
|
||||
}
|
||||
|
||||
jl = 0; // lower bound
|
||||
ju = size - 1; // upper bound
|
||||
ascend = (table[ju] >= table[jl]) ? 1 : 0; // determine the order of the the table: 1 if ascending order of table, 0 otherwise
|
||||
|
||||
while (ju - jl > 1) { //If we are not yet done,
|
||||
jm = (ju + jl) >> 1; //compute a midpoint,
|
||||
|
||||
if ((value >= table[jm]) == ascend) {
|
||||
jl = jm; // replace the lower limit
|
||||
} else {
|
||||
ju = jm; //replace the upper limit
|
||||
}
|
||||
|
||||
LOG_T(NR_MAC, "[UE] searching BSR index %d for (BSR TABLE %d < value %d)\n",
|
||||
jm, table[jm], value);
|
||||
}
|
||||
|
||||
if (value == table[jl]) {
|
||||
return jl;
|
||||
} else {
|
||||
return jl + 1; //equally ju
|
||||
}
|
||||
}
|
||||
|
||||
int nr_get_sf_periodicBSRTimer(uint8_t sf_offset) {
|
||||
switch (sf_offset) {
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf1:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf5:
|
||||
return 5;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf10:
|
||||
return 10;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf16:
|
||||
return 16;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf20:
|
||||
return 20;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf32:
|
||||
return 32;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf40:
|
||||
return 40;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf64:
|
||||
return 64;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf80:
|
||||
return 80;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf128:
|
||||
return 128;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf160:
|
||||
return 160;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf320:
|
||||
return 320;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf640:
|
||||
return 640;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf1280:
|
||||
return 1280;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_sf2560:
|
||||
return 2560;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__periodicBSR_Timer_infinity:
|
||||
default:
|
||||
return 0xFFFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int nr_get_sf_retxBSRTimer(uint8_t sf_offset) {
|
||||
switch (sf_offset) {
|
||||
case NR_BSR_Config__retxBSR_Timer_sf10:
|
||||
return 10;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf20:
|
||||
return 20;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf40:
|
||||
return 40;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf80:
|
||||
return 80;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf160:
|
||||
return 160;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf320:
|
||||
return 320;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf640:
|
||||
return 640;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf1280:
|
||||
return 1280;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf2560:
|
||||
return 2560;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf5120:
|
||||
return 5120;
|
||||
break;
|
||||
|
||||
case NR_BSR_Config__retxBSR_Timer_sf10240:
|
||||
return 10240;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// PUSCH scheduler:
|
||||
// - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2,
|
||||
// - where K2 is the offset between the slot in which UL DCI is received and the slot
|
||||
@@ -2041,6 +2370,261 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
|
||||
|
||||
|
||||
#define MAX_LCID 8 // NR_MAX_NUM_LCID shall be used but the mac_rlc_data_req function can fetch data for max 8 LCID
|
||||
typedef struct {
|
||||
uint8_t bsr_len;
|
||||
uint8_t bsr_ce_len;
|
||||
uint8_t bsr_header_len;
|
||||
uint8_t phr_len;
|
||||
uint8_t phr_ce_len;
|
||||
uint8_t phr_header_len;
|
||||
uint16_t sdu_length_total;
|
||||
NR_BSR_SHORT *bsr_s;
|
||||
NR_BSR_LONG *bsr_l;
|
||||
NR_BSR_SHORT *bsr_t;
|
||||
//NR_POWER_HEADROOM_CMD *phr_pr;
|
||||
int tot_mac_ce_len;
|
||||
uint8_t total_mac_pdu_header_len;
|
||||
} NR_UE_MAC_CE_INFO;
|
||||
|
||||
/*
|
||||
nr_ue_get_sdu_mac_ce_pre finds length in various mac_ce field
|
||||
Need nothing from mac_ce_p:
|
||||
Update the following in mac_ce_p:
|
||||
bsr_len;
|
||||
bsr_ce_len;
|
||||
bsr_header_len;
|
||||
phr_len; TBD
|
||||
phr_ce_len; TBD
|
||||
phr_header_len; TBD
|
||||
*/
|
||||
int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe,
|
||||
uint8_t gNB_index,
|
||||
uint8_t *ulsch_buffer,
|
||||
uint16_t buflen,
|
||||
NR_UE_MAC_CE_INFO *mac_ce_p) {
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
|
||||
int num_lcg_id_with_data = 0;
|
||||
// Preparing the MAC CEs sub-PDUs and get the total size
|
||||
mac_ce_p->bsr_header_len = 0;
|
||||
mac_ce_p->phr_header_len = 0; //sizeof(SCH_SUBHEADER_FIXED);
|
||||
int lcg_id = 0;
|
||||
while (lcg_id < NR_MAX_NUM_LCGID) {
|
||||
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
|
||||
num_lcg_id_with_data++;
|
||||
}
|
||||
|
||||
lcg_id++;
|
||||
}
|
||||
|
||||
//Restart ReTxBSR Timer at new grant indication (38.321)
|
||||
if (mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) {
|
||||
mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer);
|
||||
}
|
||||
|
||||
// periodicBSR-Timer expires, trigger BSR
|
||||
if ((mac->scheduling_info.periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity)
|
||||
&& (mac->scheduling_info.periodicBSR_SF == 0)) {
|
||||
// Trigger BSR Periodic
|
||||
mac->BSR_reporting_active |= NR_BSR_TRIGGER_PERIODIC;
|
||||
LOG_D(NR_MAC, "[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n",
|
||||
module_idP, frameP, subframe, buflen);
|
||||
}
|
||||
|
||||
//Compute BSR Length if Regular or Periodic BSR is triggered
|
||||
//WARNING: if BSR long is computed, it may be changed to BSR short during or after multiplexing if there remains less than 1 LCGROUP with data after Tx
|
||||
if (mac->BSR_reporting_active) {
|
||||
AssertFatal((mac->BSR_reporting_active & NR_BSR_TRIGGER_PADDING) == 0,
|
||||
"Inconsistent BSR Trigger=%d !\n",
|
||||
mac->BSR_reporting_active);
|
||||
|
||||
//A Regular or Periodic BSR can only be sent if TBS is sufficient as transmitting only a BSR is not allowed if UE has data to transmit
|
||||
if (num_lcg_id_with_data <= 1) {
|
||||
if (buflen >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED)+1)) {
|
||||
mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte
|
||||
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte
|
||||
}
|
||||
} else {
|
||||
if (buflen >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT)+1)) {
|
||||
mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size
|
||||
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mac_ce_p->bsr_len = mac_ce_p->bsr_ce_len + mac_ce_p->bsr_header_len;
|
||||
return (mac_ce_p->bsr_len + mac_ce_p->phr_len);
|
||||
}
|
||||
|
||||
/*
|
||||
nr_ue_get_sdu_mac_ce_post recalculates length and prepares the mac_ce field
|
||||
Need the following from mac_ce_p:
|
||||
bsr_ce_len
|
||||
bsr_len
|
||||
sdu_length_total
|
||||
total_mac_pdu_header_len
|
||||
Update the following in mac_ce_p:
|
||||
bsr_ce_len
|
||||
bsr_header_len
|
||||
bsr_len
|
||||
tot_mac_ce_len
|
||||
total_mac_pdu_header_len
|
||||
bsr_s
|
||||
bsr_l
|
||||
bsr_t
|
||||
*/
|
||||
void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe,
|
||||
uint8_t gNB_index,
|
||||
uint8_t *ulsch_buffer,
|
||||
uint16_t buflen,
|
||||
NR_UE_MAC_CE_INFO *mac_ce_p) {
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
|
||||
// Compute BSR Values and update Nb LCGID with data after multiplexing
|
||||
unsigned short padding_len = 0;
|
||||
uint8_t lcid = 0;
|
||||
int lcg_id = 0;
|
||||
int num_lcg_id_with_data = 0;
|
||||
int lcg_id_bsr_trunc = 0;
|
||||
for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) {
|
||||
if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) {
|
||||
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
|
||||
} else {
|
||||
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
|
||||
}
|
||||
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
|
||||
num_lcg_id_with_data++;
|
||||
lcg_id_bsr_trunc = lcg_id;
|
||||
}
|
||||
}
|
||||
|
||||
// TS 38.321 Section 5.4.5
|
||||
// Check BSR padding: it is done after PHR according to Logical Channel Prioritization order
|
||||
// Check for max padding size, ie MAC Hdr for last RLC PDU = 1
|
||||
/* For Padding BSR:
|
||||
- if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader:
|
||||
- if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission;
|
||||
- else report Short BSR.
|
||||
- else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR.
|
||||
*/
|
||||
if (mac_ce_p->sdu_length_total) {
|
||||
padding_len = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total);
|
||||
}
|
||||
|
||||
if ((padding_len) && (mac_ce_p->bsr_len == 0)) {
|
||||
/* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR */
|
||||
if (padding_len >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT))) {
|
||||
mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size
|
||||
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes
|
||||
// Trigger BSR Padding
|
||||
mac->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING;
|
||||
} else if (padding_len >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED))) {
|
||||
mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte
|
||||
mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte
|
||||
|
||||
if (num_lcg_id_with_data > 1) {
|
||||
// REPORT SHORT TRUNCATED BSR
|
||||
//Get LCGID of highest priority LCID with data (todo)
|
||||
for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) {
|
||||
lcg_id = mac->scheduling_info.LCGID[lcid];
|
||||
if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.BSR_bytes[lcg_id])) {
|
||||
lcg_id_bsr_trunc = lcg_id;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Report SHORT BSR, clear bsr_t
|
||||
mac_ce_p->bsr_t = NULL;
|
||||
}
|
||||
|
||||
// Trigger BSR Padding
|
||||
mac->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING;
|
||||
}
|
||||
|
||||
mac_ce_p->bsr_len = mac_ce_p->bsr_header_len + mac_ce_p->bsr_ce_len;
|
||||
mac_ce_p->tot_mac_ce_len += mac_ce_p->bsr_len;
|
||||
mac_ce_p->total_mac_pdu_header_len += mac_ce_p->bsr_len;
|
||||
}
|
||||
|
||||
//Fill BSR Infos
|
||||
if (mac_ce_p->bsr_ce_len == 0) {
|
||||
mac_ce_p->bsr_s = NULL;
|
||||
mac_ce_p->bsr_l = NULL;
|
||||
mac_ce_p->bsr_t = NULL;
|
||||
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_SHORT)) {
|
||||
mac_ce_p->bsr_s = NULL;
|
||||
mac_ce_p->bsr_t = NULL;
|
||||
mac_ce_p->bsr_l->Buffer_size0 = mac->scheduling_info.BSR[0];
|
||||
mac_ce_p->bsr_l->Buffer_size1 = mac->scheduling_info.BSR[1];
|
||||
mac_ce_p->bsr_l->Buffer_size2 = mac->scheduling_info.BSR[2];
|
||||
mac_ce_p->bsr_l->Buffer_size3 = mac->scheduling_info.BSR[3];
|
||||
mac_ce_p->bsr_l->Buffer_size4 = mac->scheduling_info.BSR[4];
|
||||
mac_ce_p->bsr_l->Buffer_size5 = mac->scheduling_info.BSR[5];
|
||||
mac_ce_p->bsr_l->Buffer_size6 = mac->scheduling_info.BSR[6];
|
||||
mac_ce_p->bsr_l->Buffer_size7 = mac->scheduling_info.BSR[7];
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report LONG BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d level LCGID4 %d,level LCGID5 %d,level LCGID6 %d,level LCGID7 %d)\n",
|
||||
module_idP, frameP, subframe,
|
||||
mac->BSR_reporting_active,
|
||||
mac->scheduling_info.BSR[0],
|
||||
mac->scheduling_info.BSR[1],
|
||||
mac->scheduling_info.BSR[2],
|
||||
mac->scheduling_info.BSR[3],
|
||||
mac->scheduling_info.BSR[4],
|
||||
mac->scheduling_info.BSR[5],
|
||||
mac->scheduling_info.BSR[6],
|
||||
mac->scheduling_info.BSR[7]);
|
||||
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_FIXED)) {
|
||||
mac_ce_p->bsr_l = NULL;
|
||||
|
||||
if ((mac_ce_p->bsr_t != NULL) && (mac->BSR_reporting_active & NR_BSR_TRIGGER_PADDING)) {
|
||||
//Truncated BSR
|
||||
mac_ce_p->bsr_s = NULL;
|
||||
mac_ce_p->bsr_t->LcgID = lcg_id_bsr_trunc;
|
||||
mac_ce_p->bsr_t->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
|
||||
module_idP, frameP, subframe,
|
||||
mac->BSR_reporting_active,
|
||||
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
|
||||
} else {
|
||||
mac_ce_p->bsr_t = NULL;
|
||||
mac_ce_p->bsr_s->LcgID = lcg_id_bsr_trunc;
|
||||
mac_ce_p->bsr_s->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
|
||||
module_idP, frameP, subframe,
|
||||
mac->BSR_reporting_active,
|
||||
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n", module_idP);
|
||||
mac->scheduling_info.SR_pending = 0;
|
||||
mac->scheduling_info.SR_COUNTER = 0;
|
||||
|
||||
/* Actions when a BSR is sent */
|
||||
if (mac_ce_p->bsr_ce_len) {
|
||||
LOG_D(NR_MAC, "[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n",
|
||||
module_idP, mac_ce_p->bsr_ce_len, mac_ce_p->bsr_header_len, buflen);
|
||||
// Reset ReTx BSR Timer
|
||||
mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer);
|
||||
LOG_D(NR_MAC, "[UE %d] MAC ReTx BSR Timer Reset =%d\n", module_idP, mac->scheduling_info.retxBSR_SF);
|
||||
|
||||
// Reset Periodic Timer except when BSR is truncated
|
||||
if ((mac_ce_p->bsr_t == NULL) && (mac->scheduling_info.periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity)) {
|
||||
mac->scheduling_info.periodicBSR_SF = nr_get_sf_periodicBSRTimer(mac->scheduling_info.periodicBSR_Timer);
|
||||
LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset =%d\n",
|
||||
module_idP,
|
||||
mac->scheduling_info.periodicBSR_SF);
|
||||
}
|
||||
|
||||
// Reset BSR Trigger flags
|
||||
mac->BSR_reporting_active = BSR_TRIGGER_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function: to fetch data to be transmitted from RLC, place it in the ULSCH PDU buffer
|
||||
@@ -2061,31 +2645,45 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
||||
uint8_t gNB_index,
|
||||
uint8_t *ulsch_buffer,
|
||||
uint16_t buflen) {
|
||||
|
||||
NR_UE_MAC_CE_INFO mac_ce_info;
|
||||
NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info;
|
||||
int16_t buflen_remain = 0;
|
||||
mac_ce_p->bsr_len = 0;
|
||||
mac_ce_p->bsr_ce_len = 0;
|
||||
mac_ce_p->bsr_header_len = 0;
|
||||
mac_ce_p->phr_len = 0;
|
||||
//mac_ce_p->phr_ce_len = 0;
|
||||
//mac_ce_p->phr_header_len = 0;
|
||||
|
||||
uint8_t lcid = 0;
|
||||
uint16_t sdu_length = 0;
|
||||
uint16_t num_sdus = 0;
|
||||
uint16_t sdu_length_total = 0;
|
||||
mac_ce_p->sdu_length_total = 0;
|
||||
NR_BSR_SHORT bsr_short, bsr_truncated;
|
||||
NR_BSR_LONG bsr_long;
|
||||
mac_ce_p->bsr_s = &bsr_short;
|
||||
mac_ce_p->bsr_l = &bsr_long;
|
||||
mac_ce_p->bsr_t = &bsr_truncated;
|
||||
//NR_POWER_HEADROOM_CMD phr;
|
||||
//mac_ce_p->phr_p = &phr;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
//int highest_priority = 16;
|
||||
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
|
||||
// Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer
|
||||
uint8_t *pdu = ulsch_buffer;
|
||||
|
||||
// Preparing the MAC CEs sub-PDUs and get the total size
|
||||
unsigned char mac_header_control_elements[16] = {0};
|
||||
int tot_mac_ce_len = nr_write_ce_ulsch_pdu(&mac_header_control_elements[0], mac);
|
||||
uint8_t total_mac_pdu_header_len = tot_mac_ce_len;
|
||||
//nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
|
||||
mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p);
|
||||
mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len;
|
||||
|
||||
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen);
|
||||
|
||||
// Check for DCCH first
|
||||
// TO DO: Multiplex in the order defined by the logical channel prioritization
|
||||
for (lcid = UL_SCH_LCID_SRB1;
|
||||
lcid < MAX_LCID; lcid++) {
|
||||
for (lcid = UL_SCH_LCID_SRB1; lcid < MAX_LCID; lcid++) {
|
||||
|
||||
buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size);
|
||||
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
|
||||
|
||||
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d bytes, buflen_remain %d bytes)\n",
|
||||
__FUNCTION__,
|
||||
@@ -2094,8 +2692,8 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
||||
subframe,
|
||||
lcid,
|
||||
buflen,
|
||||
sdu_length_total,
|
||||
tot_mac_ce_len,
|
||||
mac_ce_p->sdu_length_total,
|
||||
mac_ce_p->tot_mac_ce_len,
|
||||
buflen_remain);
|
||||
|
||||
while (buflen_remain > 0){
|
||||
@@ -2125,7 +2723,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
||||
|
||||
if (sdu_length > 0) {
|
||||
|
||||
LOG_D(MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__,
|
||||
LOG_D(NR_MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__,
|
||||
num_sdus + 1,
|
||||
sdu_length,
|
||||
lcid,
|
||||
@@ -2145,40 +2743,53 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
||||
#endif
|
||||
|
||||
pdu += sdu_length;
|
||||
sdu_length_total += sdu_length;
|
||||
total_mac_pdu_header_len += sh_size;
|
||||
mac_ce_p->sdu_length_total += sdu_length;
|
||||
mac_ce_p->total_mac_pdu_header_len += sh_size;
|
||||
|
||||
num_sdus++;
|
||||
|
||||
} else {
|
||||
pdu -= sh_size;
|
||||
LOG_D(MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid);
|
||||
LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid);
|
||||
break;
|
||||
}
|
||||
|
||||
buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size);
|
||||
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
|
||||
|
||||
//Update Buffer remain and BSR bytes after transmission
|
||||
mac->scheduling_info.LCID_buffer_remain[lcid] -= sdu_length;
|
||||
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] -= sdu_length;
|
||||
LOG_D(NR_MAC, "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n",
|
||||
module_idP, frameP, subframe, mac->scheduling_info.LCGID[lcid],
|
||||
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]]);
|
||||
if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] < 0)
|
||||
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (tot_mac_ce_len > 0) {
|
||||
//nr_ue_get_sdu_mac_ce_post recalculates all mac_ce related header fields since buffer has been changed after mac_rlc_data_req.
|
||||
//Also, BSR padding is handled here after knowing mac_ce_p->sdu_length_total.
|
||||
nr_ue_get_sdu_mac_ce_post(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p);
|
||||
|
||||
LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, tot_mac_ce_len);
|
||||
memcpy((void *) pdu, (void *) mac_header_control_elements, tot_mac_ce_len);
|
||||
pdu += (unsigned char) tot_mac_ce_len;
|
||||
if (mac_ce_p->tot_mac_ce_len > 0) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len);
|
||||
nr_write_ce_ulsch_pdu(pdu, mac, 0, NULL, mac_ce_p->bsr_t, mac_ce_p->bsr_s, mac_ce_p->bsr_l);
|
||||
pdu += (unsigned char) mac_ce_p->tot_mac_ce_len;
|
||||
|
||||
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
||||
LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, tot_mac_ce_len);
|
||||
log_dump(NR_MAC, mac_header_control_elements, tot_mac_ce_len, LOG_DUMP_CHAR, "\n");
|
||||
LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len);
|
||||
log_dump(NR_MAC, mac_header_control_elements, mac_ce_p->tot_mac_ce_len, LOG_DUMP_CHAR, "\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total);
|
||||
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total);
|
||||
|
||||
// Compute final offset for padding and fill remainder of ULSCH with 0
|
||||
if (buflen_remain > 0) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s filling remainder %d bytes to the UL PDU \n", __FUNCTION__, buflen_remain);
|
||||
((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING;
|
||||
|
||||
|
||||
@@ -261,6 +261,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
|
||||
else
|
||||
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
|
||||
int bwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
|
||||
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
|
||||
if ( get_nr_prach_info_from_index(config_index,
|
||||
@@ -387,7 +389,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
|
||||
const int16_t N_RA_RB = get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, mu_pusch);
|
||||
uint16_t *vrb_map_UL = &cc->vrb_map_UL[slotP * MAX_BWP_SIZE];
|
||||
for (int i = 0; i < N_RA_RB * fdm; ++i)
|
||||
vrb_map_UL[rach_ConfigGeneric->msg1_FrequencyStart + i] = 0xff; // all symbols
|
||||
vrb_map_UL[bwp_start + rach_ConfigGeneric->msg1_FrequencyStart + i] = 0xff; // all symbols
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -772,7 +774,6 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
|
||||
// generation of DCI 0_0 to schedule msg3 retransmission
|
||||
NR_SearchSpace_t *ss = ra->ra_ss;
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = *ss->controlResourceSetId==0 ? &nr_mac->type0_PDCCH_CSS_config[ra->beam_id] : NULL;
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(module_idP, scc, NULL, ss, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n");
|
||||
|
||||
@@ -787,7 +788,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
ul_dci_req->numPdus += 1;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, type0_PDCCH_CSS_config);
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
@@ -917,10 +918,19 @@ void nr_get_Msg3alloc(module_id_t module_id,
|
||||
LOG_D(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
|
||||
const uint16_t bwpSize = NRRIV2BW(ubwp ?
|
||||
ubwp->bwp_Common->genericParameters.locationAndBandwidth :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
|
||||
int bwpSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int bwpStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
if (ra->CellGroup) {
|
||||
AssertFatal(ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n", ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
|
||||
NR_BWP_Uplink_t *ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
|
||||
int act_bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int act_bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
if (!((bwpStart >= act_bwp_start) && ((bwpStart+bwpSize) <= (act_bwp_start+act_bwp_size))))
|
||||
bwpStart = act_bwp_start;
|
||||
}
|
||||
|
||||
/* search msg3_nb_rb free RBs */
|
||||
int rbSize = 0;
|
||||
@@ -928,16 +938,17 @@ void nr_get_Msg3alloc(module_id_t module_id,
|
||||
while (rbSize < msg3_nb_rb) {
|
||||
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
||||
rbSize = 0;
|
||||
while (rbStart < bwpSize && vrb_map_UL[rbStart])
|
||||
while (rbStart < bwpSize && vrb_map_UL[rbStart + bwpStart])
|
||||
rbStart++;
|
||||
AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n");
|
||||
while (rbStart + rbSize < bwpSize
|
||||
&& !vrb_map_UL[rbStart + rbSize]
|
||||
&& !vrb_map_UL[rbStart + bwpStart + rbSize]
|
||||
&& rbSize < msg3_nb_rb)
|
||||
rbSize++;
|
||||
}
|
||||
ra->msg3_nb_rb = msg3_nb_rb;
|
||||
ra->msg3_first_rb = rbStart;
|
||||
ra->msg3_bwp_start = bwpStart;
|
||||
}
|
||||
|
||||
|
||||
@@ -1023,12 +1034,12 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
|
||||
for (int i = 0; i < ra->msg3_nb_rb; ++i) {
|
||||
AssertFatal(!vrb_map_UL[i + ra->msg3_first_rb],
|
||||
AssertFatal(!vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start],
|
||||
"RB %d in %4d.%2d is already taken, cannot allocate Msg3!\n",
|
||||
i + ra->msg3_first_rb,
|
||||
ra->Msg3_frame,
|
||||
ra->Msg3_slot);
|
||||
vrb_map_UL[i + ra->msg3_first_rb] = 1;
|
||||
vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start] = 1;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Slot %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
|
||||
@@ -1047,9 +1058,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
|
||||
|
||||
int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int abwp_size = ibwp_size;
|
||||
int abwp_start = ibwp_start;
|
||||
int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||
int fh = 0;
|
||||
int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
|
||||
@@ -1062,8 +1070,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
|
||||
startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
|
||||
mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType;
|
||||
abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
fh = ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping ? 1 : 0;
|
||||
}
|
||||
@@ -1078,17 +1084,11 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
ra->msg3_round,
|
||||
ra->rnti);
|
||||
|
||||
int bwp_start;
|
||||
if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
|
||||
bwp_start = abwp_start;
|
||||
else
|
||||
bwp_start = ibwp_start;
|
||||
|
||||
fill_msg3_pusch_pdu(pusch_pdu,scc,
|
||||
ra->msg3_round,
|
||||
startSymbolAndLength,
|
||||
ra->rnti, scs,
|
||||
ibwp_size, bwp_start,
|
||||
ibwp_size, ra->msg3_bwp_start,
|
||||
mappingtype, fh,
|
||||
ra->msg3_first_rb, ra->msg3_nb_rb);
|
||||
future_ul_tti_req->n_pdus += 1;
|
||||
@@ -1150,7 +1150,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
uint16_t *vrb_map = cc[CC_id].vrb_map;
|
||||
for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
|
||||
if (vrb_map[rbStart + i]) {
|
||||
if (vrb_map[BWPStart + rbStart + i]) {
|
||||
rbStart += i;
|
||||
i = 0;
|
||||
}
|
||||
@@ -1204,7 +1204,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, type0_PDCCH_CSS_config);
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
@@ -1364,7 +1364,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
for (int rb = 0; rb < rbSize; rb++) {
|
||||
vrb_map[rb + rbStart] = 1;
|
||||
vrb_map[BWPStart + rb + rbStart] = 1;
|
||||
}
|
||||
|
||||
ra->state = WAIT_Msg3;
|
||||
@@ -1547,7 +1547,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
int i = 0;
|
||||
while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) {
|
||||
if (vrb_map[rbStart + i]) {
|
||||
if (vrb_map[BWPStart + rbStart + i]) {
|
||||
rbStart += i+1;
|
||||
i = 0;
|
||||
} else {
|
||||
@@ -1580,7 +1580,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, type0_PDCCH_CSS_config);
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
@@ -1723,7 +1723,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) {
|
||||
vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
|
||||
vrb_map[BWPStart + rb + pdsch_pdu_rel15->rbStart] = 1;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
|
||||
|
||||
@@ -339,6 +339,8 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset));
|
||||
fill_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space,type0_PDCCH_CSS_config);
|
||||
fill_coresetZero(gNB_mac->sched_ctrlCommon->coreset,type0_PDCCH_CSS_config);
|
||||
gNB_mac->cset0_bwp_start = type0_PDCCH_CSS_config->cset_start_rb;
|
||||
gNB_mac->cset0_bwp_size = type0_PDCCH_CSS_config->num_rbs;
|
||||
}
|
||||
|
||||
gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation;
|
||||
@@ -436,7 +438,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15,
|
||||
nr_configure_pdcch(NULL,
|
||||
pdcch_pdu_rel15,
|
||||
gNB_mac->sched_ctrlCommon->search_space,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
scc,
|
||||
|
||||
@@ -548,7 +548,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
&RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
const long f = (sched_ctrl->active_bwp ||bwpd) ? sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0;
|
||||
@@ -738,7 +738,7 @@ void pf_dl(module_id_t module_id,
|
||||
&scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
int rbStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
/* Find a free CCE */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
@@ -827,6 +827,10 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const uint16_t BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp ?
|
||||
sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
uint8_t rballoc_mask[bwpSize];
|
||||
@@ -834,7 +838,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
// calculate mask: init with "NOT" vrb_map:
|
||||
// if any RB in vrb_map is blocked (1), the current RBG will be 0
|
||||
rballoc_mask[i] = !vrb_map[i];
|
||||
rballoc_mask[i] = !vrb_map[i+BWPStart];
|
||||
n_rb_sched += rballoc_mask[i];
|
||||
}
|
||||
|
||||
@@ -1001,7 +1005,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %d, bwp %d, cs %d\n",UE_id,bwpid,coresetid);
|
||||
NR_SearchSpace_t *ss = (bwp||bwpd) ? sched_ctrl->search_space:gNB_mac->sched_ctrlCommon->search_space;
|
||||
NR_ControlResourceSet_t *coreset = (bwp||bwpd)? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset;
|
||||
nr_configure_pdcch(pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_configure_pdcch(gNB_mac, pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu;
|
||||
}
|
||||
|
||||
|
||||
@@ -280,6 +280,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
/* find largest unallocated chunk */
|
||||
const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = 0;
|
||||
int rbSize = 0;
|
||||
if (target_dl_bw>bwpSize)
|
||||
@@ -288,11 +289,11 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
/* loop ensures that we allocate exactly target_dl_bw, or return */
|
||||
while (true) {
|
||||
/* advance to first free RB */
|
||||
while (rbStart < bwpSize && vrb_map[rbStart])
|
||||
while (rbStart < bwpSize && vrb_map[rbStart + BWPStart])
|
||||
rbStart++;
|
||||
rbSize = 1;
|
||||
/* iterate until we are at target_dl_bw or no available RBs */
|
||||
while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && rbSize < target_dl_bw)
|
||||
while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize + BWPStart] && rbSize < target_dl_bw)
|
||||
rbSize++;
|
||||
/* found target_dl_bw? */
|
||||
if (rbSize == target_dl_bw)
|
||||
@@ -397,7 +398,7 @@ 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;
|
||||
vrb_map[rb + sched_pdsch->rbStart + BWPStart] = 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);
|
||||
}
|
||||
@@ -459,8 +460,11 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
uint16_t rbSize;
|
||||
|
||||
const int bw = NRRIV2BW(sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
if (target_ul_bw>bw)
|
||||
rbSize = bw;
|
||||
@@ -471,7 +475,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
|
||||
const uint16_t symb = ((1 << ps->nrOfSymbols) - 1) << ps->startSymbolIndex;
|
||||
for (int i = rbStart; i < rbStart + rbSize; ++i) {
|
||||
if ((vrb_map_UL[i] & symb) != 0) {
|
||||
if ((vrb_map_UL[i+BWPStart] & symb) != 0) {
|
||||
LOG_E(MAC,
|
||||
"%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n",
|
||||
__func__,
|
||||
@@ -540,6 +544,6 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = rbStart; rb < rbStart + rbSize; rb++)
|
||||
vrb_map_UL[rb] = 1;
|
||||
vrb_map_UL[rb+BWPStart] = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -723,7 +723,8 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) {
|
||||
return(default_pucch_csset[pucch_ResourceCommon]);
|
||||
}
|
||||
|
||||
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
void nr_configure_pdcch(gNB_MAC_INST *gNB_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
@@ -731,9 +732,19 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) {
|
||||
|
||||
int sps;
|
||||
if (bwp && *ss->controlResourceSetId!=0) { // This is not for coreset0
|
||||
pdcch_pdu->BWPSize = NRRIV2BW(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
AssertFatal(*ss->controlResourceSetId == coreset->controlResourceSetId,
|
||||
"coreset id in SS %ld does not correspond to the one in coreset %ld",
|
||||
*ss->controlResourceSetId, coreset->controlResourceSetId);
|
||||
|
||||
if (bwp) { // This is not for SIB1
|
||||
if(coreset->controlResourceSetId == 0){
|
||||
pdcch_pdu->BWPSize = gNB_mac->cset0_bwp_size;
|
||||
pdcch_pdu->BWPStart = gNB_mac->cset0_bwp_start;
|
||||
}
|
||||
else {
|
||||
pdcch_pdu->BWPSize = NRRIV2BW(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
}
|
||||
pdcch_pdu->SubcarrierSpacing = bwp->subcarrierSpacing;
|
||||
pdcch_pdu->CyclicPrefix = (bwp->cyclicPrefix==NULL) ? 0 : *bwp->cyclicPrefix;
|
||||
|
||||
@@ -2257,20 +2268,20 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
csirs_pdu_rel15->row = 1;
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
|
||||
csirs_pdu_rel15->row = 2;
|
||||
csirs_pdu_rel15->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) |
|
||||
((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<8)&0xff0));
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4:
|
||||
csirs_pdu_rel15->row = 4;
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other:
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f;
|
||||
@@ -2281,18 +2292,18 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p2:
|
||||
csirs_pdu_rel15->row = 3;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p4:
|
||||
csirs_pdu_rel15->row = 5;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p8:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 8;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
}
|
||||
else{
|
||||
int num_k = 0;
|
||||
@@ -2301,12 +2312,12 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
if(num_k==4) {
|
||||
csirs_pdu_rel15->row = 6;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 7;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2314,12 +2325,12 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 10;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 9;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0);
|
||||
}
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p16:
|
||||
@@ -2328,24 +2339,24 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
else
|
||||
csirs_pdu_rel15->row = 11;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0));
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p24:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 14;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
}
|
||||
else{
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
|
||||
csirs_pdu_rel15->row = 15;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 13;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2353,18 +2364,18 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 17;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
}
|
||||
else{
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
|
||||
csirs_pdu_rel15->row = 18;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (7 << csirs_pdu_rel15->symb_l0);
|
||||
}
|
||||
else {
|
||||
csirs_pdu_rel15->row = 16;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -294,6 +294,7 @@ uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
@@ -520,6 +521,11 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
curr_pucch->csi_bits +=
|
||||
nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id);
|
||||
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ?
|
||||
&sched_ctrl->active_ubwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
|
||||
// going through the list of PUCCH resources to find the one indexed by resource_id
|
||||
uint16_t *vrb_map_UL = &RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
|
||||
const int m = pucch_Config->resourceToAddModList->list.count;
|
||||
@@ -550,7 +556,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
}
|
||||
// verify resources are free
|
||||
for (int i = start; i < start + len; ++i) {
|
||||
vrb_map_UL[i] |= mask;
|
||||
vrb_map_UL[i+bwp_start] |= mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1390,18 +1396,32 @@ int nr_acknack_scheduling(int mod_id,
|
||||
pucch_Config = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||
}
|
||||
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ?
|
||||
&sched_ctrl->active_ubwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
|
||||
/* verify that at that slot and symbol, resources are free. We only do this
|
||||
* for initialCyclicShift 0 (we assume it always has that one), so other
|
||||
* initialCyclicShifts can overlap with ICS 0!*/
|
||||
if (pucch_Config) {
|
||||
const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator];
|
||||
DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0);
|
||||
int second_hop_prb = resource->secondHopPRB!= NULL ? *resource->secondHopPRB : 0;
|
||||
int nr_of_symbols = resource->format.choice.format0->nrofSymbols;
|
||||
if (resource->format.choice.format0->initialCyclicShift == 0) {
|
||||
uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE];
|
||||
const uint16_t symb = 1 << resource->format.choice.format0->startingSymbolIndex;
|
||||
if ((vrb_map_UL[resource->startingPRB] & symb) != 0)
|
||||
LOG_W(NR_MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot);
|
||||
vrb_map_UL[resource->startingPRB] |= symb;
|
||||
for (int l=0; l<nr_of_symbols; l++) {
|
||||
uint16_t symb = 1 << (resource->format.choice.format0->startingSymbolIndex + l);
|
||||
int prb;
|
||||
if (l==1 && second_hop_prb != 0)
|
||||
prb = second_hop_prb;
|
||||
else
|
||||
prb = resource->startingPRB;
|
||||
if ((vrb_map_UL[bwp_start+prb] & symb) != 0)
|
||||
LOG_W(MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot);
|
||||
vrb_map_UL[bwp_start+prb] |= symb;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -34,34 +34,7 @@
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include <openair2/UTIL/OPT/opt.h>
|
||||
|
||||
|
||||
//38.321 Table 6.1.3.1-1
|
||||
const uint32_t NR_SHORT_BSR_TABLE[32] = {
|
||||
0, 10, 14, 20, 28, 38, 53, 74,
|
||||
102, 142, 198, 276, 384, 535, 745, 1038,
|
||||
1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726,
|
||||
20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000
|
||||
};
|
||||
|
||||
//38.321 Table 6.1.3.1-2
|
||||
const uint32_t NR_LONG_BSR_TABLE[256] ={
|
||||
0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
|
||||
28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71,
|
||||
75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193,
|
||||
205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526,
|
||||
560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439,
|
||||
1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934,
|
||||
4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760,
|
||||
11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431,
|
||||
31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505,
|
||||
85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209,
|
||||
234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350,
|
||||
641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644,
|
||||
1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902,
|
||||
4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006,
|
||||
13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553,
|
||||
35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295
|
||||
};
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
|
||||
int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
|
||||
@@ -896,7 +869,7 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
|
||||
* (2) there is a scheduling request
|
||||
* (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;
|
||||
const bool high_inactivity = diff >= nrmac->ulsch_max_frame_inactivity * n;
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
|
||||
frame,
|
||||
@@ -930,7 +903,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL;
|
||||
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;
|
||||
int rbStart = 0; // wrt BWP start
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2;
|
||||
@@ -1066,10 +1039,10 @@ void pf_ul(module_id_t module_id,
|
||||
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %d\n",UE_id);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
int rbStart = 0; // wrt BWP start
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0;
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
|
||||
@@ -1320,6 +1293,10 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const uint16_t bwpStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
|
||||
MAX_BWP_SIZE);
|
||||
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
@@ -1333,10 +1310,10 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
if (RC.nrmac[module_id]->ulprbbl[i] == 1) vrb_map_UL[i]=symb;
|
||||
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
while ((vrb_map_UL[i] & symb) != 0 && i < bwpSize)
|
||||
while ((vrb_map_UL[bwpStart + i] & symb) != 0 && i < bwpSize)
|
||||
i++;
|
||||
st = i;
|
||||
while ((vrb_map_UL[i] & symb) == 0 && i < bwpSize)
|
||||
while ((vrb_map_UL[bwpStart + i] & symb) == 0 && i < bwpSize)
|
||||
i++;
|
||||
if (i - st > len) {
|
||||
len = i - st;
|
||||
@@ -1659,7 +1636,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
ul_dci_req->numPdus += 1;
|
||||
nr_configure_pdcch(pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu, ss, coreset, scc, genericParameters, NULL);
|
||||
pdcch_pdu_bwp_coreset[bwpid][coresetid] = pdcch_pdu;
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +248,8 @@ void find_search_space(int ss_type,
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_SearchSpace_t *ss);
|
||||
|
||||
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
void nr_configure_pdcch(gNB_MAC_INST *gNB_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
|
||||
@@ -145,6 +145,8 @@ typedef struct {
|
||||
uint8_t msg3_first_rb;
|
||||
/// Msg3 number of RB
|
||||
uint8_t msg3_nb_rb;
|
||||
/// Msg3 BWP start
|
||||
uint8_t msg3_bwp_start;
|
||||
/// Msg3 TPC command
|
||||
uint8_t msg3_TPC;
|
||||
/// Msg3 ULdelay command
|
||||
@@ -758,7 +760,7 @@ typedef struct gNB_MAC_INST_s {
|
||||
int *preferred_ul_tda[MAX_NUM_BWP];
|
||||
|
||||
/// maximum number of slots before a UE will be scheduled ULSCH automatically
|
||||
uint32_t ulsch_max_slots_inactivity;
|
||||
uint32_t ulsch_max_frame_inactivity;
|
||||
|
||||
/// DL preprocessor for differentiated scheduling
|
||||
nr_pp_impl_dl pre_processor_dl;
|
||||
@@ -766,6 +768,8 @@ typedef struct gNB_MAC_INST_s {
|
||||
nr_pp_impl_ul pre_processor_ul;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrlCommon;
|
||||
uint16_t cset0_bwp_start;
|
||||
uint16_t cset0_bwp_size;
|
||||
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
|
||||
|
||||
bool first_MIB;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "pdcp.h"
|
||||
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h"
|
||||
|
||||
#define TODO do { \
|
||||
printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
|
||||
@@ -447,10 +448,18 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
|
||||
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(entity->has_sdapDLheader){
|
||||
size -= SDAP_HDR_LENGTH;
|
||||
len = write(nas_sock_fd[0], &buf[SDAP_HDR_LENGTH], size);
|
||||
} else {
|
||||
len = write(nas_sock_fd[0], buf, size);
|
||||
}
|
||||
|
||||
if (len != size) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
for (i = 0; i < 5; i++) {
|
||||
@@ -480,7 +489,10 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id = entity->pdusession_id;
|
||||
if (offset==1) LOG_D(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
|
||||
if (offset==1) {
|
||||
LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
|
||||
sdap_gnb_ul_header_handler(buf[0]); // Handler for the UL gNB SDAP Header
|
||||
}
|
||||
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size-offset);
|
||||
itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p);
|
||||
}
|
||||
@@ -828,10 +840,6 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
|
||||
has_sdap = 1;
|
||||
has_sdapULheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present ? 1 : 0;
|
||||
has_sdapDLheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present ? 1 : 0;
|
||||
if (has_sdapDLheader==1) {
|
||||
LOG_E(PDCP,"%s:%d:%s: fatal, no support for SDAP DL yet\n",__FILE__,__LINE__,__FUNCTION__);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
/* TODO(?): accept different UL and DL SN sizes? */
|
||||
if (sn_size_ul != sn_size_dl) {
|
||||
@@ -903,9 +911,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list)
|
||||
//struct NR_RLC_Config *rlc_Config)
|
||||
@@ -975,9 +981,7 @@ boolean_t rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCenc,
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB)
|
||||
{
|
||||
return 0;
|
||||
@@ -1240,10 +1244,8 @@ boolean_t pdcp_data_req(
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t mode
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
,const uint32_t *const sourceL2Id
|
||||
,const uint32_t *const destinationL2Id
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (srb_flagP) {
|
||||
|
||||
@@ -270,7 +270,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
|
||||
+ buf_stat.retx_size
|
||||
+ buf_stat.tx_size;
|
||||
} else {
|
||||
if (!(frameP%128)) //to supress this warning message
|
||||
if (!(frameP%128)) //to suppress this warning message
|
||||
LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
|
||||
ret.bytes_in_buffer = 0;
|
||||
}
|
||||
@@ -334,6 +334,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
|
||||
+ buf_stat.retx_size
|
||||
+ buf_stat.tx_size;
|
||||
} else {
|
||||
if (!(frameP%128)) //to suppress this warning message
|
||||
LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
@@ -953,16 +955,16 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt
|
||||
if ((drb2add_listP != NULL) && (rlc_bearer2add_list != NULL)) {
|
||||
for (i = 0; i < drb2add_listP->list.count; i++) {
|
||||
if (rlc_bearer2add_list != NULL) {
|
||||
for(j = 0; j < rlc_bearer2add_list->list.count; j++){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
|
||||
if(drb2add_listP->list.array[i]->drb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
|
||||
add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]);
|
||||
for(j = 0; j < rlc_bearer2add_list->list.count; j++){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
|
||||
if(drb2add_listP->list.array[i]->drb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
|
||||
add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3618,9 +3618,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
, (LTE_PMCH_InfoList_r9_t *) NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
/* Refresh SRBs/DRBs */
|
||||
@@ -3629,11 +3627,9 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
*SRB_configList2, // NULL,
|
||||
*DRB_configList,
|
||||
NULL
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
, (LTE_PMCH_InfoList_r9_t *) NULL,
|
||||
0,
|
||||
0
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6331,9 +6327,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
, (LTE_PMCH_InfoList_r9_t *) NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
/* Refresh SRBs/DRBs */
|
||||
@@ -6342,11 +6336,9 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
|
||||
*SRB_configList2, // NULL,
|
||||
*DRB_configList,
|
||||
NULL
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
, (LTE_PMCH_InfoList_r9_t *) NULL,
|
||||
0,
|
||||
0
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1182,9 +1182,9 @@ void fill_initial_SpCellConfig(rnti_t rnti,
|
||||
AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30,
|
||||
"SCS != 30kHz\n");
|
||||
AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5,
|
||||
"TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
|
||||
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8+(10*((rnti>>1)&3)) + (rnti&1);
|
||||
"TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
|
||||
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8 + 10*((rnti>>1)&3) + (rnti&1);
|
||||
schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
|
||||
*schedulingRequestResourceConfig->resource = 0;
|
||||
ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
|
||||
|
||||
@@ -106,9 +106,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
|
||||
|
||||
@@ -1010,7 +1008,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
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->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||
sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_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));
|
||||
@@ -1305,51 +1303,22 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
||||
|
||||
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
|
||||
|
||||
#ifndef PHYSIM
|
||||
uint8_t *k_kdf = NULL;
|
||||
/* Derive the keys from kgnb */
|
||||
if (DRB_configList != NULL) {
|
||||
k_kdf = NULL;
|
||||
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
|
||||
k_kdf = NULL;
|
||||
&kUPenc);
|
||||
nr_derive_key_up_int(ue_context_pP->ue_context.integrity_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kUPint: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPint = malloc(16);
|
||||
if (kUPint == NULL) exit(1);
|
||||
memcpy(kUPint, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
&kUPint);
|
||||
}
|
||||
|
||||
k_kdf = NULL;
|
||||
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kRRCenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kRRCenc = malloc(16);
|
||||
if (kRRCenc == NULL) exit(1);
|
||||
memcpy(kRRCenc, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
|
||||
k_kdf = NULL;
|
||||
&kRRCenc);
|
||||
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kRRCint: last 128 bits of key derivation function which returns 256 bits */
|
||||
kRRCint = malloc(16);
|
||||
if (kRRCint == NULL) exit(1);
|
||||
memcpy(kRRCint, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
#endif
|
||||
&kRRCint);
|
||||
/* Refresh SRBs/DRBs */
|
||||
MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)",
|
||||
MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
|
||||
@@ -308,43 +308,19 @@ nr_rrc_pdcp_config_security(
|
||||
uint8_t *kUPenc = NULL;
|
||||
static int print_keys= 1;
|
||||
|
||||
#ifndef PHYSIM
|
||||
|
||||
uint8_t *k_kdf = NULL;
|
||||
|
||||
/* Derive the keys from kgnb */
|
||||
if (SRB_configList != NULL) {
|
||||
k_kdf = NULL;
|
||||
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
&kUPenc);
|
||||
}
|
||||
|
||||
k_kdf = NULL;
|
||||
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kRRCenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kRRCenc = malloc(16);
|
||||
if (kRRCenc == NULL) exit(1);
|
||||
memcpy(kRRCenc, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
|
||||
k_kdf = NULL;
|
||||
&kRRCenc);
|
||||
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
|
||||
ue_context_pP->ue_context.kgnb,
|
||||
&k_kdf);
|
||||
/* kRRCint: last 128 bits of key derivation function which returns 256 bits */
|
||||
kRRCint = malloc(16);
|
||||
if (kRRCint == NULL) exit(1);
|
||||
memcpy(kRRCint, k_kdf+16, 16);
|
||||
free(k_kdf);
|
||||
#endif
|
||||
&kRRCint);
|
||||
if (!IS_SOFTMODEM_IQPLAYER) {
|
||||
SET_LOG_DUMP(DEBUG_SECURITY) ;
|
||||
}
|
||||
|
||||
@@ -52,9 +52,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
|
||||
|
||||
@@ -215,25 +213,12 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm);
|
||||
|
||||
/* derive UP security key */
|
||||
unsigned char *kUPenc_kdf;
|
||||
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPenc_kdf);
|
||||
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, kUPenc_kdf+16, 16);
|
||||
free(kUPenc_kdf);
|
||||
|
||||
unsigned char *kUPint_kdf;
|
||||
&kUPenc);
|
||||
nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPint_kdf);
|
||||
/* kUPint: last 128 bits of key derivation function which returns 256 bits */
|
||||
kUPint = malloc(16);
|
||||
if (kUPint == NULL) exit(1);
|
||||
memcpy(kUPint, kUPint_kdf+16, 16);
|
||||
free(kUPint_kdf);
|
||||
&kUPint);
|
||||
|
||||
e_NR_CipheringAlgorithm cipher_algo;
|
||||
switch (ue_context_p->ue_context.ciphering_algorithm) {
|
||||
|
||||
+85
-63
@@ -187,9 +187,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
|
||||
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
|
||||
#endif
|
||||
,rb_id_t *const defaultDRB,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
|
||||
|
||||
@@ -1661,45 +1659,40 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
|
||||
uint8_t *kRRCenc = NULL;
|
||||
uint8_t *kUPenc = NULL;
|
||||
uint8_t *kRRCint = NULL;
|
||||
pdcp_t *pdcp_p = NULL;
|
||||
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
|
||||
hashtable_rc_t h_rc;
|
||||
key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES);
|
||||
h_rc = hashtable_get(pdcp_coll_p, key, (void **) &pdcp_p);
|
||||
nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
|
||||
&kUPenc);
|
||||
nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
|
||||
&kRRCenc);
|
||||
nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
|
||||
&kRRCint);
|
||||
LOG_I(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB="
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x\n",
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]);
|
||||
|
||||
if (h_rc == HASH_TABLE_OK) {
|
||||
LOG_D(NR_RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key);
|
||||
LOG_D(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB="
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x\n",
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27],
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]);
|
||||
derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
|
||||
derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
|
||||
derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
|
||||
|
||||
if (securityMode != 0xff) {
|
||||
pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm
|
||||
| (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
|
||||
kRRCenc, kRRCint, kUPenc);
|
||||
} else {
|
||||
LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
|
||||
}
|
||||
if (securityMode != 0xff) {
|
||||
pdcp_config_set_security(ctxt_pP, NULL, DCCH, DCCH+2,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm
|
||||
| (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
|
||||
kRRCenc, kRRCint, kUPenc);
|
||||
} else {
|
||||
LOG_I(NR_RRC, "Could not get PDCP instance where key=0x%ld\n", key);
|
||||
LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
|
||||
}
|
||||
|
||||
if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) {
|
||||
@@ -2044,21 +2037,12 @@ nr_rrc_ue_establish_srb2(
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *k_kdf = NULL;
|
||||
uint8_t *kRRCenc = NULL;
|
||||
uint8_t *kRRCint = NULL;
|
||||
nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
|
||||
kRRCenc = malloc(16);
|
||||
if (kRRCenc == NULL) exit(1);
|
||||
memcpy(kRRCenc, k_kdf + 16, 16);
|
||||
free(k_kdf);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
|
||||
nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
|
||||
kRRCint = malloc(16);
|
||||
if (kRRCint == NULL) exit(1);
|
||||
memcpy(kRRCint, k_kdf + 16, 16);
|
||||
free(k_kdf);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
|
||||
|
||||
// Refresh SRBs
|
||||
nr_rrc_pdcp_config_asn1_req(ctxt_pP,
|
||||
@@ -2100,6 +2084,7 @@ nr_rrc_ue_establish_srb2(
|
||||
|
||||
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n",
|
||||
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
|
||||
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,1,true); //todo handle mac_LogicalChannelConfig
|
||||
// rrc_mac_config_req_ue
|
||||
}
|
||||
} else {
|
||||
@@ -2115,6 +2100,7 @@ nr_rrc_ue_establish_srb2(
|
||||
|
||||
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n",
|
||||
ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
|
||||
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,2,true); //todo handle mac_LogicalChannelConfig
|
||||
// rrc_mac_config_req_ue
|
||||
}
|
||||
} // srb2
|
||||
@@ -2135,28 +2121,33 @@ nr_rrc_ue_establish_srb2(
|
||||
memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1],
|
||||
radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t));
|
||||
} else {
|
||||
LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]);
|
||||
//LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt];
|
||||
int j;
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list = NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList;
|
||||
if (rlc_bearer2add_list != NULL) {
|
||||
for(j = 0; j < rlc_bearer2add_list->list.count; j++){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
|
||||
if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
|
||||
if(DRB_id == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
|
||||
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB lcid %ld gNB %d) --->][MAC_UE][MOD %02d][]\n",
|
||||
ctxt_pP->frame, ctxt_pP->module_id, rlc_bearer2add_list->list.array[j]->logicalChannelIdentity, 0, ctxt_pP->module_id);
|
||||
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,rlc_bearer2add_list->list.array[j]->logicalChannelIdentity,true); //todo handle mac_LogicalChannelConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *k_kdf = NULL;
|
||||
uint8_t *kUPenc = NULL;
|
||||
uint8_t *kUPint = NULL;
|
||||
|
||||
nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
|
||||
kUPenc = malloc(16);
|
||||
if (kUPenc == NULL) exit(1);
|
||||
memcpy(kUPenc, k_kdf + 16, 16);
|
||||
free(k_kdf);
|
||||
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);
|
||||
nr_derive_key_up_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
|
||||
kUPint = malloc(16);
|
||||
if (kUPint == NULL) exit(1);
|
||||
memcpy(kUPint, k_kdf + 16, 16);
|
||||
free(k_kdf);
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPint);
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_RRC_UE,
|
||||
@@ -2199,6 +2190,15 @@ nr_rrc_ue_establish_srb2(
|
||||
}
|
||||
}
|
||||
|
||||
if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList != NULL) {
|
||||
for (i = 0; i < NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.count; i++) {
|
||||
NR_LogicalChannelIdentity_t lcid = *NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.array[i];
|
||||
LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (RB lcid %ld gNB %d release) --->][MAC_UE][MOD %02d][]\n",
|
||||
ctxt_pP->frame, ctxt_pP->module_id, lcid, 0, ctxt_pP->module_id);
|
||||
nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,lcid,false); //todo handle mac_LogicalChannelConfig
|
||||
}
|
||||
}
|
||||
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED;
|
||||
LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index);
|
||||
}
|
||||
@@ -2511,6 +2511,28 @@ nr_rrc_ue_establish_srb2(
|
||||
NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
|
||||
break;
|
||||
|
||||
case NAS_KENB_REFRESH_REQ:
|
||||
memcpy((void *)NR_UE_rrc_inst[ue_mod_id].kgnb, (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(NR_UE_rrc_inst[ue_mod_id].kgnb));
|
||||
LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KgNB = "
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x\n",
|
||||
ue_mod_id, ITTI_MSG_NAME (msg_p),
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[0], NR_UE_rrc_inst[ue_mod_id].kgnb[1], NR_UE_rrc_inst[ue_mod_id].kgnb[2], NR_UE_rrc_inst[ue_mod_id].kgnb[3],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[4], NR_UE_rrc_inst[ue_mod_id].kgnb[5], NR_UE_rrc_inst[ue_mod_id].kgnb[6], NR_UE_rrc_inst[ue_mod_id].kgnb[7],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[8], NR_UE_rrc_inst[ue_mod_id].kgnb[9], NR_UE_rrc_inst[ue_mod_id].kgnb[10], NR_UE_rrc_inst[ue_mod_id].kgnb[11],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[12], NR_UE_rrc_inst[ue_mod_id].kgnb[13], NR_UE_rrc_inst[ue_mod_id].kgnb[14], NR_UE_rrc_inst[ue_mod_id].kgnb[15],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[16], NR_UE_rrc_inst[ue_mod_id].kgnb[17], NR_UE_rrc_inst[ue_mod_id].kgnb[18], NR_UE_rrc_inst[ue_mod_id].kgnb[19],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[20], NR_UE_rrc_inst[ue_mod_id].kgnb[21], NR_UE_rrc_inst[ue_mod_id].kgnb[22], NR_UE_rrc_inst[ue_mod_id].kgnb[23],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[24], NR_UE_rrc_inst[ue_mod_id].kgnb[25], NR_UE_rrc_inst[ue_mod_id].kgnb[26], NR_UE_rrc_inst[ue_mod_id].kgnb[27],
|
||||
NR_UE_rrc_inst[ue_mod_id].kgnb[28], NR_UE_rrc_inst[ue_mod_id].kgnb[29], NR_UE_rrc_inst[ue_mod_id].kgnb[30], NR_UE_rrc_inst[ue_mod_id].kgnb[31]);
|
||||
break;
|
||||
|
||||
case NAS_UPLINK_DATA_REQ: {
|
||||
uint32_t length;
|
||||
uint8_t *buffer;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "nr_sdap_gnb.h"
|
||||
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
|
||||
|
||||
boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id
|
||||
) {
|
||||
if(sdu_buffer == NULL) {
|
||||
LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(sdu_buffer_size == 0) {
|
||||
LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL or 0 sdu_buffer_size \n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uint8_t *sdap_buf = (uint8_t *)malloc(sdu_buffer_size+SDAP_HDR_LENGTH);
|
||||
nr_sdap_dl_hdr_t sdap_hdr;
|
||||
sdap_hdr.RDI = 0; // SDAP_Hardcoded -
|
||||
sdap_hdr.RQI = 0; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION
|
||||
sdap_hdr.QFI = 1; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION
|
||||
memcpy(&sdap_buf[0], &sdap_hdr, 1);
|
||||
memcpy(&sdap_buf[1], sdu_buffer, sdu_buffer_size);
|
||||
rb_id_t sdap_drb_id = rb_id; // SDAP_Hardcoded - Should get this info from QFI to DRB mapping table
|
||||
boolean_t ret = pdcp_data_req(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size+1,
|
||||
sdap_buf,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id);
|
||||
|
||||
if(!ret) {
|
||||
LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - PDCP DL refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
free(sdap_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(sdap_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr) {
|
||||
nr_sdap_ul_hdr_t *sdap_hdr_ul = (nr_sdap_ul_hdr_t *)&sdap_gnb_ul_hdr;
|
||||
|
||||
switch (sdap_hdr_ul->DC) {
|
||||
case SDAP_HDR_UL_DATA_PDU:
|
||||
LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - UL Received SDAP Data PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
break;
|
||||
|
||||
case SDAP_HDR_UL_CTRL_PDU:
|
||||
LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - Received SDAP Control PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _NR_SDAP_GNB_
|
||||
#define _NR_SDAP_GNB_
|
||||
|
||||
#include "openair2/COMMON/platform_types.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#define SDAP_BITMASK_DC (0x80)
|
||||
#define SDAP_BITMASK_R (0x40)
|
||||
#define SDAP_BITMASK_QFI (0x3F)
|
||||
#define SDAP_HDR_UL_DATA_PDU (1)
|
||||
#define SDAP_HDR_UL_CTRL_PDU (0)
|
||||
#define SDAP_HDR_LENGTH (1)
|
||||
|
||||
typedef struct nr_sdap_dl_hdr_s {
|
||||
uint8_t QFI:6;
|
||||
uint8_t RQI:1;
|
||||
uint8_t RDI:1;
|
||||
} __attribute__((packed)) nr_sdap_dl_hdr_t;
|
||||
|
||||
typedef struct nr_sdap_ul_hdr_s {
|
||||
uint8_t QFI:6;
|
||||
uint8_t R:1;
|
||||
uint8_t DC:1;
|
||||
} __attribute__((packed)) nr_sdap_ul_hdr_t;
|
||||
|
||||
boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t mui,
|
||||
const confirm_t confirm,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t pt_mode,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id
|
||||
);
|
||||
|
||||
void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr);
|
||||
|
||||
#endif
|
||||
@@ -121,6 +121,8 @@ int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
|
||||
string[6] = 0x01;
|
||||
|
||||
kdf(string, 7, key, 32, out, 32);
|
||||
// in NR, we use the last 16 bytes, ignoring the first 16 ones
|
||||
memcpy(*out, *out+16, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user