nr-ue.c 32.3 KB
Newer Older
Thomas Laurent's avatar
Thomas Laurent committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * 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.0  (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
 */

Guido Casati's avatar
Guido Casati committed
22
#include "executables/nr-uesoftmodem.h"
Thomas Laurent's avatar
Thomas Laurent committed
23
24
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/INIT/phy_init.h"
25
#include "NR_MAC_UE/mac_proto.h"
Thomas Laurent's avatar
Thomas Laurent committed
26
#include "RRC/NR_UE/rrc_proto.h"
Guido Casati's avatar
Guido Casati committed
27
#include "SCHED_NR_UE/phy_frame_config_nr.h"
Thomas Laurent's avatar
Thomas Laurent committed
28
29
#include "SCHED_NR_UE/defs.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
30
#include "executables/softmodem-common.h"
Sakthivel Velumani's avatar
Sakthivel Velumani committed
31
#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
Thomas Laurent's avatar
Thomas Laurent committed
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

/*
 *  NR SLOT PROCESSING SEQUENCE
 *
 *  Processing occurs with following steps for connected mode:
 *
 *  - Rx samples for a slot are received,
 *  - PDCCH processing (including DCI extraction for downlink and uplink),
 *  - PDSCH processing (including transport blocks decoding),
 *  - PUCCH/PUSCH (transmission of acknowledgements, CSI, ... or data).
 *
 *  Time between reception of the slot and related transmission depends on UE processing performance.
 *  It is defined by the value NR_UE_CAPABILITY_SLOT_RX_TO_TX.
 *
 *  In NR, network gives the duration between Rx slot and Tx slot in the DCI:
 *  - for reception of a PDSCH and its associated acknowledgment slot (with a PUCCH or a PUSCH),
 *  - for reception of an uplink grant and its associated PUSCH slot.
 *
 *  So duration between reception and it associated transmission depends on its transmission slot given in the DCI.
 *  NR_UE_CAPABILITY_SLOT_RX_TO_TX means the minimum duration but higher duration can be given by the network because UE can support it.
 *
 *                                                                                                    Slot k
 *                                                                                  -------+------------+--------
 *                Frame                                                                    | Tx samples |
 *                Subframe                                                                 |   buffer   |
 *                Slot n                                                            -------+------------+--------
 *       ------ +------------+--------                                                     |
 *              | Rx samples |                                                             |
 *              |   buffer   |                                                             |
 *       -------+------------+--------                                                     |
 *                           |                                                             |
 *                           V                                                             |
 *                           +------------+                                                |
 *                           |   PDCCH    |                                                |
 *                           | processing |                                                |
 *                           +------------+                                                |
 *                           |            |                                                |
 *                           |            v                                                |
 *                           |            +------------+                                   |
 *                           |            |   PDSCH    |                                   |
 *                           |            | processing | decoding result                   |
 *                           |            +------------+    -> ACK/NACK of PDSCH           |
 *                           |                         |                                   |
 *                           |                         v                                   |
 *                           |                         +-------------+------------+        |
 *                           |                         | PUCCH/PUSCH | Tx samples |        |
 *                           |                         |  processing | transfer   |        |
 *                           |                         +-------------+------------+        |
 *                           |                                                             |
 *                           |/___________________________________________________________\|
 *                            \  duration between reception and associated transmission   /
 *
 * Remark: processing is done slot by slot, it can be distribute on different threads which are executed in parallel.
 * This is an architecture optimization in order to cope with real time constraints.
 * By example, for LTE, subframe processing is spread over 4 different threads.
 *
 */

#ifndef NO_RAT_NR
  #define DURATION_RX_TO_TX           (NR_UE_CAPABILITY_SLOT_RX_TO_TX)  /* for NR this will certainly depends to such UE capability which is not yet defined */
#else
93
  #define DURATION_RX_TO_TX           (6)   /* For LTE, this duration is fixed to 4 and it is linked to LTE standard for both modes FDD/TDD */
Thomas Laurent's avatar
Thomas Laurent committed
94
#endif
Sakthivel Velumani's avatar
Sakthivel Velumani committed
95
96
#define RX_JOB_ID 0x1010
#define TX_JOB_ID 100
Thomas Laurent's avatar
Thomas Laurent committed
97
98

typedef enum {
99
100
101
  pss = 0,
  pbch = 1,
  si = 2
Thomas Laurent's avatar
Thomas Laurent committed
102
103
} sync_mode_t;

104
105
106
void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
                     uint8_t UE_id,
                     uint8_t abstraction_flag)
