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