nfapi_vnf.c 70.6 KB
Newer Older
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
/*
 * 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
 */

#define _GNU_SOURCE

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

34
#include "nfapi_nr_interface_scf.h"
35
36
37
38
39
#include "nfapi_vnf_interface.h"
#include "nfapi.h"
#include "vendor_ext.h"

#include "nfapi_vnf.h"
40
41
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
MaheshK1995's avatar
MaheshK1995 committed
42
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
43
#include <targets/RT/USER/lte-softmodem.h>
44
45

#include "common/ran_context.h"
MaheshK1995's avatar
MaheshK1995 committed
46
47
48

#define TEST

49
extern RAN_CONTEXT_t RC;
50
extern UL_RCC_IND_t  UL_RCC_INFO;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

typedef struct {
  uint8_t enabled;
  uint32_t rx_port;
  uint32_t tx_port;
  char tx_addr[80];
} udp_data;

typedef struct {
  uint16_t index;
  uint16_t id;
  uint8_t rfs[2];
  uint8_t excluded_rfs[2];

  udp_data udp;

  char local_addr[80];
  int local_port;

frtabu's avatar
frtabu committed
70
  char *remote_addr;
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
  int remote_port;

  uint8_t duplex_mode;
  uint16_t dl_channel_bw_support;
  uint16_t ul_channel_bw_support;
  uint8_t num_dl_layers_supported;
  uint8_t num_ul_layers_supported;
  uint16_t release_supported;
  uint8_t nmm_modes_supported;

  uint8_t dl_ues_per_subframe;
  uint8_t ul_ues_per_subframe;

  uint8_t first_subframe_ind;

  // timing information recevied from the vnf
  uint8_t timing_window;
  uint8_t timing_info_mode;
  uint8_t timing_info_period;

} phy_info;

typedef struct {
  uint16_t index;
  uint16_t band;
  int16_t max_transmit_power;
  int16_t min_transmit_power;
  uint8_t num_antennas_supported;
  uint32_t min_downlink_frequency;
  uint32_t max_downlink_frequency;
  uint32_t max_uplink_frequency;
  uint32_t min_uplink_frequency;
} rf_info;

typedef struct {

  int release;
  phy_info phys[2];
  rf_info rfs[2];

  uint8_t sync_mode;
  uint8_t location_mode;
  uint8_t location_coordinates[6];
  uint32_t dl_config_timing;
  uint32_t ul_config_timing;
  uint32_t tx_timing;
  uint32_t hi_dci0_timing;

  uint16_t max_phys;
  uint16_t max_total_bw;
  uint16_t max_total_dl_layers;
  uint16_t max_total_ul_layers;
  uint8_t shared_bands;
  uint8_t shared_pa;
  int16_t max_total_power;
  uint8_t oui;

  uint8_t wireshark_test_mode;

} pnf_info;

typedef struct mac mac_t;

typedef struct mac {

frtabu's avatar
frtabu committed
136
  void *user_data;
137

frtabu's avatar
frtabu committed
138
139
140
141
  void (*dl_config_req)(mac_t *mac, nfapi_dl_config_request_t *req);
  void (*ul_config_req)(mac_t *mac, nfapi_ul_config_request_t *req);
  void (*hi_dci0_req)(mac_t *mac, nfapi_hi_dci0_request_t *req);
  void (*tx_req)(mac_t *mac, nfapi_tx_request_t *req);
142
143
144
145
146
147
148
149
150
151
152
153
} mac_t;

typedef struct {

  int local_port;
  char local_addr[80];

  unsigned timing_window;
  unsigned periodic_timing_enabled;
  unsigned aperiodic_timing_enabled;
  unsigned periodic_timing_period;

frtabu's avatar
frtabu committed
154
  // This is not really the right place if we have multiple PHY,
155
156
157
158
159
  // should be part of the phy struct
  udp_data udp;

  uint8_t thread_started;

frtabu's avatar
frtabu committed
160
  nfapi_vnf_p7_config_t *config;
161

frtabu's avatar
frtabu committed
162
  mac_t *mac;
163
164
165
166
167
168
169
170
171
172
173

} vnf_p7_info;

typedef struct {

  uint8_t wireshark_test_mode;
  pnf_info pnfs[2];
  vnf_p7_info p7_vnfs[2];

} vnf_info;

frtabu's avatar
frtabu committed
174
int vnf_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) {
175
  //NFAPI_TRACE(NFAPI_TRACE_INFO, "vnf_pack_vendor_extension_tlv\n");
frtabu's avatar
frtabu committed
176
177
  nfapi_tl_t *tlv = (nfapi_tl_t *)ve;

178
  switch(tlv->tag) {
frtabu's avatar
frtabu committed
179
180
181
182
183
184
185
186
187
188
    case VENDOR_EXT_TLV_2_TAG: {
      //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n");
      vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)tlv;

      if(!push32(ve->dummy, ppWritePackedMsg, end))
        return 0;

      return 1;
    }
    break;
189
  }
frtabu's avatar
frtabu committed
190

191
192
193
  return -1;
}

frtabu's avatar
frtabu committed
194
int vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p4_p5_codec_config_t *codec) {
195
196
  return -1;
}
MaheshK1995's avatar
MaheshK1995 committed
197
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst);
198
199
200
void install_schedule_handlers(IF_Module_t *if_inst);
extern int single_thread_flag;
extern uint16_t sf_ahead;
201
extern uint16_t slot_ahead;
202
203
204
205

void oai_create_enb(void) {
  int bodge_counter=0;
  PHY_VARS_eNB *eNB = RC.eNB[0][0];
frtabu's avatar
frtabu committed
206
207
  printf("[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d single_thread_flag:%d if_inst:%p\n", eNB->Mod_id, eNB->CC_id, RC.nb_CC[0], eNB->abstraction_flag,
         eNB->single_thread_flag, eNB->if_inst);
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
  eNB->Mod_id  = bodge_counter;
  eNB->CC_id   = bodge_counter;
  eNB->abstraction_flag   = 0;
  eNB->single_thread_flag = 0;//single_thread_flag;
  RC.nb_CC[bodge_counter] = 1;

  if (eNB->if_inst==0) {
    eNB->if_inst = IF_Module_init(bodge_counter);
  }

  // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY
  // that will result in eNB->configured being set to TRUE.
  // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values
  if (RC.eNB[0][0]->if_inst==0 || RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0) {
    printf("RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it\n");
    install_schedule_handlers(RC.eNB[0][0]->if_inst);
  }

  do {
    printf("%s() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__);
    usleep(50000);
  } while(eNB->configured != 1);

  printf("%s() eNB is now configured\n", __FUNCTION__);
}

void oai_enb_init(void) {
  printf("%s() About to call init_eNB_afterRU()\n", __FUNCTION__);
  init_eNB_afterRU();
}

MaheshK1995's avatar
MaheshK1995 committed
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

void oai_create_gnb(void) {
  int bodge_counter=0;
  PHY_VARS_gNB *gNB = RC.gNB[0];
  RC.nb_nr_CC = (int *)malloc(sizeof(int)); // TODO: find a better function to place this in
  
  gNB->Mod_id  = bodge_counter;
  gNB->CC_id   = bodge_counter;
  gNB->abstraction_flag   = 0;
  gNB->single_thread_flag = 0;//single_thread_flag;
  RC.nb_nr_CC[bodge_counter] = 1;

  if (gNB->if_inst==0) {
    gNB->if_inst = NR_IF_Module_init(bodge_counter);
  }
  

  // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY
  // that will result in gNB->configured being set to TRUE.
  // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values
  if (RC.gNB[0]->if_inst==0 || RC.gNB[0]->if_inst->NR_PHY_config_req==0 || RC.gNB[0]->if_inst->NR_Schedule_response==0) {
    printf("RC.gNB[0][0]->if_inst->NR_PHY_config_req is not installed - install it\n");
    install_nr_schedule_handlers(RC.gNB[0]->if_inst);
  }

  do {
    printf("%s() Waiting for gNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__);
    usleep(50000);
  } while(gNB->configured != 1);

  printf("%s() gNB is now configured\n", __FUNCTION__);
}

frtabu's avatar
frtabu committed
272
int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
273
  printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
Mahesh K's avatar
Mahesh K committed
274
  oai_create_enb();
275
276
277
278
279
280
281
  nfapi_pnf_param_request_t req;
  memset(&req, 0, sizeof(req));
  req.header.message_id = NFAPI_PNF_PARAM_REQUEST;
  nfapi_vnf_pnf_param_req(config, p5_idx, &req);
  return 0;
}

Mahesh K's avatar
Mahesh K committed
282
283
284
285
286
287
288
289
290
int pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
  printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
  oai_create_gnb();
  nfapi_nr_pnf_param_request_t req;
  memset(&req, 0, sizeof(req));
  req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST;
  nfapi_nr_vnf_pnf_param_req(config, p5_idx, &req);
  return 0;
}
Mahesh K's avatar
Mahesh K committed
291