Thomas Laurent's avatar
Thomas Laurent committed
107
{
108

109
110
  int nb_connected_gNB = 1, gNB_id;

Thomas Laurent's avatar
Thomas Laurent committed
111
112
  ue->Mod_id      = UE_id;
  ue->mac_enabled = 1;
113
  ue->if_inst     = nr_ue_if_module_init(0);
114
  ue->dci_thres   = 0;
Khalid Ahmed's avatar
Khalid Ahmed committed
115

116
117
118
119
120
121
  // Setting UE mode to NOT_SYNCHED by default
  for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){
    ue->UE_mode[gNB_id] = NOT_SYNCHED;
    ue->prach_resources[gNB_id] = (NR_PRACH_RESOURCES_t *)malloc16_clear(sizeof(NR_PRACH_RESOURCES_t));
  }

Thomas Laurent's avatar
Thomas Laurent committed
122
  // initialize all signal buffers
123
  init_nr_ue_signal(ue, nb_connected_gNB, abstraction_flag);
124

Thomas Laurent's avatar
Thomas Laurent committed
125
  // intialize transport
126
  init_nr_ue_transport(ue, abstraction_flag);
127
128
129

  // init N_TA offset
  init_N_TA_offset(ue);
Thomas Laurent's avatar
Thomas Laurent committed
130
131
132
133
134
135
136
}

/*!
 * It performs band scanning and synchonization.
 * \param arg is a pointer to a \ref PHY_VARS_NR_UE structure.
 */

Sakthivel Velumani's avatar
Sakthivel Velumani committed
137
typedef nr_rxtx_thread_data_t syncData_t;
Thomas Laurent's avatar
Thomas Laurent committed
138
139
140
141
142
143

static void UE_synch(void *arg) {
  syncData_t *syncD=(syncData_t *) arg;
  int i, hw_slot_offset;
  PHY_VARS_NR_UE *UE = syncD->UE;
  sync_mode_t sync_mode = pbch;
144
  //int CC_id = UE->CC_id;
145
  static int freq_offset=0;
Thomas Laurent's avatar
Thomas Laurent committed
146
147
148
149
  UE->is_synchronized = 0;

  if (UE->UE_scan == 0) {

150
    #ifdef FR2_TEST
151
152
153
154
155
    // Overwrite DL frequency (for FR2 testing)
    if (downlink_frequency[0][0]!=0){
       UE->frame_parms.dl_CarrierFreq = downlink_frequency[0][0];
       UE->frame_parms.ul_CarrierFreq = downlink_frequency[0][0];
    }
156
    #endif
Thomas Laurent's avatar
Thomas Laurent committed
157
158
159

    for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {

160
      LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %f, UL %f (RF card %d, oai_exit %d, channel %d, rx_num_channels %d)\n",
161
162
163
164
165
166
167
        openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i],
        openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i],
        UE->rf_map.card,
        oai_exit,
        i,
        openair0_cfg[0].rx_num_channels);

Thomas Laurent's avatar
Thomas Laurent committed
168
169
170
171
    }

    sync_mode = pbch;
  } else {
172
173
    LOG_E(PHY,"Fixme!\n");
    /*
Thomas Laurent's avatar
Thomas Laurent committed
174
175
176
177
178
179
180
181
182
    for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
      downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
      uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] =
        bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
      openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
      openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
        downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
      openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
    }
183
    */
Thomas Laurent's avatar
Thomas Laurent committed
184
185
186
187
188
  }

  LOG_W(PHY, "Starting sync detection\n");

  switch (sync_mode) {
189
    /*
Thomas Laurent's avatar
Thomas Laurent committed
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
    case pss:
      LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
      //lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
      current_offset += 20000000; // increase by 20 MHz

      if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
        current_band++;
        current_offset=0;
      }

      if (current_band==bands_to_scan.nbands) {
        current_band=0;
        oai_exit=1;
      }

      for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
        downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
        uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
        openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
        openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
        openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;

        if (UE->UE_scan_carrier) {
          openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
        }
      }

      break;
218
    */
Thomas Laurent's avatar
Thomas Laurent committed
219
220
221
    case pbch:
      LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);

222
223
224
225
      uint64_t dl_carrier, ul_carrier;
      double rx_gain_off = 0;
      nr_get_carrier_frequencies(&UE->frame_parms, &dl_carrier, &ul_carrier);

Guido Casati's avatar
Guido Casati committed
226
      if (nr_initial_sync(&syncD->proc, UE, 2) == 0) {
Thomas Laurent's avatar
Thomas Laurent committed
227
        freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
228
        hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) +
Sakthivel Velumani's avatar
Sakthivel Velumani committed
229
                         round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0);
Thomas Laurent's avatar
Thomas Laurent committed
230
231

        // rerun with new cell parameters and frequency-offset
232
233
        // todo: the freq_offset computed on DL shall be scaled before being applied to UL
        nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset);
