1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
/*
* 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
*/
/*! \file mac.h
* \brief MAC data structures, constant, and function prototype
* \author Navid Nikaein and Raymond Knopp, WIE-TAI CHEN
* \date 2011, 2018
* \version 0.5
* \company Eurecom, NTUST
* \email navid.nikaein@eurecom.fr, kroempa@gmail.com
*/
/** @defgroup _oai2 openair2 Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
/*@}*/
#ifndef __LAYER2_NR_MAC_GNB_H__
#define __LAYER2_NR_MAC_GNB_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Commmon */
#include "targets/ARCH/COMMON/common_lib.h"
#include "COMMON/platform_constants.h"
#include "common/ran_context.h"
/* RRC */
#include "NR_BCCH-BCH-Message.h"
#include "NR_CellGroupConfig.h"
#include "NR_ServingCellConfigCommon.h"
#include "NR_MeasConfig.h"
/* PHY */
#include "PHY/defs_gNB.h"
#include "PHY/TOOLS/time_meas.h"
/* Interface */
#include "nfapi_nr_interface_scf.h"
#include "NR_PHY_INTERFACE/NR_IF_Module.h"
/* MAC */
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "NR_TAG.h"
#include <openair3/UICC/usim_interface.h>
/* Defs */
#define MAX_NUM_BWP 2
#define MAX_NUM_CORESET 2
#define MAX_NUM_CCE 90
/*!\brief Maximum number of random access process */
#define NR_NB_RA_PROC_MAX 4
#define MAX_NUM_OF_SSB 64
typedef enum {
RA_IDLE = 0,
Msg2 = 1,
WAIT_Msg3 = 2,
Msg4 = 3,
WAIT_Msg4_ACK = 4
} RA_gNB_state_t;
typedef struct NR_preamble_ue {
uint8_t num_preambles;
uint8_t *preamble_list;
} NR_preamble_ue_t;
/*! \brief gNB template for the Random access information */
typedef struct {
/// Flag to indicate this process is active
RA_gNB_state_t state;
/// BWP id of RA process
int bwp_id;
/// CORESET0 configured flag
int coreset0_configured;
/// Slot where preamble was received
uint8_t preamble_slot;
/// Subframe where Msg2 is to be sent
uint8_t Msg2_slot;
/// Frame where Msg2 is to be sent
frame_t Msg2_frame;
/// Subframe where Msg3 is to be sent
sub_frame_t Msg3_slot;
/// Frame where Msg3 is to be sent
frame_t Msg3_frame;
/// Msg3 time domain allocation index
uint8_t Msg3_tda_id;
/// Subframe where Msg4 is to be sent
sub_frame_t Msg4_slot;
/// Frame where Msg4 is to be sent
frame_t Msg4_frame;
/// harq_pid used for Msg4 transmission
uint8_t harq_pid;
/// UE RNTI allocated during RAR
rnti_t rnti;
/// RA RNTI allocated from received PRACH
uint16_t RA_rnti;
/// Received preamble_index
uint8_t preamble_index;
/// Received UE Contention Resolution Identifier
uint8_t cont_res_id[6];
/// Timing offset indicated by PHY
int16_t timing_offset;
/// Timeout for RRC connection
int16_t RRC_timer;
/// Msg3 first RB
uint8_t msg3_first_rb;
/// Msg3 number of RB
uint8_t msg3_nb_rb;
/// Msg3 TPC command
uint8_t msg3_TPC;
/// Msg3 ULdelay command
uint8_t msg3_ULdelay;
/// Msg3 cqireq command
uint8_t msg3_cqireq;
/// Round of Msg3 HARQ
uint8_t msg3_round;
/// TBS used for Msg4
int msg4_TBsize;
/// MCS used for Msg4
int msg4_mcs;
/// RA search space
NR_SearchSpace_t *ra_ss;
// Beam index
uint8_t beam_id;
/// secondaryCellGroup for UE in NSA that is to come
NR_CellGroupConfig_t *secondaryCellGroup;
/// Preambles for contention-free access
NR_preamble_ue_t preambles;
/// NSA: the UEs C-RNTI to use
rnti_t crnti;
/// CFRA flag
bool cfra;
} NR_RA_t;
/*! \brief gNB common channels */
typedef struct {
int physCellId;
int p_gNB;
int Ncp;
int nr_band;
lte_frame_type_t frame_type;
uint64_t dl_CarrierFreq;
NR_BCCH_BCH_Message_t *mib;
NR_ServingCellConfigCommon_t *ServingCellConfigCommon;
NR_ARFCN_ValueEUTRA_t ul_CarrierFreq;
long ul_Bandwidth;
/// Outgoing MIB PDU for PHY
MIB_PDU MIB_pdu;
/// Outgoing BCCH pdu for PHY
BCCH_PDU BCCH_pdu;
/// Outgoing BCCH DCI allocation
uint32_t BCCH_alloc_pdu;
/// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu;
/// Outgoing PCCH DCI allocation
uint32_t PCCH_alloc_pdu;
/// Outgoing PCCH pdu for PHY
PCCH_PDU PCCH_pdu;
/// Outgoing RAR pdu for PHY
RAR_PDU RAR_pdu;
/// Template for RA computations
NR_RA_t ra[NR_NB_RA_PROC_MAX];
/// VRB map for common channels
uint16_t vrb_map[275];
/// VRB map for common channels and PUSCH, dynamically allocated because
/// length depends on number of slots and RBs
uint16_t *vrb_map_UL;
/// number of subframe allocation pattern available for MBSFN sync area
uint8_t num_sf_allocation_pattern;
///Number of active SSBs
uint8_t num_active_ssb;
//Total available prach occasions per configuration period
uint32_t total_prach_occasions_per_config_period;
//Total available prach occasions
uint32_t total_prach_occasions;
//Max Association period
uint8_t max_association_period;
//SSB index
uint8_t ssb_index[MAX_NUM_OF_SSB];
} NR_COMMON_channels_t;
// SP ZP CSI-RS Resource Set Activation/Deactivation MAC CE
typedef struct sp_zp_csirs {
bool is_scheduled; //ZP CSI-RS ACT/Deact MAC CE is scheduled
bool act_deact; //Activation/Deactivation indication
uint8_t serv_cell_id; //Identity of Serving cell for which MAC CE applies
uint8_t bwpid; //Downlink BWP id
uint8_t rsc_id; //SP ZP CSI-RS resource set
} sp_zp_csirs_t;
//SP CSI-RS / CSI-IM Resource Set Activation/Deactivation MAC CE
#define MAX_CSI_RESOURCE_SET 64
typedef struct csi_rs_im {
bool is_scheduled;
bool act_deact;
uint8_t serv_cellid;
uint8_t bwp_id;
bool im;
uint8_t csi_im_rsc_id;
uint8_t nzp_csi_rsc_id;
uint8_t nb_tci_resource_set_id;
uint8_t tci_state_id [ MAX_CSI_RESOURCE_SET ];
} csi_rs_im_t;
typedef struct pdcchStateInd {
bool is_scheduled;
uint8_t servingCellId;
uint8_t coresetId;
uint8_t tciStateId;
} pdcchStateInd_t;
typedef struct SPCSIReportingpucch {
bool is_scheduled;
uint8_t servingCellId;
uint8_t bwpId;
bool s0tos3_actDeact[4];
} SPCSIReportingpucch_t;
#define MAX_APERIODIC_TRIGGER_STATES 128 //38.331
typedef struct aperiodicCSI_triggerStateSelection {
bool is_scheduled;
uint8_t servingCellId;
uint8_t bwpId;
uint8_t highestTriggerStateSelected;
bool triggerStateSelection[MAX_APERIODIC_TRIGGER_STATES];
} aperiodicCSI_triggerStateSelection_t;
#define MAX_TCI_STATES 128 //38.331
typedef struct pdschTciStatesActDeact {
bool is_scheduled;
uint8_t servingCellId;
uint8_t bwpId;
uint8_t highestTciStateActivated;
bool tciStateActDeact[MAX_TCI_STATES];
} pdschTciStatesActDeact_t;
typedef struct UE_info {
sp_zp_csirs_t sp_zp_csi_rs;
csi_rs_im_t csi_im;
pdcchStateInd_t pdcch_state_ind;
SPCSIReportingpucch_t SP_CSI_reporting_pucch;
aperiodicCSI_triggerStateSelection_t aperi_CSI_trigger;
pdschTciStatesActDeact_t pdsch_TCI_States_ActDeact;
} NR_UE_mac_ce_ctrl_t;
typedef struct NR_sched_pucch {
int frame;
int ul_slot;
bool sr_flag;
int csi_bits;
bool simultaneous_harqcsi;
uint8_t dai_c;
uint8_t timing_indicator;
uint8_t resource_indicator;
} NR_sched_pucch_t;
/* this struct is a helper: as long as the TDA and DCI format remain the same
* over the same uBWP and search space, there is no need to recalculate all
* S/L, MCS table, or DMRS-related parameters over and over again. Hence, we
* store them in this struct for easy reference. */
typedef struct NR_sched_pusch_save {
int dci_format;
int time_domain_allocation;
uint8_t num_dmrs_cdm_grps_no_data;
int startSymbolIndex;
int nrOfSymbols;
NR_PUSCH_Config_t *pusch_Config;
uint8_t transform_precoding;
uint8_t mcs_table;
long mapping_type;
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig;
uint16_t dmrs_config_type;
uint16_t ul_dmrs_symb_pos;
uint8_t num_dmrs_symb;
uint8_t N_PRB_DMRS;
} NR_sched_pusch_save_t;
typedef struct NR_sched_pusch {
int frame;
int slot;
/// RB allocation within active uBWP
uint16_t rbSize;
uint16_t rbStart;
// time-domain allocation for scheduled RBs
int time_domain_allocation;
/// MCS
uint8_t mcs;
/// TBS-related info
uint16_t R;
uint8_t Qm;
uint32_t tb_size;
} NR_sched_pusch_t;
typedef struct NR_UE_harq {
uint8_t is_waiting;
uint8_t ndi;
uint8_t round;
uint16_t feedback_slot;
} NR_UE_harq_t;
typedef struct NR_UE_old_sched {
uint16_t rbSize;
int time_domain_allocation;
uint8_t mcsTableIdx;
uint8_t mcs;
uint8_t numDmrsCdmGrpsNoData;
} NR_UE_ret_info_t;
typedef enum {
INACTIVE = 0,
ACTIVE_NOT_SCHED,
ACTIVE_SCHED
} NR_UL_harq_states_t;
typedef struct NR_UE_ul_harq {
uint8_t ndi;
uint8_t round;
uint16_t last_tx_slot;
NR_UL_harq_states_t state;
} NR_UE_ul_harq_t;
typedef struct {
uint8_t nb_ssbri_cri;
uint8_t cri_ssbri_bitlen;
uint8_t rsrp_bitlen;
uint8_t diff_rsrp_bitlen;
}CRI_SSBRI_RSRP_bitlen_t;
#define MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG 16
typedef struct nr_csi_report {
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR CSI_Resource_type;
uint8_t nb_of_nzp_csi_report;
uint8_t nb_of_csi_ssb_report;
CRI_SSBRI_RSRP_bitlen_t CSI_report_bitlen[MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG];
} nr_csi_report_t;
/*! \brief scheduling control information set through an API */
typedef struct {
/// total amount of data awaiting for this UE
uint32_t num_total_bytes;
/// per-LC status data
mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID];
/// the currently active BWP in DL
NR_BWP_Downlink_t *active_bwp;
/// the currently active BWP in UL
NR_BWP_Uplink_t *active_ubwp;
/// PUCCH scheduling information. Array of three, we assume for the moment:
/// HARQ in the first field, SR in second, CSI in third (as fixed by RRC
/// conf., i.e. if actually present). The order is important for
/// nr_acknack_scheduling()!
NR_sched_pucch_t sched_pucch[3];
NR_sched_pusch_save_t pusch_save;
NR_sched_pusch_t sched_pusch;
/// CCE index and aggregation, should be coherent with cce_list
NR_SearchSpace_t *search_space;
NR_ControlResourceSet_t *coreset;
int cce_index;
uint8_t aggregation_level;
/// RB allocation within active BWP
uint16_t rbSize;
uint16_t rbStart;
// time-domain allocation for scheduled RBs
int time_domain_allocation;
/// MCS-related infos
uint8_t mcsTableIdx;
uint8_t mcs;
uint8_t numDmrsCdmGrpsNoData;
/// Retransmission-related information
NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES];
uint16_t ta_frame;
int16_t ta_update;
bool ta_apply;
uint8_t tpc0;
uint8_t tpc1;
uint16_t ul_rssi;
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
NR_UE_ul_harq_t ul_harq_processes[NR_MAX_NB_HARQ_PROCESSES];
int dummy;
NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information
} NR_UE_sched_ctrl_t;
typedef struct {
boolean_t fiveG_connected;
uicc_t *uicc;
} NRUEcontext_t;
typedef struct {
int lc_bytes_tx[64];
int lc_bytes_rx[64];
int dlsch_rounds[8];
int dlsch_errors;
int dlsch_total_bytes;
int ulsch_rounds[8];
int ulsch_errors;
int ulsch_total_bytes_scheduled;
int ulsch_total_bytes_rx;
} NR_mac_stats_t;
/*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in
* the scheduler and to keep "classes" of users. */
typedef struct {
int head;
int next[MAX_MOBILES_PER_GNB];
} NR_UE_list_t;
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
#define MAX_CSI_REPORTCONFIG 48
typedef struct {
/// scheduling control info
nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG];
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB];
NR_UE_list_t list;
int num_UEs;
bool active[MAX_MOBILES_PER_GNB];
rnti_t rnti[MAX_MOBILES_PER_GNB];
NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB];
/// CCE indexing
int Y[MAX_MOBILES_PER_GNB][3][160];
int m[MAX_MOBILES_PER_GNB];
int num_pdcch_cand[MAX_MOBILES_PER_GNB][MAX_NUM_CORESET];
// UE selected beam index
uint8_t UE_beam_index[MAX_MOBILES_PER_GNB];
} NR_UE_info_t;
typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd);
typedef void (*nr_pp_impl_ul)(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
uint64_t ulsch_in_slot_bitmap);
/*! \brief top level eNB MAC structure */
typedef struct gNB_MAC_INST_s {
/// Ethernet parameters for northbound midhaul interface
eth_params_t eth_params_n;
/// Ethernet parameters for fronthaul interface
eth_params_t eth_params_s;
/// Module
module_id_t Mod_id;
/// timing advance group
NR_TAG_t *tag;
/// Pointer to IF module instance for PHY
NR_IF_Module_t *if_inst;
/// Pusch target SNR
int pusch_target_snrx10;
/// Pucch target SNR
int pucch_target_snrx10;
/// Common cell resources
NR_COMMON_channels_t common_channels[NFAPI_CC_MAX];
/// current PDU index (BCH,DLSCH)
uint16_t pdu_index[NFAPI_CC_MAX];
/// NFAPI Config Request Structure
nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX];
/// NFAPI DL Config Request Structure
nfapi_nr_dl_tti_request_t DL_req[NFAPI_CC_MAX];
/// NFAPI UL TTI Request Structure, simple pointer into structure
/// UL_tti_req_ahead for current frame/slot
nfapi_nr_ul_tti_request_t *UL_tti_req[NFAPI_CC_MAX];
/// NFAPI UL TTI Request Structure for future TTIs, dynamically allocated
/// because length depends on number of slots
nfapi_nr_ul_tti_request_t *UL_tti_req_ahead[NFAPI_CC_MAX];
/// NFAPI HI/DCI0 Config Request Structure
nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX];
/// NFAPI DL PDU structure
nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX];
NR_UE_info_t UE_info;
/// UL handle
uint32_t ul_handle;
//UE_info_t UE_info;
// MAC function execution peformance profiler
/// processing time of eNB scheduler
time_stats_t eNB_scheduler;
/// processing time of eNB scheduler for SI
time_stats_t schedule_si;
/// processing time of eNB scheduler for Random access
time_stats_t schedule_ra;
/// processing time of eNB ULSCH scheduler
time_stats_t schedule_ulsch;
/// processing time of eNB DCI generation
time_stats_t fill_DLSCH_dci;
/// processing time of eNB MAC preprocessor
time_stats_t schedule_dlsch_preprocessor;
/// processing time of eNB DLSCH scheduler
time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor
/// processing time of eNB MCH scheduler
time_stats_t schedule_mch;
/// processing time of eNB ULSCH reception
time_stats_t rx_ulsch_sdu; // include rlc_data_ind
/// processing time of eNB PCH scheduler
time_stats_t schedule_pch;
/// CCE lists
int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
/// PUCCH: keep track of the resources has already been used by saving the
/// highest index not yet been used in a given slot. Dynamically allocated
/// so we can have it for every slot as a function of the numerology
int *pucch_index_used[MAX_NUM_BWP];
/// DL preprocessor for differentiated scheduling
nr_pp_impl_dl pre_processor_dl;
/// UL preprocessor for differentiated scheduling
nr_pp_impl_ul pre_processor_ul;
NR_UE_sched_ctrl_t *sched_ctrlCommon;
NR_CellGroupConfig_t *secondaryCellGroupCommon;
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
} gNB_MAC_INST;
#endif /*__LAYER2_NR_MAC_GNB_H__ */