frtabu's avatar
frtabu committed
292
int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
293
  printf("[VNF] pnf disconnection indication idx:%d\n", p5_idx);
frtabu's avatar
frtabu committed
294
  vnf_info *vnf = (vnf_info *)(config->user_data);
295
296
  pnf_info *pnf = vnf->pnfs;
  phy_info *phy = pnf->phys;
frtabu's avatar
frtabu committed
297
  vnf_p7_info *p7_vnf = vnf->p7_vnfs;
298
299
300
  nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id);
  return 0;
}
Mahesh K's avatar
Mahesh K committed
301

Mahesh K's avatar
Mahesh K committed
302
int pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_param_response_t *resp) {
303
  printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code);
frtabu's avatar
frtabu committed
304
  vnf_info *vnf = (vnf_info *)(config->user_data);
305
306
  pnf_info *pnf = vnf->pnfs;

frtabu's avatar
frtabu committed
307
  for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) {
308
    phy_info phy;
309
    memset(&phy,0,sizeof(phy));
310
311
312
313
    phy.index = resp->pnf_phy.phy[i].phy_config_index;
    printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index);
    nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id));

frtabu's avatar
frtabu committed
314
    for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) {
315
316
317
318
319
320
      printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index);
      phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index;
    }

    pnf->phys[0] = phy;
  }
Mahesh K's avatar
Mahesh K committed
321
  nfapi_nr_pnf_config_request_t req;
Mahesh K's avatar
Mahesh K committed
322
323
324
325
326
327
328
329
330
331
  memset(&req, 0, sizeof(req));
  req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
  req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG;
  req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size();
  printf("DJP:Hard coded num phy rf to 2\n");

  for(unsigned i = 0; i < 2; ++i) {
    req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id;
    req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index;
    req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0];
332
  }
Mahesh K's avatar
Mahesh K committed
333

Mahesh K's avatar
Mahesh K committed
334
  nfapi_nr_vnf_pnf_config_req(config, p5_idx, &req);
Mahesh K's avatar
Mahesh K committed
335
336
  return 0;
}
Mahesh K's avatar
Mahesh K committed
337

Mahesh K's avatar
Mahesh K committed
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_response_t *resp) {
  printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code);
  vnf_info *vnf = (vnf_info *)(config->user_data);
  pnf_info *pnf = vnf->pnfs;

  for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) {
    phy_info phy;
    memset(&phy,0,sizeof(phy));
    phy.index = resp->pnf_phy.phy[i].phy_config_index;
    printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index);
    nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id));

    for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) {
      printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index);
      phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index;
    }

    pnf->phys[0] = phy;
  }
Mahesh K's avatar
Mahesh K committed
357
358
359
360
361
362
363
  for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) {
    rf_info rf;
    memset(&rf,0,sizeof(rf));
    rf.index = resp->pnf_rf.rf[i].rf_config_index;
    printf("[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index);
    pnf->rfs[0] = rf;
  }
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  nfapi_pnf_config_request_t req;
  memset(&req, 0, sizeof(req));
  req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
  req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG;
  req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size();
  printf("DJP:Hard coded num phy rf to 2\n");

  for(unsigned i = 0; i < 2; ++i) {
    req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id;
    req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index;
    req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0];
  }

  nfapi_vnf_pnf_config_req(config, p5_idx, &req);
  return 0;
}

Mahesh K's avatar
Mahesh K committed
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
int pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_config_response_t *resp) {
  printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length);

  if(1) {
    nfapi_nr_pnf_start_request_t req;
    memset(&req, 0, sizeof(req));
    req.header.phy_id = resp->header.phy_id;
    req.header.message_id = NFAPI_PNF_START_REQUEST;
    nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req);
  } else {
    // Rather than send the pnf_start_request we will demonstrate
    // sending a vendor extention message. The start request will be
    // send when the vendor extension response is received
    //vnf_info* vnf = (vnf_info*)(config->user_data);
    vendor_ext_p5_req req;
    memset(&req, 0, sizeof(req));
    req.header.message_id = P5_VENDOR_EXT_REQ;
    req.dummy1 = 45;
    req.dummy2 = 1977;
    nfapi_vnf_vendor_extension(config, p5_idx, &req.header);
  }

  return 0;
}

frtabu's avatar
frtabu committed
406
int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_response_t *resp) {
407
408
409
  printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length);

  if(1) {
frtabu's avatar
frtabu committed
410
411
412
413
414
    nfapi_pnf_start_request_t req;
    memset(&req, 0, sizeof(req));
    req.header.phy_id = resp->header.phy_id;
    req.header.message_id = NFAPI_PNF_START_REQUEST;
    nfapi_vnf_pnf_start_req(config, p5_idx, &req);
415
416
417
  } else {
    // Rather than send the pnf_start_request we will demonstrate
    // sending a vendor extention message. The start request will be
frtabu's avatar
frtabu committed
418
    // send when the vendor extension response is received
419
420
421
422
423
424
425
426
    //vnf_info* vnf = (vnf_info*)(config->user_data);
    vendor_ext_p5_req req;
    memset(&req, 0, sizeof(req));
    req.header.message_id = P5_VENDOR_EXT_REQ;
    req.dummy1 = 45;
    req.dummy2 = 1977;
    nfapi_vnf_vendor_extension(config, p5_idx, &req.header);
  }
frtabu's avatar
frtabu committed
427

428
429
430
  return 0;
}