Thomas Laurent's avatar
Thomas Laurent committed
234

235
        LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n",
236
237
              hw_slot_offset,
              freq_offset,
238
              openair0_cfg[UE->rf_map.card].rx_gain[0],
239
              openair0_cfg[UE->rf_map.card].rx_freq[0],
240
              openair0_cfg[UE->rf_map.card].tx_freq[0]);
241

Thomas Laurent's avatar
Thomas Laurent committed
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
        if (UE->mode != loop_through_memory) {
          UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
          //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
          //UE->rfdevice.trx_stop_func(&UE->rfdevice);
          // sleep(1);
          /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
            LOG_E(HW,"Could not start the device\n");
            oai_exit=1;
            }*/
        }

        if (UE->UE_scan_carrier == 1) {
          UE->UE_scan_carrier = 0;
        } else {
          UE->is_synchronized = 1;
        }
      } else {
259

260
        if (UE->UE_scan_carrier == 1) {
261

Thomas Laurent's avatar
Thomas Laurent committed
262
263
264
265
          if (freq_offset >= 0)
            freq_offset += 100;

          freq_offset *= -1;
266

267
          nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset);
Thomas Laurent's avatar
Thomas Laurent committed
268

269
          LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset);
Thomas Laurent's avatar
Thomas Laurent committed
270
271
272

          if (UE->mode != loop_through_memory)
            UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
273
        }
Thomas Laurent's avatar
Thomas Laurent committed
274
275
276
277
278
279
280
281
282
283

        break;

      case si:
      default:
        break;
      }
  }
}

Sakthivel Velumani's avatar
Sakthivel Velumani committed
284
285
void processSlotTX(void *arg) {

286
  nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
287
288
  UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
  PHY_VARS_NR_UE    *UE   = rxtxD->UE;
289
  fapi_nr_config_request_t *cfg = &UE->nrUE_config;
290
  int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
291
  uint8_t gNB_id = 0;
292
293

  if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){
Florian Kaltenberger's avatar
Florian Kaltenberger committed
294

295
296
297
298
299
300
301
302
303
304
    // trigger L2 to run ue_scheduler thru IF module
    // [TODO] mapping right after NR initial sync
    if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
      nr_uplink_indication_t ul_indication;
      memset((void*)&ul_indication, 0, sizeof(ul_indication));

      ul_indication.module_id = UE->Mod_id;
      ul_indication.gNB_index = gNB_id;
      ul_indication.cc_id     = UE->CC_id;
      ul_indication.frame_rx  = proc->frame_rx;
305
      ul_indication.slot_rx   = proc->nr_slot_rx;
306
      ul_indication.frame_tx  = proc->frame_tx;
307
308
      ul_indication.slot_tx   = proc->nr_slot_tx;
      ul_indication.thread_id = proc->thread_id;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
309

310
311
      UE->if_inst->ul_indication(&ul_indication);
    }
312

Florian Kaltenberger's avatar
Florian Kaltenberger committed
313
    if (UE->mode != loop_through_memory) {
314
      phy_procedures_nrUE_TX(UE,proc,0);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
315
316
317
318
    }
  }
}

Sakthivel Velumani's avatar
Sakthivel Velumani committed
319
void processSlotRX(void *arg) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
320

321
  nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
322
323
  UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
  PHY_VARS_NR_UE    *UE   = rxtxD->UE;
324
  fapi_nr_config_request_t *cfg = &UE->nrUE_config;
325
  int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_slot_rx);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
326
  int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
Guido Casati's avatar
Guido Casati committed
327
  uint8_t gNB_id = 0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
328

329
  if (rx_slot_type == NR_DOWNLINK_SLOT || rx_slot_type == NR_MIXED_SLOT){
Florian Kaltenberger's avatar
Florian Kaltenberger committed
330

Guido Casati's avatar
Guido Casati committed
331
    if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
332
      nr_downlink_indication_t dl_indication;
Guido Casati's avatar
Guido Casati committed
333
      nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id);
334
335
      UE->if_inst->dl_indication(&dl_indication, NULL);
    }
336

Florian Kaltenberger's avatar
Florian Kaltenberger committed
337
  // Process Rx data for one sub-frame
Thomas Laurent's avatar
Thomas Laurent committed
338
#ifdef UE_SLOT_PARALLELISATION
Guido Casati's avatar
Guido Casati committed
339
    phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
Thomas Laurent's avatar
Thomas Laurent committed
340
#else
Thomas Laurent's avatar
Thomas Laurent committed
341
    uint64_t a=rdtsc();
342
    phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &rxtxD->txFifo);
