O-RAN E Maintenance Release contribution for ODULOW
[o-du/phy.git] / fhi_lib / test / common / xran_lib_wrap.hpp
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 #ifndef XRAN_LIB_WRAP_HPP
21 #define XRAN_LIB_WRAP_HPP
22
23 #include <exception>
24 #include <random>
25 #include <string>
26 #include <utility>
27 #include <vector>
28
29 #include <malloc.h>
30 #include <stdint.h>
31
32 #include "common.hpp"
33 #include "xran_fh_o_du.h"
34 #include "xran_common.h"
35 #include "xran_frame_struct.h"
36
37
38 #define XRAN_UT_CFG_FILENAME            "conf.json"
39
40 #define XRAN_UT_KEY_GLOBALCFG           "GLOBAL"
41 #define XRAN_UT_KEY_GLOBALCFG_IO        "io_cfg"
42 #define XRAN_UT_KEY_GLOBALCFG_EAXCID    "eAxCId_cfg"
43 #define XRAN_UT_KEY_GLOBALCFG_PRACH     "prach_cfg"
44 #define XRAN_UT_KEY_GLOBALCFG_RU        "ru_cfg"
45 #define XRAN_UT_KEY_GLOBALCFG_SLOT      "slotcfg_"
46
47 #define MAX_NUM_OF_XRAN_CTX             (2)
48
49 #define SW_FPGA_TOTAL_BUFFER_LEN        (4*1024*1024*1024)
50 #define SW_FPGA_SEGMENT_BUFFER_LEN      (1*1024*1024*1024)
51 #define SW_FPGA_FH_TOTAL_BUFFER_LEN     (1*1024*1024*1024)
52 #define FPGA_TO_SW_PRACH_RX_BUFFER_LEN  (8192)
53
54 #define MAX_ANT_CARRIER_SUPPORTED (XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR)
55
56 extern "C"
57 {
58 extern uint32_t xran_lib_ota_tti[];
59 extern uint32_t xran_lib_ota_sym[];
60 extern uint32_t xran_lib_ota_sym_idx[];
61
62 void sym_ota_cb(struct rte_timer *tim, void *arg);
63 void tti_ota_cb(struct rte_timer *tim, void *arg);
64 }
65
66
67 class xranLibWraper
68 {
69 public:
70     typedef enum
71     {
72         XRANFTHTX_OUT = 0,
73         XRANFTHTX_PRB_MAP_OUT,
74         XRANFTHTX_SEC_DESC_OUT,
75         XRANFTHRX_IN,
76         XRANFTHRX_PRB_MAP_IN,
77         XRANFTHTX_SEC_DESC_IN,
78         XRANFTHRACH_IN,
79         MAX_SW_XRAN_INTERFACE_NUM
80     } SWXRANInterfaceTypeEnum;
81
82 struct xran_io_buf_ctrl {
83     /* -1-this subframe is not used in current frame format
84          0-this subframe can be transmitted, i.e., data is ready
85           1-this subframe is waiting transmission, i.e., data is not ready
86          10 - DL transmission missing deadline. When FE needs this subframe data but bValid is still 1,
87         set bValid to 10.
88     */
89     int32_t bValid ; // when UL rx, it is subframe index.
90     int32_t nSegToBeGen;
91     int32_t nSegGenerated; // how many date segment are generated by DL LTE processing or received from FE
92                        // -1 means that DL packet to be transmitted is not ready in BS
93     int32_t nSegTransferred; // number of data segments has been transmitted or received
94     //struct rte_mbuf *pData[N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
95     struct xran_buffer_list sBufferList;
96 };
97
98 struct xran_io_shared_ctrl {
99     /* io struct */
100     struct xran_io_buf_ctrl sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
101     struct xran_io_buf_ctrl sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
102     struct xran_io_buf_ctrl sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
103     struct xran_io_buf_ctrl sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
104     struct xran_io_buf_ctrl sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
105     struct xran_io_buf_ctrl sFHPrachRxBbuIoBufCtrlDecomp[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
106
107     /* Cat B */
108     struct xran_io_buf_ctrl sFHSrsRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR];
109     struct xran_io_buf_ctrl sFHSrsRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR];
110
111     /* buffers lists */
112     struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
113     struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
114     struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
115     struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
116     struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
117     struct xran_flat_buffer sFHPrachRxBuffersDecomp[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
118     
119     /* Cat B SRS buffers */
120     struct xran_flat_buffer sFHSrsRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT];
121     struct xran_flat_buffer sFHSrsRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR];
122 };
123
124 struct bbu_xran_io_if {
125     void*    nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; /* instance per ORAN port */
126     uint32_t nBufPoolIndex[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM];   /* every api owns unique buffer pool */
127     uint16_t nInstanceNum[XRAN_PORTS_NUM];
128     struct xran_io_shared_ctrl ioCtrl[XRAN_PORTS_NUM]; /**< for each O-RU port */
129 };
130
131     enum nChBw
132     {
133         PHY_BW_5MHZ   =   5, PHY_BW_10MHZ  =  10, PHY_BW_15MHZ  =  15,
134         PHY_BW_20MHZ  =  20, PHY_BW_25MHZ  =  25, PHY_BW_30MHZ  =  30,
135         PHY_BW_40MHZ  =  40, PHY_BW_50MHZ  =  50, PHY_BW_60MHZ  =  60,
136         PHY_BW_70MHZ  =  70, PHY_BW_80MHZ  =  80, PHY_BW_90MHZ  =  90,
137         PHY_BW_100MHZ = 100, PHY_BW_200MHZ = 200, PHY_BW_400MHZ = 400
138     };
139
140     // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
141     const uint16_t nNumRbsPerSymF1[3][13] =
142     {
143     //      5MHz   10MHz   15MHz   20MHz   25MHz   30MHz   40MHz   50MHz   60MHz   70MHz   80MHz   90MHz  100MHz
144         {    25,     52,     79,    106,    133,    160,    216,    270,      0,      0,      0,      0,      0 },  // Numerology 0 (15KHz)
145         {    11,     24,     38,     51,     65,     78,    106,    133,    162,      0,    217,    245,    273 },  // Numerology 1 (30KHz)
146         {     0,     11,     18,     24,     31,     38,     51,     65,     79,      0,    107,    121,    135 }   // Numerology 2 (60KHz)
147     };
148
149     // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
150     const uint16_t nNumRbsPerSymF2[2][4] =
151     {
152     //     50MHz  100MHz  200MHz  400MHz
153         {    66,    132,    264,      0 },  // Numerology 2 (60KHz)
154         {    32,     66,    132,    264 }   // Numerology 3 (120KHz)
155     };
156
157 protected:
158     char argv[25] = "unittest";
159
160     std::string m_dpdk_dev_up, m_dpdk_dev_cp, m_dpdk_bbdev;
161
162     void *m_xranhandle;
163
164     uint8_t m_du_mac[6] = { 0x00,0x11, 0x22, 0x33, 0x44, 0x66 };
165     uint8_t m_ru_mac[6] = { 0x00,0x11, 0x22, 0x33, 0x44, 0x55 };
166     bool m_bSub6;
167     uint32_t m_nSlots = 10;
168
169     struct xran_fh_config   m_xranConf;
170     struct xran_fh_init     m_xranInit;
171
172     struct xran_timer_ctx {
173         uint32_t    tti_to_process;
174         } m_timer_ctx[MAX_NUM_OF_XRAN_CTX];
175
176     struct bbu_xran_io_if  m_gsXranIoIf;
177
178     uint32_t m_nSW_ToFpga_FTH_TxBufferLen;
179     uint32_t m_nFpgaToSW_FTH_RxBufferLen;
180
181     int32_t m_nSectorIndex[XRAN_MAX_SECTOR_NR];
182
183     int iq_bfw_buffer_size_dl = 0;
184     int iq_bfw_buffer_size_ul = 0;
185
186     /* beamforming weights for UL (O-DU) */
187     int16_t *p_tx_dl_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
188     int32_t tx_dl_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
189     int32_t tx_dl_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
190
191     /* beamforming weights for UL (O-DU) */
192     int16_t *p_tx_ul_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
193     int32_t tx_ul_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
194     int32_t tx_ul_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
195
196 private:
197     json m_global_cfg;
198
199     template<typename T>
200     T get_globalcfg(const std::string &type, const std::string &parameter_name)
201     {
202         return m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name];
203     }
204
205     template<typename T>
206     std::vector<T> get_globalcfg_array(const std::string &type, const std::string &parameter_name)
207     {
208         auto array_size = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name].size();
209
210         std::vector<T> result(array_size);
211
212         for(unsigned number = 0; number < array_size; number++)
213             result.at(number) = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name][number];
214
215         return result;
216     }
217
218     uint16_t get_eaxcid_mask(int numbit, int shift)
219     {
220         uint16_t result = 0;
221
222         for(int i=0; i < numbit; i++) {
223             result = result << 1; result +=1;
224             }
225         return (result << shift);
226     }
227
228     int init_memory(uint32_t o_xu_id)
229     {
230         xran_status_t status;
231         int32_t i, j, k, z, m;
232         SWXRANInterfaceTypeEnum eInterfaceType;
233         void *ptr;
234         void *mb;
235         uint32_t *u32dptr;
236         uint16_t *u16dptr;
237         uint8_t  *u8dptr;
238
239         struct bbu_xran_io_if *psBbuIo = (struct bbu_xran_io_if*)&m_gsXranIoIf;
240         struct xran_io_shared_ctrl *psIoCtrl =  (struct xran_io_shared_ctrl *)&psBbuIo->ioCtrl[o_xu_id];
241
242         uint32_t xran_max_antenna_nr = RTE_MAX(get_num_eaxc(), get_num_eaxc_ul());
243         uint32_t xran_max_ant_array_elm_nr = RTE_MAX(get_num_antelmtrx(), xran_max_antenna_nr);
244
245
246         std::cout << "XRAN front haul xran_mm_init" << std::endl;
247         status = xran_mm_init(m_xranhandle, (uint64_t) SW_FPGA_FH_TOTAL_BUFFER_LEN, SW_FPGA_SEGMENT_BUFFER_LEN);
248         if(status != XRAN_STATUS_SUCCESS) {
249             std::cout << "Failed at XRAN front haul xran_mm_init" << std::endl;
250             return (-1);
251             }
252
253         /* initialize maximum instances to have flexibility for the tests */
254
255         /* initialize maximum supported CC to have flexibility on the test */
256         int32_t nSectorNum = 6;//XRAN_MAX_SECTOR_NR;
257
258         k = o_xu_id;
259         psBbuIo->nInstanceNum[k] = nSectorNum;
260         status = xran_sector_get_instances(k, m_xranhandle, psBbuIo->nInstanceNum[k], &psBbuIo->nInstanceHandle[k][0]);
261             if(status != XRAN_STATUS_SUCCESS) {
262             std::cout  << "get sector instance failed " << k << " for XRAN nInstanceNum " << psBbuIo->nInstanceNum[k] << std::endl;
263                 return (-1);
264                 }
265         for (i = 0; i < psBbuIo->nInstanceNum[k]; i++)
266             std::cout << __func__ << " [" << k << "]: CC " << i << " handle " << psBbuIo->nInstanceHandle[k][i] << std::endl;
267
268         std::cout << "Sucess xran_mm_init" << std::endl;
269
270         /* Init Memory */
271         for(i = 0; i<nSectorNum; i++) {
272             eInterfaceType = XRANFTHTX_OUT;
273             status = xran_bm_init(psBbuIo->nInstanceHandle[o_xu_id][i],
274                             &psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType],
275                             XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
276                             m_nSW_ToFpga_FTH_TxBufferLen);
277             if(status != XRAN_STATUS_SUCCESS) {
278                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
279                 return (-1);
280                 }
281             for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
282                 for(z = 0; z < xran_max_antenna_nr; z++){
283                     psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
284                     psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
285                     psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
286                     psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
287                     psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
288                     psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psIoCtrl->sFrontHaulTxBuffers[j][i][z][0];
289
290                     for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
291                         psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = m_nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
292                         psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
293                         psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
294                         status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[o_xu_id][i], psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
295                         if(status != XRAN_STATUS_SUCCESS) {
296                             std::cout << __LINE__ << " Failed at  xran_bm_allocate_buffer, status " << status << std::endl;
297                             return (-1);
298                             }
299                         psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
300                         psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
301
302                         if(ptr) {
303                             u32dptr = (uint32_t*)(ptr);
304                             uint8_t *ptr_temp = (uint8_t *)ptr;
305                             memset(u32dptr, 0x0, m_nSW_ToFpga_FTH_TxBufferLen);
306                             }
307                         }
308                     }
309                 }
310
311             /* C-plane DL */
312             eInterfaceType = XRANFTHTX_SEC_DESC_OUT;
313             status = xran_bm_init(psBbuIo->nInstanceHandle[o_xu_id][i],
314                             &psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType],
315                             XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT*XRAN_MAX_SECTIONS_PER_SLOT*XRAN_MAX_FRAGMENT, sizeof(struct xran_section_desc));
316             if(XRAN_STATUS_SUCCESS != status) {
317                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
318                 return (-1);
319             }
320             eInterfaceType = XRANFTHTX_PRB_MAP_OUT;
321             status = xran_bm_init(psBbuIo->nInstanceHandle[o_xu_id][i],
322                             &psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType],
323                             XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
324                             sizeof(struct xran_prb_map));
325             if(status != XRAN_STATUS_SUCCESS) {
326                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
327                 return (-1);
328             }
329             for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
330                 for(z = 0; z < xran_max_antenna_nr; z++) {
331                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
332                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
333                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
334                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
335                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
336                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psIoCtrl->sFrontHaulTxPrbMapBuffers[j][i][z];
337
338                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
339                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
340                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
341
342                     status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[o_xu_id][i], psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
343                     if(status != XRAN_STATUS_SUCCESS) {
344                         std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
345                         return (-1);
346                         }
347                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
348                     psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
349                     void *sd_ptr;
350                     void *sd_mb;
351                     int  elm_id;
352                     struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr;
353                     //memcpy(ptr, &startupConfiguration.PrbMap, sizeof(struct xran_prb_map));
354                     for (elm_id = 0; elm_id < XRAN_MAX_SECTIONS_PER_SLOT; elm_id++){
355                         struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
356                         for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
357                             for(m = 0; m < XRAN_MAX_FRAGMENT; m++){
358                                 status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[o_xu_id][i], psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][XRANFTHTX_SEC_DESC_OUT], &sd_ptr, &sd_mb);
359                             if(XRAN_STATUS_SUCCESS != status){
360                                 std::cout << __LINE__ << "SD Failed at  xran_bm_allocate_buffer , status %d\n" << status << std::endl;
361                                 return (-1);
362                             }
363                                 pPrbElem->p_sec_desc[k][m] = (struct xran_section_desc *)sd_ptr;
364                             }
365                         }
366                     }
367                  }
368              }
369         }
370
371         for(i = 0; i<nSectorNum; i++) {
372             eInterfaceType = XRANFTHRX_IN;
373             status = xran_bm_init(psBbuIo->nInstanceHandle[o_xu_id][i],
374                             &psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType],
375                             XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
376                             m_nSW_ToFpga_FTH_TxBufferLen);  /* ????, actual alloc size is m_nFpgaToSW_FTH_RxBUfferLen */
377             if(status != XRAN_STATUS_SUCCESS) {
378                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
379                 return (-1);
380                 }
381
382             for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) {
383                 for(z = 0; z < xran_max_antenna_nr; z++) {
384                     psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid                  = 0;
385                     psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated           = -1;
386                     psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen             = -1;
387                     psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred         = 0;
388                     psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
389                     psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers    = &psIoCtrl->sFrontHaulRxBuffers[j][i][z][0];
390                     for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
391                         psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes  = m_nFpgaToSW_FTH_RxBufferLen;
392                         psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements   = 1;
393                         psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes      = 0;
394                         status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[o_xu_id][i], psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType],&ptr, &mb);
395                         if(status != XRAN_STATUS_SUCCESS) {
396                             std::cout << __LINE__ << " Failed at  xran_bm_allocate_buffer, status " << status << std::endl;
397                             return (-1);
398                             }
399                         psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData   = (uint8_t *)ptr;
400                         psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl   = (void *) mb;
401                         if(ptr) {
402                             u32dptr = (uint32_t*)(ptr);
403                             uint8_t *ptr_temp = (uint8_t *)ptr;
404                             memset(u32dptr, 0x0, m_nFpgaToSW_FTH_RxBufferLen);
405                             }
406                         }
407                     }
408                 }
409
410             eInterfaceType = XRANFTHTX_SEC_DESC_IN;
411             status = xran_bm_init(psBbuIo->nInstanceHandle[o_xu_id][i],
412                             &psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType],
413                             XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT*XRAN_MAX_SECTIONS_PER_SLOT*XRAN_MAX_FRAGMENT, sizeof(struct xran_section_desc));
414             if(XRAN_STATUS_SUCCESS != status) {
415                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
416                 return (-1);
417             }
418             eInterfaceType = XRANFTHRX_PRB_MAP_IN;
419             status = xran_bm_init(psBbuIo->nInstanceHandle[o_xu_id][i],
420                                 &psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType],
421                                 XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
422                                 sizeof(struct xran_prb_map));
423             if(status != XRAN_STATUS_SUCCESS) {
424                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
425                 return (-1);
426             }
427
428             for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) {
429                 for(z = 0; z < xran_max_antenna_nr; z++) {
430                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid                    = 0;
431                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated             = -1;
432                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen               = -1;
433                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred           = 0;
434                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers   = XRAN_NUM_OF_SYMBOL_PER_SLOT;
435                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers      = &psIoCtrl->sFrontHaulRxPrbMapBuffers[j][i][z];
436
437                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes  = sizeof(struct xran_prb_map);
438                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements   = 1;
439                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes      = 0;
440                     status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[o_xu_id][i],psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
441                     if(status != XRAN_STATUS_SUCCESS) {
442                         std::cout << __LINE__ << " Failed at  xran_bm_allocate_buffer , status " << status << std::endl;
443                         return (-1);
444                         }
445                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData   = (uint8_t *)ptr;
446                     psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl   = (void *)mb;
447                     void *sd_ptr;
448                     void *sd_mb;
449                     int  elm_id;
450                     struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr;
451                     //memcpy(ptr, &startupConfiguration.PrbMap, sizeof(struct xran_prb_map));
452                     for (elm_id = 0; elm_id < XRAN_MAX_SECTIONS_PER_SLOT; elm_id++){
453                         struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
454                         for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
455                             for(m = 0; m < XRAN_MAX_FRAGMENT; m++){
456                                 status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[o_xu_id][i], psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][XRANFTHTX_SEC_DESC_IN], &sd_ptr, &sd_mb);
457                             if(XRAN_STATUS_SUCCESS != status){
458                                 std::cout << __LINE__ << "SD Failed at  xran_bm_allocate_buffer , status %d\n" << status << std::endl;
459                                 return (-1);
460                             }
461                                 pPrbElem->p_sec_desc[k][m] = (struct xran_section_desc *)sd_ptr;
462                             }
463                         }
464                     }
465                 }
466             }
467         }
468
469         for(i = 0; i<nSectorNum; i++) {
470             eInterfaceType = XRANFTHRACH_IN;
471
472             status = xran_bm_init(psBbuIo->nInstanceHandle[o_xu_id][i],
473                                 &psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType],
474                                 XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
475                                 PRACH_PLAYBACK_BUFFER_BYTES);
476             if(status != XRAN_STATUS_SUCCESS) {
477                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
478                 return (-1);
479                 }
480             for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
481                 for(z = 0; z < xran_max_antenna_nr; z++) {
482                     psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid                    = 0;
483                     psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated             = -1;
484                     psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen               = -1;
485                     psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred           = 0;
486                     psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers   = xran_max_antenna_nr;
487                     psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers      = &psIoCtrl->sFHPrachRxBuffers[j][i][z][0];
488                     for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
489                         psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes    = PRACH_PLAYBACK_BUFFER_BYTES;
490                         psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements     = 1;
491                         psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes        = 0;
492                         status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[o_xu_id][i], psBbuIo->nBufPoolIndex[o_xu_id][m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
493                         if(status != XRAN_STATUS_SUCCESS) {
494                             std::cout << __LINE__ << " Failed at  xran_bm_allocate_buffer, status " << status << std::endl;
495                             return (-1);
496                             }
497                         psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
498                         psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
499                         if(ptr) {
500                             u32dptr = (uint32_t*)(ptr);
501                             memset(u32dptr, 0x0, PRACH_PLAYBACK_BUFFER_BYTES);
502                             }
503                         }
504                     }
505                 }
506             }
507
508         return (0);
509     }
510
511
512 public:
513     xranLibWraper()
514     {
515         int i, temp;
516         std::string tmpstr;
517         unsigned int tmp_mac[6];
518
519         m_global_cfg = read_json_from_file(XRAN_UT_CFG_FILENAME);
520
521         memset(&m_xranInit, 0, sizeof(xran_fh_init));
522
523         m_xranInit.io_cfg.id  = 0;
524
525         /* DPDK configuration */
526         m_dpdk_dev_up = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdk_dev_up");
527         m_dpdk_dev_cp = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdk_dev_cp");
528         m_xranInit.io_cfg.num_vfs = 2;
529         m_xranInit.io_cfg.dpdk_dev[XRAN_UP_VF]  = (m_dpdk_dev_up == "") ? NULL : (char *)&m_dpdk_dev_up;
530         m_xranInit.io_cfg.dpdk_dev[XRAN_CP_VF]  = (m_dpdk_dev_cp == "") ? NULL : (char *)&m_dpdk_dev_cp;
531
532         m_xranInit.io_cfg.core              = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "core");
533         m_xranInit.io_cfg.system_core       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "system_core");
534         m_xranInit.io_cfg.pkt_proc_core     = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "pkt_proc_core");
535         m_xranInit.io_cfg.pkt_aux_core      = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "pkt_aux_core");
536         m_xranInit.io_cfg.timing_core       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "timing_core");
537         m_xranInit.io_cfg.dpdkMemorySize    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdkMemorySize");
538
539         m_xranInit.xran_ports = 1;
540
541         std::string bbdev_mode = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "bbdev_mode");
542         if(bbdev_mode == "sw")
543             m_xranInit.io_cfg.bbdev_mode    = XRAN_BBDEV_MODE_HW_OFF;
544         else if(bbdev_mode == "hw")
545             m_xranInit.io_cfg.bbdev_mode    = XRAN_BBDEV_MODE_HW_ON;
546         else if(bbdev_mode == "none")
547             m_xranInit.io_cfg.bbdev_mode    = XRAN_BBDEV_NOT_USED;
548         else {
549             std::cout << "Invalid BBDev mode [" << bbdev_mode << "], bbdev won't be used." << std::endl;
550             m_xranInit.io_cfg.bbdev_mode    = XRAN_BBDEV_NOT_USED;
551             }
552
553         m_xranInit.dpdkBasebandFecMode      = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdkBasebandFecMode");
554
555
556         m_dpdk_bbdev = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdkBasebandDevice");
557         m_xranInit.dpdkBasebandDevice       = (m_dpdk_bbdev == "") ? NULL : (char *)&m_dpdk_bbdev;
558
559         /* Network configurations */
560         m_xranInit.mtu          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "mtu");
561
562         std::string du_mac_str = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "o_du_macaddr");
563         std::string ru_mac_str = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "o_ru_macaddr");
564         /* using temp variables to resolve KW issue */
565         std::sscanf(du_mac_str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x",
566                                            &tmp_mac[0], &tmp_mac[1], &tmp_mac[2],
567                                            &tmp_mac[3], &tmp_mac[4], &tmp_mac[5]);
568         for(i=0; i<6; i++)
569             m_du_mac[i] = (uint8_t)tmp_mac[i];
570         std::sscanf(du_mac_str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x",
571                                            &tmp_mac[0], &tmp_mac[1], &tmp_mac[2],
572                                            &tmp_mac[3], &tmp_mac[4], &tmp_mac[5]);
573         for(i=0; i<6; i++)
574             m_ru_mac[i] = (uint8_t)tmp_mac[i];
575         m_xranInit.p_o_du_addr  = (int8_t *)m_du_mac;
576         m_xranInit.p_o_ru_addr  = (int8_t *)m_ru_mac;
577         m_xranConf.cp_vlan_tag  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "cp_vlan_tag");
578         m_xranConf.up_vlan_tag  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "up_vlan_tag");
579
580         /* eAxCID configurations */
581         int bitnum_cuport   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_cuPortId");
582         int bitnum_bandsec  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_bandSectorId");
583         int bitnum_ccid     = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_ccId");
584         int bitnum_ruport   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_ruPortId");
585
586         m_xranInit.eAxCId_conf.bit_cuPortId       = bitnum_bandsec + bitnum_ccid + bitnum_ruport;
587         m_xranInit.eAxCId_conf.bit_bandSectorId   = bitnum_ccid + bitnum_ruport;
588         m_xranInit.eAxCId_conf.bit_ccId           = bitnum_ruport;
589         m_xranInit.eAxCId_conf.bit_ruPortId       = 0;
590         m_xranInit.eAxCId_conf.mask_cuPortId      = get_eaxcid_mask(bitnum_cuport, m_xranInit.eAxCId_conf.bit_cuPortId);
591         m_xranInit.eAxCId_conf.mask_bandSectorId  = get_eaxcid_mask(bitnum_bandsec, m_xranInit.eAxCId_conf.bit_bandSectorId);
592         m_xranInit.eAxCId_conf.mask_ccId          = get_eaxcid_mask(bitnum_ccid, m_xranInit.eAxCId_conf.bit_ccId);
593         m_xranInit.eAxCId_conf.mask_ruPortId      = get_eaxcid_mask(bitnum_ruport, m_xranInit.eAxCId_conf.bit_ruPortId);
594
595         m_xranInit.totalBfWeights   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "totalBfWeights");
596         m_xranInit.filePrefix   = "wls";
597
598         m_bSub6     = get_globalcfg<bool>(XRAN_UT_KEY_GLOBALCFG_RU, "sub6");
599
600         memset(&m_xranConf, 0, sizeof(struct xran_fh_config));
601
602         m_xranConf.Tadv_cp_dl       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Tadv_cp_dl");
603         m_xranConf.T2a_min_cp_dl    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_cp_dl");
604         m_xranConf.T2a_max_cp_dl    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_cp_dl");
605         m_xranConf.T2a_min_cp_ul    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_cp_ul");
606         m_xranConf.T2a_max_cp_ul    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_cp_ul");
607         m_xranConf.T2a_min_up       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_up");
608         m_xranConf.T2a_max_up       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_up");
609         m_xranConf.Ta3_min          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta3_min");
610         m_xranConf.Ta3_max          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta3_max");
611         m_xranConf.T1a_min_cp_dl    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_cp_dl");
612         m_xranConf.T1a_max_cp_dl    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_cp_dl");
613         m_xranConf.T1a_min_cp_ul    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_cp_ul");
614         m_xranConf.T1a_max_cp_ul    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_cp_ul");
615         m_xranConf.T1a_min_up       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_up");
616         m_xranConf.T1a_max_up       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_up");
617         m_xranConf.Ta4_min          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta4_min");
618         m_xranConf.Ta4_max          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta4_max");
619
620         m_xranConf.enableCP         = 1;
621         m_xranConf.prachEnable      = 1;
622         m_xranConf.debugStop        = 0;
623         m_xranConf.debugStopCount   = 0;
624         m_xranConf.DynamicSectionEna= 0;
625
626         tmpstr = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "duplex");
627         if(tmpstr == "FDD") {
628             m_xranConf.frame_conf.nFrameDuplexType  = 0;
629             }
630         else if(tmpstr == "TDD") {
631             m_xranConf.frame_conf.nFrameDuplexType  = 1;
632
633             std::string slotcfg_key = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "slot_config");
634
635             int numcfg = get_globalcfg<int>(slotcfg_key, "period");
636             m_xranConf.frame_conf.nTddPeriod = numcfg;
637
638             for(int i=0; i< numcfg; i++) {
639                 std::stringstream slotcfgname;
640                 slotcfgname << "slot" << i;
641                 std::vector<int> slotcfg = get_globalcfg_array<int>(slotcfg_key, slotcfgname.str());
642                 for(int j=0; j < slotcfg.size(); j++) {
643                     m_xranConf.frame_conf.sSlotConfig[i].nSymbolType[j] = slotcfg[j];
644                     }
645                 m_xranConf.frame_conf.sSlotConfig[i].reserved[0] = 0;
646                 m_xranConf.frame_conf.sSlotConfig[i].reserved[1] = 0;
647                 }
648             }
649         else {
650             std::cout << "*** Invalid Duplex type [" << tmpstr << "] !!!" << std::endl;
651             std::cout << "****** Set it to FDD... " << std::endl;
652             m_xranConf.frame_conf.nFrameDuplexType  = 0;
653             }
654
655         m_xranConf.frame_conf.nNumerology = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "mu");
656         if(m_xranConf.frame_conf.nNumerology > 3) {
657             std::cout << "*** Invalid Numerology [" << m_xranConf.frame_conf.nNumerology << "] !!!" << std::endl;
658             m_xranConf.frame_conf.nNumerology   = 0;
659             std::cout << "****** Set it to " << m_xranConf.frame_conf.nNumerology << "..." << std::endl;
660             }
661
662         m_xranConf.nCC = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "num_cc");
663         if(m_xranConf.nCC > XRAN_MAX_SECTOR_NR) {
664             std::cout << "*** Exceeds maximum number of carriers supported [" << m_xranConf.nCC << "] !!!" << std::endl;
665             m_xranConf.nCC = XRAN_MAX_SECTOR_NR;
666             std::cout << "****** Adjusted to " << m_xranConf.nCC << "..." << std::endl;
667             }
668         m_xranConf.neAxc = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "num_eaxc");
669         if(m_xranConf.neAxc > XRAN_MAX_ANTENNA_NR) {
670             std::cout << "*** Exceeds maximum number of antenna supported [" << m_xranConf.neAxc << "] !!!" << std::endl;
671             m_xranConf.neAxc = XRAN_MAX_ANTENNA_NR;
672             std::cout << "****** Adjusted to " << m_xranConf.neAxc << "..." << std::endl;
673             }
674
675         m_bSub6     = get_globalcfg<bool>(XRAN_UT_KEY_GLOBALCFG_RU, "sub6");
676         temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "chbw_dl");
677         m_xranConf.nDLRBs = get_num_rbs(get_numerology(), temp, m_bSub6);
678         temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "chbw_ul");
679         m_xranConf.nULRBs = get_num_rbs(get_numerology(), temp, m_bSub6);
680         m_xranConf.dpdk_port    = 0;
681
682         m_xranConf.nAntElmTRx = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "ant_elm_trx");
683         m_xranConf.nDLFftSize = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
684         m_xranConf.nULFftSize = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
685
686         m_xranConf.prach_conf.nPrachConfIdx     = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "config_id");
687         m_xranConf.prach_conf.nPrachSubcSpacing = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "scs");
688         m_xranConf.prach_conf.nPrachFreqStart   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "freq_start");
689         m_xranConf.prach_conf.nPrachFreqOffset  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "freq_offset");
690         m_xranConf.prach_conf.nPrachFilterIdx   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "filter_id");
691         m_xranConf.prach_conf.nPrachZeroCorrConf= 0;
692         m_xranConf.prach_conf.nPrachRestrictSet = 0;
693         m_xranConf.prach_conf.nPrachRootSeqIdx  = 0;
694
695         tmpstr = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "category");
696         if(tmpstr == "A")
697             m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_A;
698         else if(tmpstr == "B")
699             m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_B;
700         else {
701             std::cout << "*** Invalid RU Category [" << tmpstr << "] !!!" << std::endl;
702             std::cout << "****** Set it to Category A... " << std::endl;
703             m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_A;
704             }
705
706         m_xranConf.ru_conf.iqWidth  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "iq_width");
707         m_xranConf.ru_conf.compMeth = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "comp_meth");
708
709         temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
710         m_xranConf.ru_conf.fftSize  = 0;
711         while (temp >>= 1)
712             ++m_xranConf.ru_conf.fftSize;
713
714         m_xranConf.ru_conf.byteOrder    =  XRAN_NE_BE_BYTE_ORDER;
715         m_xranConf.ru_conf.iqOrder      =  XRAN_I_Q_ORDER;
716
717         m_xranConf.log_level    = 0;
718 /*
719         m_xranConf.bbdev_enc = nullptr;
720         m_xranConf.bbdev_dec = nullptr;
721         m_xranConf.ttiCb    = nullptr;
722         m_xranConf.ttiCbParam   = nullptr;
723 */
724     }
725
726     ~xranLibWraper()
727     {
728     }
729
730     int SetUp()
731     {
732         int i;
733
734         printf("O-DU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
735             m_xranInit.p_o_du_addr[0],
736             m_xranInit.p_o_du_addr[1],
737             m_xranInit.p_o_du_addr[2],
738             m_xranInit.p_o_du_addr[3],
739             m_xranInit.p_o_du_addr[4],
740             m_xranInit.p_o_du_addr[5]);
741
742         printf("O-RU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
743             m_xranInit.p_o_ru_addr[0],
744             m_xranInit.p_o_ru_addr[1],
745             m_xranInit.p_o_ru_addr[2],
746             m_xranInit.p_o_ru_addr[3],
747             m_xranInit.p_o_ru_addr[4],
748             m_xranInit.p_o_ru_addr[5]);
749
750         printf("eAxCID - %d:%d:%d:%d (%04x, %04x, %04x, %04x)\n",
751             m_xranInit.eAxCId_conf.bit_cuPortId,
752             m_xranInit.eAxCId_conf.bit_bandSectorId,
753             m_xranInit.eAxCId_conf.bit_ccId,
754             m_xranInit.eAxCId_conf.bit_ruPortId,
755             m_xranInit.eAxCId_conf.mask_cuPortId,
756             m_xranInit.eAxCId_conf.mask_bandSectorId,
757             m_xranInit.eAxCId_conf.mask_ccId,
758             m_xranInit.eAxCId_conf.mask_ruPortId);
759
760         printf("Total BF Weights : %d\n", m_xranInit.totalBfWeights);
761
762         xran_init(0, NULL, &m_xranInit, &argv[0], &m_xranhandle);
763
764
765
766         for(i = 0; i < XRAN_MAX_SECTOR_NR; i++)
767             m_nSectorIndex[i] = i;
768
769         /* set to maximum length to support multiple cases */
770         m_nFpgaToSW_FTH_RxBufferLen     = 13168; /* 273*12*4 + 64*/
771         m_nSW_ToFpga_FTH_TxBufferLen    = 13168; /* 273*12*4 + 64*/
772
773         if(init_memory(0) < 0) {
774             std::cout << "Fatal Error on Initialization !!!" << std::endl;
775             std::cout << "INIT FAILED" << std::endl;
776             return (-1);
777             }
778
779         std::cout << "INIT DONE" << std::endl;
780         return (0);
781     }
782
783     void TearDown()
784     {
785         if(m_xranhandle) {
786             xran_close(m_xranhandle);
787             m_xranhandle = nullptr;
788             std::cout << "CLOSE DONE" << std::endl;
789             }
790         else
791             std::cout << "ALREADY CLOSED" << std::endl;
792     }
793
794     int Init(uint32_t o_xu_id, struct xran_fh_config *pCfg = nullptr)
795     {
796         xran_status_t status;
797         int32_t nSectorNum;
798         int32_t i, j, k, z;
799         void *ptr;
800         void *mb;
801         uint32_t *u32dptr;
802         uint16_t *u16dptr;
803         uint8_t  *u8dptr;
804         SWXRANInterfaceTypeEnum eInterfaceType;
805         int32_t cc_id, ant_id, sym_id, tti;
806         int32_t flowId;
807         char    *pos        = NULL;
808         struct xran_prb_map *pRbMap = NULL;
809
810         struct bbu_xran_io_if *psBbuIo = (struct bbu_xran_io_if*)&m_gsXranIoIf;
811         struct xran_io_shared_ctrl *psIoCtrl =  (struct xran_io_shared_ctrl *)&psBbuIo->ioCtrl[o_xu_id];
812
813         uint32_t xran_max_antenna_nr = RTE_MAX(get_num_eaxc(), get_num_eaxc_ul());
814         uint32_t xran_max_ant_array_elm_nr = RTE_MAX(get_num_antelmtrx(), xran_max_antenna_nr);
815
816
817         /* Update member variables */
818         if(pCfg)
819             memcpy(&m_xranConf, pCfg, sizeof(struct xran_fh_config));
820
821         /* Init timer context */
822         for (i=0; i<XRAN_PORTS_NUM; i++)
823         {
824             xran_lib_ota_sym[i] = 0;
825             xran_lib_ota_sym_idx[i] = 0;
826             xran_lib_ota_tti[i]        = 0;
827         }
828         for(i=0; i < MAX_NUM_OF_XRAN_CTX; i++)
829             m_timer_ctx[i].tti_to_process = i;
830
831         nSectorNum = get_num_cc();
832
833         /* Cat B RU support */
834         if(get_rucategory() == XRAN_CATEGORY_B) {
835             /* 10 * [14*32*273*2*2] = 4892160 bytes */
836             iq_bfw_buffer_size_dl = (m_nSlots * N_SYM_PER_SLOT * get_num_antelmtrx() * get_num_dlrbs() * 4L);
837             iq_bfw_buffer_size_ul = (m_nSlots * N_SYM_PER_SLOT * get_num_antelmtrx() * get_num_ulrbs() * 4L);
838
839             for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(get_num_cc() * get_num_eaxc()); i++) {
840                 p_tx_dl_bfw_buffer[i]   = (int16_t*)malloc(iq_bfw_buffer_size_dl);
841                 tx_dl_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_dl;
842                 if(p_tx_dl_bfw_buffer[i] == NULL)
843                     return(-1);
844
845                 memset(p_tx_dl_bfw_buffer[i], 'D', iq_bfw_buffer_size_dl);
846                 tx_dl_bfw_buffer_position[i] = 0;
847
848                 p_tx_ul_bfw_buffer[i]    = (int16_t*)malloc(iq_bfw_buffer_size_ul);
849                 tx_ul_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_ul;
850                 if(p_tx_ul_bfw_buffer[i] == NULL)
851                     return (-1);
852
853                 memset(p_tx_ul_bfw_buffer[i], 'U', iq_bfw_buffer_size_ul);
854                 tx_ul_bfw_buffer_position[i] = 0;
855             }
856         }
857
858         /* Init RB map */
859         for(cc_id = 0; cc_id <nSectorNum; cc_id++) {
860             for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti ++) {
861                 for(ant_id = 0; ant_id < xran_max_antenna_nr; ant_id++) {
862                     flowId = xran_max_antenna_nr*cc_id + ant_id;
863
864                     /* C-plane DL */
865                     pRbMap = (struct xran_prb_map *)psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
866                     if(pRbMap) {
867                         pRbMap->dir                     = XRAN_DIR_DL;
868                         pRbMap->xran_port               = 0;
869                         pRbMap->band_id                 = 0;
870                         pRbMap->cc_id                   = cc_id;
871                         pRbMap->ru_port_id              = ant_id;
872                         pRbMap->tti_id                  = tti;
873                         pRbMap->start_sym_id            = 0;
874
875                         pRbMap->nPrbElm                 = 1;
876                         pRbMap->prbMap[0].nRBStart      = 0;
877                         pRbMap->prbMap[0].nRBSize       = get_num_dlrbs();
878                         pRbMap->prbMap[0].nStartSymb    = 0;
879                         pRbMap->prbMap[0].numSymb       = 14;
880                         pRbMap->prbMap[0].nBeamIndex    = 0;
881                         pRbMap->prbMap[0].compMethod    = XRAN_COMPMETHOD_NONE;
882
883                         if(get_rucategory() == XRAN_CATEGORY_A) {
884                             pRbMap->prbMap[0].BeamFormingType   = XRAN_BEAM_ID_BASED;
885                             pRbMap->prbMap[0].bf_weight_update  = 0;
886                             //pRbMap->prbMap[0].bf_attribute.weight[];
887                             //pRbMap->prbMap[0].bf_precoding.weight[];
888                             }
889                         else if(get_rucategory() == XRAN_CATEGORY_B) {
890                             int idxElm;
891                             int iPrb;
892                             char *dl_bfw_pos = ((char*)p_tx_dl_bfw_buffer[flowId]) + tx_dl_bfw_buffer_position[flowId];
893                             struct xran_prb_elm* p_prbMap = NULL;
894                             int num_antelm;
895
896                             pRbMap->prbMap[0].BeamFormingType   = XRAN_BEAM_WEIGHT;
897                             pRbMap->prbMap[0].bf_weight_update  = 1;
898
899                             num_antelm = get_num_antelmtrx();
900 #if 0
901                             /* populate beam weights to C-plane for each elm */
902                             pRbMap->bf_weight.nAntElmTRx = num_antelm;
903                             for(idxElm = 0;  idxElm < pRbMap->nPrbElm; idxElm++){
904                                 p_prbMap = &pRbMap->prbMap[idxElm];
905                                 for (iPrb = p_prbMap->nRBStart; iPrb < (p_prbMap->nRBStart + p_prbMap->nRBSize); iPrb++) {
906                                     /* copy BF W IQs for 1 PRB of */
907                                     memcpy(&pRbMap->bf_weight.weight[iPrb][0], (dl_bfw_pos + (iPrb * num_antelm)*4), num_antelm*4);
908                                     }
909                                 }
910 #endif
911                             } /* else if(get_rucategory() == XRAN_CATEGORY_B) */
912                         } /* if(pRbMap) */
913                     else {
914                         std::cout << "DL pRbMap ==NULL" << std::endl;
915                         }
916
917                     /* C-plane UL */
918                     pRbMap = (struct xran_prb_map *)psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
919                     if(pRbMap) {
920                         pRbMap->dir                     = XRAN_DIR_UL;
921                         pRbMap->xran_port               = 0;
922                         pRbMap->band_id                 = 0;
923                         pRbMap->cc_id                   = cc_id;
924                         pRbMap->ru_port_id              = ant_id;
925                         pRbMap->tti_id                  = tti;
926                         pRbMap->start_sym_id            = 0;
927
928                         pRbMap->nPrbElm                 = 1;
929                         pRbMap->prbMap[0].nRBStart      = 0;
930                         pRbMap->prbMap[0].nRBSize       = get_num_ulrbs();
931                         pRbMap->prbMap[0].nStartSymb    = 0;
932                         pRbMap->prbMap[0].numSymb       = 14;
933                         pRbMap->prbMap[0].nBeamIndex    = 0;
934                         pRbMap->prbMap[0].compMethod    = XRAN_COMPMETHOD_NONE;
935
936                         if(get_rucategory() == XRAN_CATEGORY_A) {
937                             pRbMap->prbMap[0].BeamFormingType   = XRAN_BEAM_ID_BASED;
938                             pRbMap->prbMap[0].bf_weight_update  = 0;
939                             //pRbMap->prbMap[0].bf_attribute.weight[];
940                             //pRbMap->prbMap[0].bf_precoding.weight[];
941                             }
942                         else if(get_rucategory() == XRAN_CATEGORY_B) {
943                             int idxElm;
944                             int iPrb;
945                             char *ul_bfw_pos =  ((char*)p_tx_ul_bfw_buffer[flowId]) + tx_ul_bfw_buffer_position[flowId];
946                             struct xran_prb_elm* p_prbMap = NULL;
947                             int num_antelm;
948
949                             pRbMap->prbMap[0].BeamFormingType   = XRAN_BEAM_WEIGHT;
950                             pRbMap->prbMap[0].bf_weight_update  = 1;
951
952                             num_antelm = get_num_antelmtrx();
953 #if 0
954                             /* populate beam weights to C-plane for each elm */
955                             pRbMap->bf_weight.nAntElmTRx = num_antelm;
956                             for (idxElm = 0;  idxElm < pRbMap->nPrbElm; idxElm++){
957                                 p_prbMap = &pRbMap->prbMap[idxElm];
958                                 for (iPrb = p_prbMap->nRBStart; iPrb < (p_prbMap->nRBStart + p_prbMap->nRBSize); iPrb++){
959                                     /* copy BF W IQs for 1 PRB of */
960                                     memcpy(&pRbMap->bf_weight.weight[iPrb][0], (ul_bfw_pos + (iPrb*num_antelm)*4), num_antelm*4);
961                                     }
962                                 }
963 #endif
964                             } /* else if(get_rucategory() == XRAN_CATEGORY_B) */
965
966                         } /* if(pRbMap) */
967                     else {
968                         std::cout << "UL: pRbMap ==NULL" << std::endl;
969                         }
970                     }
971                 }
972             }
973
974         return (0);
975     }
976
977     void Cleanup()
978     {
979         int i;
980
981         if(get_rucategory() == XRAN_CATEGORY_B) {
982             for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(get_num_cc() * get_num_eaxc()); i++) {
983                 if(p_tx_dl_bfw_buffer[i]) {
984                     free(p_tx_dl_bfw_buffer[i]);
985                     p_tx_dl_bfw_buffer[i] == NULL;
986                     }
987
988                 if(p_tx_ul_bfw_buffer[i]) {
989                     free(p_tx_ul_bfw_buffer[i]);
990                     p_tx_ul_bfw_buffer[i] == NULL;
991                     }
992                 }
993             }
994
995         return;
996     }
997
998
999     void Open(uint32_t o_xu_id, xran_ethdi_mbuf_send_fn send_cp, xran_ethdi_mbuf_send_fn send_up,
1000             void *fh_rx_callback, void *fh_rx_prach_callback, void *fh_srs_callback)
1001     {
1002         struct xran_fh_config *pXranConf;
1003         int32_t nSectorNum;
1004         int i, j, k, z;
1005
1006         struct bbu_xran_io_if *psBbuIo = (struct bbu_xran_io_if*)&m_gsXranIoIf;
1007         struct xran_io_shared_ctrl *psIoCtrl =  (struct xran_io_shared_ctrl *)&psBbuIo->ioCtrl[o_xu_id];
1008
1009         uint32_t xran_max_antenna_nr = RTE_MAX(get_num_eaxc(), get_num_eaxc_ul());
1010         uint32_t xran_max_ant_array_elm_nr = RTE_MAX(get_num_antelmtrx(), xran_max_antenna_nr);
1011
1012         struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
1013         struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
1014         struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
1015         struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
1016         struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
1017         struct xran_buffer_list *pFthRxRachBufferDecomp[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
1018         struct xran_buffer_list *pFthRxSrsBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];
1019         struct xran_buffer_list *pFthRxSrsPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];
1020
1021 #if 0
1022         xran_reg_physide_cb(xranHandle, physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI);
1023         xran_reg_physide_cb(xranHandle, physide_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX);
1024         xran_reg_physide_cb(xranHandle, physide_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX);
1025 #endif
1026         nSectorNum = get_num_cc();
1027
1028         for(i=0; i<nSectorNum; i++) {
1029             for(j=0; j<XRAN_N_FE_BUF_LEN; j++) {
1030                 for(z = 0; z < /*xran_max_antenna_nr*/XRAN_MAX_ANTENNA_NR; z++) {
1031                     pFthTxBuffer[i][z][j]       = NULL;
1032                     pFthTxPrbMapBuffer[i][z][j] = NULL;
1033                     pFthRxBuffer[i][z][j]       = NULL;
1034                     pFthRxPrbMapBuffer[i][z][j] = NULL;
1035                     pFthRxRachBuffer[i][z][j]   = NULL;
1036                     pFthRxRachBufferDecomp[i][z][j]   = NULL;
1037                 }
1038                 for(z = 0; z < /*xran_max_ant_array_elm_nr*/XRAN_MAX_ANT_ARRAY_ELM_NR; z++) {
1039                     pFthRxSrsBuffer[i][z][j] = NULL;
1040                     pFthRxSrsPrbMapBuffer[i][z][j] = NULL;
1041                 }
1042             }
1043         }
1044
1045         for(i=0; i<nSectorNum; i++) {
1046             for(j=0; j<XRAN_N_FE_BUF_LEN; j++) {
1047                 for(z = 0; z < /*xran_max_antenna_nr*/XRAN_MAX_ANTENNA_NR; z++) {
1048                     pFthTxBuffer[i][z][j]       = &(psIoCtrl->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
1049                     pFthTxPrbMapBuffer[i][z][j] = &(psIoCtrl->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
1050                     pFthRxBuffer[i][z][j]       = &(psIoCtrl->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
1051                     pFthRxPrbMapBuffer[i][z][j] = &(psIoCtrl->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
1052                     pFthRxRachBuffer[i][z][j]   = &(psIoCtrl->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
1053                     pFthRxRachBufferDecomp[i][z][j]   = &(psIoCtrl->sFHPrachRxBbuIoBufCtrlDecomp[j][i][z].sBufferList);                    
1054                     }
1055                 for(z = 0; z < XRAN_MAX_ANT_ARRAY_ELM_NR /*xran_max_ant_array_elm_nr && xran_max_ant_array_elm_nr*/; z++) {
1056                     pFthRxSrsBuffer[i][z][j] = &(psIoCtrl->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList);
1057                     pFthRxSrsPrbMapBuffer[i][z][j] = &(psIoCtrl->sFHSrsRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
1058             }
1059                 }
1060             }
1061
1062         if(psBbuIo->nInstanceHandle[o_xu_id] != NULL) {
1063             for(i = 0; i<nSectorNum; i++) {
1064                 xran_5g_fronthault_config(psBbuIo->nInstanceHandle[o_xu_id][i],
1065                         pFthTxBuffer[i], pFthTxPrbMapBuffer[i],
1066                         pFthRxBuffer[i], pFthRxPrbMapBuffer[i],
1067                         (void (*)(void *, xran_status_t))fh_rx_callback, &pFthRxBuffer[i][0]);
1068                 xran_5g_prach_req(psBbuIo->nInstanceHandle[o_xu_id][i], pFthRxRachBuffer[i],pFthRxRachBufferDecomp[i],
1069                         (void (*)(void *, xran_status_t))fh_rx_prach_callback, &pFthRxRachBuffer[i]);
1070                 }
1071
1072             /* add SRS callback here */
1073             for (i = 0; i<nSectorNum && xran_max_ant_array_elm_nr; i++) {
1074                 xran_5g_srs_req(psBbuIo->nInstanceHandle[o_xu_id][i], pFthRxSrsBuffer[i], pFthRxSrsPrbMapBuffer[i],
1075                     (void (*)(void *, xran_status_t))fh_srs_callback, pFthRxSrsBuffer[i]);
1076                 }
1077
1078             }
1079
1080         xran_register_cb_mbuf2ring(send_cp, send_up);
1081         xran_open(m_xranhandle, &m_xranConf);
1082     }
1083
1084     void Close()
1085     {
1086         if(m_xranhandle)
1087             xran_close(m_xranhandle);
1088     }
1089
1090     int Start()
1091     {
1092         if(m_xranhandle)
1093             return(xran_start(m_xranhandle));
1094         else
1095             return (-1);
1096     }
1097
1098     int Stop()
1099     {
1100         if(m_xranhandle)
1101             return(xran_stop(m_xranhandle));
1102         else
1103             return (-1);
1104     }
1105
1106     /* emulation of timer */
1107     void update_tti()
1108     {
1109         tti_ota_cb(nullptr, get_timer_ctx());
1110     }
1111
1112     void update_symbol_index()
1113     {
1114         int i;
1115         for (i=0; i<XRAN_PORTS_NUM; i++)
1116             xran_lib_ota_sym_idx[i]++;
1117         if((xran_lib_ota_sym_idx[0] % N_SYM_PER_SLOT) == 0) {
1118             update_tti();
1119             }
1120         for (i=0; i<XRAN_PORTS_NUM; i++)
1121         {
1122             xran_lib_ota_sym[i]++;
1123             if(xran_lib_ota_sym[i] >= N_SYM_PER_SLOT)
1124                 xran_lib_ota_sym[i] = 0;
1125         }
1126
1127     }
1128
1129     int apply_cpenable(bool flag)
1130     {
1131         struct xran_device_ctx *pCtx = xran_dev_get_ctx();
1132
1133         if(is_running())
1134             return (-1);
1135
1136         if(pCtx == nullptr)
1137             return (-1);
1138
1139         if(flag == true) {
1140             m_xranConf.enableCP = 1;
1141             pCtx->enableCP = 1;
1142             }
1143         else {
1144             m_xranConf.enableCP = 0;
1145             pCtx->enableCP = 0;
1146             }
1147
1148         return (0);
1149     }
1150
1151
1152     int get_slot_config(const std::string &cfgname, struct xran_frame_config *pCfg)
1153     {
1154         int numcfg, i, j;
1155         std::vector<int> slotcfg;
1156
1157         numcfg = get_globalcfg<int>(cfgname, "period");
1158         pCfg->nTddPeriod = numcfg;
1159         for(i=0; i < numcfg; i++) {
1160             std::stringstream slotcfgname;
1161
1162             slotcfgname << "slot" << i;
1163             std::vector<int> slotcfg = get_globalcfg_array<int>(cfgname, slotcfgname.str());
1164
1165             for(j=0; j < slotcfg.size(); j++)
1166                 pCfg->sSlotConfig[i].nSymbolType[j] = slotcfg[j];
1167             pCfg->sSlotConfig[i].reserved[0] = 0; pCfg->sSlotConfig[i].reserved[1] = 0;
1168             }
1169
1170         return (numcfg);
1171     }
1172
1173     int get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, bool nSub6)
1174     {
1175         if(nNumerology > 3)
1176             return (-1);
1177
1178         if(nSub6) {
1179             if (nNumerology < 3) {
1180                 /* F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB */
1181                 switch(nBandwidth) {
1182                     case PHY_BW_5MHZ:   return(nNumRbsPerSymF1[nNumerology][0]);
1183                     case PHY_BW_10MHZ:  return(nNumRbsPerSymF1[nNumerology][1]);
1184                     case PHY_BW_15MHZ:  return(nNumRbsPerSymF1[nNumerology][2]);
1185                     case PHY_BW_20MHZ:  return(nNumRbsPerSymF1[nNumerology][3]);
1186                     case PHY_BW_25MHZ:  return(nNumRbsPerSymF1[nNumerology][4]);
1187                     case PHY_BW_30MHZ:  return(nNumRbsPerSymF1[nNumerology][5]);
1188                     case PHY_BW_40MHZ:  return(nNumRbsPerSymF1[nNumerology][6]);
1189                     case PHY_BW_50MHZ:  return(nNumRbsPerSymF1[nNumerology][7]);
1190                     case PHY_BW_60MHZ:  return(nNumRbsPerSymF1[nNumerology][8]);
1191                     case PHY_BW_70MHZ:  return(nNumRbsPerSymF1[nNumerology][9]);
1192                     case PHY_BW_80MHZ:  return(nNumRbsPerSymF1[nNumerology][10]);
1193                     case PHY_BW_90MHZ:  return(nNumRbsPerSymF1[nNumerology][11]);
1194                     case PHY_BW_100MHZ: return(nNumRbsPerSymF1[nNumerology][12]);
1195                 }
1196             }
1197         }
1198         else { /* if(nSub6) */
1199             if((nNumerology >= 2) && (nNumerology <= 3)) {
1200                 nNumerology -= 2;
1201                 /* F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB */
1202                 switch(nBandwidth) {
1203                     case PHY_BW_50MHZ:  return(nNumRbsPerSymF2[nNumerology][0]); break;
1204                     case PHY_BW_100MHZ: return(nNumRbsPerSymF2[nNumerology][1]); break;
1205                     case PHY_BW_200MHZ: return(nNumRbsPerSymF2[nNumerology][2]); break;
1206                     case PHY_BW_400MHZ: return(nNumRbsPerSymF2[nNumerology][3]); break;
1207                 }
1208             }
1209         }
1210
1211         return(-1);
1212     }
1213
1214     void *get_xranhandle()  { return(m_xranhandle); }
1215     void *get_timer_ctx()   { return((void *)xran_dev_get_ctx()); }
1216
1217     int get_symbol_index()  { return (xran_lib_ota_sym[0]); }
1218
1219     bool is_running()       { return((xran_get_if_state() == XRAN_RUNNING)?true:false); }
1220
1221     enum xran_category get_rucategory()    { return(m_xranConf.ru_conf.xranCat); }
1222
1223     int get_numerology()    { return(m_xranConf.frame_conf.nNumerology); }
1224     int get_duplextype()    { return(m_xranConf.frame_conf.nFrameDuplexType); }
1225     int get_num_cc()        { return(m_xranConf.nCC); }
1226     int get_num_eaxc()      { return(m_xranConf.neAxc); }
1227     int get_num_eaxc_ul()   { return(m_xranConf.neAxcUl); }
1228     int get_num_dlrbs()     { return(m_xranConf.nDLRBs); }
1229     int get_num_ulrbs()     { return(m_xranConf.nULRBs); }
1230     int get_num_antelmtrx() { return(m_xranConf.nAntElmTRx); }
1231
1232     bool is_cpenable()      { return(m_xranConf.enableCP); };
1233     bool is_prachenable()   { return(m_xranConf.prachEnable); };
1234     bool is_dynamicsection() { return(m_xranConf.DynamicSectionEna?true:false); }
1235
1236     void get_cfg_prach(struct xran_prach_config *pCfg)
1237     {
1238         if(pCfg)
1239             memcpy(pCfg, &m_xranConf.prach_conf, sizeof(struct xran_prach_config));
1240     }
1241
1242     void get_cfg_frame(struct xran_frame_config *pCfg)
1243     {
1244         if(pCfg)
1245             memcpy(pCfg, &m_xranConf.frame_conf, sizeof(struct xran_frame_config));
1246     }
1247
1248     void get_cfg_ru(struct xran_ru_config *pCfg)
1249     {
1250         if(pCfg)
1251             memcpy(pCfg, &m_xranConf.ru_conf, sizeof(struct xran_ru_config));
1252     }
1253
1254     void get_cfg_fh(struct xran_fh_config *pCfg)
1255     {
1256         if(pCfg)
1257             memcpy(pCfg, &m_xranConf, sizeof(struct xran_fh_config));
1258     }
1259
1260 };
1261
1262
1263 /* external declaration for the instance */
1264 extern xranLibWraper *xranlib;
1265
1266
1267 #endif //XRAN_LIB_WRAP_HPP