431
int wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) {
Mahesh K's avatar
Mahesh K committed
432
433
434
  struct timespec curr_t;
  clock_gettime(CLOCK_MONOTONIC,&curr_t);
 //printf("\n wake_gNB_rxtx before assignment sfn:%d slot:%d TIME %d.%d",sfn,slot,curr_t.tv_sec,curr_t.tv_nsec);
435
436
437
438
439
440
441
  gNB_L1_proc_t *proc=&gNB->proc;
  gNB_L1_rxtx_proc_t *L1_proc= (slot&1)? &proc->L1_proc : &proc->L1_proc_tx;

  NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
  //printf("%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf);
  //int i;
  struct timespec wait;
442
443
  clock_gettime(CLOCK_REALTIME, &wait);
  wait.tv_sec = 0;
Mahesh K's avatar
Mahesh K committed
444
  wait.tv_nsec +=5000L;
445
  //wait.tv_nsec = 0;
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
  // wake up TX for subframe n+sf_ahead
  // lock the TX mutex and make sure the thread is ready
  if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
    LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
    exit_fun( "error locking mutex_rxtx" );
    return(-1);
  }

  {
    static uint16_t old_slot = 0;
    static uint16_t old_sfn = 0;
    proc->slot_rx = old_slot;
    proc->frame_rx = old_sfn;
    // Try to be 1 frame back
    old_slot = slot;
    old_sfn = sfn;
462
    //printf("\n wake_gNB_rxtx after assignment sfn:%d slot:%d",proc->frame_rx,proc->slot_rx);
463
464
465
466
467
468
469
470
471
472
473
    if (old_slot == 0 && old_sfn % 100 == 0) LOG_W( PHY,"[gNB] sfn/slot:%d%d old_sfn/slot:%d%d proc[rx:%d%d]\n", sfn, slot, old_sfn, old_slot, proc->frame_rx, proc->slot_rx);
  }

  ++L1_proc->instance_cnt;
  //LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx);
  // We have just received and processed the common part of a subframe, say n.
  // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
  // transmitted timestamp of the next TX slot (first).
  // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
  // we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti,
  // and proc->subframe_tx = proc->subframe_rx+sf_ahead
Mahesh K's avatar
Mahesh K committed
474
  L1_proc->timestamp_tx = proc->timestamp_rx + (slot_ahead *fp->samples_per_subframe);
475
476
  L1_proc->frame_rx     = proc->frame_rx;
  L1_proc->slot_rx      = proc->slot_rx;
477
  L1_proc->frame_tx     = (L1_proc->slot_rx > (19-slot_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
478
479
  L1_proc->slot_tx      = (L1_proc->slot_rx + slot_ahead)%20;

Mahesh K's avatar
Mahesh K committed
480
  //LOG_I(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx, L1_proc->frame_rx, L1_proc->slot_rx);
481
  //printf("\nEntering wake_gNB_rxtx sfn %d slot %d\n",L1_proc->frame_rx,L1_proc->slot_rx);
482
483
484
  // the thread can now be woken up
  if (pthread_cond_signal(&L1_proc->cond) != 0) {
    LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n");
485
    exit_fun( "ERROR pthread_clond_signal" );
486
487
488
489
490
491
492
493
494
    return(-1);
  }

  //LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__);
  pthread_mutex_unlock( &L1_proc->mutex );
  //LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__);
  return(0);
}

495
int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) {
496
497
  L1_proc_t *proc=&eNB->proc;
  L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx;
498
499
500
501
502
503
504
505
506
  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
  //printf("%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf);
  //int i;
  struct timespec wait;
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;

  // wake up TX for subframe n+sf_ahead
  // lock the TX mutex and make sure the thread is ready
507
508
509
510
511
  //if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
  //  LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt );
  //  exit_fun( "error locking mutex_rxtx" );
  //  return(-1);
  //}
512
513
514
515
516
517
518
519
520
521

  {
    static uint16_t old_sf = 0;
    static uint16_t old_sfn = 0;
    proc->subframe_rx = old_sf;
    proc->frame_rx = old_sfn;
    // Try to be 1 frame back
    old_sf = sf;
    old_sfn = sfn;

Robert Schmidt's avatar
Robert Schmidt committed
522
523
524
525
526
527
528
529
530
    if (old_sf == 0 && old_sfn % 100==0)
      LOG_D(PHY,
            "[eNB] sfn/sf:%d%d old_sfn/sf:%d%d proc[rx:%d%d]\n",
            sfn,
            sf,
            old_sfn,
            old_sf,
            proc->frame_rx,
            proc->subframe_rx);
531
  }
HARADA Masayuki's avatar
HARADA Masayuki committed
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  // wake up TX for subframe n+sf_ahead
  // lock the TX mutex and make sure the thread is ready
  if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt );
      //exit_fun( "error locking mutex_rxtx" );
      return(-1);
  }
  static int busy_log_cnt=0;
  if(L1_proc->instance_cnt < 0){
    ++L1_proc->instance_cnt;
    if(busy_log_cnt!=0){
      LOG_E(MAC,"RCC singal to rxtx frame %d subframe %d busy end %d (frame %d subframe %d)\n",L1_proc->frame_rx,L1_proc->subframe_rx,busy_log_cnt,proc->frame_rx,proc->subframe_rx);
    }
    busy_log_cnt=0;
  }else{
    if(busy_log_cnt==0){
      LOG_E(MAC,"RCC singal to rxtx frame %d subframe %d busy %d (frame %d subframe %d)\n",L1_proc->frame_rx,L1_proc->subframe_rx,L1_proc->instance_cnt,proc->frame_rx,proc->subframe_rx);
    }
    pthread_mutex_unlock( &L1_proc->mutex );
    busy_log_cnt++;
    return(0);
  }

  pthread_mutex_unlock( &L1_proc->mutex );
556

Wang Tsu-Han's avatar
Wang Tsu-Han committed
557
  //LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx);
558
559
560
561
562
563
  // We have just received and processed the common part of a subframe, say n.
  // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
  // transmitted timestamp of the next TX slot (first).
  // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
  // we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti,
  // and proc->subframe_tx = proc->subframe_rx+sf_ahead
Wang Tsu-Han's avatar
Wang Tsu-Han committed
564
565
566
567
568
  L1_proc->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
  L1_proc->frame_rx     = proc->frame_rx;
  L1_proc->subframe_rx  = proc->subframe_rx;
  L1_proc->frame_tx     = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
  L1_proc->subframe_tx  = (L1_proc->subframe_rx + sf_ahead)%10;
569

Wang Tsu-Han's avatar
Wang Tsu-Han committed
570
  //LOG_D(PHY, "sfn/sf:%d%d proc[rx:%d%d] L1_proc[instance_cnt_rxtx:%d rx:%d%d] About to wake rxtx thread\n\n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx, L1_proc->frame_rx, L1_proc->subframe_rx);
571
572

  // the thread can now be woken up
Wang Tsu-Han's avatar
Wang Tsu-Han committed
573
  if (pthread_cond_signal(&L1_proc->cond) != 0) {
574
575
576
577
578
579
580
581
582
583
584
585
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }

  return(0);
}

extern pthread_cond_t nfapi_sync_cond;
extern pthread_mutex_t nfapi_sync_mutex;
extern int nfapi_sync_var;