Guido Casati's avatar
Guido Casati committed
343
    LOG_D(PHY, "In %s: slot %d, time %lu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc()-a)/3500);
Thomas Laurent's avatar
Thomas Laurent committed
344
#endif
knopp's avatar
knopp committed
345

Guido Casati's avatar
Guido Casati committed
346
347
    if(IS_SOFTMODEM_NOS1){
      NR_UE_MAC_INST_t *mac = get_mac_inst(0);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
348
      protocol_ctxt_t ctxt;
Guido Casati's avatar
Guido Casati committed
349
      PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, mac->crnti, proc->frame_rx, proc->nr_slot_rx, 0);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
350
      pdcp_run(&ctxt);
351
352
353
354
355
356
357
358

      /* send tick to RLC and PDCP every ms */
      if (proc->nr_slot_rx % UE->frame_parms.slots_per_subframe == 0) {
        void nr_rlc_tick(int frame, int subframe);
        void nr_pdcp_tick(int frame, int subframe);
        nr_rlc_tick(proc->frame_rx, proc->nr_slot_rx / UE->frame_parms.slots_per_subframe);
        nr_pdcp_tick(proc->frame_rx, proc->nr_slot_rx / UE->frame_parms.slots_per_subframe);
      }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
359
    }
Thomas Laurent's avatar
Thomas Laurent committed
360

361
    // Wait for PUSCH processing to finish
362
363
364
    notifiedFIFO_elt_t *res;
    res = pullTpool(&rxtxD->txFifo,&(get_nrUE_params()->Tpool));
    delNotifiedFIFO_elt(res);
Thomas Laurent's avatar
Thomas Laurent committed
365

366
367
  } else {
    processSlotTX(rxtxD);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
368
  }
Thomas Laurent's avatar
Thomas Laurent committed
369

Sakthivel Velumani's avatar
Sakthivel Velumani committed
370
  if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){
Sakthivel Velumani's avatar
Sakthivel Velumani committed
371
372
373
374
375
376
377
    if (UE->UE_mode[gNB_id] <= PUSCH) {
      if (get_softmodem_params()->usim_test==0) {
        pucch_procedures_ue_nr(UE,
                               gNB_id,
                               proc,
                               FALSE);
      }
Thomas Laurent's avatar
Thomas Laurent committed
378

Sakthivel Velumani's avatar
Sakthivel Velumani committed
379
380
381
382
383
      LOG_D(PHY, "Sending Uplink data \n");
      nr_ue_pusch_common_procedures(UE,
                                    proc->nr_slot_tx,
                                    &UE->frame_parms,1);
    }
Thomas Laurent's avatar
Thomas Laurent committed
384

Sakthivel Velumani's avatar
Sakthivel Velumani committed
385
386
387
388
    if (UE->UE_mode[gNB_id] > NOT_SYNCHED && UE->UE_mode[gNB_id] < PUSCH) {
      nr_ue_prach_procedures(UE, proc, gNB_id);
    }
    LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", proc->frame_tx, proc->nr_slot_tx);
389
  }
390

Sakthivel Velumani's avatar
Sakthivel Velumani committed
391
  ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
Thomas Laurent's avatar
Thomas Laurent committed
392
393
}

394
void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
Thomas Laurent's avatar
Thomas Laurent committed
395
396
397
  void *dummy_tx[UE->frame_parms.nb_antennas_tx];

  for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
398
    dummy_tx[i]=malloc16_clear(writeBlockSize*4);
Thomas Laurent's avatar
Thomas Laurent committed
399

400
401
402
403
404
405
406
  AssertFatal( writeBlockSize ==
               UE->rfdevice.trx_write_func(&UE->rfdevice,
               timestamp,
               dummy_tx,
               writeBlockSize,
               UE->frame_parms.nb_antennas_tx,
               4),"");
Thomas Laurent's avatar
Thomas Laurent committed
407
408
409
410
411

  for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
    free(dummy_tx[i]);
}

412
void readFrame(PHY_VARS_NR_UE *UE,  openair0_timestamp *timestamp, bool toTrash) {
Thomas Laurent's avatar
Thomas Laurent committed
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
  void *rxp[NB_ANTENNAS_RX];

  for(int x=0; x<20; x++) {  // two frames for initial sync
    for (int slot=0; slot<UE->frame_parms.slots_per_subframe; slot ++ ) {
      for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) {
        if (toTrash)
          rxp[i]=malloc16(UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms)*4);
        else
          rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) +
                   4*((x*UE->frame_parms.samples_per_subframe)+
                   UE->frame_parms.get_samples_slot_timestamp(slot,&UE->frame_parms,0));
      }
        
      AssertFatal( UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms) ==
                   UE->rfdevice.trx_read_func(&UE->rfdevice,
                   timestamp,
                   rxp,
                   UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms),
                   UE->frame_parms.nb_antennas_rx), "");

      if (IS_SOFTMODEM_RFSIM)
        dummyWrite(UE,*timestamp, UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms));
      if (toTrash)
        for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
          free(rxp[i]);
