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
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
/*
* 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 PHY/defs_RU.h
\brief Top-level defines and structure definitions
\author R. Knopp, F. Kaltenberger
\date 2018
\version 0.1
\company Eurecom
\email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
\note
\warning
*/
#ifndef __PHY_DEFS_RU__H__
#define __PHY_DEFS_RU__H__
#include "common_lib.h"
#include "openairinterface5g_limits.h"
#include "PHY/TOOLS/time_meas.h"
#include "defs_common.h"
#include "nfapi_nr_interface_scf.h"
#define MAX_BANDS_PER_RRU 4
#define MAX_RRU_CONFIG_SIZE 1024
typedef enum {
normal_txrx=0,
rx_calib_ue=1,
rx_calib_ue_med=2,
rx_calib_ue_byp=3,
debug_prach=4,
no_L2_connect=5,
calib_prach_tx=6,
rx_dump_frame=7,
loop_through_memory=8
} runmode_t;
/*! \brief Extension Type */
typedef enum {
CYCLIC_PREFIX,
CYCLIC_SUFFIX,
ZEROS,
NONE
} Extension_t;
enum transmission_access_mode {
NO_ACCESS=0,
POSTPONED_ACCESS,
CANCELED_ACCESS,
UNKNOWN_ACCESS,
SCHEDULED_ACCESS,
CBA_ACCESS
};
typedef enum {
eNodeB_3GPP=0, // classical eNodeB function
NGFI_RAU_IF5, // RAU with NGFI IF5
NGFI_RAU_IF4p5, // RAU with NFGI IF4p5
NGFI_RRU_IF5, // NGFI_RRU (NGFI remote radio-unit,IF5)
NGFI_RRU_IF4p5, // NGFI_RRU (NGFI remote radio-unit,IF4p5)
MBP_RRU_IF5, // Mobipass RRU
gNodeB_3GPP
} node_function_t;
typedef enum {
synch_to_ext_device=0, // synch to RF or Ethernet device
synch_to_other, // synch to another source_(timer, other RU)
synch_to_mobipass_standalone // special case for mobipass in standalone mode
} node_timing_t;
typedef struct {
/// \brief Holds the transmit data in the frequency domain (1 frame).
/// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: ? [0..samples_per_frame[
int32_t **txdata;
/// \brief holds the transmit data after beamforming in the frequency domain (1 slot).
/// - first index: tx antenna [0..nb_antennas_tx[
/// - second index: sample [0..samples_per_slot_woCP]
int32_t **txdataF_BF;
/// \brief holds the transmit data before beamforming in the frequency domain (1 frame).
/// - first index: tx antenna [0..nb_antenna_ports[
/// - second index: sample [0..samples_per_frame_woCP]
int32_t **txdataF;
/// \brief holds the transmit data before beamforming for epdcch/mpdcch
/// - first index : tx antenna [0..nb_epdcch_antenna_ports[
/// - second index: sampl [0..]
int32_t **txdataF_epdcch;
/// \brief Holds the receive data in the frequency domain.
/// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[
int32_t **rxdata;
/// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset.
/// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: sample [0..samples_per_tti[
int32_t **rxdata_7_5kHz;
/// \brief Holds the received data in the frequency domain.
/// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[
int32_t **rxdataF;
/// \brief Holds output of the sync correlator.
/// - first index: sample [0..samples_per_tti*10[
uint32_t *sync_corr;
/// \brief Holds the tdd reciprocity calibration coefficients
/// - first index: eNB id [0..2] (hard coded)
/// - second index: tx antenna [0..nb_antennas_tx[
/// - third index: frequency [0..]
int32_t **tdd_calib_coeffs;
/// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU)
/// - first index: antenna port
/// - second index: beam_id [0.. symbols_per_frame[
uint8_t **beam_id;
} RU_COMMON;
typedef struct {
/// \brief Received frequency-domain signal after extraction.
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..168*N_RB_DL[
int32_t **rxdataF_ext;
/// \brief Hold the channel estimates in time domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..4*ofdm_symbol_size[
int32_t **drs_ch_estimates_time;
/// \brief Hold the channel estimates in frequency domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **drs_ch_estimates;
} RU_CALIBRATION;
typedef struct RU_prec_t_s{
/// \internal This variable is protected by \ref mutex_feptx_prec
int instance_cnt_feptx_prec;
/// pthread struct for RU TX FEP PREC worker thread
pthread_t pthread_feptx_prec;
/// pthread attributes for worker feptx prec thread
pthread_attr_t attr_feptx_prec;
/// condition varible for RU TX FEP PREC thread
pthread_cond_t cond_feptx_prec;
/// mutex for fep PREC TX worker thread
pthread_mutex_t mutex_feptx_prec;
int symbol;
int p;//logical
int aa;//physical MAX nb_tx
struct RU_t_s *ru;
int index;
} RU_prec_t;
typedef struct RU_feptx_t_s{
/// \internal This variable is protected by \ref mutex_feptx_prec
int instance_cnt_feptx;
/// pthread struct for RU TX FEP PREC worker thread
pthread_t pthread_feptx;
/// pthread attributes for worker feptx prec thread
pthread_attr_t attr_feptx;
/// condition varible for RU TX FEP PREC thread
pthread_cond_t cond_feptx;
/// mutex for fep PREC TX worker thread
pthread_mutex_t mutex_feptx;
struct RU_t_s *ru;
int aa;//physical MAX nb_tx
int half_slot;//first or second half of a slot
int slot;//current slot
int symbol;//current symbol
int nb_antenna_ports;//number of logical port
int index;
}RU_feptx_t;
typedef struct {
int frame;
int slot;
int fmt;
int numRA;
int prachStartSymbol;
int num_prach_ocas;
} RU_PRACH_list_t;
#define NUMBER_OF_NR_RU_PRACH_MAX 8
#define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12
typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor
struct RU_t_s *ru;
/// timestamp received from HW
openair0_timestamp timestamp_rx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_tx;
/// subframe (LTE) / slot (NR) to act upon for reception
int tti_rx;
/// subframe (LTE) / slot (NR) to act upon for transmission
int tti_tx;
/// slot to pass to feptx worker thread
int slot_feptx;
/// subframe to act upon for reception of prach
int subframe_prach;
/// subframe to act upon for reception of prach BL/CE UEs
int subframe_prach_br;
/// frame to act upon for reception
int frame_rx;
/// frame to act upon for transmission
int frame_tx;
/// unwrapped frame count
int frame_tx_unwrap;
/// frame to act upon for reception of prach
int frame_prach;
/// frame to act upon for reception of prach
int frame_prach_br;
/// frame offset for slave RUs (to correct for frame asynchronism at startup)
int frame_offset;
/// \brief Instance count for FH processing thread.
/// \internal This variable is protected by \ref mutex_FH.
int instance_cnt_FH;
int instance_cnt_FH1;
/// \internal This variable is protected by \ref mutex_prach.
int instance_cnt_prach;
/// \internal This variable is protected by \ref mutex_prach.
int instance_cnt_prach_br;
/// \internal This variable is protected by \ref mutex_synch.
int instance_cnt_synch;
/// \internal This variable is protected by \ref mutex_eNBs.
int instance_cnt_eNBs;
int instance_cnt_gNBs;
/// \brief Instance count for rx processing thread.
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
int instance_cnt_asynch_rxtx;
/// \internal This variable is protected by \ref mutex_fep
int instance_cnt_fep;
/// \internal This variable is protected by \ref mutex_feptx
int instance_cnt_feptx;
/// \internal This variable is protected by \ref mutex_ru_thread
int instance_cnt_ru;
/// This varible is protected by \ref mutex_emulatedRF
int instance_cnt_emulateRF;
/// pthread structure for RU FH processing thread
pthread_t pthread_FH;
pthread_t pthread_FH1;
/// pthread structure for RU control thread
pthread_t pthread_ctrl;
/// pthread structure for RU prach processing thread
pthread_t pthread_prach;
/// pthread structure for RU prach processing thread BL/CE UEs
pthread_t pthread_prach_br;
/// pthread struct for RU synch thread
pthread_t pthread_synch;
/// pthread struct for RU RX FEP worker thread
pthread_t pthread_fep;
/// pthread struct for RU TX FEP worker thread
pthread_t pthread_feptx;
/// pthread struct for emulated RF
pthread_t pthread_emulateRF;
/// pthread structure for asychronous RX/TX processing thread
pthread_t pthread_asynch_rxtx;
/// flag to indicate first RX acquisition
int first_rx;
/// flag to indicate first TX transmission
int first_tx;
/// pthread attributes for RU FH processing thread
pthread_attr_t attr_FH;
pthread_attr_t attr_FH1;
/// pthread attributes for RU control thread
pthread_attr_t attr_ctrl;
/// pthread attributes for RU prach
pthread_attr_t attr_prach;
/// pthread attributes for RU prach BL/CE UEs
pthread_attr_t attr_prach_br;
/// pthread attributes for RU synch thread
pthread_attr_t attr_synch;
/// pthread attributes for asynchronous RX thread
pthread_attr_t attr_asynch_rxtx;
/// pthread attributes for worker fep thread
pthread_attr_t attr_fep;
/// pthread attributes for worker feptx thread
pthread_attr_t attr_feptx;
/// pthread attributes for emulated RF
pthread_attr_t attr_emulateRF;
/// scheduling parameters for RU FH thread
struct sched_param sched_param_FH;
struct sched_param sched_param_FH1;
/// scheduling parameters for RU prach thread
struct sched_param sched_param_prach;
/// scheduling parameters for RU prach thread BL/CE UEs
struct sched_param sched_param_prach_br;
/// scheduling parameters for RU synch thread
struct sched_param sched_param_synch;
/// scheduling parameters for asynch_rxtx thread
struct sched_param sched_param_asynch_rxtx;
/// condition variable for RU FH thread
pthread_cond_t cond_FH;
pthread_cond_t cond_FH1;
/// condition variable for RU prach thread
pthread_cond_t cond_prach;
/// condition variable for RU prach thread BL/CE UEs
pthread_cond_t cond_prach_br;
/// condition variable for RU synch thread
pthread_cond_t cond_synch;
/// condition variable for asynch RX/TX thread
pthread_cond_t cond_asynch_rxtx;
/// condition varible for RU RX FEP thread
pthread_cond_t cond_fep;
/// condition varible for RU TX FEP thread
pthread_cond_t cond_feptx;
/// condition varible for emulated RF
pthread_cond_t cond_emulateRF;
/// condition variable for eNB signal
pthread_cond_t cond_eNBs;
/// condition variable for gNB signal
pthread_cond_t cond_gNBs;
/// condition variable for ru_thread
pthread_cond_t cond_ru_thread;
/// mutex for RU FH
pthread_mutex_t mutex_FH;
pthread_mutex_t mutex_FH1;
/// mutex for RU prach
pthread_mutex_t mutex_prach;
/// mutex for RU prach BL/CE UEs
pthread_mutex_t mutex_prach_br;
/// mutex for RU synch
pthread_mutex_t mutex_synch;
/// mutex for eNB signal
pthread_mutex_t mutex_eNBs;
/// mutex for eNB signal
pthread_mutex_t mutex_gNBs;
/// mutex for asynch RX/TX thread
pthread_mutex_t mutex_asynch_rxtx;
/// mutex for fep RX worker thread
pthread_mutex_t mutex_fep;
/// mutex for fep TX worker thread
pthread_mutex_t mutex_feptx;
/// mutex for ru_thread
pthread_mutex_t mutex_ru;
/// mutex for emulated RF thread
pthread_mutex_t mutex_emulateRF;
/// symbol mask for IF4p5 reception per subframe
uint32_t symbol_mask[10];
/// time measurements for each subframe
struct timespec t[10];
/// number of slave threads
int num_slaves;
/// array of pointers to slaves
struct RU_proc_t_s **slave_proc;
#ifdef PHY_TX_THREAD
/// pthread structure for PRACH thread
pthread_t pthread_phy_tx;
pthread_mutex_t mutex_phy_tx;
pthread_cond_t cond_phy_tx;
/// \internal This variable is protected by \ref mutex_phy_tx.
int instance_cnt_phy_tx;
/// frame to act upon for transmission
int frame_phy_tx;
/// subframe to act upon for transmission
int subframe_phy_tx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_phy_tx;
/// pthread structure for RF TX thread
pthread_t pthread_rf_tx;
pthread_mutex_t mutex_rf_tx;
pthread_cond_t cond_rf_tx;
/// \internal This variable is protected by \ref mutex_rf_tx.
int instance_cnt_rf_tx;
#endif
#if defined(PRE_SCD_THREAD)
pthread_t pthread_pre_scd;
/// condition variable for time processing thread
pthread_cond_t cond_pre_scd;
/// mutex for time thread
pthread_mutex_t mutex_pre_scd;
int instance_pre_scd;
#endif
/// pipeline ready state
int ru_rx_ready;
int ru_tx_ready;
int emulate_rf_busy;
/// structure for precoding thread
RU_prec_t prec[16];
/// structure for feptx thread
RU_feptx_t feptx[16];
/// mask for checking process finished
int feptx_mask;
} RU_proc_t;
typedef enum {
LOCAL_RF =0,
REMOTE_IF5 =1,
REMOTE_MBP_IF5 =2,
REMOTE_IF4p5 =3,
REMOTE_IF1pp =4,
MAX_RU_IF_TYPES =5
//EMULATE_RF =6
} RU_if_south_t;
typedef enum {
RU_IDLE = 0,
RU_CONFIG = 1,
RU_READY = 2,
RU_RUN = 3,
RU_ERROR = 4,
RU_SYNC = 5,
RU_CHECK_SYNC = 6
} rru_state_t;
/// Some commands to RRU. Not sure we should do it like this !
typedef enum {
EMPTY = 0,
STOP_RU = 1,
RU_FRAME_RESYNCH = 2,
WAIT_RESYNCH = 3
} rru_cmd_t;
typedef struct RU_t_s {
/// index of this ru
uint32_t idx;
/// pointer to first RU
struct RU_t_s *ru0;
/// pointer to ru_mask
uint64_t *ru_mask;
/// pointer to ru_mutex
pthread_mutex_t *ru_mutex;
/// pointer to ru_cond
pthread_cond_t *ru_cond;
/// Pointer to configuration file
char *rf_config_file;
/// southbound interface
RU_if_south_t if_south;
/// timing
node_timing_t if_timing;
/// function
node_function_t function;
/// Ethernet parameters for fronthaul interface
eth_params_t eth_params;
/// flag to indicate RF emulation mode
int emulate_rf;
/// numerology index
int numerology;
/// flag to indicate basicsim operation
int basicsim;
/// flag to indicate the RU is in sync with a master reference
int in_synch;
/// timing offset
int rx_offset;
/// south in counter
int south_in_cnt;
/// south out counter
int south_out_cnt;
/// north in counter
int north_in_cnt;
/// north out counter
int north_out_cnt;
/// flag to indicate the RU is a slave to another source
int is_slave;
/// flag to indicate if the RU has to perform OTA sync
int ota_sync_enable;
/// flag to indicate that the RU should generate the DMRS sequence in slot 2 (subframe 1) for OTA synchronization and calibration
int generate_dmrs_sync;
/// flag to indicate if the RU has a control channel
int has_ctrl_prt;
/// counter to delay start of processing of RU until HW settles
int wait_cnt;
/// counter to delay start of slave RUs until stable synchronization
int wait_check;
/// Total gain of receive chain
uint32_t rx_total_gain_dB;
/// number of bands that this device can support
int num_bands;
/// band list
int band[MAX_BANDS_PER_RRU];
/// number of RX paths on device
int nb_rx;
/// number of TX paths on device
int nb_tx;
/// number of logical antennas at TX beamformer input
int nb_log_antennas;
/// maximum PDSCH RS EPRE
int max_pdschReferenceSignalPower;
/// maximum RX gain
int max_rxgain;
/// Attenuation of RX paths on device
int att_rx;
/// Attenuation of TX paths on device
int att_tx;
/// flag to indicate precoding operation in RU
int do_precoding;
/// TX processing advance in subframes
int sf_ahead;
/// FAPI confiuration
nfapi_nr_config_request_scf_t config;
/// Frame parameters
struct LTE_DL_FRAME_PARMS *frame_parms;
struct NR_DL_FRAME_PARMS *nr_frame_parms;
///timing offset used in TDD
int N_TA_offset;
/// SF extension used in TDD (unit: number of samples at 30.72MHz) (this is an expert option)
int sf_extension;
/// "end of burst delay" used in TDD (unit: number of samples at 30.72MHz) (this is an expert option)
int end_of_burst_delay;
/// RF device descriptor
openair0_device rfdevice;
/// HW configuration
openair0_config_t openair0_cfg;
/// Number of NBs using this RU
int num_eNB;
int num_gNB;
/// list of NBs using this RU
struct PHY_VARS_eNB_s *eNB_list[NUMBER_OF_eNB_MAX];
struct PHY_VARS_gNB_s *gNB_list[NUMBER_OF_gNB_MAX];
/// Mapping of antenna ports to RF chain index
openair0_rf_map rf_map;
/// IF device descriptor
openair0_device ifdevice;
/// Pointer for ifdevice buffer struct
if_buffer_t ifbuffer;
/// if prach processing is to be performed in RU
int do_prach;
/// function pointer to synchronous RX fronthaul function (RRU,3GPP_eNB/3GPP_gNB)
void (*fh_south_in)(struct RU_t_s *ru, int *frame, int *subframe);
/// function pointer to synchronous TX fronthaul function
void (*fh_south_out)(struct RU_t_s *ru, int frame_tx, int tti_tx, uint64_t timestamp_tx);
/// function pointer to synchronous RX fronthaul function (RRU)
void (*fh_north_in)(struct RU_t_s *ru, int *frame, int *subframe);
/// function pointer to synchronous RX fronthaul function (RRU)
void (*fh_north_out)(struct RU_t_s *ru);
/// function pointer to asynchronous fronthaul interface
void (*fh_north_asynch_in)(struct RU_t_s *ru, int *frame, int *subframe);
/// function pointer to asynchronous fronthaul interface
void (*fh_south_asynch_in)(struct RU_t_s *ru, int *frame, int *subframe);
/// function pointer to initialization function for radio interface
int (*start_rf)(struct RU_t_s *ru);
/// function pointer to release function for radio interface
int (*stop_rf)(struct RU_t_s *ru);
/// function pointer to initialization function for radio interface
int (*start_if)(struct RU_t_s *ru, struct PHY_VARS_eNB_s *eNB);
int (*nr_start_if)(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB);
/// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL)
void (*feprx)(struct RU_t_s *ru, int subframe);
/// function pointer to TX front-end processing routine (IDFTs and prefix removal or NULL)
void (*feptx_ofdm)(struct RU_t_s *ru, int frame_tx, int tti_tx);
/// function pointer to TX front-end processing routine (PRECODING)
void (*feptx_prec)(struct RU_t_s *ru, int frame_tx, int tti_tx);
/// function pointer to wakeup routine in lte-enb/nr-gnb.
int (*wakeup_rxtx)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru);
int (*nr_wakeup_rxtx)(struct PHY_VARS_gNB_s *gNB, struct RU_t_s *ru);
/// function pointer to wakeup routine in lte-enb/nr-gnb.
void (*wakeup_prach_eNB)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru, int frame, int subframe);
void (*wakeup_prach_gNB)(struct PHY_VARS_gNB_s *gNB, struct RU_t_s *ru, int frame, int subframe);
/// function pointer to wakeup routine in lte-enb.
void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru, int frame, int subframe);
/// function pointer to start a thread of tx write for USRP.
int (*start_write_thread)(struct RU_t_s *ru);
/// function pointer to NB entry routine
void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string, struct RU_t_s *ru);
void (*gNB_top)(struct PHY_VARS_gNB_s *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru);
/// Timing data copy statistics (TX)
time_stats_t txdataF_copy_stats;
/// Timing statistics (TX)
time_stats_t precoding_stats;
/// Timing statistics
time_stats_t ofdm_demod_stats;
/// Timing statistics (TX)
time_stats_t ofdm_mod_stats;
/// Timing statistics (TX)
time_stats_t ofdm_total_stats;
/// Timing wait statistics
time_stats_t ofdm_demod_wait_stats;
/// Timing wakeup statistics
time_stats_t ofdm_demod_wakeup_stats;
/// Timing wait statistics (TX)
time_stats_t ofdm_mod_wait_stats;
/// Timing wakeup statistics (TX)
time_stats_t ofdm_mod_wakeup_stats;
/// Timing statistics (RX Fronthaul + Compression)
time_stats_t rx_fhaul;
/// Timing statistics (TX Fronthaul + Compression)
time_stats_t tx_fhaul;
/// Timing statistics (Compression)
time_stats_t compression;
/// Timing statistics (Fronthaul transport)
time_stats_t transport;
/// RX and TX buffers for precoder output
RU_COMMON common;
RU_CALIBRATION calibration;
/// beamforming weight list size
int nb_bfw;
/// beamforming weight list of values
int32_t *bw_list[NUMBER_OF_eNB_MAX+1];
/// beamforming weight vectors
int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15];
/// prach commands
RU_PRACH_list_t prach_list[NUMBER_OF_NR_RU_PRACH_MAX];
/// mutex for prach_list access
pthread_mutex_t prach_list_mutex;
/// received frequency-domain signal for PRACH (IF4p5 RRU)
int16_t **prach_rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX];
/// received frequency-domain signal for PRACH BR (IF4p5 RRU)
int16_t **prach_rxsigF_br[4];
/// sequence number for IF5
uint8_t seqno;
/// initial timestamp used as an offset make first real timestamp 0
openair0_timestamp ts_offset;
/// Current state of the RU
rru_state_t state;
/// Command to do
rru_cmd_t cmd;
/// value to be passed using command
uint16_t cmdval;
/// process scheduling variables
RU_proc_t proc;
/// stats thread pthread descriptor
pthread_t ru_stats_thread;
/// OTA synchronization signal
int16_t *dmrssync;
/// OTA synchronization correlator output
uint64_t *dmrs_corr;
/// sleep time in us for delaying L1 wakeup
int wakeup_L1_sleeptime;
/// maximum number of sleeps
int wakeup_L1_sleep_cnt_max;
/// DL IF frequency in Hz
uint64_t if_frequency;
/// UL IF frequency offset to DL IF frequency in Hz
int if_freq_offset;
} RU_t;
typedef enum {
RAU_tick=0,
RRU_capabilities=1,
RRU_config=2,
RRU_config_ok=3,
RRU_start=4,
RRU_stop=5,
RRU_sync_ok=6,
RRU_frame_resynch=7,
RRU_MSG_max_num=8,
RRU_check_sync = 9,
RRU_config_update=10,
RRU_config_update_ok=11
} rru_config_msg_type_t;
typedef struct RRU_CONFIG_msg_s {
rru_config_msg_type_t type;
ssize_t len;
uint8_t msg[MAX_RRU_CONFIG_SIZE];
} RRU_CONFIG_msg_t;
typedef enum {
OAI_IF5_only =0,
OAI_IF4p5_only =1,
OAI_IF5_and_IF4p5 =2,
MBP_IF5 =3,
MAX_FH_FMTs =4
} FH_fmt_options_t;
typedef struct RRU_capabilities_s {
/// Fronthaul format
FH_fmt_options_t FH_fmt;
/// number of EUTRA bands (<=4) supported by RRU
uint8_t num_bands;
/// EUTRA band list supported by RRU
uint8_t band_list[MAX_BANDS_PER_RRU];
/// Number of concurrent bands (component carriers)
uint8_t num_concurrent_bands;
/// Maximum TX EPRE of each band
int8_t max_pdschReferenceSignalPower[MAX_BANDS_PER_RRU];
/// Maximum RX gain of each band
uint8_t max_rxgain[MAX_BANDS_PER_RRU];
/// Number of RX ports of each band
uint8_t nb_rx[MAX_BANDS_PER_RRU];
/// Number of TX ports of each band
uint8_t nb_tx[MAX_BANDS_PER_RRU];
/// max DL bandwidth (1,6,15,25,50,75,100)
uint8_t N_RB_DL[MAX_BANDS_PER_RRU];
/// max UL bandwidth (1,6,15,25,50,75,100)
uint8_t N_RB_UL[MAX_BANDS_PER_RRU];
} RRU_capabilities_t;
typedef struct RRU_config_s {
/// Fronthaul format
RU_if_south_t FH_fmt;
/// number of EUTRA bands (<=4) configured in RRU
uint8_t num_bands;
/// EUTRA band list configured in RRU
uint8_t band_list[MAX_BANDS_PER_RRU];
/// TDD configuration (0-6)
uint8_t tdd_config[MAX_BANDS_PER_RRU];
/// TDD special subframe configuration (0-10)
uint8_t tdd_config_S[MAX_BANDS_PER_RRU];
/// TX frequency
uint32_t tx_freq[MAX_BANDS_PER_RRU];
/// RX frequency
uint32_t rx_freq[MAX_BANDS_PER_RRU];
/// TX attenuation w.r.t. max
uint8_t att_tx[MAX_BANDS_PER_RRU];
/// RX attenuation w.r.t. max
uint8_t att_rx[MAX_BANDS_PER_RRU];
/// DL bandwidth
uint8_t N_RB_DL[MAX_BANDS_PER_RRU];
/// UL bandwidth
uint8_t N_RB_UL[MAX_BANDS_PER_RRU];
/// 3/4 sampling rate
uint8_t threequarter_fs[MAX_BANDS_PER_RRU];
/// prach_FreqOffset for IF4p5
int prach_FreqOffset[MAX_BANDS_PER_RRU];
/// prach_ConfigIndex for IF4p5
int prach_ConfigIndex[MAX_BANDS_PER_RRU];
int emtc_prach_CElevel_enable[MAX_BANDS_PER_RRU][4];
/// emtc_prach_FreqOffset for IF4p5 per CE Level
int emtc_prach_FreqOffset[MAX_BANDS_PER_RRU][4];
/// emtc_prach_ConfigIndex for IF4p5 per CE Level
int emtc_prach_ConfigIndex[MAX_BANDS_PER_RRU][4];
/// mutex for async RX/TX thread
pthread_mutex_t mutex_asynch_rxtx;
/// mutex for RU access to eNB processing (PDSCH/PUSCH)
pthread_mutex_t mutex_RU;
/// mutex for RU access to eNB processing (PRACH)
pthread_mutex_t mutex_RU_PRACH;
/// mutex for RU access to eNB processing (PRACH BR)
pthread_mutex_t mutex_RU_PRACH_br;
/// mask for RUs serving eNB (PDSCH/PUSCH)
int RU_mask[10];
/// time measurements for RU arrivals
struct timespec t[10];
/// Timing statistics (RU_arrivals)
time_stats_t ru_arrival_time;
/// mask for RUs serving eNB (PRACH)
int RU_mask_prach;
/// embms mbsfn sf config
int num_MBSFN_config;
/// embms mbsfn sf config
MBSFN_config_t MBSFN_config[8];
} RRU_config_t;
typedef struct processingData_RU {
int frame_tx;
int slot_tx;
int next_slot;
openair0_timestamp timestamp_tx;
RU_t *ru;
} processingData_RU_t;
#endif //__PHY_DEFS_RU__H__