frtabu's avatar
frtabu committed
586
int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) {
587
588
  printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");

frtabu's avatar
frtabu committed
589
  if (sync==1 && nfapi_sync_var!=0) {
Mahesh K's avatar
Mahesh K committed
590
    
591
592
593
594
595
596
597
598
599
600
    printf("[VNF] Signal to OAI main code that it can go\n");
    pthread_mutex_lock(&nfapi_sync_mutex);
    nfapi_sync_var=0;
    pthread_cond_broadcast(&nfapi_sync_cond);
    pthread_mutex_unlock(&nfapi_sync_mutex);
  }

  return(0);
}

601
602
603
604
605
606
607
608
609
610
611
612

int phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot) {
  static uint8_t first_time = 1;

  if (first_time) {
    printf("[VNF] slot indication %d\n", NFAPI_SFNSLOT2DEC(sfn, slot));
    first_time = 0;
  }

  if (RC.gNB && RC.gNB[0]->configured) {
    // uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf);
    // uint16_t sf = NFAPI_SFNSF2SF(sfn_sf);
613
    LOG_D(PHY,"[VNF] slot indication sfn:%d sf:%d\n", sfn, slot);
614
615
616
617
618
619
620
621
622
623
    wake_gNB_rxtx(RC.gNB[0], sfn, slot); // DONE: find NR equivalent
  } else {
    printf("[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB);

    if (RC.gNB) printf("RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured);
  }

  return 0;
}

frtabu's avatar
frtabu committed
624
int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) {
625
  static uint8_t first_time = 1;
frtabu's avatar
frtabu committed
626

627
628
629
630
631
632
633
634
635
636
637
638
  if (first_time) {
    printf("[VNF] subframe indication %d\n", NFAPI_SFNSF2DEC(sfn_sf));
    first_time = 0;
  }

  if (RC.eNB && RC.eNB[0][0]->configured) {
    uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf);
    uint16_t sf = NFAPI_SFNSF2SF(sfn_sf);
    //LOG_D(PHY,"[VNF] subframe indication sfn_sf:%d sfn:%d sf:%d\n", sfn_sf, sfn, sf);
    wake_eNB_rxtx(RC.eNB[0][0], sfn, sf);
  } else {
    printf("[VNF] %s() RC.eNB:%p\n", __FUNCTION__, RC.eNB);
frtabu's avatar
frtabu committed
639

640
641
642
643
644
645
    if (RC.eNB) printf("RC.eNB[0][0]->configured:%d\n", RC.eNB[0][0]->configured);
  }

  return 0;
}

frtabu's avatar
frtabu committed
646
int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indication_t *ind) {
647
648
649
650
  LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_preambles:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles);
  struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
  printf("[VNF] RACH_IND eNB:%p sfn_sf:%d number_of_preambles:%d\n", eNB, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles);
  pthread_mutex_lock(&eNB->UL_INFO_mutex);
651
652
653
654
655
656
657
658
659
660
  if(NFAPI_MODE == NFAPI_MODE_VNF){
    int8_t index = -1;
    for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
      if((UL_RCC_INFO.rach_ind[i].header.message_id == 0) && (index == -1)){
        index = i;
        break;
      }
    }
    if(index == -1){
      LOG_E(MAC,"phy_rach_indication : num of rach reach max \n");
661
      pthread_mutex_unlock(&eNB->UL_INFO_mutex);
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
      return 0;
    }
    UL_RCC_INFO.rach_ind[index] = *ind;

    if (ind->rach_indication_body.number_of_preambles > 0)
      UL_RCC_INFO.rach_ind[index].rach_indication_body.preamble_list = malloc(sizeof(nfapi_preamble_pdu_t)*ind->rach_indication_body.number_of_preambles );

    for (int i=0; i<ind->rach_indication_body.number_of_preambles; i++) {
      if (ind->rach_indication_body.preamble_list[i].preamble_rel8.tl.tag == NFAPI_PREAMBLE_REL8_TAG) {

        printf("preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n",
              i,
              ind->rach_indication_body.preamble_list[i].preamble_rel8.rnti,
              ind->rach_indication_body.preamble_list[i].preamble_rel8.preamble,
              ind->rach_indication_body.preamble_list[i].preamble_rel8.timing_advance
              );
      }
      if(ind->rach_indication_body.preamble_list[i].preamble_rel13.tl.tag == NFAPI_PREAMBLE_REL13_TAG) {
        printf("RACH PREAMBLE REL13 present\n");
      }

      UL_RCC_INFO.rach_ind[index].rach_indication_body.preamble_list[i] = ind->rach_indication_body.preamble_list[i];
    }
  }else{
686
687
688
  eNB->UL_INFO.rach_ind = *ind;
  eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = eNB->preamble_list;

frtabu's avatar
frtabu committed
689
  for (int i=0; i<ind->rach_indication_body.number_of_preambles; i++) {
690
    if (ind->rach_indication_body.preamble_list[i].preamble_rel8.tl.tag == NFAPI_PREAMBLE_REL8_TAG) {
frtabu's avatar
frtabu committed
691
692
693
694
695
696
      printf("preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n",
             i,
             ind->rach_indication_body.preamble_list[i].preamble_rel8.rnti,
             ind->rach_indication_body.preamble_list[i].preamble_rel8.preamble,
             ind->rach_indication_body.preamble_list[i].preamble_rel8.timing_advance
            );
697
698
699
700
701
702
703
704
    }

    if(ind->rach_indication_body.preamble_list[i].preamble_rel13.tl.tag == NFAPI_PREAMBLE_REL13_TAG) {
      printf("RACH PREAMBLE REL13 present\n");
    }

    eNB->preamble_list[i] = ind->rach_indication_body.preamble_list[i];
  }
705
  }
frtabu's avatar
frtabu committed
706
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
707
708
709
710
711
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_rach_ind(p7_vnf->mac, ind);
  return 1;
}

frtabu's avatar
frtabu committed
712
int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind) {
713
714
715
  struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
  LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_harqs:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->harq_indication_body.number_of_harqs);
  pthread_mutex_lock(&eNB->UL_INFO_mutex);
716
717
718
719
720
721
722
723
724
725
  if(NFAPI_MODE == NFAPI_MODE_VNF){
    int8_t index = -1;
    for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
      if((UL_RCC_INFO.harq_ind[i].header.message_id == 0) && (index == -1)){
        index = i;
        break;
      }
    }
    if(index == -1){
      LOG_E(MAC,"phy_harq_indication : num of harq reach max \n");
726
      pthread_mutex_unlock(&eNB->UL_INFO_mutex);
727
728
729
730
731
732
733
734
735
736
      return 0;
    }
    UL_RCC_INFO.harq_ind[index] = *ind;

    if (ind->harq_indication_body.number_of_harqs > 0)
      UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list = malloc(sizeof(nfapi_harq_indication_pdu_t)*ind->harq_indication_body.number_of_harqs );
    for (int i=0; i<ind->harq_indication_body.number_of_harqs; i++) {
        memcpy(&UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list[i], &ind->harq_indication_body.harq_pdu_list[i], sizeof(nfapi_harq_indication_pdu_t));
    }
  }else{
737
738
739
740
741
742
  eNB->UL_INFO.harq_ind = *ind;
  eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list;

  for (int i=0; i<ind->harq_indication_body.number_of_harqs; i++) {
    memcpy(&eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i], &ind->harq_indication_body.harq_pdu_list[i], sizeof(eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i]));
  }