439
    }
Thomas Laurent's avatar
Thomas Laurent committed
440
441
442
443
444
  }

}

void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
445

Thomas Laurent's avatar
Thomas Laurent committed
446
447
    LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);

Sakthivel Velumani's avatar
Sakthivel Velumani committed
448
    *timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
Thomas Laurent's avatar
Thomas Laurent committed
449
450
    for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
      int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
451
452
453
      // we write before read becasue gNB waits for UE to write and both executions halt
      // this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
      if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
Thomas Laurent's avatar
Thomas Laurent committed
454
455
456
457
458
459
      AssertFatal(unitTransfer ==
                  UE->rfdevice.trx_read_func(&UE->rfdevice,
                                             timestamp,
                                             (void **)UE->common_vars.rxdata,
                                             unitTransfer,
                                             UE->frame_parms.nb_antennas_rx),"");
Sakthivel Velumani's avatar
Sakthivel Velumani committed
460
      *timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
Thomas Laurent's avatar
Thomas Laurent committed
461
462
463
464
465
466
467
    }

}

int computeSamplesShift(PHY_VARS_NR_UE *UE) {

  // compute TO compensation that should be applied for this frame
468
469
470
  if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2  &&
       UE->rx_offset > 0 ) {
    //LOG_I(PHY,"!!!adjusting -1 samples!!!\n");
Thomas Laurent's avatar
Thomas Laurent committed
471
    return -1 ;
472
  }
Thomas Laurent's avatar
Thomas Laurent committed
473

474
475
476
  if ( UE->rx_offset > UE->frame_parms.samples_per_frame/2 &&
       UE->rx_offset < UE->frame_parms.samples_per_frame ) {
    //LOG_I(PHY,"!!!adjusting +1 samples!!!\n");
Thomas Laurent's avatar
Thomas Laurent committed
477
    return 1;
478
  }
Thomas Laurent's avatar
Thomas Laurent committed
479

Thomas Laurent's avatar
Thomas Laurent committed
480
481
482
  return 0;
}

483
static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
484
485
486
487
488
489
490
  if (fp->numerology_index == 0)
    return fp->nb_prefix_samples0 + fp->ofdm_symbol_size;
  int num_samples = (slot%(fp->slots_per_subframe/2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
  num_samples += fp->ofdm_symbol_size;
  return num_samples;
}

491
static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
492
493
494
495
496
497
498
  int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp);
  int next_slot_first_symbol = 0;
  if (slot < (fp->slots_per_frame-1))
    next_slot_first_symbol = get_firstSymSamp(slot+1, fp);
  return rem_samples + next_slot_first_symbol;
}

Thomas Laurent's avatar
Thomas Laurent committed
499
void *UE_thread(void *arg) {
Thomas Laurent's avatar
Thomas Laurent committed
500
  //this thread should be over the processing thread to keep in real time
Thomas Laurent's avatar
Thomas Laurent committed
501
502
  PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
  //  int tx_enabled = 0;
503
  openair0_timestamp timestamp, writeTimestamp;
Thomas Laurent's avatar
Thomas Laurent committed
504
505
506
507
  void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
  int start_rx_stream = 0;
  AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
  UE->rfdevice.host_type = RAU_HOST;
508
509
  UE->lost_sync = 0;
  UE->is_synchronized = 0;
Thomas Laurent's avatar
Thomas Laurent committed
510
  AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
Sakthivel Velumani's avatar
Sakthivel Velumani committed
511

Thomas Laurent's avatar
Thomas Laurent committed
512
513
  notifiedFIFO_t nf;
  initNotifiedFIFO(&nf);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
514

515
516
  notifiedFIFO_t freeBlocks;
  initNotifiedFIFO_nothreadSafe(&freeBlocks);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
517

518
  int nbSlotProcessing=0;
Thomas Laurent's avatar
Thomas Laurent committed
519
  int thread_idx=0;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
520
  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
Thomas Schlichter's avatar
Thomas Schlichter committed
521
  int timing_advance = UE->timing_advance;
Thomas Laurent's avatar
Thomas Laurent committed
522

Thomas Laurent's avatar
fixes    
Thomas Laurent committed
523
  bool syncRunning=false;
524
  const int nb_slot_frame = UE->frame_parms.slots_per_frame;
525
  int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0;
Thomas Laurent's avatar
Thomas Laurent committed
526

Sakthivel Velumani's avatar
Sakthivel Velumani committed
527
  for (int i=0; i<NR_RX_NB_TH+1; i++) {// NR_RX_NB_TH working + 1 we are making to be pushed
528
529
530
531
    notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), RX_JOB_ID,&nf,processSlotRX);
    nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(newElt);
    initNotifiedFIFO(&curMsg->txFifo);
    pushNotifiedFIFO_nothreadSafe(&freeBlocks, newElt);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
