* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / app / src / sample-app.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2020 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  * @brief Main module of sample application. Demonstration of usage of xRAN library for ORAN
21  *        WG4 Front haul
22  * @file sample-app.c
23  * @ingroup xran
24  * @author Intel Corporation
25  *
26  **/
27
28 #define _GNU_SOURCE
29 #include <unistd.h>
30 #include <immintrin.h>
31 #include <sys/syscall.h>
32 #include <sys/sysinfo.h>
33 #include <sched.h>
34 #include <assert.h>
35 #include <err.h>
36 #include <libgen.h>
37 #include <sys/time.h>
38 #include <time.h>
39 #include <unistd.h>
40 #include <stdio.h>
41 #include <fcntl.h>
42 #include <pthread.h>
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #include <getopt.h>
46 #include <string.h>
47
48 #include "common.h"
49 #include "config.h"
50 #include "xran_mlog_lnx.h"
51
52 #include "xran_fh_o_du.h"
53 #include "xran_sync_api.h"
54 #include "xran_mlog_task_id.h"
55 #include "app_io_fh_xran.h"
56 #include "app_profile_xran.h"
57 #ifdef FWK_ENABLED
58 #include "app_bbu_pool.h"
59 #endif
60 #include "xran_ecpri_owd_measurements.h"
61
62 #define MAX_BBU_POOL_CORE_MASK  (4)
63 #ifndef NS_PER_SEC
64 #define NS_PER_SEC 1E9
65 #endif
66 #define MAIN_PRIORITY 98
67 #define CPU_HZ ticks_per_usec /* us */
68
69 struct sample_app_params {
70     int num_vfs;
71     int num_o_xu;
72     char *cfg_file;
73     char *usecase_file;
74     char vf_pcie_addr[XRAN_PORTS_NUM][XRAN_VF_MAX][32];
75 };
76
77 struct app_sym_cb_ctx {
78     int32_t cb_param;
79     struct  xran_sense_of_time sense_of_time;
80 };
81
82 static enum app_state state;
83 static uint64_t  ticks_per_usec;
84
85 UsecaseConfig* p_usecaseConfiguration = {NULL};
86 RuntimeConfig* p_startupConfiguration[XRAN_PORTS_NUM] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
87
88 struct app_sym_cb_ctx cb_sym_ctx[XRAN_CB_SYM_MAX];
89
90 long old_rx_counter[XRAN_PORTS_NUM] = {0,0,0,0,0,0,0,0};
91 long old_tx_counter[XRAN_PORTS_NUM] = {0,0,0,0,0,0,0,0};
92
93 static void
94 app_print_menu()
95 {
96     puts("+---------------------------------------+");
97     puts("| Press 1 to start 5G NR XRAN traffic   |");
98     puts("| Press 2 reserved for future use       |");
99     puts("| Press 3 to quit                       |");
100     puts("+---------------------------------------+");
101 }
102
103 uint64_t
104 app_timer_get_ticks(void)
105 {
106     uint64_t ret;
107     union
108     {
109         uint64_t tsc_64;
110         struct
111         {
112             uint32_t lo_32;
113             uint32_t hi_32;
114         };
115     } tsc;
116
117     __asm volatile("rdtsc" :
118              "=a" (tsc.lo_32),
119              "=d" (tsc.hi_32));
120
121      ret = ((uint64_t)tsc.tsc_64);
122      return ret;
123 }
124
125 //-------------------------------------------------------------------------------------------
126 /** @ingroup xran
127  *
128  *  @param   void
129  *
130  *  @return  0 if SUCCESS
131  *
132  *  @description
133  *  This function gets the clock speed of the core and figures out number of ticks per usec.
134  *  It is used by l1app and testmac applications to initialize the mlog utility
135  *
136 **/
137 //-------------------------------------------------------------------------------------------
138 int32_t
139 app_timer_set_tsc_freq_from_clock(void)
140 {
141     struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */
142     struct timespec t_start, t_end;
143     uint64_t tsc_resolution_hz = 0;
144
145     if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) {
146         unsigned long ns, end, start = app_timer_get_ticks();
147         nanosleep(&sleeptime,NULL);
148         clock_gettime(CLOCK_MONOTONIC_RAW, &t_end);
149         end = app_timer_get_ticks();
150         ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC);
151         ns += (t_end.tv_nsec - t_start.tv_nsec);
152
153         double secs = (double)ns/NS_PER_SEC;
154         tsc_resolution_hz = (unsigned long)((end - start)/secs);
155
156         ticks_per_usec = (tsc_resolution_hz / 1000000);
157         printf("System clock (rdtsc) resolution %lu [Hz]\n", tsc_resolution_hz);
158         printf("Ticks per us %lu\n", ticks_per_usec);
159         return 0;
160     }
161
162     return -1;
163 }
164
165 void
166 app_version_print(void)
167 {
168     char            sysversion[100];
169     char           *compilation_date = __DATE__;
170     char           *compilation_time = __TIME__;
171     char            compiler[100];
172
173     snprintf(sysversion, 99, "Version: %s", VERSIONX);
174
175 #if defined(__clang__)
176     snprintf(compiler, 99, "family clang: %s", __clang_version__);
177 #elif defined(__ICC) || defined(__INTEL_COMPILER)
178     snprintf(compiler, 99, "family icc: version %d", __INTEL_COMPILER);
179 #elif defined(__INTEL_LLVM_COMPILER)
180     snprintf(compiler, 99, "family icx: version %d", __INTEL_LLVM_COMPILER);
181 #elif defined(__GNUC__) || defined(__GNUG__)
182     snprintf(compiler, 99, "family gcc: version %d.%d.%d", __GNUC__, __GNUC_MINOR__,__GNUC_PATCHLEVEL__);
183 #endif
184
185     printf("\n\n");
186     printf("===========================================================================================================\n");
187     printf("SAMPLE-APP VERSION\n");
188     printf("===========================================================================================================\n");
189
190     printf("%s\n", sysversion);
191     printf("build-date: %s\n", compilation_date);
192     printf("build-time: %s\n", compilation_time);
193     printf("build-with: %s\n", compiler);
194 }
195
196 static void
197 app_help(void)
198 {
199     char help_content[] =  \
200             "sample application\n\n"\
201             "Usage: sample-app --usecasefile ./usecase_du.cfg --num_eth_vfs 12"\
202                                 "--vf_addr_o_xu_a \"0000:51:01.0,0000:51:01.1,0000:51:01.2,0000:51:01.3\""\
203                                 "--vf_addr_o_xu_b \"0000:51:01.4,0000:51:01.5,0000:51:01.6,0000:51:01.7\""\
204                                 "--vf_addr_o_xu_c \"0000:51:02.0,0000:51:02.1,0000:51:02.2,0000:51:02.3\"\n\n"\
205             "or     sample-app --usecasefile ./usecase_du.cfg --num_eth_vfs 2"\
206                                 "--vf_addr_o_xu_a \"0000:51:01.0,0000:51:01.1\""\
207                 "supports the following options:\n\n"\
208             "-p | --num_eth_pfs <number of ETH ports to connect to O-RU|O-DU>     2 - default\n"
209             "-a | --vf_addr_o_xu_a <list of PCIe Bus Address separated by comma for VFs of O-xU0 >"
210             "-b | --vf_addr_o_xu_b <list of PCIe Bus Address separated by comma for VFs of O-xU1 >"
211             "-c | --vf_addr_o_xu_c <list of PCIe Bus Address separated by comma for VFs of O-xU2 >"
212             "-d | --vf_addr_o_xu_d <list of PCIe Bus Address separated by comma for VFs of O-xU3 >"
213             "-u | --usecasefile <name of use case file for multiple O-DU|O-RUs>\n"\
214             "-h | --help         print usage\n";
215
216     printf("%s", help_content);
217 }
218
219 /**
220  *******************************************************************************
221  *
222  * @fn    app_parse_args
223  * @brief is used to parse incoming app args
224  *
225  * @description
226  *    The routine is parse input args and convert them into app startup params
227  *
228  * @references
229  *
230  * @ingroup xran_lib
231  *
232  ******************************************************************************/
233 static int32_t
234 app_parse_cmdline_args(int argc, char ** argv, struct sample_app_params* params)
235 {
236     int32_t c = 0;
237     int32_t vf_cnt = 0;
238     int32_t cnt = 0;
239     size_t optlen = 0;
240     char *saveptr = NULL;
241     char *token = NULL;
242     int32_t port = 8;
243
244     static struct option long_options[] = {
245         {"cfgfile", required_argument, 0, 'z'},
246         {"usecasefile", required_argument, 0, 'u'},
247         {"num_eth_vfs", required_argument, 0, 'p'},
248         {"vf_addr_o_xu_a", required_argument, 0, 'a'},
249         {"vf_addr_o_xu_b", required_argument, 0, 'b'},
250         {"vf_addr_o_xu_c", required_argument, 0, 'c'},
251         {"vf_addr_o_xu_d", required_argument, 0, 'd'},
252         {"vf_addr_o_xu_e", required_argument, 0, 'e'},
253         {"vf_addr_o_xu_f", required_argument, 0, 'F'},
254         {"vf_addr_o_xu_g", required_argument, 0, 'g'},
255         {"vf_addr_o_xu_h", required_argument, 0, 'H'},
256         {"help", no_argument, 0, 'h'},
257         {0, 0, 0, 0}
258     };
259
260     memset(params, 0, sizeof (*params));
261
262     while (1) {
263         //int this_option_optind = optind ? optind : 1;
264         int option_index = 0;
265
266         c = getopt_long(argc, argv, "a:b:c:d:e:f:F:g:h:H:p:u:v", long_options, &option_index);
267
268         if (c == -1)
269             break;
270
271         cnt += 1;
272         port = 8;
273
274         switch (c) {
275             case 'f':
276                 params->cfg_file = optarg;
277                 optlen = strlen(optarg) + 1;
278                 printf("%s:%d: %s [len %ld]\n",__FUNCTION__, __LINE__, params->cfg_file, optlen);
279                 break;
280             case 'p':
281                 params->num_vfs = atoi(optarg);
282                 printf("%s:%d: %d\n",__FUNCTION__, __LINE__, params->num_vfs);
283                 break;
284             case 'u':
285                 params->usecase_file = optarg;
286                 optlen = strlen(optarg) + 1;
287                 printf("%s:%d: %s [len %ld]\n",__FUNCTION__, __LINE__, params->usecase_file, optlen);
288                 break;
289             case 'a':
290                 port -= 1;
291             case 'b':
292                 port -= 1;
293             case 'c':
294                 port -= 1;
295             case 'd':
296                 port -= 1;
297             case 'e':
298                 port -= 1;
299             case 'F':
300                 port -= 1;
301             case 'g':
302                 port -= 1;
303             case 'H':
304                 port -= 1;
305                 vf_cnt = 0;
306                 optlen = strlen(optarg) + 1;
307                 printf("%s:%d: port %d %s [len %ld]\n",__FUNCTION__, __LINE__, port, optarg, optlen);
308                 token = strtok_r(optarg, ",", &saveptr);
309                 while (token != NULL) {
310                     optlen = strlen(token) + 1;
311                     snprintf(&params->vf_pcie_addr[port][vf_cnt][0], optlen, "%s", token);
312                     printf("%s:%d: port %d %s [len %ld]\n",__FUNCTION__, __LINE__, port, &params->vf_pcie_addr[port][vf_cnt][0], optlen);
313                     token = strtok_r(NULL, ",", &saveptr);
314                     vf_cnt +=1;
315                 }
316                 break;
317             case 'h':
318                 app_help();
319                 exit(0);
320         }
321     }
322     return cnt;
323 }
324
325 int32_t
326 app_apply_slot_cfg(RuntimeConfig *config)
327 {
328     int32_t ret = 0;
329     int32_t slot_idx = 0;
330     int32_t cc_idx = 0;
331     int32_t ant_idx = 0;
332     int32_t section_idx = 0;
333     int32_t direction = 0;
334
335     int32_t enable = 0;
336
337     for (slot_idx = 0; slot_idx  < config->numSlots; slot_idx++) {
338         for (direction = 0; direction < XRAN_DIR_MAX; direction++) {
339             for (cc_idx = 0; cc_idx < config->numCC; cc_idx++) {
340                 for (ant_idx = 0; ant_idx < ((direction == XRAN_DIR_UL) ? config->numUlAxc :config->numAxc); ant_idx++) {
341                     for (section_idx = 0; section_idx < config->p_SlotPrbMap[direction][slot_idx]->nPrbElm && section_idx < XRAN_MAX_SECTIONS_PER_SLOT; section_idx++) {
342                         if (config->SlotPrbCCmask[direction][slot_idx][section_idx] & (1L << cc_idx)) {
343                             if (config->SlotPrbAntCMask[direction][slot_idx][section_idx] & (1L << ant_idx)) {
344                                 struct xran_prb_map  *pRbMap = config->p_RunSlotPrbMap[direction][slot_idx][cc_idx][ant_idx];
345                                 pRbMap->dir = direction;
346                                 pRbMap->xran_port = config->o_xu_id;
347                                 pRbMap->band_id = 0;
348                                 pRbMap->cc_id = cc_idx;
349                                 pRbMap->ru_port_id = ant_idx;
350                                 pRbMap->tti_id = slot_idx;
351                                 pRbMap->start_sym_id = 0;
352                                 if (pRbMap->nPrbElm < XRAN_MAX_SECTIONS_PER_SLOT && section_idx < XRAN_MAX_SECTIONS_PER_SLOT) {
353                                     struct xran_prb_elm *pMapElmRun = &pRbMap->prbMap[pRbMap->nPrbElm];
354                                     struct xran_prb_elm *pMapElmCfg = &config->p_SlotPrbMap[direction][slot_idx]->prbMap[section_idx];
355                                     memcpy(pMapElmRun, pMapElmCfg, sizeof(struct xran_prb_elm));
356             } else {
357                                     rte_panic("Incorrect slot cfg\n");
358             }
359                                 pRbMap->nPrbElm++;
360                                 enable = 1;
361         }
362     }
363 }
364             }
365             }
366         }
367     }
368
369     config->RunSlotPrbMapEnabled = enable;
370     printf("[%d]config->RunSlotPrbMapEnabled %d\n",config->o_xu_id, config->RunSlotPrbMapEnabled);
371
372     return ret;
373 }
374
375 int32_t
376 app_parse_all_cfgs(struct sample_app_params* p_args, UsecaseConfig* p_use_cfg,  RuntimeConfig* p_o_xu_cfg)
377 {
378     int32_t ret     = 0;
379     int32_t vf_num  = 0;
380     int32_t o_xu_id = 0;
381     char filename[512];
382     char bbu_filename[512];
383     char *dir;
384     size_t len;
385
386     if (p_use_cfg) {
387         memset(p_use_cfg, 0, sizeof(UsecaseConfig));
388     } else {
389         printf("p_use_cfg error.\n");
390         exit(-1);
391     }
392
393     p_use_cfg->dlCpProcBurst = 1;
394
395     if (p_args) {
396         if (p_args->usecase_file) { /* use case for multiple O-RUs */
397             printf("p_args->usecase_file (%s)\n", p_args->usecase_file);
398             len = strlen(p_args->usecase_file) + 1;
399             if (len > 511){
400                 printf("app_parse_all_cfgs: Name of p_args->usecase_file, %s is too long.  Maximum is 511 characters!!\n", p_args->usecase_file);
401                 return -1;
402             } else {
403                 strncpy(filename, p_args->usecase_file, RTE_MIN (512,len));
404             }
405             if (parseUsecaseFile(filename, p_use_cfg) != 0) {
406                 printf("Use case config file error.\n");
407                 return -1;
408             }
409             if (p_use_cfg->oXuNum > XRAN_PORTS_NUM) {
410                 printf("Use case config file error.\n");
411                 return -1;
412             }
413
414             if (p_o_xu_cfg) {
415                 int32_t i;
416                 RuntimeConfig* p_o_xu_cfg_loc = p_o_xu_cfg;
417                 for (i = 0; i < p_use_cfg->oXuNum; i++) {
418                     config_init(p_o_xu_cfg_loc);
419                     p_o_xu_cfg_loc++;
420                 }
421             } else {
422                 printf("p_o_xu_cfg error.\n");
423                 exit(-1);
424             }
425             /* use cmdline pcie address */
426             for (o_xu_id = 0; o_xu_id < p_use_cfg->oXuNum && o_xu_id < XRAN_PORTS_NUM; o_xu_id++) {
427                 for (vf_num = 0; vf_num <  XRAN_VF_MAX && p_args->num_vfs ; vf_num++) {
428                     strncpy(&p_use_cfg->o_xu_pcie_bus_addr[o_xu_id][vf_num][0], &p_args->vf_pcie_addr[o_xu_id][vf_num][0], RTE_MIN (512,strlen(&p_args->vf_pcie_addr[o_xu_id][vf_num][0])));
429                 }
430             }
431
432
433             dir = dirname(p_args->usecase_file);
434             if(strlen(p_use_cfg->o_xu_bbu_cfg_file)){
435                 memset(bbu_filename, 0, sizeof(bbu_filename));
436                 printf("dir (%s)\n",dir);
437                 len = strlen(dir) + 1;
438                 if (len > 511){
439                     printf("app_parse_all_cfgs: Name of directory, %s, xu_id = %d is too long.  Maximum is 511 characters!!\n", dir, o_xu_id);
440                     return -1;
441                 } else {
442                     strncpy(bbu_filename, dir, RTE_MIN(512,len));
443                 }
444                 strncat(bbu_filename, "/", 1);
445                 len +=1;
446                 len = (sizeof(bbu_filename)) - len;
447                 if (len > strlen(p_use_cfg->o_xu_bbu_cfg_file)) {
448                     strncat(bbu_filename, p_use_cfg->o_xu_bbu_cfg_file, RTE_MIN (len, strlen(p_use_cfg->o_xu_bbu_cfg_file)));
449                 } else {
450                     printf("File name error\n");
451                     return -1;
452                 }
453                 strncpy(p_use_cfg->o_xu_bbu_cfg_file, bbu_filename, RTE_MIN (512, strlen(bbu_filename)));
454                 printf("bbu_cfg_file (%s)\n",p_use_cfg->o_xu_bbu_cfg_file);
455 #ifdef FWK_ENABLED
456                 p_use_cfg->bbu_offload = 1;
457 #else
458                 p_use_cfg->bbu_offload = 0;
459 #endif
460             } else {
461                 printf("bbu_cfg_file is not provided\n");
462                 p_use_cfg->bbu_offload = 0;
463             }
464
465             for (o_xu_id = 0; o_xu_id < p_use_cfg->oXuNum && o_xu_id < XRAN_PORTS_NUM; o_xu_id++) {
466                 memset(filename, 0, sizeof(filename));
467                 printf("dir (%s)\n",dir);
468                 len = strlen(dir) + 1;
469                 if (len > 511){
470                     printf("app_parse_all_cfgs: Name of directory, %s, xu_id = %d is too long.  Maximum is 511 characters!!\n", dir, o_xu_id);
471         return -1;
472                 } else {
473                     strncpy(filename, dir, RTE_MIN (512,len));
474     }
475                 strncat(filename, "/", 1);
476                 len +=1;
477                 len = (sizeof(filename)) - len;
478
479                 if (len > strlen(p_use_cfg->o_xu_cfg_file[o_xu_id])) {
480                     strncat(filename, p_use_cfg->o_xu_cfg_file[o_xu_id], RTE_MIN (len, strlen(p_use_cfg->o_xu_cfg_file[o_xu_id])));
481                 } else {
482                     printf("File name error\n");
483                     return -1;
484                 }
485                 printf("cfg_file (%s)\n",filename);
486                 printf("\n=================== O-XU %d===================\n", o_xu_id);
487                 if (parseConfigFile(filename, p_o_xu_cfg) != 0) {
488                     printf("Configuration file error\n");
489                     return -1;
490                 }
491                 p_o_xu_cfg->o_xu_id = o_xu_id;
492                 config_init2(p_o_xu_cfg);
493                 if (p_o_xu_cfg->SlotNum_fileEnabled) {
494                     if (parseSlotConfigFile(dir, p_o_xu_cfg) != 0) {
495                         printf("parseSlotConfigFiles\n");
496                         return -1;
497                     }
498                     if (app_apply_slot_cfg(p_o_xu_cfg)!= 0) {
499                         printf("app_apply_slot_cfg\n");
500                         return -1;
501                     }
502                 }
503
504                 p_o_xu_cfg++;
505             }
506         } else {
507             printf("p_args error\n");
508             app_help();
509         exit(-1);
510     }
511     } else {
512         printf("p_args error\n");
513         exit(-1);
514     }
515
516     return ret;
517 }
518
519 int32_t
520 app_setup_o_xu_buffers(UsecaseConfig* p_use_cfg,  RuntimeConfig* p_o_xu_cfg, struct xran_fh_init* p_xran_fh_init)
521 {
522     int32_t ret  = 0;
523     int32_t i    = 0;
524     int32_t j    = 0;
525     char filename[256];
526     struct o_xu_buffers *p_iq = NULL;
527
528     if (p_o_xu_cfg->p_buff) {
529         p_iq = p_o_xu_cfg->p_buff;
530         printf("IQ files size is %d slots\n", p_o_xu_cfg->numSlots);
531
532         //printf("numSlots=%u\n", p_o_xu_cfg->numSlots);
533         //getchar();
534         p_iq->iq_playback_buffer_size_dl = (p_o_xu_cfg->numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
535                                     app_xran_get_num_rbs(p_o_xu_cfg->xranTech, p_o_xu_cfg->mu_number,
536                                     p_o_xu_cfg->nDLBandwidth, p_o_xu_cfg->nDLAbsFrePointA) *4L);
537
538         p_iq->iq_playback_buffer_size_ul = (p_o_xu_cfg->numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
539                                     app_xran_get_num_rbs(p_o_xu_cfg->xranTech, p_o_xu_cfg->mu_number,
540                                     p_o_xu_cfg->nULBandwidth, p_o_xu_cfg->nULAbsFrePointA) *4L);
541
542
543         /* 10 * [273*32*2*2] = 349440 bytes */
544         p_iq->iq_bfw_buffer_size_dl = (p_o_xu_cfg->numSlots * N_SYM_PER_SLOT *  p_o_xu_cfg->antElmTRx *
545                                     app_xran_get_num_rbs(p_o_xu_cfg->xranTech, p_o_xu_cfg->mu_number,
546                                     p_o_xu_cfg->nDLBandwidth, p_o_xu_cfg->nDLAbsFrePointA) *4L);
547
548         /* 10 * [273*32*2*2] = 349440 bytes */
549         p_iq->iq_bfw_buffer_size_ul = (p_o_xu_cfg->numSlots * N_SYM_PER_SLOT * p_o_xu_cfg->antElmTRx *
550                                     app_xran_get_num_rbs(p_o_xu_cfg->xranTech, p_o_xu_cfg->mu_number,
551                                     p_o_xu_cfg->nULBandwidth, p_o_xu_cfg->nULAbsFrePointA) *4L);
552
553     /* 10 * [1*273*2*2] = 349440 bytes */
554         p_iq->iq_srs_buffer_size_ul = (p_o_xu_cfg->numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
555                                     app_xran_get_num_rbs(p_o_xu_cfg->xranTech, p_o_xu_cfg->mu_number,
556                                     p_o_xu_cfg->nULBandwidth, p_o_xu_cfg->nULAbsFrePointA)*4L);
557
558         p_iq->numSlots = p_o_xu_cfg->numSlots;
559
560         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
561             p_iq->p_tx_play_buffer[i]    = (int16_t*)malloc(p_iq->iq_playback_buffer_size_dl);
562             p_iq->tx_play_buffer_size[i] = (int32_t)p_iq->iq_playback_buffer_size_dl;
563
564             if (p_iq->p_tx_play_buffer[i] == NULL)
565             exit(-1);
566
567
568             p_iq->tx_play_buffer_size[i] = sys_load_file_to_buff(p_o_xu_cfg->ant_file[i],
569                             "DL IFFT IN IQ Samples in binary format",
570                                 (uint8_t*)p_iq->p_tx_play_buffer[i],
571                                 p_iq->tx_play_buffer_size[i],
572                             1);
573     }
574
575         if (p_o_xu_cfg->appMode == APP_O_DU && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
576             for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
577
578                 p_iq->p_tx_dl_bfw_buffer[i]    = (int16_t*)malloc(p_iq->iq_bfw_buffer_size_dl);
579                 p_iq->tx_dl_bfw_buffer_size[i] = (int32_t)p_iq->iq_bfw_buffer_size_dl;
580
581                 if (p_iq->p_tx_dl_bfw_buffer[i] == NULL)
582                 exit(-1);
583
584                 p_iq->tx_dl_bfw_buffer_size[i] = sys_load_file_to_buff(p_o_xu_cfg->dl_bfw_file[i],
585                                 "DL BF weights IQ Samples in binary format",
586                                     (uint8_t*) p_iq->p_tx_dl_bfw_buffer[i],
587                                     p_iq->tx_dl_bfw_buffer_size[i],
588                                 1);
589         }
590     }
591
592         if (p_o_xu_cfg->appMode == APP_O_DU && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
593
594             for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
595                 p_iq->p_tx_ul_bfw_buffer[i]    = (int16_t*)malloc(p_iq->iq_bfw_buffer_size_ul);
596                 p_iq->tx_ul_bfw_buffer_size[i] = (int32_t)p_iq->iq_bfw_buffer_size_ul;
597
598                 if (p_iq->p_tx_ul_bfw_buffer[i] == NULL)
599                 exit(-1);
600
601                 p_iq->tx_ul_bfw_buffer_size[i] = sys_load_file_to_buff(p_o_xu_cfg->ul_bfw_file[i],
602                                 "UL BF weights IQ Samples in binary format",
603                                     (uint8_t*) p_iq->p_tx_ul_bfw_buffer[i],
604                                     p_iq->tx_ul_bfw_buffer_size[i],
605                                 1);
606         }
607     }
608
609         if (p_o_xu_cfg->appMode == APP_O_RU && p_o_xu_cfg->enablePrach) {
610             for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
611                 p_iq->p_tx_prach_play_buffer[i]    = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES);
612                 p_iq->tx_prach_play_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES;
613
614                 if (p_iq->p_tx_prach_play_buffer[i] == NULL)
615                  exit(-1);
616
617                 memset(p_iq->p_tx_prach_play_buffer[i], 0, PRACH_PLAYBACK_BUFFER_BYTES);
618
619                 p_iq->tx_prach_play_buffer_size[i] = sys_load_file_to_buff(p_o_xu_cfg->prach_file[i],
620                                  "PRACH IQ Samples in binary format",
621                                     (uint8_t*) p_iq->p_tx_prach_play_buffer[i],
622                                     p_iq->tx_prach_play_buffer_size[i],
623                                  1);
624                 p_iq->tx_prach_play_buffer_position[i] = 0;
625          }
626     }
627
628         if (p_o_xu_cfg->appMode == APP_O_RU && p_o_xu_cfg->enableSrs) {
629          for(i = 0;
630                 i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(p_o_xu_cfg->numCC  * p_o_xu_cfg->antElmTRx);
631              i++) {
632
633                 p_iq->p_tx_srs_play_buffer[i]    = (int16_t*)malloc(p_iq->iq_srs_buffer_size_ul);
634                 p_iq->tx_srs_play_buffer_size[i] = (int32_t)p_iq->iq_srs_buffer_size_ul;
635
636                 if (p_iq->p_tx_srs_play_buffer[i] == NULL)
637                  exit(-1);
638
639                 memset(p_iq->p_tx_srs_play_buffer[i], 0, p_iq->iq_srs_buffer_size_ul);
640                 p_iq->tx_srs_play_buffer_size[i] = sys_load_file_to_buff(p_o_xu_cfg->ul_srs_file[i],
641                                  "SRS IQ Samples in binary format",
642                                     (uint8_t*) p_iq->p_tx_srs_play_buffer[i],
643                                     p_iq->tx_srs_play_buffer_size[i],
644                                  1);
645
646                 p_iq->tx_srs_play_buffer_position[i] = 0;
647          }
648     }
649
650     /* log of ul */
651         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
652
653             p_iq->p_rx_log_buffer[i]    = (int16_t*)malloc(p_iq->iq_playback_buffer_size_ul);
654             p_iq->rx_log_buffer_size[i] = (int32_t)p_iq->iq_playback_buffer_size_ul;
655
656             if (p_iq->p_rx_log_buffer[i] == NULL)
657             exit(-1);
658
659             memset(p_iq->p_rx_log_buffer[i], 0, p_iq->rx_log_buffer_size[i]);
660     }
661
662     /* log of prach */
663         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
664
665             p_iq->p_prach_log_buffer[i]    = (int16_t*)malloc(p_o_xu_cfg->numSlots*XRAN_NUM_OF_SYMBOL_PER_SLOT*PRACH_PLAYBACK_BUFFER_BYTES);
666             p_iq->prach_log_buffer_size[i] = (int32_t)p_o_xu_cfg->numSlots*XRAN_NUM_OF_SYMBOL_PER_SLOT*PRACH_PLAYBACK_BUFFER_BYTES;
667
668             if (p_iq->p_prach_log_buffer[i] == NULL)
669             exit(-1);
670
671             memset(p_iq->p_prach_log_buffer[i], 0, p_iq->prach_log_buffer_size[i]);
672     }
673
674     /* log of SRS */
675         if (p_o_xu_cfg->appMode == APP_O_DU && p_o_xu_cfg->enableSrs) {
676         for(i = 0;
677                 i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->antElmTRx);
678             i++) {
679
680                 p_iq->p_srs_log_buffer[i]    = (int16_t*)malloc(p_iq->iq_srs_buffer_size_ul);
681                 p_iq->srs_log_buffer_size[i] = (int32_t)p_iq->iq_srs_buffer_size_ul;
682
683                 if (p_iq->p_srs_log_buffer[i] == NULL)
684                  exit(-1);
685
686                 memset(p_iq->p_srs_log_buffer[i], 0, p_iq->iq_srs_buffer_size_ul);
687             }
688         }
689
690         /* log of BFWs */
691         if (p_o_xu_cfg->appMode == APP_O_RU && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
692             for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
693
694                 p_iq->p_tx_dl_bfw_log_buffer[i]    = (int16_t*)malloc(p_iq->iq_bfw_buffer_size_dl);
695                 p_iq->tx_dl_bfw_log_buffer_size[i] = (int32_t)p_iq->iq_bfw_buffer_size_dl;
696
697                 if (p_iq->p_tx_dl_bfw_log_buffer[i] == NULL)
698                     exit(-1);
699
700                 memset(p_iq->p_tx_dl_bfw_log_buffer[i], 0, p_iq->iq_bfw_buffer_size_dl);
701             }
702         }
703
704         if (p_o_xu_cfg->appMode == APP_O_RU && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
705             for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
706
707                 p_iq->p_tx_ul_bfw_log_buffer[i]    = (int16_t*)malloc(p_iq->iq_bfw_buffer_size_ul);
708                 p_iq->tx_ul_bfw_log_buffer_size[i] = (int32_t)p_iq->iq_bfw_buffer_size_ul;
709
710                 if (p_iq->p_tx_ul_bfw_log_buffer[i] == NULL)
711                     exit(-1);
712
713                 memset(p_iq->p_tx_ul_bfw_log_buffer[i], 0, p_iq->iq_bfw_buffer_size_ul);
714     }
715     }
716
717         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
718
719             snprintf(filename, sizeof(filename), "./logs/%s%d-play_ant%d.txt",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id,  i);
720         sys_save_buf_to_file_txt(filename,
721                             "DL IFFT IN IQ Samples in human readable format",
722                                 (uint8_t*) p_iq->p_tx_play_buffer[i],
723                                 p_iq->tx_play_buffer_size[i],
724                             1);
725
726             snprintf(filename, sizeof(filename),"./logs/%s%d-play_ant%d.bin",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id, i);
727         sys_save_buf_to_file(filename,
728                             "DL IFFT IN IQ Samples in binary format",
729                                 (uint8_t*) p_iq->p_tx_play_buffer[i],
730                                 p_iq->tx_play_buffer_size[i]/sizeof(short),
731                             sizeof(short));
732
733
734             if (p_o_xu_cfg->appMode == APP_O_DU && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
735                 snprintf(filename, sizeof(filename),"./logs/%s%d-dl_bfw_ue%d.txt",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id,  i);
736             sys_save_buf_to_file_txt(filename,
737                                 "DL Beamformig weights IQ Samples in human readable format",
738                                     (uint8_t*) p_iq->p_tx_dl_bfw_buffer[i],
739                                     p_iq->tx_dl_bfw_buffer_size[i],
740                                 1);
741
742                 snprintf(filename, sizeof(filename),"./logs/%s%d-dl_bfw_ue%d.bin",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"),p_o_xu_cfg->o_xu_id, i);
743             sys_save_buf_to_file(filename,
744                                 "DL Beamformig weightsIQ Samples in binary format",
745                                     (uint8_t*) p_iq->p_tx_dl_bfw_buffer[i],
746                                     p_iq->tx_dl_bfw_buffer_size[i]/sizeof(short),
747                                 sizeof(short));
748
749
750                 snprintf(filename, sizeof(filename), "./logs/%s%d-ul_bfw_ue%d.txt",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id, i);
751             sys_save_buf_to_file_txt(filename,
752                                 "UL Beamformig weights IQ Samples in human readable format",
753                                     (uint8_t*) p_iq->p_tx_ul_bfw_buffer[i],
754                                     p_iq->tx_ul_bfw_buffer_size[i],
755                                 1);
756
757                 snprintf(filename, sizeof(filename),"./logs/%s%d-ul_bfw_ue%d.bin",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id, i);
758             sys_save_buf_to_file(filename,
759                                 "UL Beamformig weightsIQ Samples in binary format",
760                                     (uint8_t*) p_iq->p_tx_ul_bfw_buffer[i],
761                                     p_iq->tx_ul_bfw_buffer_size[i]/sizeof(short),
762                                 sizeof(short));
763
764         }
765     }
766
767         if (p_o_xu_cfg->appMode == APP_O_RU && p_o_xu_cfg->enableSrs && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
768        for(i = 0;
769             i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->antElmTRx);
770            i++) {
771
772                 snprintf(filename, sizeof(filename), "./logs/%s%d-play_srs_ant%d.txt",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id, i);
773             sys_save_buf_to_file_txt(filename,
774                             "SRS IQ Samples in human readable format",
775                                 (uint8_t*)p_iq->p_tx_srs_play_buffer[i],
776                                 p_iq->tx_srs_play_buffer_size[i],
777                             1);
778
779                 snprintf(filename,sizeof(filename), "./logs/%s%d-play_srs_ant%d.bin",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id, i);
780             sys_save_buf_to_file(filename,
781                                 "SRS IQ Samples in binary format",
782                                     (uint8_t*) p_iq->p_tx_srs_play_buffer[i],
783                                     p_iq->tx_srs_play_buffer_size[i]/sizeof(short),
784                                 sizeof(short));
785         }
786     }
787
788         if (p_o_xu_cfg->iqswap == 1) {
789             for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
790             printf("TX: Swap I and Q to match RU format: [%d]\n",i);
791             {
792                 /* swap I and Q */
793                 int32_t j;
794                     signed short *ptr = (signed short *) p_iq->p_tx_play_buffer[i];
795                 signed short temp;
796
797                     for (j = 0; j < (int32_t)(p_iq->tx_play_buffer_size[i]/sizeof(short)) ; j = j + 2) {
798                    temp    = ptr[j];
799                    ptr[j]  = ptr[j + 1];
800                    ptr[j + 1] = temp;
801                 }
802             }
803                 if (p_o_xu_cfg->appMode == APP_O_DU && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
804                 printf("DL BFW: Swap I and Q to match RU format: [%d]\n",i);
805                 {
806                     /* swap I and Q */
807                     int32_t j;
808                         signed short *ptr = (signed short *) p_iq->p_tx_dl_bfw_buffer[i];
809                     signed short temp;
810
811                         for (j = 0; j < (int32_t)(p_iq->tx_dl_bfw_buffer_size[i]/sizeof(short)) ; j = j + 2) {
812                        temp    = ptr[j];
813                        ptr[j]  = ptr[j + 1];
814                        ptr[j + 1] = temp;
815                     }
816                 }
817                 printf("UL BFW: Swap I and Q to match RU format: [%d]\n",i);
818                 {
819                     /* swap I and Q */
820                     int32_t j;
821                         signed short *ptr = (signed short *)  p_iq->p_tx_ul_bfw_buffer[i];
822                     signed short temp;
823
824                         for (j = 0; j < (int32_t)(p_iq->tx_ul_bfw_buffer_size[i]/sizeof(short)) ; j = j + 2) {
825                        temp    = ptr[j];
826                        ptr[j]  = ptr[j + 1];
827                        ptr[j + 1] = temp;
828                     }
829                 }
830             }
831         }
832
833             if (p_o_xu_cfg->appMode == APP_O_RU) {
834                 for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
835                 printf("PRACH: Swap I and Q to match RU format: [%d]\n",i);
836                 {
837                     /* swap I and Q */
838                     int32_t j;
839                         signed short *ptr = (signed short *) p_iq-> p_tx_prach_play_buffer[i];
840                     signed short temp;
841
842                         for (j = 0; j < (int32_t)(p_iq->tx_prach_play_buffer_size[i]/sizeof(short)) ; j = j + 2) {
843                        temp    = ptr[j];
844                        ptr[j]  = ptr[j + 1];
845                        ptr[j + 1] = temp;
846                     }
847                 }
848             }
849         }
850
851             if (p_o_xu_cfg->appMode == APP_O_RU) {
852             for(i = 0;
853                 i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->antElmTRx);
854                i++) {
855                  printf("SRS: Swap I and Q to match RU format: [%d]\n",i);
856                 {
857                     /* swap I and Q */
858                     int32_t j;
859                         signed short *ptr = (signed short *) p_iq->p_tx_srs_play_buffer[i];
860                     signed short temp;
861
862                         for (j = 0; j < (int32_t)(p_iq->tx_srs_play_buffer_size[i]/sizeof(short)) ; j = j + 2) {
863                        temp    = ptr[j];
864                        ptr[j]  = ptr[j + 1];
865                        ptr[j + 1] = temp;
866                     }
867                 }
868             }
869         }
870     }
871
872 #if 0
873         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
874
875         sprintf(filename, "./logs/swap_IQ_play_ant%d.txt", i);
876         sys_save_buf_to_file_txt(filename,
877                             "DL IFFT IN IQ Samples in human readable format",
878                                 (uint8_t*) p_iq->p_tx_play_buffer[i],
879                                 p_iq->tx_play_buffer_size[i],
880                             1);
881     }
882 #endif
883         if (p_o_xu_cfg->nebyteorderswap == 1 && p_o_xu_cfg->compression == 0) {
884             for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
885             printf("TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
886                 for (j = 0; j < p_iq->tx_play_buffer_size[i]/sizeof(short); j++) {
887                     p_iq->p_tx_play_buffer[i][j]  = rte_cpu_to_be_16(p_iq->p_tx_play_buffer[i][j]);
888             }
889
890                 if (p_o_xu_cfg->appMode == APP_O_DU && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
891                 printf("DL BFW: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
892                     for (j = 0; j < p_iq->tx_dl_bfw_buffer_size[i]/sizeof(short); j++) {
893                         p_iq->p_tx_dl_bfw_buffer[i][j]  = rte_cpu_to_be_16(p_iq->p_tx_dl_bfw_buffer[i][j]);
894                 }
895                 printf("UL BFW: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
896                     for (j = 0; j < p_iq->tx_ul_bfw_buffer_size[i]/sizeof(short); j++) {
897                         p_iq->p_tx_ul_bfw_buffer[i][j]  = rte_cpu_to_be_16(p_iq->p_tx_ul_bfw_buffer[i][j]);
898                 }
899             }
900         }
901
902             if (p_o_xu_cfg->appMode == APP_O_RU && p_o_xu_cfg->enablePrach) {
903                 for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
904                 printf("PRACH: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
905                     for (j = 0; j < p_iq->tx_prach_play_buffer_size[i]/sizeof(short); j++) {
906                         p_iq->p_tx_prach_play_buffer[i][j]  = rte_cpu_to_be_16(p_iq->p_tx_prach_play_buffer[i][j]);
907                 }
908             }
909         }
910
911             if (p_o_xu_cfg->appMode == APP_O_RU && p_o_xu_cfg->enableSrs) {
912                for(i = 0;
913                 i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(p_o_xu_cfg->numCC  * p_o_xu_cfg->antElmTRx);
914                i++)  {
915                 printf("SRS: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
916                     for (j = 0; j < p_iq->tx_srs_play_buffer_size[i]/sizeof(short); j++) {
917                         p_iq->p_tx_srs_play_buffer[i][j]  = rte_cpu_to_be_16(p_iq->p_tx_srs_play_buffer[i][j]);
918                 }
919             }
920         }
921
922     }
923
924 #if 0
925         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
926
927         sprintf(filename, "./logs/swap_be_play_ant%d.txt", i);
928         sys_save_buf_to_file_txt(filename,
929                             "DL IFFT IN IQ Samples in human readable format",
930                                 (uint8_t*) p_iq->p_tx_play_buffer[i],
931                                 p_iq->tx_play_buffer_size[i],
932                             1);
933     }
934 #endif
935     }
936
937     return ret;
938 }
939
940 int32_t
941 app_dump_o_xu_buffers(UsecaseConfig* p_use_cfg,  RuntimeConfig* p_o_xu_cfg)
942 {
943     int32_t ret  = 0;
944     int32_t i    = 0;
945     int32_t j    = 0;
946     char filename[256];
947     struct o_xu_buffers* p_iq = NULL;
948
949     if (p_o_xu_cfg->p_buff) {
950         p_iq = p_o_xu_cfg->p_buff;
951     } else {
952         printf("Error p_o_xu_cfg->p_buff\n");
953         exit(-1);
954     }
955
956     if (p_o_xu_cfg->iqswap == 1) {
957         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
958             printf("RX: Swap I and Q to match CPU format: [%d]\n",i);
959             {
960                 /* swap I and Q */
961                 int32_t j;
962                 signed short *ptr = (signed short *)  p_iq->p_rx_log_buffer[i];
963                 signed short temp;
964
965                 for (j = 0; j < (int32_t)(p_iq->rx_log_buffer_size[i]/sizeof(short)) ; j = j + 2) {
966                    temp    = ptr[j];
967                    ptr[j]  = ptr[j + 1];
968                    ptr[j + 1] = temp;
969                 }
970             }
971         }
972
973         if (p_o_xu_cfg->appMode == APP_O_DU && p_o_xu_cfg->enableSrs) {
974             for (i = 0;
975             i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->antElmTRx);
976             i++)  {
977                 printf("SRS: Swap I and Q to match CPU format: [%d]\n",i);
978                 {
979                     /* swap I and Q */
980                     int32_t j;
981                     signed short *ptr = (signed short *)  p_iq->p_srs_log_buffer[i];
982                     signed short temp;
983
984                     for (j = 0; j < (int32_t)(p_iq->srs_log_buffer_size[i]/sizeof(short)) ; j = j + 2) {
985                        temp    = ptr[j];
986                        ptr[j]  = ptr[j + 1];
987                        ptr[j + 1] = temp;
988                     }
989                 }
990             }
991         }
992     }
993
994     if (p_o_xu_cfg->nebyteorderswap == 1 && p_o_xu_cfg->compression == 0) {
995
996         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
997             printf("RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
998             for (j = 0; j < p_iq->rx_log_buffer_size[i]/sizeof(short); j++) {
999                 p_iq->p_rx_log_buffer[i][j]  = rte_be_to_cpu_16(p_iq->p_rx_log_buffer[i][j]);
1000             }
1001     }
1002
1003         if (p_o_xu_cfg->appMode == APP_O_DU && p_o_xu_cfg->enableSrs) {
1004             for (i = 0;
1005             i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->antElmTRx);
1006             i++)  {
1007                 printf("SRS: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
1008                 for (j = 0; j < p_iq->srs_log_buffer_size[i]/sizeof(short); j++) {
1009                     p_iq->p_srs_log_buffer[i][j]  = rte_be_to_cpu_16(p_iq->p_srs_log_buffer[i][j]);
1010                 }
1011             }
1012         }
1013     }
1014
1015     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
1016
1017         snprintf(filename, sizeof(filename), "./logs/%s%d-rx_log_ant%d.txt",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id, i);
1018         sys_save_buf_to_file_txt(filename,
1019                             "UL FFT OUT IQ Samples in human readable format",
1020                             (uint8_t*) p_iq->p_rx_log_buffer[i],
1021                             p_iq->rx_log_buffer_size[i],
1022                             1);
1023
1024         snprintf(filename, sizeof(filename), "./logs/%s%d-rx_log_ant%d.bin",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id, i);
1025         sys_save_buf_to_file(filename,
1026                             "UL FFT OUT IQ Samples in binary format",
1027                             (uint8_t*) p_iq->p_rx_log_buffer[i],
1028                             p_iq->rx_log_buffer_size[i]/sizeof(short),
1029                             sizeof(short));
1030
1031         if (p_o_xu_cfg->appMode == APP_O_RU && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
1032             snprintf(filename, sizeof(filename),"./logs/%s%d-dl_bfw_log_ue%d.txt",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id,  i);
1033             sys_save_buf_to_file_txt(filename,
1034                                 "DL Beamformig weights IQ Samples in human readable format",
1035                                 (uint8_t*) p_iq->p_tx_dl_bfw_log_buffer[i],
1036                                 p_iq->tx_dl_bfw_log_buffer_size[i],
1037                                 1);
1038
1039             snprintf(filename, sizeof(filename),"./logs/%s%d-dl_bfw_log_ue%d.bin",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"),p_o_xu_cfg->o_xu_id, i);
1040             sys_save_buf_to_file(filename,
1041                                 "DL Beamformig weightsIQ Samples in binary format",
1042                                 (uint8_t*) p_iq->p_tx_dl_bfw_log_buffer[i],
1043                                 p_iq->tx_dl_bfw_log_buffer_size[i]/sizeof(short),
1044                                 sizeof(short));
1045
1046         }
1047         if (p_o_xu_cfg->appMode == APP_O_RU && p_o_xu_cfg->xranCat == XRAN_CATEGORY_B) {
1048             snprintf(filename, sizeof(filename),"./logs/%s%d-ul_bfw_log_ue%d.txt",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id,  i);
1049             sys_save_buf_to_file_txt(filename,
1050                                 "DL Beamformig weights IQ Samples in human readable format",
1051                                 (uint8_t*) p_iq->p_tx_ul_bfw_log_buffer[i],
1052                                 p_iq->tx_ul_bfw_log_buffer_size[i],
1053                                 1);
1054
1055             snprintf(filename, sizeof(filename),"./logs/%s%d-ul_bfw_log_ue%d.bin",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"),p_o_xu_cfg->o_xu_id, i);
1056             sys_save_buf_to_file(filename,
1057                                 "DL Beamformig weightsIQ Samples in binary format",
1058                                 (uint8_t*) p_iq->p_tx_ul_bfw_log_buffer[i],
1059                                 p_iq->tx_ul_bfw_log_buffer_size[i]/sizeof(short),
1060                                 sizeof(short));
1061         }
1062
1063     }
1064
1065     if (p_o_xu_cfg->appMode == APP_O_DU && p_o_xu_cfg->enableSrs) {
1066         for (i = 0;
1067         i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->antElmTRx);
1068         i++) {
1069             snprintf(filename, sizeof(filename), "./logs/%s%d-srs_log_ant%d.txt",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id, i);
1070             sys_save_buf_to_file_txt(filename,
1071                                 "SRS UL FFT OUT IQ Samples in human readable format",
1072                                 (uint8_t*)p_iq-> p_srs_log_buffer[i],
1073                                 p_iq->srs_log_buffer_size[i],
1074                                 1);
1075
1076             snprintf(filename, sizeof(filename),  "./logs/%s%d-srs_log_ant%d.bin",((p_o_xu_cfg->appMode == APP_O_DU) ? "o-du" : "o-ru"), p_o_xu_cfg->o_xu_id, i);
1077             sys_save_buf_to_file(filename,
1078                                 "SRS UL FFT OUT IQ Samples in binary format",
1079                                 (uint8_t*) p_iq->p_srs_log_buffer[i],
1080                                 p_iq->srs_log_buffer_size[i]/sizeof(short),
1081                                 sizeof(short));
1082         }
1083     }
1084
1085     if (p_o_xu_cfg->enablePrach) {
1086         if (p_o_xu_cfg->iqswap == 1) {
1087             for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
1088                 printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i);
1089                 {
1090                     /* swap I and Q */
1091                     int32_t j;
1092                     signed short *ptr = (signed short *)  p_iq->p_prach_log_buffer[i];
1093                     signed short temp;
1094
1095                     for (j = 0; j < (int32_t)(p_iq->prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2) {
1096                        temp    = ptr[j];
1097                        ptr[j]  = ptr[j + 1];
1098                        ptr[j + 1] = temp;
1099                     }
1100                 }
1101             }
1102         }
1103
1104         if (p_o_xu_cfg->nebyteorderswap == 1 && p_o_xu_cfg->compression == 0) {
1105             for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
1106                 printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
1107                 for (j = 0; j < p_iq->prach_log_buffer_size[i]/sizeof(short); j++) {
1108                     p_iq->p_prach_log_buffer[i][j]  = rte_be_to_cpu_16(p_iq->p_prach_log_buffer[i][j]);
1109                 }
1110             }
1111         }
1112
1113         for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(p_o_xu_cfg->numCC * p_o_xu_cfg->numAxc); i++) {
1114
1115             if (p_o_xu_cfg->appMode == APP_O_DU)
1116                 snprintf(filename, sizeof(filename), "./logs/%s%d%s_ant%d.txt","o-du",p_o_xu_cfg->o_xu_id,"-prach_log", i);
1117     else
1118                 snprintf(filename, sizeof(filename), "./logs/%s%d%s_ant%d.txt","o-ru",p_o_xu_cfg->o_xu_id,"-play_prach", i);
1119             sys_save_buf_to_file_txt(filename,
1120                                 "PRACH IQ Samples in human readable format",
1121                                 (uint8_t*) p_iq->p_prach_log_buffer[i],
1122                                 p_iq->prach_log_buffer_size[i],
1123                                 1);
1124
1125             if (p_o_xu_cfg->appMode == APP_O_DU)
1126                 snprintf(filename, sizeof(filename), "./logs/%s%d%s_ant%d.bin","o-du",p_o_xu_cfg->o_xu_id,"-prach_log", i);
1127             else
1128                 snprintf(filename, sizeof(filename), "./logs/%s%d%s_ant%d.bin","o-ru",p_o_xu_cfg->o_xu_id,"-play_prach", i);
1129             sys_save_buf_to_file(filename,
1130                                 "PRACH IQ Samples in binary format",
1131                                 (uint8_t*) p_iq->p_prach_log_buffer[i],
1132                                 p_iq->prach_log_buffer_size[i]/sizeof(short),
1133                                 sizeof(short));
1134         }
1135     }
1136     return ret;
1137 }
1138
1139 int32_t
1140 app_set_main_core(UsecaseConfig* p_usecase)
1141 {
1142     struct sched_param sched_param;
1143     cpu_set_t cpuset;
1144     int32_t   result = 0;
1145     memset(&sched_param, 0, sizeof(struct sched_param));
1146     /* set main thread affinity mask to CPU2 */
1147     sched_param.sched_priority = 99;
1148     CPU_ZERO(&cpuset);
1149
1150     printf("This system has %d processors configured and %d processors available.\n",  get_nprocs_conf(), get_nprocs());
1151
1152     if (p_usecase->main_core < get_nprocs_conf())
1153         CPU_SET(p_usecase->main_core, &cpuset);
1154     else
1155         return -1;
1156
1157     if ((result = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset)))
1158     {
1159         printf("pthread_setaffinity_np failed: coreId = 2, result = %d\n",result);
1160     }
1161     printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__,  sched_getcpu(), getpid());
1162 #if 0
1163     if ((result = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param)))
1164     {
1165         printf("priority is not changed: coreId = 2, result = %d\n",result);
1166     }
1167 #endif
1168     return result;
1169 }
1170
1171 int32_t
1172 app_alloc_all_cfgs(void)
1173 {
1174     void * ptr =  NULL;
1175     RuntimeConfig* p_rt_cfg = NULL;
1176     int32_t i = 0;
1177
1178     ptr = _mm_malloc(sizeof(UsecaseConfig), 256);
1179     if (ptr == NULL) {
1180         rte_panic("_mm_malloc: Can't allocate %lu bytes\n", sizeof(UsecaseConfig));
1181     }
1182
1183     p_usecaseConfiguration = (UsecaseConfig*)ptr;
1184
1185     ptr = _mm_malloc(sizeof(RuntimeConfig)*XRAN_PORTS_NUM, 256);
1186     if (ptr == NULL) {
1187         rte_panic("_mm_malloc: Can't allocate %lu bytes\n", sizeof(RuntimeConfig)*XRAN_PORTS_NUM);
1188     }
1189     p_rt_cfg = (RuntimeConfig*)ptr;
1190
1191     for (i = 0; i < XRAN_PORTS_NUM; i++) {
1192         p_startupConfiguration[i] = p_rt_cfg++;
1193     }
1194
1195     return 0;
1196 }
1197
1198 int main(int argc, char *argv[])
1199 {
1200     int32_t o_xu_id = 0;
1201     char filename[256];
1202     int32_t xret = 0;
1203     struct stat st = {0};
1204     uint32_t filenameLength = strlen(argv[1]);
1205     enum xran_if_state xran_curr_if_state = XRAN_INIT;
1206     struct sample_app_params arg_params;
1207     uint64_t nActiveCoreMask[MAX_BBU_POOL_CORE_MASK] = {0};
1208     uint64_t nTotalTime;
1209     uint64_t nUsedTime;
1210     uint32_t nCoresUsed;
1211     uint32_t nCoreUsedNum[64];
1212     //float nUsedPercent;
1213
1214     app_version_print();
1215     app_timer_set_tsc_freq_from_clock();
1216
1217     if (xran_is_synchronized() != 0)
1218         printf("Machine is not synchronized using PTP!\n");
1219     else
1220         printf("Machine is synchronized using PTP!\n");
1221
1222     if (filenameLength >= 256) {
1223         printf("Config file name input is too long, exiting!\n");
1224         exit(-1);
1225     }
1226
1227     if ((xret = app_alloc_all_cfgs()) < 0) {
1228         printf("app_alloc_all_cfgs failed %d\n", xret);
1229         exit(-1);
1230     }
1231
1232     if ((xret = app_parse_cmdline_args(argc, argv, &arg_params)) < 0) {
1233         printf("app_parse_args failed %d\n", xret);
1234         exit(-1);
1235     }
1236
1237     if ((xret = app_parse_all_cfgs(&arg_params, p_usecaseConfiguration, p_startupConfiguration[0])) < 0) {
1238         printf("app_parse_all_cfgs failed %d\n", xret);
1239         exit(-1);
1240     }
1241 #ifdef FWK_ENABLED
1242     if(p_usecaseConfiguration->bbu_offload) {
1243         if(p_startupConfiguration[0]->appMode == APP_O_DU) {
1244             if ((xret = app_bbu_init(argc, argv, p_usecaseConfiguration->o_xu_bbu_cfg_file, p_usecaseConfiguration, p_startupConfiguration,
1245                                         nActiveCoreMask)) < 0) {
1246                 printf("app_bbu_init failed %d\n", xret);
1247             }
1248
1249             uint32_t i;
1250             uint64_t nMask = 1;
1251             /* use only 1 worker for BBU offload */
1252             for (i = 0; i < 64; i++)
1253             {
1254                 if(p_usecaseConfiguration->io_core < 64) {
1255                     if (nMask & p_usecaseConfiguration->io_worker) {
1256                         p_usecaseConfiguration->io_worker = nMask;
1257                         p_usecaseConfiguration->io_worker_64_127 = 0;
1258                         break;
1259                     }
1260                 }
1261                 if(p_usecaseConfiguration->io_core  >= 64) {
1262                     if (nMask & p_usecaseConfiguration->io_worker_64_127) {
1263                         p_usecaseConfiguration->io_worker_64_127 = nMask;
1264                         p_usecaseConfiguration->io_worker = 0;
1265                         break;
1266                     }
1267                 }
1268                 nMask = nMask << 1;
1269             }
1270         }
1271     }
1272 #endif
1273     if ((xret = app_set_main_core(p_usecaseConfiguration)) < 0) {
1274         printf("app_set_main_core failed %d\n", xret);
1275         exit(-1);
1276     }
1277
1278     app_io_xran_if_alloc();
1279
1280     /* one init for all O-XU */
1281     app_io_xran_fh_init_init(p_usecaseConfiguration, p_startupConfiguration[0], &app_io_xran_fh_init);
1282     xret =  xran_init(argc, argv, &app_io_xran_fh_init, argv[0], &app_io_xran_handle);
1283     if (xret != XRAN_STATUS_SUCCESS) {
1284         printf("xran_init failed %d\n", xret);
1285         exit(-1);
1286     }
1287
1288     if (app_io_xran_handle == NULL)
1289         exit(1);
1290
1291     if (stat("./logs", &st) == -1) {
1292         mkdir("./logs", 0777);
1293     }
1294
1295     snprintf(filename, sizeof(filename),"mlog-%s", p_usecaseConfiguration->appMode == 0 ? "o-du" : "o-ru");
1296
1297     /* Init mlog */
1298     unsigned int mlogSubframes = 128;
1299     unsigned int mlogCores = 32;
1300     unsigned int mlogSize = 10000;
1301
1302     // Open Mlog Buffers and initalize variables
1303     MLogOpen(mlogSubframes, mlogCores, mlogSize, 0, filename);
1304     MLogSetMask(0);
1305
1306     puts("----------------------------------------");
1307     printf("MLog Info: virt=0x%p size=%d\n", MLogGetFileLocation(), MLogGetFileSize());
1308     puts("----------------------------------------");
1309
1310
1311     uint32_t totalCC =  0;
1312
1313     if(((1 << app_io_xran_fh_init.io_cfg.timing_core) | app_io_xran_fh_init.io_cfg.pkt_proc_core) & nActiveCoreMask[0])
1314         rte_panic("[0 - 63] BBU and IO cores conflict\n");
1315     if(app_io_xran_fh_init.io_cfg.pkt_proc_core_64_127 & nActiveCoreMask[1])
1316         rte_panic("[64-127] BBU and IO cores conflict\n");
1317
1318     nActiveCoreMask[0] |= ((1 << app_io_xran_fh_init.io_cfg.timing_core) | app_io_xran_fh_init.io_cfg.pkt_proc_core);
1319     nActiveCoreMask[1] |= app_io_xran_fh_init.io_cfg.pkt_proc_core_64_127;
1320
1321     MLogSetup(nActiveCoreMask[0], nActiveCoreMask[1], nActiveCoreMask[2], nActiveCoreMask[3]);
1322
1323     for (o_xu_id = 0; o_xu_id <  p_usecaseConfiguration->oXuNum;  o_xu_id++) {
1324         RuntimeConfig* p_o_xu_cfg = p_startupConfiguration[o_xu_id];
1325         totalCC += p_o_xu_cfg->numCC;
1326     }
1327     MLogAddTestCase(nActiveCoreMask, totalCC);
1328
1329     /** process all the O-RU|O-DU for use case */
1330     for (o_xu_id = 0; o_xu_id <  p_usecaseConfiguration->oXuNum;  o_xu_id++) {
1331         RuntimeConfig* p_o_xu_cfg = p_startupConfiguration[o_xu_id];
1332         if (o_xu_id == 0)
1333             app_io_xran_buffers_max_sz_set(p_o_xu_cfg);
1334
1335         if (p_o_xu_cfg->ant_file[0] == NULL) {
1336             printf("it looks like test vector for antennas were not provided\n");
1337             exit(-1);
1338         }
1339         if (p_o_xu_cfg->numCC > XRAN_MAX_SECTOR_NR) {
1340             printf("Number of cells %d exceeds max number supported %d!\n", p_o_xu_cfg->numCC, XRAN_MAX_SECTOR_NR);
1341             p_o_xu_cfg->numCC = XRAN_MAX_SECTOR_NR;
1342
1343         }
1344         if (p_o_xu_cfg->antElmTRx > XRAN_MAX_ANT_ARRAY_ELM_NR) {
1345             printf("Number of Antenna elements %d exceeds max number supported %d!\n", p_o_xu_cfg->antElmTRx, XRAN_MAX_ANT_ARRAY_ELM_NR);
1346             p_o_xu_cfg->antElmTRx = XRAN_MAX_ANT_ARRAY_ELM_NR;
1347         }
1348
1349         printf("Numm CC %d numAxc %d numUlAxc %d\n", p_o_xu_cfg->numCC, p_o_xu_cfg->numAxc, p_o_xu_cfg->numUlAxc);
1350
1351         app_setup_o_xu_buffers(p_usecaseConfiguration, p_o_xu_cfg, &app_io_xran_fh_init);
1352
1353         app_io_xran_fh_config_init(p_usecaseConfiguration, p_o_xu_cfg, &app_io_xran_fh_init, &app_io_xran_fh_config[o_xu_id]);
1354
1355         xret = xran_open(app_io_xran_handle, &app_io_xran_fh_config[o_xu_id]);
1356     if(xret != XRAN_STATUS_SUCCESS){
1357         printf("xran_open failed %d\n", xret);
1358         exit(-1);
1359     }
1360         if (app_io_xran_interface(o_xu_id, p_startupConfiguration[o_xu_id], p_usecaseConfiguration, &app_io_xran_fh_init) != 0)
1361             exit(-1);
1362
1363         app_io_xran_iq_content_init(o_xu_id, p_startupConfiguration[o_xu_id]);
1364 #ifdef FWK_ENABLED
1365         if(p_o_xu_cfg->appMode == APP_O_DU && p_usecaseConfiguration->bbu_offload) {
1366             if ((xret = xran_reg_physide_cb(app_io_xran_handle, app_bbu_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
1367                 printf("xran_reg_physide_cb failed %d\n", xret);
1368                 exit(-1);
1369             }
1370         } else {
1371             if ((xret = xran_reg_physide_cb(app_io_xran_handle, app_io_xran_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
1372                 printf("xran_reg_physide_cb failed %d\n", xret);
1373                 exit(-1);
1374             }
1375         }
1376 #else
1377         if ((xret = xran_reg_physide_cb(app_io_xran_handle, app_io_xran_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
1378             printf("xran_reg_physide_cb failed %d\n", xret);
1379             exit(-1);
1380         }
1381 #endif
1382         if ((xret = xran_reg_physide_cb(app_io_xran_handle, app_io_xran_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX)) != XRAN_STATUS_SUCCESS) {
1383             printf("xran_reg_physide_cb failed %d\n", xret);
1384             exit(-1);
1385         }
1386         if ((xret = xran_reg_physide_cb(app_io_xran_handle, app_io_xran_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX)) != XRAN_STATUS_SUCCESS) {
1387             printf("xran_reg_physide_cb failed %d\n", xret);
1388             exit(-1);
1389         }
1390 #ifdef TEST_SYM_CBS
1391         if ((xret = xran_reg_sym_cb(app_io_xran_handle, app_io_xran_ul_custom_sym_call_back,
1392                                     (void*)&cb_sym_ctx[0].cb_param,
1393                                     &cb_sym_ctx[0].sense_of_time,
1394                                     3, XRAN_CB_SYM_RX_WIN_BEGIN)) != XRAN_STATUS_SUCCESS) {
1395             printf("xran_reg_sym_cb failed %d\n", xret);
1396             exit(-1);
1397         }
1398
1399         if ((xret = xran_reg_sym_cb(app_io_xran_handle, app_io_xran_ul_custom_sym_call_back,
1400                                     (void*)&cb_sym_ctx[1].cb_param,
1401                                     &cb_sym_ctx[1].sense_of_time,
1402                                     3, XRAN_CB_SYM_RX_WIN_END)) != XRAN_STATUS_SUCCESS) {
1403             printf("xran_reg_sym_cb failed %d\n", xret);
1404             exit(-1);
1405         }
1406
1407         if ((xret = xran_reg_sym_cb(app_io_xran_handle, app_io_xran_ul_custom_sym_call_back,
1408                                     (void*)&cb_sym_ctx[2].cb_param,
1409                                     &cb_sym_ctx[2].sense_of_time,
1410                                     3, XRAN_CB_SYM_TX_WIN_BEGIN)) != XRAN_STATUS_SUCCESS) {
1411             printf("xran_reg_sym_cb failed %d\n", xret);
1412             exit(-1);
1413         }
1414
1415         if ((xret = xran_reg_sym_cb(app_io_xran_handle, app_io_xran_ul_custom_sym_call_back,
1416                                     (void*)&cb_sym_ctx[3].cb_param,
1417                                     &cb_sym_ctx[3].sense_of_time,
1418                                     3, XRAN_CB_SYM_TX_WIN_END)) != XRAN_STATUS_SUCCESS) {
1419             printf("xran_reg_sym_cb failed %d\n", xret);
1420             exit(-1);
1421         }
1422 #endif
1423     }
1424
1425
1426
1427     fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
1428
1429     state = APP_RUNNING;
1430     printf("Start XRAN traffic\n");
1431     xran_start(app_io_xran_handle);
1432     app_print_menu();
1433
1434     struct xran_common_counters x_counters[XRAN_PORTS_NUM];
1435     int is_mlog_on = 0;
1436     for (;;) {
1437         char input[10];
1438         sleep(1);
1439         xran_curr_if_state = xran_get_if_state();
1440
1441         if (xran_get_common_counters(app_io_xran_handle, &x_counters[0]) == XRAN_STATUS_SUCCESS) {
1442             for (o_xu_id = 0; o_xu_id <  p_usecaseConfiguration->oXuNum;  o_xu_id++) {
1443                 if (o_xu_id == 0) {
1444                     xran_get_time_stats(&nTotalTime, &nUsedTime, &nCoresUsed, nCoreUsedNum, 1);
1445                     //nUsedPercent = 0.0;
1446                     //if (nTotalTime) {
1447                     //    nUsedPercent = ((float)nUsedTime * 100.0) / (float)nTotalTime;
1448                     //}
1449                     mlog_times.core_total_time += nTotalTime;
1450                     mlog_times.core_used_time += nUsedTime;
1451
1452 #if 0
1453                     printf("[nCoresUsed: %d] [MainCore: %d - Util: %5.2f %%]", nCoresUsed, nCoreUsedNum[0], nUsedPercent);
1454                     if (nCoresUsed > 1) {
1455                         printf("[Additional Cores: ");
1456                         for (int nCore = 1; nCore < nCoresUsed; nCore++) {
1457                             printf("%d ", nCoreUsedNum[nCore]);
1458                         }
1459                         printf("]");
1460                     }
1461                     printf("\n");
1462 #endif
1463                 }
1464                 printf("[%s%d][rx %7ld pps %7ld kbps %7ld][tx %7ld pps %7ld kbps %7ld] [on_time %ld early %ld late %ld corrupt %ld pkt_dupl %ld Invalid_Ext1_packets %ld Total %ld]\n",
1465                     ((p_usecaseConfiguration->appMode == APP_O_DU) ? "o-du" : "o-ru"),
1466                     o_xu_id,
1467                     x_counters[o_xu_id].rx_counter,
1468                     x_counters[o_xu_id].rx_counter-old_rx_counter[o_xu_id],
1469                     x_counters[o_xu_id].rx_bytes_per_sec*8/1000L,
1470                     x_counters[o_xu_id].tx_counter,
1471                     x_counters[o_xu_id].tx_counter-old_tx_counter[o_xu_id],
1472                     x_counters[o_xu_id].tx_bytes_per_sec*8/1000L,
1473                     x_counters[o_xu_id].Rx_on_time,
1474                     x_counters[o_xu_id].Rx_early,
1475                     x_counters[o_xu_id].Rx_late,
1476                     x_counters[o_xu_id].Rx_corrupt,
1477                     x_counters[o_xu_id].Rx_pkt_dupl,
1478                     x_counters[o_xu_id].rx_invalid_ext1_packets,
1479                     x_counters[o_xu_id].Total_msgs_rcvd);
1480
1481                 if (x_counters[o_xu_id].rx_counter > old_rx_counter[o_xu_id])
1482                     old_rx_counter[o_xu_id] = x_counters[o_xu_id].rx_counter;
1483                 if (x_counters[o_xu_id].tx_counter > old_tx_counter[o_xu_id])
1484                     old_tx_counter[o_xu_id] = x_counters[o_xu_id].tx_counter;
1485
1486                 if(o_xu_id == 0){
1487                     if(is_mlog_on == 0 && x_counters[o_xu_id].rx_counter > 0 && x_counters[o_xu_id].tx_counter > 0) {
1488                         xran_set_debug_stop(p_startupConfiguration[0]->debugStop, p_startupConfiguration[0]->debugStopCount);
1489                 MLogSetMask(0xFFFFFFFF);
1490                         is_mlog_on =  1;
1491                     }
1492                 }
1493             }
1494         } else {
1495             printf("error xran_get_common_counters\n");
1496         }
1497
1498         if (xran_curr_if_state == XRAN_STOPPED){
1499             break;
1500         }
1501         if (NULL == fgets(input, 10, stdin)) {
1502             continue;
1503         }
1504
1505         const int sel_opt = atoi(input);
1506         switch (sel_opt) {
1507             case 1:
1508                 xran_start(app_io_xran_handle);
1509                 printf("Start XRAN traffic\n");
1510                 break;
1511             case 2:
1512                 break;
1513             case 3:
1514                 xran_stop(app_io_xran_handle);
1515                 printf("Stop XRAN traffic\n");
1516                 state = APP_STOPPED;
1517                 break;
1518             default:
1519                 puts("Wrong option passed!");
1520                 break;
1521         }
1522         if (APP_STOPPED == state)
1523             break;
1524     }
1525
1526     /** process all the O-RU|O-DU for use case */
1527     for (o_xu_id = 0; o_xu_id <  p_usecaseConfiguration->oXuNum;  o_xu_id++) {
1528         app_io_xran_iq_content_get(o_xu_id, p_startupConfiguration[o_xu_id]);
1529         /* Check for owd results */
1530         if (p_usecaseConfiguration->owdmEnable)
1531             {
1532
1533             FILE *file= NULL;
1534             uint64_t avgDelay =0;
1535             snprintf(filename, sizeof(filename), "./logs/%s%d-owd_results.txt", ((p_startupConfiguration[o_xu_id]->appMode == APP_O_DU)?"o-du":"o-ru"),o_xu_id);
1536             file = fopen(filename, "w");
1537             if (file == NULL) {
1538                 printf("can't open file %s\n",filename);
1539                 exit (-1);
1540         }
1541             if (xran_get_delay_measurements_results (app_io_xran_handle, (uint16_t) p_startupConfiguration[o_xu_id]->o_xu_id,  p_usecaseConfiguration->appMode, &avgDelay))
1542                 {
1543                 fprintf(file,"OWD Measurements failed for port %d and appMode %d \n", p_startupConfiguration[o_xu_id]->o_xu_id,p_usecaseConfiguration->appMode);
1544         }
1545             else
1546                 {
1547                 fprintf(file,"OWD Measurements passed for port %d and appMode %d with AverageDelay %lu [ns]\n", p_startupConfiguration[o_xu_id]->o_xu_id,p_usecaseConfiguration->appMode, avgDelay);
1548                 }
1549             fflush(file);
1550             fclose(file);
1551             }
1552         }
1553
1554     MLogSetMask(0x0);
1555     puts("Closing l1 app... Ending all threads...");
1556
1557     xran_close(app_io_xran_handle);
1558 #ifdef FWK_ENABLED
1559     if(p_startupConfiguration[0]->appMode == APP_O_DU && p_usecaseConfiguration->bbu_offload) {
1560         app_bbu_close();
1561         }
1562 #endif
1563     app_io_xran_if_stop();
1564
1565     puts("Dump IQs...");
1566     for (o_xu_id = 0; o_xu_id <  p_usecaseConfiguration->oXuNum;  o_xu_id++) {
1567         app_dump_o_xu_buffers(p_usecaseConfiguration,  p_startupConfiguration[o_xu_id]);
1568     }
1569
1570     if(is_mlog_on) {
1571         app_profile_xran_print_mlog_stats(arg_params.usecase_file);
1572         rte_pause();
1573     }
1574
1575     app_io_xran_if_free();
1576     return 0;
1577 }