743
  }
744
745
746
747
748
749
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_harq_ind(p7_vnf->mac, ind);
  return 1;
}

frtabu's avatar
frtabu committed
750
int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_t *ind) {
751
752
  struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
  pthread_mutex_lock(&eNB->UL_INFO_mutex);
753
754
755
756
757
758
759
760
761
762
763
764
765
  if(NFAPI_MODE == NFAPI_MODE_VNF){
    int8_t index = -1;
    for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
      if((UL_RCC_INFO.crc_ind[i].header.message_id == 0) && (index == -1)){
        index = i;
      }
      if(UL_RCC_INFO.rx_ind[i].sfn_sf == ind->sfn_sf){
        index = i;
        break;
      }
    }
    if(index == -1){
      LOG_E(MAC,"phy_crc_indication : num of crc reach max \n");
766
      pthread_mutex_unlock(&eNB->UL_INFO_mutex);
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
      return 0;
    }
    UL_RCC_INFO.crc_ind[index] = *ind;

    if (ind->crc_indication_body.number_of_crcs > 0)
      UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list = malloc(sizeof(nfapi_crc_indication_pdu_t)*ind->crc_indication_body.number_of_crcs );

    for (int i=0; i<ind->crc_indication_body.number_of_crcs; i++) {
      memcpy(&UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list[i], &ind->crc_indication_body.crc_pdu_list[i], sizeof(ind->crc_indication_body.crc_pdu_list[0]));

      LOG_D(MAC, "%s() NFAPI SFN/SF:%d CRC_IND:number_of_crcs:%u UL_INFO:crcs:%d PDU[%d] rnti:%04x UL_INFO:rnti:%04x\n",
          __FUNCTION__,
          NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, UL_RCC_INFO.crc_ind[index].crc_indication_body.number_of_crcs,
          i,
          ind->crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti,
          UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti);
    }
  }else{
785
786
787
788
789
790
791
  eNB->UL_INFO.crc_ind = *ind;
  nfapi_crc_indication_t *dest_ind = &eNB->UL_INFO.crc_ind;
  nfapi_crc_indication_pdu_t *dest_pdu_list = eNB->crc_pdu_list;
  *dest_ind = *ind;
  dest_ind->crc_indication_body.crc_pdu_list = dest_pdu_list;

  if (ind->crc_indication_body.number_of_crcs==0)
frtabu's avatar
frtabu committed
792
793
    LOG_D(MAC, "%s() NFAPI SFN/SF:%d IND:number_of_crcs:%u UL_INFO:crcs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs,
          eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs);
794
795
796

  for (int i=0; i<ind->crc_indication_body.number_of_crcs; i++) {
    memcpy(&dest_ind->crc_indication_body.crc_pdu_list[i], &ind->crc_indication_body.crc_pdu_list[i], sizeof(ind->crc_indication_body.crc_pdu_list[0]));
frtabu's avatar
frtabu committed
797
798
799
800
801
802
    LOG_D(MAC, "%s() NFAPI SFN/SF:%d CRC_IND:number_of_crcs:%u UL_INFO:crcs:%d PDU[%d] rnti:%04x UL_INFO:rnti:%04x\n",
          __FUNCTION__,
          NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
          i,
          ind->crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti,
          eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti);
803
  }
804
  }
805
806
807
808
809
810
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_crc_ind(p7_vnf->mac, ind);
  return 1;
}

frtabu's avatar
frtabu committed
811
int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t *ind) {
812
813
814
815
816
817
818
  struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];

  if (ind->rx_indication_body.number_of_pdus==0) {
    LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_pdus:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus);
  }

  pthread_mutex_lock(&eNB->UL_INFO_mutex);
819
820
821
822
823
824
825
826
827
828
829
830
831
  if(NFAPI_MODE == NFAPI_MODE_VNF){
    int8_t index = -1;
    for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
      if((UL_RCC_INFO.rx_ind[i].header.message_id == 0) && (index == -1)){
        index = i;
      }
      if(UL_RCC_INFO.crc_ind[i].sfn_sf == ind->sfn_sf){
        index = i;
        break;
      }
    }
    if(index == -1){
      LOG_E(MAC,"phy_rx_indication : num of rx reach max \n");
832
      pthread_mutex_unlock(&eNB->UL_INFO_mutex);
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
      return 0;
    }
    UL_RCC_INFO.rx_ind[index] = *ind;

    if (ind->rx_indication_body.number_of_pdus > 0)
      UL_RCC_INFO.rx_ind[index].rx_indication_body.rx_pdu_list = malloc(sizeof(nfapi_rx_indication_pdu_t)*ind->rx_indication_body.number_of_pdus );

    for (int i=0; i<ind->rx_indication_body.number_of_pdus; i++) {
      nfapi_rx_indication_pdu_t *dest_pdu = &UL_RCC_INFO.rx_ind[index].rx_indication_body.rx_pdu_list[i];
      nfapi_rx_indication_pdu_t *src_pdu = &ind->rx_indication_body.rx_pdu_list[i];

      memcpy(dest_pdu, src_pdu, sizeof(*src_pdu));
      // DJP - TODO FIXME - intentional memory leak
      if(dest_pdu->rx_indication_rel8.length > 0){
        dest_pdu->data = malloc(dest_pdu->rx_indication_rel8.length);
        memcpy(dest_pdu->data, src_pdu->data, dest_pdu->rx_indication_rel8.length);
      }else{
        dest_pdu->data = NULL;
      }

      LOG_D(PHY, "%s() NFAPI SFN/SF:%d PDUs:%d [PDU:%d] handle:%d rnti:%04x length:%d offset:%d ul_cqi:%d ta:%d data:%p\n",
          __FUNCTION__,
          NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, i,
          dest_pdu->rx_ue_information.handle,
          dest_pdu->rx_ue_information.rnti,
          dest_pdu->rx_indication_rel8.length,
          dest_pdu->rx_indication_rel8.offset,
          dest_pdu->rx_indication_rel8.ul_cqi,
          dest_pdu->rx_indication_rel8.timing_advance,
          dest_pdu->data
          );
    }
  }else{
866
867
868
869
870
871
872
873
874
875
876
877
878
  nfapi_rx_indication_t *dest_ind = &eNB->UL_INFO.rx_ind;
  nfapi_rx_indication_pdu_t *dest_pdu_list = eNB->rx_pdu_list;
  *dest_ind = *ind;
  dest_ind->rx_indication_body.rx_pdu_list = dest_pdu_list;

  for(int i=0; i<ind->rx_indication_body.number_of_pdus; i++) {
    nfapi_rx_indication_pdu_t *dest_pdu = &dest_ind->rx_indication_body.rx_pdu_list[i];
    nfapi_rx_indication_pdu_t *src_pdu = &ind->rx_indication_body.rx_pdu_list[i];
    memcpy(dest_pdu, src_pdu, sizeof(*src_pdu));
    // DJP - TODO FIXME - intentional memory leak
    dest_pdu->data = malloc(dest_pdu->rx_indication_rel8.length);
    memcpy(dest_pdu->data, src_pdu->data, dest_pdu->rx_indication_rel8.length);
    LOG_D(PHY, "%s() NFAPI SFN/SF:%d PDUs:%d [PDU:%d] handle:%d rnti:%04x length:%d offset:%d ul_cqi:%d ta:%d data:%p\n",
frtabu's avatar
frtabu committed
879
880
881
882
883
884
885
886
887
888
          __FUNCTION__,
          NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, i,
          dest_pdu->rx_ue_information.handle,
          dest_pdu->rx_ue_information.rnti,
          dest_pdu->rx_indication_rel8.length,
          dest_pdu->rx_indication_rel8.offset,
          dest_pdu->rx_indication_rel8.ul_cqi,
          dest_pdu->rx_indication_rel8.timing_advance,
          dest_pdu->data
         );
889
  }
890
  }