532
533
  }

Thomas Laurent's avatar
Thomas Laurent committed
534
  while (!oai_exit) {
535
    if (UE->lost_sync) {
536
537
538
      int nb = abortTpool(&(get_nrUE_params()->Tpool),RX_JOB_ID);
      nb += abortNotifiedFIFO(&nf, RX_JOB_ID);
      LOG_I(PHY,"Number of aborted slots %d\n",nb);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
539
      for (int i=0; i<nb; i++)
540
541
        pushNotifiedFIFO_nothreadSafe(&freeBlocks, newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), RX_JOB_ID,&nf,processSlotRX));
      nbSlotProcessing = 0;
542
543
544
545
      UE->is_synchronized = 0;
      UE->lost_sync = 0;
    }

546
    if (syncRunning) {
547
      notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool));
548
549
550
551

      if (res) {
        syncRunning=false;
        syncData_t *tmp=(syncData_t *)NotifiedFifoData(res);
552
553
554
        if (UE->is_synchronized) {
          decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
          // shift the frame index with all the frames we trashed meanwhile we perform the synch search
555
          decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
556
        }
557
        delNotifiedFIFO_elt(res);
558
        start_rx_stream=0;
Thomas Laurent's avatar
Thomas Laurent committed
559
      } else {
560
        readFrame(UE, &timestamp, true);
561
        trashed_frames+=2;
562
        continue;
Thomas Laurent's avatar
Thomas Laurent committed
563
      }
564
    }
Thomas Laurent's avatar
Thomas Laurent committed
565

566
    AssertFatal( !syncRunning, "At this point synchronization can't be running\n");
567
568

    if (!UE->is_synchronized) {
569
      readFrame(UE, &timestamp, false);
570
571
572
573
      notifiedFIFO_elt_t *Msg=newNotifiedFIFO_elt(sizeof(syncData_t),0,&nf,UE_synch);
      syncData_t *syncMsg=(syncData_t *)NotifiedFifoData(Msg);
      syncMsg->UE=UE;
      memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
574
      pushTpool(&(get_nrUE_params()->Tpool), Msg);
575
576
      trashed_frames=0;
      syncRunning=true;
Thomas Laurent's avatar
Thomas Laurent committed
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
      continue;
    }

    if (start_rx_stream==0) {
      start_rx_stream=1;
      syncInFrame(UE, &timestamp);
      UE->rx_offset=0;
      UE->time_sync_cell=0;
      // read in first symbol
      AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
                   UE->rfdevice.trx_read_func(&UE->rfdevice,
                                              &timestamp,
                                              (void **)UE->common_vars.rxdata,
                                              UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
                                              UE->frame_parms.nb_antennas_rx),"");
Thomas Laurent's avatar
fixes    
Thomas Laurent committed
592
593
      // we have the decoded frame index in the return of the synch process
      // and we shifted above to the first slot of next frame
594
      decoded_frame_rx++;
595
      // we do ++ first in the regular processing, so it will be begin of frame;
596
      absolute_slot=decoded_frame_rx*nb_slot_frame -1;
Thomas Laurent's avatar
Thomas Laurent committed
597
598
599
      continue;
    }

600

Thomas Laurent's avatar
Thomas Laurent committed
601
    absolute_slot++;
602

603
604
    // whatever means thread_idx
    // Fix me: will be wrong when slot 1 is slow, as slot 2 finishes
Sakthivel Velumani's avatar
Sakthivel Velumani committed
605
    // Slot 3 will overlap if NR_RX_NB_TH is 2
606
    // this is general failure in UE !!!
Sakthivel Velumani's avatar
Sakthivel Velumani committed
607
    thread_idx = absolute_slot % NR_RX_NB_TH;
Thomas Laurent's avatar
fixes    
Thomas Laurent committed
608
    int slot_nr = absolute_slot % nb_slot_frame;
609
    notifiedFIFO_elt_t *msgToPush;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
610
    AssertFatal((msgToPush=pullTpool(&freeBlocks,&(get_nrUE_params()->Tpool))) != NULL,"chained list failure");
611
    nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush);
612
    curMsg->UE=UE;
Thomas Laurent's avatar
Thomas Laurent committed
613
    // update thread index for received subframe
614
615
616
617
618
619
    curMsg->proc.thread_id   = thread_idx;
    curMsg->proc.CC_id       = UE->CC_id;
    curMsg->proc.nr_slot_rx  = slot_nr;
    curMsg->proc.nr_slot_tx  = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
    curMsg->proc.frame_rx    = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER;
    curMsg->proc.frame_tx    = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER;
