Front Haul Interface Library update to first seed code contribution
[o-du/phy.git] / fhi_lib / app / src / sample-app.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2019 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18
19
20 #define _GNU_SOURCE
21 #include <unistd.h>
22 #include <sys/syscall.h>
23 #include <sched.h>
24 #include <assert.h>
25 #include <err.h>
26 #include <libgen.h>
27 #include <sys/time.h>
28 #include <time.h>
29 #include <unistd.h>
30 #include <stdio.h>
31 #include <fcntl.h>
32 #include <pthread.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35
36
37 #include "common.h"
38 #include "config.h"
39 #include "xran_mlog_lnx.h"
40
41 #include "xran_fh_o_du.h"
42 #include "xran_cp_api.h"
43 #include "xran_sync_api.h"
44 #include "xran_mlog_task_id.h"
45
46 #define MAX_BBU_POOL_CORE_MASK  (4)
47
48
49 #define SW_FPGA_TOTAL_BUFFER_LEN 4*1024*1024*1024
50 #define SW_FPGA_SEGMENT_BUFFER_LEN 1*1024*1024*1024
51 #define SW_FPGA_FH_TOTAL_BUFFER_LEN 1*1024*1024*1024
52 #define FPGA_TO_SW_PRACH_RX_BUFFER_LEN   (8192)
53
54 #define NSEC_PER_SEC 1000000000
55
56 #define MAX_PKT_BURST (448+4) // 4x14x8
57 #define N_MAX_BUFFER_SEGMENT MAX_PKT_BURST
58
59 #define MAIN_PRIORITY 98
60 #define NUM_OF_SUBFRAME_PER_FRAME (10)
61
62 enum app_state state;
63
64 uint64_t  tick_per_usec;
65 static volatile uint64_t timer_last_irq_tick = 0;
66 static uint64_t tsc_resolution_hz = 0;
67
68 RuntimeConfig startupConfiguration = {0};
69
70 /* buffers size */
71 uint32_t    nFpgaToSW_FTH_RxBufferLen;
72 uint32_t    nFpgaToSW_PRACH_RxBufferLen;
73 uint32_t    nSW_ToFpga_FTH_TxBufferLen;
74
75 static struct xran_fh_init xranInit;
76 void * xranHandle = NULL;
77
78 struct xran_fh_config  xranConf;
79 struct xran_fh_config  *pXranConf = NULL;
80
81 typedef struct
82 {
83     uint32_t phaseFlag   :1;
84     uint32_t NRARFCN     :22;
85     uint32_t SULFreShift :1;
86     uint32_t SULFlag     :1;
87     uint32_t rsv         :7;
88 }FPGAPhaseCompCfg;
89
90 typedef struct XranLibConfig
91 {
92     uint32_t nDriverCoreId;
93     uint32_t nTimingAdvance;
94     uint32_t nFhConfig;
95     uint32_t nFhBufIntFlag;
96     uint32_t nSectorNum;
97     uint32_t nNrOfSlotInSf;
98     uint32_t nNrofSfInFrame;
99     void *   pFthInstanceHandles;
100 }XranLibConfigStruct;
101 typedef enum {
102     XRANFTHTX_OUT = 0,
103     XRANFTHTX_PRB_MAP_OUT,
104     XRANFTHRX_IN,
105     XRANFTHRX_PRB_MAP_IN,
106     XRANFTHRACH_IN,
107     MAX_SW_XRAN_INTERFACE_NUM
108 }SWXRANInterfaceTypeEnum;
109
110 /*
111  * manage one cell's all Ethernet frames for one DL or UL LTE subframe
112  */
113 typedef struct {
114     /* -1-this subframe is not used in current frame format
115          0-this subframe can be transmitted, i.e., data is ready
116           1-this subframe is waiting transmission, i.e., data is not ready
117          10 - DL transmission missing deadline. When FE needs this subframe data but bValid is still 1,
118         set bValid to 10.
119     */
120     int32_t bValid ; // when UL rx, it is subframe index.
121     int32_t nSegToBeGen;
122     int32_t nSegGenerated; // how many date segment are generated by DL LTE processing or received from FE
123                        // -1 means that DL packet to be transmitted is not ready in BS
124     int32_t nSegTransferred; // number of data segments has been transmitted or received
125     struct rte_mbuf *pData[N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
126     struct xran_buffer_list sBufferList;
127 } BbuIoBufCtrlStruct;
128
129 typedef struct  {
130     uint64_t nCoreMask;
131     int16_t cpuSocketId;
132     uint8_t nDriverCoreId;
133     uint8_t nFHCoreId;
134
135     struct rte_mempool *bbuio_buf_pool;
136
137     /* io struct */
138     BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
139     BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
140     BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
141     BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
142     BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
143
144     /* buffers lists */
145     struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
146     struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
147     struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
148     struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
149     struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
150
151     void*    nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
152     uint32_t nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM];   // every api owns unique buffer pool
153     uint16_t nInstanceNum;
154
155     uint64_t nTscTiming[XRAN_N_FE_BUF_LEN]; // records the TSC when a timing packet is received.
156 } BbuXranIoIfStruct;
157
158 static BbuXranIoIfStruct    gsXranIoIf;
159 static XranLibConfigStruct *gpXranLibConfig = NULL;
160
161 extern long rx_counter;
162 extern long tx_counter;
163
164 #define CPU_HZ tick_per_usec //us
165
166 /* Application User space functions */
167 void xran_fh_rx_callback(void *pCallbackTag, int32_t status);
168 void xran_fh_rx_prach_callback(void *pCallbackTag, int32_t status);
169
170 static BbuXranIoIfStruct *xran_get_ctx(void)
171 {
172     return &gsXranIoIf;
173 }
174
175 static void print_menu()
176 {
177     puts("+---------------------------------------+");
178     puts("| Press 1 to start 5G NR XRAN traffic   |");
179     puts("| Press 2 reserved for future use       |");
180     puts("| Press 3 to quit                       |");
181     puts("+---------------------------------------+");
182 }
183
184 static int32_t get_xran_sfidx(uint8_t nNrOfSlotInSf)
185 {
186     int32_t nSfIdx = -1;
187     uint32_t nFrameIdx;
188     uint32_t nSubframeIdx;
189     uint32_t nSlotIdx;
190     uint64_t nSecond;
191
192     uint32_t nXranTime  = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
193     nSfIdx = nFrameIdx*NUM_OF_SUBFRAME_PER_FRAME*nNrOfSlotInSf
194         + nSubframeIdx*nNrOfSlotInSf
195         + nSlotIdx;
196 #if 0
197     printf("\nxranTime is %d, return is %d, radio frame is %d, subframe is %d slot is %d tsc is %llu us",
198         nXranTime,
199         nSfIdx,
200         nFrameIdx,
201         nSubframeIdx,
202         nSlotIdx,
203         __rdtsc()/CPU_HZ);
204 #endif
205
206     return nSfIdx;
207 }
208
209 void xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
210 {
211     uint64_t t1 = MLogTick();
212     uint32_t mlogVar[10];
213     uint32_t mlogVarCnt = 0;
214     uint8_t Numerlogy = xranConf.frame_conf.nNumerology;
215     uint8_t nNrOfSlotInSf = 1<<Numerlogy;
216     int32_t sfIdx = get_xran_sfidx(nNrOfSlotInSf);
217
218     mlogVar[mlogVarCnt++] = 0xCCCCCCCC;
219     mlogVar[mlogVarCnt++] = status >> 16; /* tti */
220     mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
221     mlogVar[mlogVarCnt++] = (uint32_t)sfIdx;
222     MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
223     rte_pause();
224
225     MLogTask(PID_GNB_SYM_CB, t1, MLogTick());
226     return;
227 }
228
229 void xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
230 {
231     uint64_t t1 = MLogTick();
232     uint32_t mlogVar[10];
233     uint32_t mlogVarCnt = 0;
234
235     mlogVar[mlogVarCnt++] = 0xDDDDDDDD;
236     mlogVar[mlogVarCnt++] = status >> 16; /* tti */
237     mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
238     MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
239     rte_pause();
240
241     MLogTask(PID_GNB_PRACH_CB, t1, MLogTick());
242 }
243
244 //-------------------------------------------------------------------------------------------
245 /** @ingroup group_nbiot_source_auxlib_timer
246  *
247  *  @param   void
248  *
249  *  @return  Ticks
250  *
251  *  @description
252  *  This function reads the rtdsc clock and returns the current value in there.
253  *
254 **/
255 //-------------------------------------------------------------------------------------------
256 unsigned long timer_get_ticks(void)
257 {
258     unsigned long ret;
259     union
260     {
261         unsigned long tsc_64;
262         struct
263         {
264             uint32_t lo_32;
265             uint32_t hi_32;
266         };
267     } tsc;
268
269     __asm volatile("rdtsc" :
270              "=a" (tsc.lo_32),
271              "=d" (tsc.hi_32));
272
273      ret = ((unsigned long)tsc.tsc_64);
274      return ret;
275 }
276
277 //-------------------------------------------------------------------------------------------
278 /** @ingroup group_lte_source_auxlib_timer
279  *
280  *  @param   void
281  *
282  *  @return  0 if SUCCESS
283  *
284  *  @description
285  *  This function gets the clock speed of the core and figures out number of ticks per usec.
286  *  It is used by l1app and testmac applications to initialize the mlog utility
287  *
288 **/
289 //-------------------------------------------------------------------------------------------
290 int timer_set_tsc_freq_from_clock(void)
291 {
292 #define NS_PER_SEC 1E9
293     struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */
294     struct timespec t_start, t_end;
295     uint64_t tsc_resolution_hz = 0;
296
297     if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0)
298     {
299         unsigned long ns, end, start = timer_get_ticks();
300         nanosleep(&sleeptime,NULL);
301         clock_gettime(CLOCK_MONOTONIC_RAW, &t_end);
302         end = timer_get_ticks();
303         ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC);
304         ns += (t_end.tv_nsec - t_start.tv_nsec);
305
306         double secs = (double)ns/NS_PER_SEC;
307         tsc_resolution_hz = (unsigned long)((end - start)/secs);
308
309         tick_per_usec = (tsc_resolution_hz / 1000000);
310         printf("System clock (rdtsc) resolution %lu [Hz]\n", tsc_resolution_hz);
311         printf("Ticks per us %lu\n", tick_per_usec);
312         return 0;
313     }
314
315     return -1;
316 }
317
318 int physide_dl_tti_call_back(void * param)
319 {
320     uint64_t t1 = MLogTick();
321     rte_pause();
322     MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
323     return 0;
324 }
325
326 int physide_ul_half_slot_call_back(void * param)
327 {
328     uint64_t t1 = MLogTick();
329     rte_pause();
330     MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
331     return 0;
332 }
333
334 int physide_ul_full_slot_call_back(void * param)
335 {
336     uint64_t t1 = MLogTick();
337     rte_pause();
338     MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
339     return 0;
340 }
341
342 int32_t init_xran(void)
343 {
344     BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
345     xran_status_t status;
346     int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
347     int32_t nSectorNum;
348     int32_t i, j, k, z;
349
350     void *ptr;
351     void *mb;
352     uint32_t *u32dptr;
353     uint16_t *u16dptr;
354     uint8_t  *u8dptr;
355
356     SWXRANInterfaceTypeEnum eInterfaceType;
357
358     XranLibConfigStruct  *ptrLibConfig;
359
360     struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
361     struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
362     struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
363     struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
364     struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
365
366     for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
367     {
368         nSectorIndex[nSectorNum] = nSectorNum;
369     }
370
371     nSectorNum = numCCPorts;
372     printf ("XRAN front haul xran_mm_init \n");
373     status = xran_mm_init (xranHandle, (uint64_t) SW_FPGA_FH_TOTAL_BUFFER_LEN, SW_FPGA_SEGMENT_BUFFER_LEN);
374     if (status != XRAN_STATUS_SUCCESS)
375     {
376         printf ("Failed at XRAN front haul xran_mm_init \n");
377         exit(-1);
378     }
379
380     psBbuIo->nInstanceNum = numCCPorts;
381
382     for (k = 0; k < XRAN_PORTS_NUM; k++) {
383         status = xran_sector_get_instances (xranHandle, psBbuIo->nInstanceNum,&psBbuIo->nInstanceHandle[k][0]);
384         if (status != XRAN_STATUS_SUCCESS)
385         {
386             printf ("get sector instance failed %d for XRAN nInstanceNum %d\n",k, psBbuIo->nInstanceNum);
387             exit(-1);
388         }
389         for (i = 0; i < psBbuIo->nInstanceNum; i++){
390             printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, k, i, psBbuIo->nInstanceHandle[0][i]);
391         }
392     }
393
394     printf("Sucess xran_mm_init \n");
395     gpXranLibConfig = (XranLibConfigStruct*)malloc(sizeof(XranLibConfigStruct));
396     ptrLibConfig = gpXranLibConfig;
397     if (ptrLibConfig)
398     {
399     #if 0
400         ptrLibConfig->nDriverCoreId =  psBbuIo->nDriverCoreId;
401         ptrLibConfig->pFecInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FEC][0]);
402         ptrLibConfig->pFthInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FRONTHAUL][0]);
403         ptrLibConfig->nTimingAdvance = psFPGAInitPara->nTimeAdvance;
404         ptrLibConfig->nFhConfig = psFPGAInitPara->nEthPorts;
405         ptrLibConfig->nFhBufIntFlag = 0; //need init fronthaul buffer, then set to 1.
406         ptrLibConfig->nNrofSfInFrame = NUM_OF_SUBFRAME_PER_FRAME;
407         ptrLibConfig->nNrOfSlotInSf = pConfigParams->nNumOfSlotPerSubframe;
408         if (pConfigParams->nNumerology < 3)
409         {
410             ptrLibConfig->nSectorNum = psFPGAInitPara->nSecNum;
411         }
412     #endif
413     }
414     else
415     {
416         printf ("could not allocate ptrLibConfig in init_xran\n");
417         exit(-1);
418     }
419
420     printf("nSectorNum %d\n", nSectorNum);
421
422     /* Init Memory */
423     for(i = 0; i<nSectorNum; i++)
424     {
425         eInterfaceType = XRANFTHTX_OUT;
426         printf("nSectorIndex[%d] = %d\n",i,  nSectorIndex[i]);
427         status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
428             XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
429         if(XRAN_STATUS_SUCCESS != status)
430         {
431             printf("Failed at  xran_bm_init , status %d\n", status);
432             iAssert(status == XRAN_STATUS_SUCCESS);
433         }
434         for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
435         {
436             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
437                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
438                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
439                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
440                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
441                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
442                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxBuffers[j][i][z][0];
443
444                 for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
445                 {
446                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
447                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
448                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
449                     status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
450                     if(XRAN_STATUS_SUCCESS != status)
451                     {
452                         printf("Failed at  xran_bm_allocate_buffer , status %d\n",status);
453                         iAssert(status == XRAN_STATUS_SUCCESS);
454                     }
455                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
456                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
457
458                     if(ptr){
459                         u32dptr = (uint32_t*)(ptr);
460                         uint8_t *ptr_temp = (uint8_t *)ptr;
461                         memset(u32dptr, 0xCC, nSW_ToFpga_FTH_TxBufferLen);
462                         ptr_temp[0] = j; // TTI
463                         ptr_temp[1] = i; // Sec
464                         ptr_temp[2] = z; // Ant
465                         ptr_temp[3] = k; // sym
466                     }
467                 }
468             }
469         }
470
471         /* C-plane DL */
472         eInterfaceType = XRANFTHTX_PRB_MAP_OUT;
473         printf("nSectorIndex[%d] = %d\n",i,  nSectorIndex[i]);
474         status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
475             XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
476         if(XRAN_STATUS_SUCCESS != status)
477         {
478             printf("Failed at  xran_bm_init , status %d\n", status);
479             iAssert(status == XRAN_STATUS_SUCCESS);
480         }
481         for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
482         {
483             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
484                 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
485                 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
486                 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
487                 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
488                 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
489                 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxPrbMapBuffers[j][i][z];
490
491                 {
492                     psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
493                     psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
494                     psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
495                     status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
496                     if(XRAN_STATUS_SUCCESS != status)
497                     {
498                         printf("Failed at  xran_bm_allocate_buffer , status %d\n",status);
499                         iAssert(status == XRAN_STATUS_SUCCESS);
500                     }
501                     psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
502                     psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
503
504                     if(ptr){
505                         u32dptr = (uint32_t*)(ptr);
506                         uint8_t *ptr_temp = (uint8_t *)ptr;
507                         memset(u32dptr, 0xCC, sizeof(struct xran_prb_map));
508                         ptr_temp[0] = j; // TTI
509                         ptr_temp[1] = i; // Sec
510                         ptr_temp[2] = z; // Ant
511                         ptr_temp[3] = k; // sym
512                     }
513                 }
514             }
515         }
516     }
517
518     for(i = 0; i<nSectorNum; i++)
519     {
520         eInterfaceType = XRANFTHRX_IN;
521         status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
522         if(XRAN_STATUS_SUCCESS != status)
523         {
524             printf("Failed at xran_bm_init, status %d\n", status);
525             iAssert(status == XRAN_STATUS_SUCCESS);
526         }
527
528         for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
529         {
530             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
531                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
532                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
533                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
534                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
535                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
536                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxBuffers[j][i][z][0];
537                 for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
538                 {
539                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nFpgaToSW_FTH_RxBufferLen; // 1 symbols 3200bytes
540                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
541                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
542                     status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
543                     if(XRAN_STATUS_SUCCESS != status)
544                     {
545                         printf("Failed at  xran_bm_allocate_buffer , status %d\n",status);
546                         iAssert(status == XRAN_STATUS_SUCCESS);
547                     }
548                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
549                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *) mb;
550                     if(ptr){
551                         u32dptr = (uint32_t*)(ptr);
552                         uint8_t *ptr_temp = (uint8_t *)ptr;
553                         memset(u32dptr, 0xCC, nFpgaToSW_FTH_RxBufferLen);
554                         ptr_temp[0] = j; // TTI
555                         ptr_temp[1] = i; // Sec
556                         ptr_temp[2] = z; // Ant
557                         ptr_temp[3] = k; // sym
558                     }
559                 }
560             }
561         }
562
563         /* C-plane */
564         eInterfaceType = XRANFTHRX_PRB_MAP_IN;
565         status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
566                 XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
567         if(XRAN_STATUS_SUCCESS != status)
568         {
569             printf("Failed at xran_bm_init, status %d\n", status);
570             iAssert(status == XRAN_STATUS_SUCCESS);
571         }
572
573         for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
574         {
575             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
576                 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
577                 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
578                 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
579                 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
580                 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
581                 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxPrbMapBuffers[j][i][z];
582                 {
583                     psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
584                     psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
585                     psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
586                     status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
587                     if(XRAN_STATUS_SUCCESS != status)
588                     {
589                         printf("Failed at  xran_bm_allocate_buffer , status %d\n",status);
590                         iAssert(status == XRAN_STATUS_SUCCESS);
591                     }
592                     psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
593                     psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
594                     if(ptr){
595                         u32dptr = (uint32_t*)(ptr);
596                         uint8_t *ptr_temp = (uint8_t *)ptr;
597                         memset(u32dptr, 0xCC, sizeof(struct xran_prb_map));
598                         ptr_temp[0] = j; // TTI
599                         ptr_temp[1] = i; // Sec
600                         ptr_temp[2] = z; // Ant
601                         ptr_temp[3] = k; // sym
602                     }
603                 }
604             }
605         }
606     }
607
608     // add prach rx buffer
609     for(i = 0; i<nSectorNum; i++)
610     {
611         eInterfaceType = XRANFTHRACH_IN;
612         status = xran_bm_init(psBbuIo->nInstanceHandle[0][i],&psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
613         if(XRAN_STATUS_SUCCESS != status)
614         {
615             printf("Failed at xran_bm_init, status %d\n", status);
616             iAssert(status == XRAN_STATUS_SUCCESS);
617         }
618         for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
619         {
620             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
621                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
622                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
623                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
624                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
625                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
626                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFHPrachRxBuffers[j][i][z][0];
627                 for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
628                 {
629                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = FPGA_TO_SW_PRACH_RX_BUFFER_LEN;
630                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
631                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
632                     status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
633                     if(XRAN_STATUS_SUCCESS != status)
634                     {
635                         printf("Failed at  xran_bm_allocate_buffer, status %d\n",status);
636                         iAssert(status == XRAN_STATUS_SUCCESS);
637                     }
638                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
639                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
640                     if(ptr){
641                         u32dptr = (uint32_t*)(ptr);
642                         memset(u32dptr, 0xCC, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
643                     }
644                 }
645             }
646         }
647     }
648
649     for(i=0; i<nSectorNum; i++)
650     {
651         for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
652         {
653             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
654                 pFthTxBuffer[i][z][j]     = &(psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
655                 pFthTxPrbMapBuffer[i][z][j]     = &(psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
656                 pFthRxBuffer[i][z][j]     = &(psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
657                 pFthRxPrbMapBuffer[i][z][j]     = &(psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
658                 pFthRxRachBuffer[i][z][j] = &(psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
659             }
660         }
661     }
662
663     if(NULL != psBbuIo->nInstanceHandle[0])
664     {
665         for (i = 0; i<nSectorNum; i++)
666         {
667             xran_5g_fronthault_config (psBbuIo->nInstanceHandle[0][i],
668                 pFthTxBuffer[i],
669                 pFthTxPrbMapBuffer[i],
670                 pFthRxBuffer[i],
671                 pFthRxPrbMapBuffer[i],
672                 xran_fh_rx_callback,  &pFthRxBuffer[i][0]);
673         }
674
675         // add prach callback here
676         for (i = 0; i<nSectorNum; i++)
677         {
678             xran_5g_prach_req(psBbuIo->nInstanceHandle[0][i], pFthRxRachBuffer[i],
679                 xran_fh_rx_prach_callback,&pFthRxRachBuffer[i][0]);
680         }
681         ptrLibConfig->nFhBufIntFlag = 1;
682     }
683
684     return status;
685 }
686
687 int init_xran_iq_content(void)
688 {
689     BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
690     xran_status_t status;
691     int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
692     int32_t nSectorNum;
693     int32_t cc_id, ant_id, sym_id, tti;
694     int32_t flowId;
695
696     uint8_t    frame_id    = 0;
697     uint8_t    subframe_id = 0;
698     uint8_t    slot_id     = 0;
699     uint8_t    sym         = 0;
700
701     void *ptr;
702     uint32_t *u32dptr;
703     uint16_t *u16dptr;
704     uint8_t  *u8dptr;
705
706     char        *pos = NULL;
707     struct xran_prb_map *pRbMap = NULL;
708
709     for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
710     {
711         nSectorIndex[nSectorNum] = nSectorNum;
712     }
713     nSectorNum = numCCPorts;
714     printf ("init_xran_iq_content\n");
715
716     /* Init Memory */
717     for(cc_id = 0; cc_id <nSectorNum; cc_id++)
718     {
719         for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti ++) {
720             for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
721                 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
722
723                     flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id;
724
725                     if(p_tx_play_buffer[flowId]){
726                         pos =  ((char*)p_tx_play_buffer[flowId]) + tx_play_buffer_position[flowId];
727                         ptr = psBbuIo->sFrontHaulTxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
728
729                         if(ptr && pos){
730                             u32dptr = (uint32_t*)(ptr);
731                             rte_memcpy(u32dptr, pos, pXranConf->nDLRBs*N_SC_PER_PRB*4);
732 #ifdef DEBUG_XRAN_BUFFERS
733                             uint8_t *ptr_temp = (uint8_t *)ptr;
734                                 ptr_temp[0] = tti; // TTI
735                                 ptr_temp[1] = cc_id; // Sec
736                                 ptr_temp[2] = ant_id; // Ant
737                                 ptr_temp[3] = sym_id; // sym
738 #endif
739                         } else {
740                             exit(-1);
741                             printf("ptr ==NULL\n");
742                         }
743
744                         /* c-plane DL */
745                         pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
746                         if(pRbMap){
747                             pRbMap->dir = XRAN_DIR_DL;
748                             pRbMap->xran_port = 0;
749                             pRbMap->band_id = 0;
750                             pRbMap->cc_id = cc_id;
751                             pRbMap->ru_port_id = ant_id;
752                             pRbMap->tti_id = tti;
753                             pRbMap->start_sym_id = 0;
754                             pRbMap->nPrbElm = 1;
755                             pRbMap->prbMap[0].nRBStart = 0;
756                             pRbMap->prbMap[0].nRBSize = pXranConf->nDLRBs;
757                             pRbMap->prbMap[0].nBeamIndex = 0;
758                             pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
759                         }else{
760                             printf("DL pRbMap ==NULL\n");
761                             exit(-1);
762                         }
763
764                         /* c-plane UL */
765                         pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
766                         if(pRbMap){
767                             pRbMap->dir = XRAN_DIR_UL;
768                             pRbMap->xran_port = 0;
769                             pRbMap->band_id = 0;
770                             pRbMap->cc_id = cc_id;
771                             pRbMap->ru_port_id = ant_id;
772                             pRbMap->tti_id = tti;
773                             pRbMap->start_sym_id = 0;
774                             pRbMap->nPrbElm = 1;
775                             pRbMap->prbMap[0].nRBStart = 0;
776                             pRbMap->prbMap[0].nRBSize = pXranConf->nULRBs;
777                             pRbMap->prbMap[0].nBeamIndex = 0;
778                             pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
779                         }else {
780                             printf("UL: pRbMap ==NULL\n");
781                             exit(-1);
782                         }
783
784                         tx_play_buffer_position[flowId] += pXranConf->nDLRBs*N_SC_PER_PRB*4;
785
786                         if(tx_play_buffer_position[flowId] >= tx_play_buffer_size[flowId])
787                             tx_play_buffer_position[flowId] = 0;
788                     } else {
789                         //printf("flowId %d\n", flowId);
790                     }
791                 }
792             }
793
794             /* prach TX for RU only */
795             if(startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
796                 for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
797                     for(sym_id = 0; sym_id < 1; sym_id++) {
798                         flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id;
799
800                         if(p_tx_prach_play_buffer[flowId]){
801                             /* (0-79 slots) 10ms of IQs */
802                             pos =  ((char*)p_tx_prach_play_buffer[flowId]);
803
804                             ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
805
806                             if(ptr && pos){
807                                 u32dptr = (uint32_t*)(ptr);
808                                 rte_memcpy(u32dptr, pos, PRACH_PLAYBACK_BUFFER_BYTES);
809 #ifdef DEBUG_XRAN_BUFFERS
810                                 uint8_t *ptr_temp = (uint8_t *)ptr;
811                                     ptr_temp[0] = tti; // TTI
812                                     ptr_temp[1] = cc_id; // Sec
813                                     ptr_temp[2] = ant_id; // Ant
814                                     ptr_temp[3] = sym_id; // sym
815 #endif
816                             } else {
817                                 exit(-1);
818                                 printf("ptr ==NULL\n");
819                             }
820                         } else {
821                             //printf("flowId %d\n", flowId);
822                         }
823                     }
824                 }
825             }
826         }
827     }
828
829     return 0;
830 }
831
832 void stop_xran(void)
833 {
834     xran_status_t status = 0;
835     SWXRANInterfaceTypeEnum eInterfaceType;
836
837     free(gpXranLibConfig);
838     gpXranLibConfig = NULL;
839
840     status += xran_mm_destroy(xranHandle)*2;
841
842     if(XRAN_STATUS_SUCCESS != status)
843     {
844         printf("Failed at  xran_mm_destroy, status %d\n",status);
845         iAssert(status == XRAN_STATUS_SUCCESS);
846     }
847 }
848
849 int get_xran_iq_content(void)
850 {
851     BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
852     xran_status_t status;
853     int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
854     int32_t nSectorNum;
855     int32_t cc_id, ant_id, sym_id, tti;
856     int32_t flowId;
857
858     uint8_t    frame_id    = 0;
859     uint8_t    subframe_id = 0;
860     uint8_t    slot_id     = 0;
861     uint8_t    sym         = 0;
862
863     void *ptr;
864     uint32_t *u32dptr;
865     uint16_t *u16dptr;
866     uint8_t  *u8dptr;
867
868     char        *pos = NULL;
869
870     for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
871     {
872         nSectorIndex[nSectorNum] = nSectorNum;
873     }
874     nSectorNum = numCCPorts;
875     printf ("get_xran_iq_content\n");
876
877     /* Init Memory */
878     for(cc_id = 0; cc_id <nSectorNum; cc_id++)
879     {
880         for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti++) {
881             for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
882                 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
883                     flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id;
884                     if(p_rx_log_buffer[flowId]){
885                         /* (0-79 slots) 10ms of IQs */
886                         pos =  ((char*)p_rx_log_buffer[flowId]) + rx_log_buffer_position[flowId];
887                         ptr = psBbuIo->sFrontHaulRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
888                         if(ptr){
889                             u32dptr = (uint32_t*)(ptr);
890                             rte_memcpy(pos, u32dptr, pXranConf->nULRBs*N_SC_PER_PRB*4);
891 #ifdef DEBUG_XRAN_BUFFERS
892                             if (pos[0] != tti||
893                                 pos[1] != cc_id  ||
894                                 pos[2] != ant_id ||
895                                 pos[3] != sym_id){
896                                     printf("[flowId %d] %d %d %d %d\n", flowId, pos[0], pos[1], pos[2], pos[3]);
897                             }
898 #endif
899                         }else
900                             printf("ptr ==NULL\n");
901
902                         rx_log_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4;
903
904                         if(rx_log_buffer_position[flowId] >= rx_log_buffer_size[flowId])
905                             rx_log_buffer_position[flowId] = 0;
906                     } else {
907                         //printf("flowId %d\n", flowId);
908                     }
909                 }
910
911                 /* prach RX for O-DU only */
912                 if(startupConfiguration.appMode == APP_O_DU){
913                     flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id;
914                     sym_id = 0;
915
916                     if(p_prach_log_buffer[flowId]){
917                         /* (0-79 slots) 10ms of IQs */
918                         pos =  ((char*)p_prach_log_buffer[flowId]) + prach_log_buffer_position[flowId];
919                         ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
920                         if(ptr){
921                             u32dptr = (uint32_t*)(ptr);
922                             rte_memcpy(pos, u32dptr, PRACH_PLAYBACK_BUFFER_BYTES);
923 #ifdef DEBUG_XRAN_BUFFERS
924                             if (pos[0] != tti||
925                                 pos[1] != cc_id  ||
926                                 pos[2] != ant_id ||
927                                 pos[3] != sym_id){
928                                     printf("[flowId %d] %d %d %d %d\n", flowId, pos[0], pos[1], pos[2], pos[3]);
929                             }
930 #endif
931                         }else
932                             printf("ptr ==NULL\n");
933
934                         prach_log_buffer_position[flowId] += PRACH_PLAYBACK_BUFFER_BYTES;
935
936                         if(prach_log_buffer_position[flowId] >= prach_log_buffer_size[flowId])
937                             prach_log_buffer_position[flowId] = 0;
938                     } else {
939                         //printf("flowId %d\n", flowId);
940                     }
941                 }
942
943             }
944         }
945     }
946
947     return 0;
948 }
949
950 void version_print(void)
951 {
952     char            sysversion[100];
953     char           *compilation_date = __DATE__;
954     char           *compilation_time = __TIME__;
955
956     uint32_t          nLen;
957     uint32_t          i;
958
959     snprintf(sysversion, 99, "Version: %s", VERSIONX);
960     nLen = strlen(sysversion);
961
962     printf("\n\n");
963     printf("===========================================================================================================\n");
964     printf("SAMPLE-APP VERSION\n");
965     printf("===========================================================================================================\n");
966
967     printf("%s\n", sysversion);
968     printf("build-date: %s\n", compilation_date);
969     printf("build-time: %s\n", compilation_time);
970 }
971
972 int main(int argc, char *argv[])
973 {
974     int i;
975     int j, len;
976     int  lcore_id = 0;
977     char filename[64];
978     uint32_t nCenterFreq;
979     int32_t xret = 0;
980     struct stat st = {0};
981     uint32_t filenameLength = strlen(argv[1]);
982     char *pCheckName1 = NULL, *pCheckName2 = NULL;
983     enum xran_if_state xran_curr_if_state = XRAN_INIT;
984
985     if (argc == 3)
986         errx(2, "Need two argument - the PCI address of the network port");
987     if (filenameLength >= 64)
988     {
989         printf("Config file name input is too long, exiting!\n");
990         exit(-1);
991     }
992
993     version_print();
994
995     //add for Klocworks
996     len = strlen(argv[1]) + 1;
997     if (len > (sizeof(filename) - 10))
998         len = (sizeof(filename) - 10);
999     strncpy(filename, argv[1], (sizeof(filename) - 10));
1000     filename[len] = '\0';
1001
1002     pCheckName1 = strstr(filename, "config_file_o_du.dat");
1003     pCheckName2 = strstr(filename, "config_file_o_ru.dat");
1004     if ((pCheckName1 == NULL) && (pCheckName2 == NULL))
1005     {
1006         printf("config file name %s is not valid!\n", filename);
1007         exit(-1);
1008     }
1009
1010     if (xran_is_synchronized() != 0)
1011         printf("Machine is not synchronized using PTP!\n");
1012     else
1013         printf("Machine is synchronized using PTP!\n");
1014
1015     memset(&startupConfiguration, 0, sizeof(RuntimeConfig));
1016
1017     if (parseConfigFile(filename, (RuntimeConfig*)&startupConfiguration) != 0) {
1018         printf("Configuration file error.\n");
1019         return 0;
1020     }
1021
1022     if(startupConfiguration.ant_file[0] == NULL){
1023         printf("it looks like test vector for antennas were not provided\n");
1024         exit(-1);
1025     }
1026     if (startupConfiguration.numCC > XRAN_MAX_SECTOR_NR)
1027     {
1028         printf("Number of cells %d exceeds max number supported %d!\n", startupConfiguration.numCC, XRAN_MAX_SECTOR_NR);
1029         startupConfiguration.numCC = XRAN_MAX_SECTOR_NR;
1030
1031     }
1032     numCCPorts = startupConfiguration.numCC;
1033     num_eAxc   = startupConfiguration.numAxc;
1034
1035     printf("numCCPorts %d num_eAxc%d\n", numCCPorts, num_eAxc);
1036
1037     if (startupConfiguration.mu_number <= 1){
1038         nFpgaToSW_FTH_RxBufferLen    = 13168; /* 273*12*4 + 64*/
1039         nFpgaToSW_PRACH_RxBufferLen  = 8192;
1040         nSW_ToFpga_FTH_TxBufferLen   = 13168; /* 273*12*4 + 64*/
1041     } else if (startupConfiguration.mu_number == 3){
1042         nFpgaToSW_FTH_RxBufferLen    = 3328;
1043         nFpgaToSW_PRACH_RxBufferLen  = 8192;
1044         nSW_ToFpga_FTH_TxBufferLen   = 3328;
1045     } else {
1046         printf("given numerology is not supported %d\n", startupConfiguration.mu_number);
1047         exit(-1);
1048     }
1049
1050     memset(&xranInit, 0, sizeof(struct xran_fh_init));
1051
1052     if(startupConfiguration.appMode == APP_O_DU) {
1053         printf("set O-DU\n");
1054         xranInit.io_cfg.id = 0;//ID_LLS_CU;
1055         xranInit.io_cfg.core          = 4+1;
1056         xranInit.io_cfg.system_core   = 0;
1057         xranInit.io_cfg.pkt_proc_core = 4+2;
1058         xranInit.io_cfg.pkt_aux_core  = 0; /* do not start*/
1059         xranInit.io_cfg.timing_core   = 4+3;
1060     } else {
1061         printf("set O-DU\n");
1062         xranInit.io_cfg.id = 1; /* ID_LLS_CU;*/
1063         xranInit.io_cfg.core          = 1;
1064         xranInit.io_cfg.system_core   = 0;
1065         xranInit.io_cfg.pkt_proc_core = 2;
1066         xranInit.io_cfg.pkt_aux_core  = 0; /* do not start */
1067         xranInit.io_cfg.timing_core   = 3;
1068     }
1069
1070     xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
1071
1072     xranInit.eAxCId_conf.mask_cuPortId      = 0xf000;
1073     xranInit.eAxCId_conf.mask_bandSectorId  = 0x0f00;
1074     xranInit.eAxCId_conf.mask_ccId          = 0x00f0;
1075     xranInit.eAxCId_conf.mask_ruPortId      = 0x000f;
1076     xranInit.eAxCId_conf.bit_cuPortId       = 12;
1077     xranInit.eAxCId_conf.bit_bandSectorId   = 8;
1078     xranInit.eAxCId_conf.bit_ccId           = 4;
1079     xranInit.eAxCId_conf.bit_ruPortId       = 0;
1080
1081     xranInit.io_cfg.dpdk_dev[XRAN_UP_VF]      = argv[2];
1082     xranInit.io_cfg.dpdk_dev[XRAN_CP_VF]      = argv[3];
1083     xranInit.mtu           = startupConfiguration.mtu;
1084
1085     xranInit.p_o_du_addr = (int8_t*)&startupConfiguration.o_du_addr;
1086     xranInit.p_o_ru_addr = (int8_t*)&startupConfiguration.o_ru_addr;
1087     xranInit.filePrefix  = "wls";
1088     xranInit.xranCat     = XRAN_CATRGORY_A;
1089
1090     xranInit.Tadv_cp_dl     = startupConfiguration.Tadv_cp_dl;
1091     xranInit.T2a_min_cp_dl  = startupConfiguration.T2a_min_cp_dl;
1092     xranInit.T2a_max_cp_dl  = startupConfiguration.T2a_max_cp_dl;
1093     xranInit.T2a_min_cp_ul  = startupConfiguration.T2a_min_cp_ul;
1094     xranInit.T2a_max_cp_ul  = startupConfiguration.T2a_max_cp_ul;
1095     xranInit.T2a_min_up     = startupConfiguration.T2a_min_up;
1096     xranInit.T2a_max_up     = startupConfiguration.T2a_max_up;
1097     xranInit.Ta3_min        = startupConfiguration.Ta3_min;
1098     xranInit.Ta3_max        = startupConfiguration.Ta3_max;
1099     xranInit.T1a_min_cp_dl  = startupConfiguration.T1a_min_cp_dl;
1100     xranInit.T1a_max_cp_dl  = startupConfiguration.T1a_max_cp_dl;
1101     xranInit.T1a_min_cp_ul  = startupConfiguration.T1a_min_cp_ul;
1102     xranInit.T1a_max_cp_ul  = startupConfiguration.T1a_max_cp_ul;
1103     xranInit.T1a_min_up     = startupConfiguration.T1a_min_up;
1104     xranInit.T1a_max_up     = startupConfiguration.T1a_max_up;
1105     xranInit.Ta4_min        = startupConfiguration.Ta4_min;
1106     xranInit.Ta4_max        = startupConfiguration.Ta4_max;
1107
1108     xranInit.enableCP       = startupConfiguration.enableCP;
1109     xranInit.prachEnable    = startupConfiguration.enablePrach;
1110     xranInit.debugStop      = startupConfiguration.debugStop;
1111     xranInit.debugStopCount = startupConfiguration.debugStopCount;
1112     xranInit.DynamicSectionEna = startupConfiguration.DynamicSectionEna;
1113     xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED; //startupConfiguration.bbdevMode;
1114
1115     xranInit.cp_vlan_tag    = startupConfiguration.cp_vlan_tag;
1116     xranInit.up_vlan_tag    = startupConfiguration.up_vlan_tag;
1117
1118     printf("IQ files size is %d slots\n", startupConfiguration.numSlots);
1119
1120     iq_playback_buffer_size_dl = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
1121                                  app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA)
1122                                  *4L);
1123
1124     iq_playback_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
1125                                  app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA)
1126                                  *4L);
1127
1128     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1129
1130         p_tx_play_buffer[i]    = (int16_t*)malloc(iq_playback_buffer_size_dl);
1131         tx_play_buffer_size[i] = (int32_t)iq_playback_buffer_size_dl;
1132
1133         if (p_tx_play_buffer[i] == NULL)
1134             exit(-1);
1135
1136         tx_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.ant_file[i],
1137                             "DL IFFT IN IQ Samples in binary format",
1138                             (uint8_t*) p_tx_play_buffer[i],
1139                             tx_play_buffer_size[i],
1140                             1);
1141         tx_play_buffer_position[i] = 0;
1142     }
1143
1144     if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
1145          for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1146              p_tx_prach_play_buffer[i]    = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES);
1147              tx_prach_play_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES;
1148
1149              if (p_tx_prach_play_buffer[i] == NULL)
1150                  exit(-1);
1151
1152              tx_prach_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.prach_file[i],
1153                                  "PRACH IQ Samples in binary format",
1154                                  (uint8_t*) p_tx_prach_play_buffer[i],
1155                                  tx_prach_play_buffer_size[i],
1156                                  1);
1157              tx_prach_play_buffer_position[i] = 0;
1158          }
1159     }
1160     /* log of ul */
1161     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1162
1163         p_rx_log_buffer[i]    = (int16_t*)malloc(iq_playback_buffer_size_ul);
1164         rx_log_buffer_size[i] = (int32_t)iq_playback_buffer_size_ul;
1165
1166         if (p_rx_log_buffer[i] == NULL)
1167             exit(-1);
1168
1169         rx_log_buffer_position[i] = 0;
1170
1171         memset(p_rx_log_buffer[i], 0, rx_log_buffer_size[i]);
1172     }
1173
1174     /* log of Prach */
1175     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1176
1177         p_prach_log_buffer[i]    = (int16_t*)malloc(startupConfiguration.numSlots*PRACH_PLAYBACK_BUFFER_BYTES);
1178         prach_log_buffer_size[i] = (int32_t)startupConfiguration.numSlots*PRACH_PLAYBACK_BUFFER_BYTES;
1179
1180         if (p_prach_log_buffer[i] == NULL)
1181             exit(-1);
1182
1183         memset(p_prach_log_buffer[i], 0, prach_log_buffer_size[i]);
1184         prach_log_buffer_position[i] = 0;
1185     }
1186
1187     if (stat("./logs", &st) == -1) {
1188         mkdir("./logs", 0777);
1189     }
1190
1191     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1192
1193         sprintf(filename, "./logs/%s-play_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
1194         sys_save_buf_to_file_txt(filename,
1195                             "DL IFFT IN IQ Samples in human readable format",
1196                             (uint8_t*) p_tx_play_buffer[i],
1197                             tx_play_buffer_size[i],
1198                             1);
1199
1200         sprintf(filename, "./logs/%s-play_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1201         sys_save_buf_to_file(filename,
1202                             "DL IFFT IN IQ Samples in binary format",
1203                             (uint8_t*) p_tx_play_buffer[i],
1204                             tx_play_buffer_size[i]/sizeof(short),
1205                             sizeof(short));
1206
1207         if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
1208             sprintf(filename, "./logs/%s-play_prach_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
1209             sys_save_buf_to_file_txt(filename,
1210                                 "DL IFFT IN IQ Samples in human readable format",
1211                                 (uint8_t*) p_tx_prach_play_buffer[i],
1212                                 tx_prach_play_buffer_size[i],
1213                                 1);
1214
1215             sprintf(filename, "./logs/%s-play_prach_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1216             sys_save_buf_to_file(filename,
1217                                 "DL IFFT IN IQ Samples in binary format",
1218                                 (uint8_t*) p_tx_prach_play_buffer[i],
1219                                 tx_prach_play_buffer_size[i]/sizeof(short),
1220                                 sizeof(short));
1221         }
1222     }
1223     if (startupConfiguration.iqswap == 1){
1224         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1225             printf("TX: Swap I and Q to match RU format: [%d]\n",i);
1226             {
1227                 /* swap I and Q */
1228                 int32_t j;
1229                 signed short *ptr = (signed short *)  p_tx_play_buffer[i];
1230                 signed short temp;
1231
1232                 for (j = 0; j < (int32_t)(tx_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
1233                    temp    = ptr[j];
1234                    ptr[j]  = ptr[j + 1];
1235                    ptr[j + 1] = temp;
1236                 }
1237             }
1238         }
1239         if (startupConfiguration.appMode == APP_O_RU){
1240             for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1241                 printf("PRACH: Swap I and Q to match RU format: [%d]\n",i);
1242                 {
1243                     /* swap I and Q */
1244                     int32_t j;
1245                     signed short *ptr = (signed short *)  p_tx_prach_play_buffer[i];
1246                     signed short temp;
1247
1248                     for (j = 0; j < (int32_t)(tx_prach_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
1249                        temp    = ptr[j];
1250                        ptr[j]  = ptr[j + 1];
1251                        ptr[j + 1] = temp;
1252                     }
1253                 }
1254             }
1255         }
1256
1257     }
1258
1259 #if 0
1260     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1261
1262         sprintf(filename, "./logs/swap_IQ_play_ant%d.txt", i);
1263         sys_save_buf_to_file_txt(filename,
1264                             "DL IFFT IN IQ Samples in human readable format",
1265                             (uint8_t*) p_tx_play_buffer[i],
1266                             tx_play_buffer_size[i],
1267                             1);
1268     }
1269 #endif
1270     if (startupConfiguration.nebyteorderswap == 1){
1271         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1272             printf("TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
1273             for (j = 0; j < tx_play_buffer_size[i]/sizeof(short); j++){
1274                 p_tx_play_buffer[i][j]  = rte_cpu_to_be_16(p_tx_play_buffer[i][j]);
1275             }
1276         }
1277
1278         if (startupConfiguration.appMode == APP_O_RU){
1279             for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1280                 printf("PRACH: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
1281                 for (j = 0; j < tx_prach_play_buffer_size[i]/sizeof(short); j++){
1282                     p_tx_prach_play_buffer[i][j]  = rte_cpu_to_be_16(p_tx_prach_play_buffer[i][j]);
1283                 }
1284             }
1285         }
1286     }
1287
1288 #if 0
1289     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1290
1291         sprintf(filename, "./logs/swap_be_play_ant%d.txt", i);
1292         sys_save_buf_to_file_txt(filename,
1293                             "DL IFFT IN IQ Samples in human readable format",
1294                             (uint8_t*) p_tx_play_buffer[i],
1295                             tx_play_buffer_size[i],
1296                             1);
1297     }
1298 #endif
1299
1300
1301     timer_set_tsc_freq_from_clock();
1302     xret =  xran_init(argc, argv, &xranInit, argv[0], &xranHandle);
1303     if(xret != XRAN_STATUS_SUCCESS){
1304         printf("xran_init failed %d\n", xret);
1305         exit(-1);
1306     }
1307
1308     if(xranHandle == NULL)
1309         exit(1);
1310
1311     memset(&xranConf, 0, sizeof(struct xran_fh_config));
1312     pXranConf = &xranConf;
1313
1314     pXranConf->sector_id                        = 0;
1315     pXranConf->nCC                              = numCCPorts;
1316     pXranConf->neAxc                            = num_eAxc;
1317
1318     pXranConf->frame_conf.nFrameDuplexType      = startupConfiguration.nFrameDuplexType;
1319     pXranConf->frame_conf.nNumerology           = startupConfiguration.mu_number;
1320     pXranConf->frame_conf.nTddPeriod            = startupConfiguration.nTddPeriod;
1321
1322     for (i = 0; i < startupConfiguration.nTddPeriod; i++){
1323         pXranConf->frame_conf.sSlotConfig[i] = startupConfiguration.sSlotConfig[i];
1324     }
1325
1326     pXranConf->prach_conf.nPrachSubcSpacing     = startupConfiguration.mu_number;
1327     pXranConf->prach_conf.nPrachFreqStart       = 0;
1328     pXranConf->prach_conf.nPrachFilterIdx       = XRAN_FILTERINDEX_PRACH_ABC;
1329     pXranConf->prach_conf.nPrachConfIdx         = startupConfiguration.prachConfigIndex;
1330     pXranConf->prach_conf.nPrachFreqOffset      = -792;
1331
1332     pXranConf->ru_conf.iqWidth                  = 16;
1333     pXranConf->ru_conf.compMeth                 = XRAN_COMPMETHOD_NONE;
1334     pXranConf->ru_conf.fftSize                  = 0;
1335     while (startupConfiguration.nULFftSize >>= 1)
1336         ++pXranConf->ru_conf.fftSize;
1337
1338     pXranConf->ru_conf.byteOrder = (startupConfiguration.nebyteorderswap == 1) ? XRAN_NE_BE_BYTE_ORDER : XRAN_CPU_LE_BYTE_ORDER  ;
1339     pXranConf->ru_conf.iqOrder   = (startupConfiguration.iqswap == 1) ? XRAN_Q_I_ORDER : XRAN_I_Q_ORDER;
1340
1341     printf("FFT Order %d\n", pXranConf->ru_conf.fftSize);
1342
1343     pXranConf->nDLRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA);
1344     pXranConf->nULRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA);
1345
1346     nCenterFreq = startupConfiguration.nDLAbsFrePointA + (((pXranConf->nDLRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
1347     pXranConf->nDLCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
1348     printf("DL center freq %d DL NR-ARFCN  %d\n", nCenterFreq, pXranConf->nDLCenterFreqARFCN);
1349
1350     nCenterFreq = startupConfiguration.nULAbsFrePointA + (((pXranConf->nULRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
1351     pXranConf->nULCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
1352     printf("UL center freq %d UL NR-ARFCN  %d\n", nCenterFreq, pXranConf->nULCenterFreqARFCN);
1353
1354     pXranConf->bbdev_dec = NULL;
1355     pXranConf->bbdev_enc = NULL;
1356
1357     if(init_xran() != 0)
1358         exit(-1);
1359
1360     xran_reg_physide_cb(xranHandle, physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI);
1361     xran_reg_physide_cb(xranHandle, physide_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX);
1362     xran_reg_physide_cb(xranHandle, physide_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX);
1363
1364     init_xran_iq_content();
1365
1366     xret = xran_open(xranHandle, pXranConf);
1367
1368     if(xret != XRAN_STATUS_SUCCESS){
1369         printf("xran_open failed %d\n", xret);
1370         exit(-1);
1371     }
1372
1373     sprintf(filename, "mlog-%s", startupConfiguration.appMode == 0 ? "o-du" : "o-ru");
1374
1375 //    MLogOpen(0, 32, 0, 0xFFFFFFFF, filename);
1376
1377     MLogOpen(256, 3, 20000, 0xFFFFFFFF, filename);
1378
1379     puts("----------------------------------------");
1380     printf("MLog Info: virt=0x%016lx size=%d\n", MLogGetFileLocation(), MLogGetFileSize());
1381     puts("----------------------------------------");
1382
1383
1384     uint64_t nActiveCoreMask[MAX_BBU_POOL_CORE_MASK] = {0};
1385      nActiveCoreMask[0] = 1 << xranInit.io_cfg.timing_core;
1386     uint32_t numCarriers = startupConfiguration.numCC;
1387
1388     MLogAddTestCase(nActiveCoreMask, numCarriers);
1389
1390     fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
1391
1392     state = APP_RUNNING;
1393     printf("Start XRAN traffic\n");
1394     xran_start(xranHandle);
1395     sleep(3);
1396     print_menu();
1397     for (;;) {
1398         struct xran_common_counters x_counters;
1399         char input[10];
1400         sleep(1);
1401         xran_curr_if_state = xran_get_if_state();
1402         if(xran_get_common_counters(xranHandle, &x_counters) == XRAN_STATUS_SUCCESS) {
1403             printf("rx %ld tx %ld  [on_time %ld early %ld late %ld corrupt %ld pkt_dupl %ld Total %ld\n", rx_counter, tx_counter,
1404                    x_counters.Rx_on_time,
1405                    x_counters.Rx_early,
1406                    x_counters.Rx_late,
1407                    x_counters.Rx_corrupt,
1408                    x_counters.Rx_pkt_dupl,
1409                    x_counters.Total_msgs_rcvd);
1410         } else {
1411             printf("error xran_get_common_counters\n");
1412         }
1413
1414         if (xran_curr_if_state == XRAN_STOPPED){
1415             break;
1416         }
1417         if (NULL == fgets(input, 10, stdin)) {
1418             continue;
1419         }
1420
1421         const int sel_opt = atoi(input);
1422         switch (sel_opt) {
1423             case 1:
1424                 xran_start(xranHandle);
1425                 printf("Start XRAN traffic\n");
1426                 break;
1427             case 2:
1428                 break;
1429             case 3:
1430                 xran_stop(xranHandle);
1431                 printf("Stop XRAN traffic\n");
1432                 state = APP_STOPPED;
1433                 break;
1434             default:
1435                 puts("Wrong option passed!");
1436                 break;
1437         }
1438         if (APP_STOPPED == state)
1439             break;
1440     }
1441
1442     get_xran_iq_content();
1443
1444     puts("Closing l1 app... Ending all threads...");
1445     xran_close(xranHandle);
1446     MLogPrint(NULL);
1447
1448     stop_xran();
1449     puts("Dump IQs...");
1450
1451     if (startupConfiguration.iqswap == 1){
1452         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1453             printf("RX: Swap I and Q to match CPU format: [%d]\n",i);
1454             {
1455                 /* swap I and Q */
1456                 int32_t j;
1457                 signed short *ptr = (signed short *)  p_rx_log_buffer[i];
1458                 signed short temp;
1459
1460                 for (j = 0; j < (int32_t)(rx_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
1461                    temp    = ptr[j];
1462                    ptr[j]  = ptr[j + 1];
1463                    ptr[j + 1] = temp;
1464                 }
1465             }
1466         }
1467     }
1468
1469     if (startupConfiguration.nebyteorderswap == 1){
1470         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1471             printf("RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
1472             for (j = 0; j < rx_log_buffer_size[i]/sizeof(short); j++){
1473                 p_rx_log_buffer[i][j]  = rte_be_to_cpu_16(p_rx_log_buffer[i][j]);
1474             }
1475         }
1476     }
1477
1478     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1479
1480         sprintf(filename, "./logs/%s-rx_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
1481         sys_save_buf_to_file_txt(filename,
1482                             "UL FFT OUT IQ Samples in human readable format",
1483                             (uint8_t*) p_rx_log_buffer[i],
1484                             rx_log_buffer_size[i],
1485                             1);
1486
1487         sprintf(filename, "./logs/%s-rx_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1488         sys_save_buf_to_file(filename,
1489                             "UL FFT OUT IQ Samples in binary format",
1490                             (uint8_t*) p_rx_log_buffer[i],
1491                             rx_log_buffer_size[i]/sizeof(short),
1492                             sizeof(short));
1493     }
1494
1495     if (startupConfiguration.appMode == APP_O_DU &&  startupConfiguration.enablePrach){
1496         if (startupConfiguration.iqswap == 1){
1497             for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1498                 printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i);
1499                 {
1500                     /* swap I and Q */
1501                     int32_t j;
1502                     signed short *ptr = (signed short *)  p_prach_log_buffer[i];
1503                     signed short temp;
1504
1505                     for (j = 0; j < (int32_t)(prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
1506                        temp    = ptr[j];
1507                        ptr[j]  = ptr[j + 1];
1508                        ptr[j + 1] = temp;
1509                     }
1510                 }
1511             }
1512         }
1513
1514
1515         if (startupConfiguration.nebyteorderswap == 1){
1516             for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1517                 printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
1518                 for (j = 0; j < prach_log_buffer_size[i]/sizeof(short); j++){
1519                     p_prach_log_buffer[i][j]  = rte_be_to_cpu_16(p_prach_log_buffer[i][j]);
1520                 }
1521             }
1522         }
1523
1524
1525         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1526
1527             sprintf(filename, "./logs/%s-prach_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
1528             sys_save_buf_to_file_txt(filename,
1529                                 "PRACH FFT OUT IQ Samples in human readable format",
1530                                 (uint8_t*) p_prach_log_buffer[i],
1531                                 prach_log_buffer_size[i],
1532                                 1);
1533
1534             sprintf(filename, "./logs/%s-prach_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1535             sys_save_buf_to_file(filename,
1536                                 "PRACH FFT OUT IQ Samples in binary format",
1537                                 (uint8_t*) p_prach_log_buffer[i],
1538                                 prach_log_buffer_size[i]/sizeof(short),
1539                                 sizeof(short));
1540         }
1541     }
1542
1543     return 0;
1544 }