891
892
893
894
895
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_rx_ind(p7_vnf->mac, ind);
  return 1;
}
frtabu's avatar
frtabu committed
896
int phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind) {
897
898
899
900
901
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_srs_ind(p7_vnf->mac, ind);
  return 1;
}

frtabu's avatar
frtabu committed
902
int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind) {
903
904
905
  struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
  LOG_D(MAC, "%s() NFAPI SFN/SF:%d srs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->sr_indication_body.number_of_srs);
  pthread_mutex_lock(&eNB->UL_INFO_mutex);
906
907
908
909
910
911
912
913
914
915
  if(NFAPI_MODE == NFAPI_MODE_VNF){
    int8_t index = -1;
    for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
      if((UL_RCC_INFO.sr_ind[i].header.message_id == 0) && (index == -1)){
        index = i;
        break;
      }
    }
    if(index == -1){
      LOG_E(MAC,"phy_sr_indication : num of sr reach max \n");
916
      pthread_mutex_unlock(&eNB->UL_INFO_mutex);
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
      return 0;
    }
    UL_RCC_INFO.sr_ind[index] = *ind;
    LOG_D(MAC,"%s() UL_INFO[%d].sr_ind.sr_indication_body.number_of_srs:%d\n", __FUNCTION__, index, eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs);
    if (ind->sr_indication_body.number_of_srs > 0)
      UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list = malloc(sizeof(nfapi_sr_indication_pdu_t)*ind->sr_indication_body.number_of_srs );

    for (int i=0; i<ind->sr_indication_body.number_of_srs; i++) {
        nfapi_sr_indication_pdu_t *dest_pdu = &UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list[i];
        nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i];

        LOG_D(MAC, "SR_IND[PDU:%d %d][rnti:%x cqi:%d channel:%d]\n", index, i, src_pdu->rx_ue_information.rnti, src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel);

        memcpy(dest_pdu, src_pdu, sizeof(*src_pdu));
    }
  }else{
933
934
935
936
937
938
  nfapi_sr_indication_t *dest_ind = &eNB->UL_INFO.sr_ind;
  nfapi_sr_indication_pdu_t *dest_pdu_list = eNB->sr_pdu_list;
  *dest_ind = *ind;
  dest_ind->sr_indication_body.sr_pdu_list = dest_pdu_list;
  LOG_D(MAC,"%s() eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs:%d\n", __FUNCTION__, eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs);

frtabu's avatar
frtabu committed
939
  for (int i=0; i<eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs; i++) {
940
941
942
943
944
    nfapi_sr_indication_pdu_t *dest_pdu = &dest_ind->sr_indication_body.sr_pdu_list[i];
    nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i];
    LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel);
    memcpy(dest_pdu, src_pdu, sizeof(*src_pdu));
  }
945
  }
946
947
948
949
950
951
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_sr_ind(p7_vnf->mac, ind);
  return 1;
}

frtabu's avatar
frtabu committed
952
int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind) {
953
954
955
956
957
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_cqi_ind(p7_vnf->mac, ind);
  struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
  LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_cqis:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->cqi_indication_body.number_of_cqis);
  pthread_mutex_lock(&eNB->UL_INFO_mutex);
958
959
960
961
962
963
964
965
966
967
  if(NFAPI_MODE == NFAPI_MODE_VNF){
    int8_t index = -1;
    for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
      if((UL_RCC_INFO.cqi_ind[i].header.message_id == 0) && (index == -1)){
        index = i;
        break;
      }
    }
    if(index == -1){
      LOG_E(MAC,"phy_cqi_indication : num of cqi reach max \n");
968
      pthread_mutex_unlock(&eNB->UL_INFO_mutex);
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
      return 0;
    }
    UL_RCC_INFO.cqi_ind[index] = *ind;
    if (ind->cqi_indication_body.number_of_cqis > 0){
      UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list = malloc(sizeof(nfapi_cqi_indication_pdu_t)*ind->cqi_indication_body.number_of_cqis );
      UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list = malloc(sizeof(nfapi_cqi_indication_raw_pdu_t)*ind->cqi_indication_body.number_of_cqis );
    }
    for (int i=0; i<ind->cqi_indication_body.number_of_cqis; i++) {
        nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i];
        LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti,
                    src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel);
        memcpy(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list[i],
               src_pdu, sizeof(nfapi_cqi_indication_pdu_t));

        memcpy(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list[i],
               &ind->cqi_indication_body.cqi_raw_pdu_list[i], sizeof(nfapi_cqi_indication_raw_pdu_t));
    }
  }else{
987
988
989
990
991
992
993
994
995
996
997
998
999
  nfapi_cqi_indication_t *dest_ind = &eNB->UL_INFO.cqi_ind;
  *dest_ind = *ind;
  dest_ind->cqi_indication_body.cqi_pdu_list = ind->cqi_indication_body.cqi_pdu_list;
  dest_ind->cqi_indication_body.cqi_raw_pdu_list = ind->cqi_indication_body.cqi_raw_pdu_list;
  for(int i=0; i<ind->cqi_indication_body.number_of_cqis; i++) {
    nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i];
    LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti,
                src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel);
    memcpy(&dest_ind->cqi_indication_body.cqi_pdu_list[i],
           src_pdu, sizeof(nfapi_cqi_indication_pdu_t));
    memcpy(&dest_ind->cqi_indication_body.cqi_raw_pdu_list[i],
           &ind->cqi_indication_body.cqi_raw_pdu_list[i], sizeof(nfapi_cqi_indication_raw_pdu_t));
  }
1000
  }
1001
1002
1003
1004
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
  return 1;
}

frtabu's avatar
frtabu committed
1005
int phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind) {
1006
1007
1008
1009
1010
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_lbt_dl_ind(p7_vnf->mac, ind);
  return 1;
}

frtabu's avatar
frtabu committed
1011
int phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind) {
1012
1013
1014
1015
1016
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_nb_harq_ind(p7_vnf->mac, ind);
  return 1;
}

frtabu's avatar
frtabu committed
1017
int phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind) {
1018
1019
1020
1021
1022
  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
  //mac_nrach_ind(p7_vnf->mac, ind);
  return 1;
}

frtabu's avatar
frtabu committed
1023
void *vnf_allocate(size_t size) {
1024
  //return (void*)memory_pool::allocate(size);
frtabu's avatar
frtabu committed
1025
  return (void *)malloc(size);
1026
1027
}

frtabu's avatar
frtabu committed
1028
void vnf_deallocate(void *ptr) {
1029
1030
1031
1032
1033
  //memory_pool::deallocate((uint8_t*)ptr);
  free(ptr);
}