620
    curMsg->proc.decoded_frame_rx=-1;
Hongzhi Wang's avatar
Hongzhi Wang committed
621
622
623
    //LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB);

#ifdef OAI_ADRV9371_ZC706
Hongzhi Wang's avatar
Hongzhi Wang committed
624
    /*uint32_t total_gain_dB_prev = 0;
Hongzhi Wang's avatar
Hongzhi Wang committed
625
    if (total_gain_dB_prev != UE->rx_total_gain_dB) {
Thomas Schlichter's avatar
Thomas Schlichter committed
626
        total_gain_dB_prev = UE->rx_total_gain_dB;
Hongzhi Wang's avatar
Hongzhi Wang committed
627
        openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB;
Hongzhi Wang's avatar
Hongzhi Wang committed
628
        UE->rfdevice.trx_set_gains_func(&UE->rfdevice,&openair0_cfg[0]);
Hongzhi Wang's avatar
Hongzhi Wang committed
629
    }*/
Hongzhi Wang's avatar
Hongzhi Wang committed
630
#endif
Thomas Laurent's avatar
Thomas Laurent committed
631

Sakthivel Velumani's avatar
Sakthivel Velumani committed
632
    int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
Thomas Laurent's avatar
Thomas Laurent committed
633
    for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
Sakthivel Velumani's avatar
Sakthivel Velumani committed
634
      rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+
635
               UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
Thomas Laurent's avatar
Thomas Laurent committed
636
637

    for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
638
      txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp(
Sakthivel Velumani's avatar
Sakthivel Velumani committed
639
               ((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH)%nb_slot_frame),&UE->frame_parms,0)];
Thomas Laurent's avatar
Thomas Laurent committed
640
641
642
643

    int readBlockSize, writeBlockSize;

    if (slot_nr<(nb_slot_frame - 1)) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
644
      readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
645
      writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms);
Thomas Laurent's avatar
Thomas Laurent committed
646
647
    } else {
      UE->rx_offset_diff = computeSamplesShift(UE);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
648
      readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
Thomas Laurent's avatar
Thomas Laurent committed
649
                    UE->rx_offset_diff;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
650
      writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff;
Thomas Laurent's avatar
Thomas Laurent committed
651
652
653
654
655
656
657
658
    }

    AssertFatal(readBlockSize ==
                UE->rfdevice.trx_read_func(&UE->rfdevice,
                                           &timestamp,
                                           rxp,
                                           readBlockSize,
                                           UE->frame_parms.nb_antennas_rx),"");
659

Thomas Laurent's avatar
Thomas Laurent committed
660
661
    if( slot_nr==(nb_slot_frame-1)) {
      // read in first symbol of next frame and adjust for timing drift
Sakthivel Velumani's avatar
Sakthivel Velumani committed
662
      int first_symbols=UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0; // first symbol of every frames
Thomas Laurent's avatar
Thomas Laurent committed
663

Thomas Schlichter's avatar
Thomas Schlichter committed
664
665
      if ( first_symbols > 0 ) {
        openair0_timestamp ignore_timestamp;
Thomas Laurent's avatar
Thomas Laurent committed
666
667
        AssertFatal(first_symbols ==
                    UE->rfdevice.trx_read_func(&UE->rfdevice,
Thomas Schlichter's avatar
Thomas Schlichter committed
668
                                               &ignore_timestamp,
Thomas Laurent's avatar
Thomas Laurent committed
669
670
671
                                               (void **)UE->common_vars.rxdata,
                                               first_symbols,
                                               UE->frame_parms.nb_antennas_rx),"");
Thomas Schlichter's avatar
Thomas Schlichter committed
672
      } else
Thomas Laurent's avatar
Thomas Laurent committed
673
674
675
        LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
    }

676
    curMsg->proc.timestamp_tx = timestamp+
677
      UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX) 
678
      - firstSymSamp;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
679

Thomas Laurent's avatar
fixes    
Thomas Laurent committed
680
    notifiedFIFO_elt_t *res;
Thomas Laurent's avatar
Thomas Laurent committed
681

Sakthivel Velumani's avatar
Sakthivel Velumani committed
682
    while (nbSlotProcessing >= NR_RX_NB_TH) {
683
      res=pullTpool(&nf, &(get_nrUE_params()->Tpool));
Thomas Schlichter's avatar
Thomas Schlichter committed
684
      nbSlotProcessing--;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
685
      nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData;
Thomas Laurent's avatar
fixes    
Thomas Laurent committed
686

Thomas Schlichter's avatar
Thomas Schlichter committed
687
688
      if (tmp->proc.decoded_frame_rx != -1)
        decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
689
      else
Thomas Laurent's avatar
Thomas Laurent committed
690
         decoded_frame_rx=-1;
Thomas Laurent's avatar
Thomas Laurent committed
691

Thomas Schlichter's avatar
Thomas Schlichter committed
692
      pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
Thomas Laurent's avatar
Thomas Laurent committed
693
694
    }

