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