frtabu's avatar
frtabu committed
1034
void vnf_trace(nfapi_trace_level_t nfapi_level, const char *message, ...) {
1035
1036
  va_list args;
  va_start(args, message);
1037
  VLOG( NFAPI_VNF, nfapitooai_level(nfapi_level), message, args);
1038
1039
1040
  va_end(args);
}

frtabu's avatar
frtabu committed
1041
1042
int phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg) {
  if(msg->message_id == P7_VENDOR_EXT_IND) {
1043
1044
    //vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg;
    //printf("[VNF] vendor_ext (error_code:%d)\n", ind->error_code);
frtabu's avatar
frtabu committed
1045
  } else {
1046
1047
    printf("[VNF] unknown %02x\n", msg->message_id);
  }
frtabu's avatar
frtabu committed
1048

1049
1050
1051
  return 0;
}

frtabu's avatar
frtabu committed
1052
1053
nfapi_p7_message_header_t *phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) {
  if(message_id == P7_VENDOR_EXT_IND) {
1054
    *msg_size = sizeof(vendor_ext_p7_ind);
frtabu's avatar
frtabu committed
1055
    return (nfapi_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_ind));
1056
  }
frtabu's avatar
frtabu committed
1057

1058
1059
1060
  return 0;
}

frtabu's avatar
frtabu committed
1061
void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
1062
1063
1064
  free(header);
}

frtabu's avatar
frtabu committed
1065
int phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p7_codec_config_t *codec) {
1066
1067
1068
1069
1070
1071
  (void)tl;
  (void)ppReadPackedMessage;
  (void)ve;
  return -1;
}

frtabu's avatar
frtabu committed
1072
int phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec) {
1073
  //NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n");
frtabu's avatar
frtabu committed
1074
  nfapi_tl_t *tlv = (nfapi_tl_t *)ve;
1075
1076

  switch(tlv->tag) {
frtabu's avatar
frtabu committed
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
    case VENDOR_EXT_TLV_1_TAG: {
      //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n");
      vendor_ext_tlv_1 *ve = (vendor_ext_tlv_1 *)tlv;

      if(!push32(ve->dummy, ppWritePackedMsg, end))
        return 0;

      return 1;
    }
    break;

1088
1089
1090
1091
1092
1093
    default:
      return -1;
      break;
  }
}

frtabu's avatar
frtabu committed
1094
int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *config) {
1095
1096
  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
  if(header->message_id == P7_VENDOR_EXT_IND) {
frtabu's avatar
frtabu committed
1097
1098
    vendor_ext_p7_ind *req = (vendor_ext_p7_ind *)(header);

1099
1100
1101
1102
1103
1104
1105
    if(!pull16(ppReadPackedMessage, &req->error_code, end))
      return 0;
  }

  return 1;
}

frtabu's avatar
frtabu committed
1106
int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
1107
1108
1109
  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
  if(header->message_id == P7_VENDOR_EXT_REQ) {
    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
frtabu's avatar
frtabu committed
1110
1111
    vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header);

1112
    if(!(push16(req->dummy1, ppWritePackedMsg, end) &&
frtabu's avatar
frtabu committed
1113
         push16(req->dummy2, ppWritePackedMsg, end)))
1114
1115
      return 0;
  }
frtabu's avatar
frtabu committed
1116

1117
1118
1119
  return 1;
}

frtabu's avatar
frtabu committed
1120
int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) {
1121
1122
  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
  if(header->message_id == P5_VENDOR_EXT_REQ) {
frtabu's avatar
frtabu committed
1123
    vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
1124
1125
    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2);
    return (!(push16(req->dummy1, ppWritePackedMsg, end) &&
frtabu's avatar
frtabu committed
1126
              push16(req->dummy2, ppWritePackedMsg, end)));
1127
  }
frtabu's avatar
frtabu committed
1128

1129
1130
1131
1132
1133
1134
  return 0;
}

static pthread_t vnf_start_pthread;
static pthread_t vnf_p7_start_pthread;

Mahesh K's avatar
Mahesh K committed
1135
1136
1137
1138
1139
1140
1141
1142
void *vnf_nr_p7_start_thread(void *ptr) {
  printf("%s()\n", __FUNCTION__);
  pthread_setname_np(pthread_self(), "VNF_P7");
  nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr;
  nfapi_nr_vnf_p7_start(config);
  return config;
}

frtabu's avatar
frtabu committed
1143
void *vnf_p7_start_thread(void *ptr) {
1144
1145
  printf("%s()\n", __FUNCTION__);
  pthread_setname_np(pthread_self(), "VNF_P7");
frtabu's avatar
frtabu committed
1146
  nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr;
1147
1148
1149
1150
1151
1152
  nfapi_vnf_p7_start(config);
  return config;
}

void set_thread_priority(int priority);

Mahesh K's avatar
Mahesh K committed
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
void *vnf_nr_p7_thread_start(void *ptr) {
  set_thread_priority(79);
  vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr;
  p7_vnf->config->port = p7_vnf->local_port;
  p7_vnf->config->sync_indication = &phy_sync_indication;
  p7_vnf->config->slot_indication = &phy_slot_indication;

  p7_vnf->config->harq_indication = &phy_harq_indication;
  p7_vnf->config->crc_indication = &phy_crc_indication;
  p7_vnf->config->rx_indication = &phy_rx_indication;
  p7_vnf->config->rach_indication = &phy_rach_indication;
  p7_vnf->config->srs_indication = &phy_srs_indication;
  p7_vnf->config->sr_indication = &phy_sr_indication;
  p7_vnf->config->cqi_indication = &phy_cqi_indication;
  p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication;
  p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication;
  p7_vnf->config->nrach_indication = &phy_nrach_indication;
  p7_vnf->config->malloc = &vnf_allocate;
  p7_vnf->config->free = &vnf_deallocate;
  p7_vnf->config->trace = &vnf_trace;
  p7_vnf->config->vendor_ext = &phy_vendor_ext;
  p7_vnf->config->user_data = p7_vnf;
  p7_vnf->mac->user_data = p7_vnf;
  p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension;
  p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension;
  p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv;
  p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv;
  p7_vnf->config->codec_config.allocate = &vnf_allocate;
  p7_vnf->config->codec_config.deallocate = &vnf_deallocate;
  p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext;
  p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext;
  NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
  pthread_create(&vnf_p7_start_pthread, NULL, &vnf_nr_p7_start_thread, p7_vnf->config);
  return 0;
}