695
    if (decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx)
Thomas Laurent's avatar
Thomas Laurent committed
696
      LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
697
            decoded_frame_rx, curMsg->proc.frame_rx);
Thomas Laurent's avatar
Thomas Laurent committed
698

699
700
701
    // use previous timing_advance value to compute writeTimestamp
    writeTimestamp = timestamp+
      UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX
Sakthivel Velumani's avatar
Sakthivel Velumani committed
702
      - NR_RX_NB_TH) - firstSymSamp - openair0_cfg[0].tx_sample_advance -
703
704
      UE->N_TA_offset - timing_advance;

705
706
707
708
709
710
    // but use current UE->timing_advance value to compute writeBlockSize
    if (UE->timing_advance != timing_advance) {
      writeBlockSize -= UE->timing_advance - timing_advance;
      timing_advance = UE->timing_advance;
    }

711
    int flags = 0;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
712
    int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - NR_RX_NB_TH;
713

714
    if (openair0_cfg[0].duplex_mode == duplex_mode_TDD) {
Guido Casati's avatar
Guido Casati committed
715
716
717
718
719
720

      uint8_t    tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
      int   nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
      uint8_t  num_UL_slots = nrofUplinkSlots + (nrofUplinkSlots != 0);
      uint8_t first_tx_slot = tdd_period - num_UL_slots;

721
722
723
724
725
726
727
      if (slot_tx_usrp % tdd_period == first_tx_slot)
        flags = 2;
      else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1)
        flags = 3;
      else if (slot_tx_usrp % tdd_period > first_tx_slot)
        flags = 1;
    } else {
728
      flags = 1;
729
    }
730

731
    if (flags || IS_SOFTMODEM_RFSIM)
732
733
734
735
736
737
738
      AssertFatal(writeBlockSize ==
                  UE->rfdevice.trx_write_func(&UE->rfdevice,
                                              writeTimestamp,
                                              txp,
                                              writeBlockSize,
                                              UE->frame_parms.nb_antennas_tx,
                                              flags),"");
739
    
740
741
742
    for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
      memset(txp[i], 0, writeBlockSize);

743
    nbSlotProcessing++;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
744
    LOG_D(PHY,"Number of slots being processed at the moment: %d\n",nbSlotProcessing);
745
    pushTpool(&(get_nrUE_params()->Tpool), msgToPush);
Thomas Laurent's avatar
Thomas Laurent committed
746

Thomas Laurent's avatar
Thomas Laurent committed
747
748
749
750
751
  } // while !oai_exit

  return NULL;
}

752
void init_NR_UE(int nb_inst, char* rrc_config_path) {
Thomas Laurent's avatar
Thomas Laurent committed
753
754
  int inst;
  NR_UE_MAC_INST_t *mac_inst;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
755
756
  NR_UE_RRC_INST_t* rrc_inst;
  
Thomas Laurent's avatar
Thomas Laurent committed
757
  for (inst=0; inst < nb_inst; inst++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
758
759
760
    AssertFatal((rrc_inst = nr_l3_init_ue(rrc_config_path)) != NULL, "can not initialize RRC module\n");
    AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n");
    AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n");
761
762
763
764
765
766
767
768
769
770
771
  }
}

void init_NR_UE_threads(int nb_inst) {
  int inst;

  pthread_t threads[nb_inst];

  for (inst=0; inst < nb_inst; inst++) {
    PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];

Thomas Laurent's avatar
Thomas Laurent committed
772
    LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
Thomas Laurent's avatar
Thomas Laurent committed
773
    threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX);
774

775
     if(get_nrUE_params()->nr_dlsch_parallel)
776
777
778
779
     {
       pthread_t dlsch0_threads;
       threadCreate(&dlsch0_threads, dlsch_thread, (void *)UE, "DLthread", -1, OAI_PRIORITY_RT_MAX-1);
     }
Thomas Laurent's avatar
Thomas Laurent committed
780
781
782
  }
}

783
784
785
786
787
788
789
790
791
792
793
/* HACK: this function is needed to compile the UE
 * fix it somehow
 */
int8_t find_dlsch(uint16_t rnti,
                  PHY_VARS_eNB *eNB,
                  find_type_t type)
{
  printf("you cannot read this\n");
  abort();
}

794
void multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP) {}