frtabu's avatar
frtabu committed
1189
void *vnf_p7_thread_start(void *ptr) {
1190
  set_thread_priority(79);
frtabu's avatar
frtabu committed
1191
  vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr;
1192
1193
1194
  p7_vnf->config->port = p7_vnf->local_port;
  p7_vnf->config->sync_indication = &phy_sync_indication;
  p7_vnf->config->subframe_indication = &phy_subframe_indication;
1195
1196
  p7_vnf->config->slot_indication = &phy_slot_indication;

1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
  p7_vnf->config->harq_indication = &phy_harq_indication;
  p7_vnf->config->crc_indication = &phy_crc_indication;
  p7_vnf->config->rx_indication = &phy_rx_indication;
  p7_vnf->config->rach_indication = &phy_rach_indication;
  p7_vnf->config->srs_indication = &phy_srs_indication;
  p7_vnf->config->sr_indication = &phy_sr_indication;
  p7_vnf->config->cqi_indication = &phy_cqi_indication;
  p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication;
  p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication;
  p7_vnf->config->nrach_indication = &phy_nrach_indication;
  p7_vnf->config->malloc = &vnf_allocate;
  p7_vnf->config->free = &vnf_deallocate;
  p7_vnf->config->trace = &vnf_trace;
  p7_vnf->config->vendor_ext = &phy_vendor_ext;
  p7_vnf->config->user_data = p7_vnf;
  p7_vnf->mac->user_data = p7_vnf;
  p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension;
  p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension;
  p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv;
  p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv;
  p7_vnf->config->codec_config.allocate = &vnf_allocate;
  p7_vnf->config->codec_config.deallocate = &vnf_deallocate;
  p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext;
  p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext;
MaheshK1995's avatar
MaheshK1995 committed
1221
  NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
1222
1223
1224
1225
  pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config);
  return 0;
}

Mahesh K's avatar
Mahesh K committed
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
int pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_start_response_t *resp) {
  vnf_info *vnf = (vnf_info *)(config->user_data);
  vnf_p7_info *p7_vnf = vnf->p7_vnfs;
  pnf_info *pnf = vnf->pnfs;
  nfapi_nr_param_request_scf_t req;
  printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started);

  if(p7_vnf->thread_started == 0) {
    pthread_t vnf_p7_thread;
    pthread_create(&vnf_p7_thread, NULL, &vnf_nr_p7_thread_start, p7_vnf);
    p7_vnf->thread_started = 1;
  } else {
    // P7 thread already running.
  }

  // start all the phys in the pnf.
  printf("[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
  memset(&req, 0, sizeof(req));
  req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST;
  req.header.phy_id = pnf->phys[0].id;
  nfapi_nr_vnf_param_req(config, p5_idx, &req);
  return 0;
}

frtabu's avatar
frtabu committed
1250
1251
int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_response_t *resp) {
  vnf_info *vnf = (vnf_info *)(config->user_data);
1252
1253
1254
1255
1256
1257
1258
1259
1260
  vnf_p7_info *p7_vnf = vnf->p7_vnfs;
  pnf_info *pnf = vnf->pnfs;
  nfapi_param_request_t req;
  printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started);

  if(p7_vnf->thread_started == 0) {
    pthread_t vnf_p7_thread;
    pthread_create(&vnf_p7_thread, NULL, &vnf_p7_thread_start, p7_vnf);
    p7_vnf->thread_started = 1;
frtabu's avatar
frtabu committed
1261
1262
  } else {
    // P7 thread already running.
1263
1264
1265
  }

  // start all the phys in the pnf.
MaheshK1995's avatar
MaheshK1995 committed
1266
  printf("[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
1267
1268
1269
1270
1271
1272
1273
1274
1275
  memset(&req, 0, sizeof(req));
  req.header.message_id = NFAPI_PARAM_REQUEST;
  req.header.phy_id = pnf->phys[0].id;
  nfapi_vnf_param_req(config, p5_idx, &req);
  return 0;
}

extern uint32_t to_earfcn(int eutra_bandP,uint32_t dl_CarrierFreq,uint32_t bw);

Mahesh K's avatar
Mahesh K committed
1276
int nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_response_scf_t *resp) {
MaheshK1995's avatar
MaheshK1995 committed
1277

1278
  printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
frtabu's avatar
frtabu committed
1279
  vnf_info *vnf = (vnf_info *)(config->user_data);
1280
1281
1282
1283
  vnf_p7_info *p7_vnf = vnf->p7_vnfs;
  pnf_info *pnf = vnf->pnfs;
  phy_info *phy = pnf->phys;
  struct sockaddr_in pnf_p7_sockaddr;
MaheshK1995's avatar
MaheshK1995 committed
1284
  nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; // check
Mahesh K's avatar
Mahesh K committed
1285
  phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value;
1286
1287
1288
  memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4);
  phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr);
  // for now just 1
frtabu's avatar
frtabu committed
1289
1290
  printf("[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled,
         p7_vnf->periodic_timing_period);
Mahesh K's avatar
Mahesh K committed
1291
  req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
1292
1293
  req->header.phy_id = phy->id;
  printf("[VNF] Send NFAPI_CONFIG_REQUEST\n");
1294
  //printf("\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]);
MaheshK1995's avatar
MaheshK1995 committed
1295

MaheshK1995's avatar
MaheshK1995 committed
1296
  req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG;
1297
1298
1299
  req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port;
  req->num_tlv++;
  printf("[VNF] DJP local_port:%d\n", p7_vnf->local_port);
MaheshK1995's avatar
MaheshK1995 committed
1300
  req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
1301
1302
1303
1304
1305
  struct sockaddr_in vnf_p7_sockaddr;
  vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr);
  memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4);
  req->num_tlv++;
  printf("[VNF] DJP local_addr:%s\n", p7_vnf->local_addr);
MaheshK1995's avatar
MaheshK1995 committed
1306
  req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
1307
  req->nfapi_config.timing_window.value = p7_vnf->timing_window;
MaheshK1995's avatar
MaheshK1995 committed
1308
  printf("\n[VNF]Timing window tag : %d Timing window:%u\n",NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, p7_vnf->timing_window);
1309
1310
1311
  req->num_tlv++;

  if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) {
MaheshK1995's avatar
MaheshK1995 committed
1312
    req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
1313
1314
1315
1316
    req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled);
    req->num_tlv++;

    if(p7_vnf->periodic_timing_enabled) {
MaheshK1995's avatar
MaheshK1995 committed
1317
      req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
1318
1319
1320
1321
      req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period;
      req->num_tlv++;
    }
  }
1322
1323
1324
1325
1326
1327
//TODO: Assign tag and value for P7 message offsets  
req->nfapi_config.dl_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET;
req->nfapi_config.ul_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET;
req->nfapi_config.ul_dci_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET;
req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET;

1328
1329
1330
1331
1332
  vendor_ext_tlv_2 ve2;
  memset(&ve2, 0, sizeof(ve2));
  ve2.tl.tag = VENDOR_EXT_TLV_2_TAG;
  ve2.dummy = 2016;
  req->vendor_extension = &ve2.tl;
Mahesh K's avatar
Mahesh K committed
1333
  nfapi_nr_vnf_config_req(config, p5_idx, req);
MaheshK1995's avatar
MaheshK1995 committed
1334
  printf("[VNF] Sent NFAPI_VNF_CONFIG_REQ num_tlv:%u\n",req->num_tlv);
1335
1336
1337
  return 0;
}

Mahesh K's avatar
Mahesh K committed
1338
1339
1340
1341
1342
1343
1344
1345
1346

int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t *resp) {
  printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
  vnf_info *vnf = (vnf_info *)(config->user_data);
  vnf_p7_info *p7_vnf = vnf->p7_vnfs;
  pnf_info *pnf = vnf->pnfs;
  phy_info *phy = pnf->phys;
  struct sockaddr_in pnf_p7_sockaddr;
  nfapi_config_request_t *req = &RC.mac[0]->config[0];
Mahesh K's avatar
Mahesh K committed
1347
  phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value;