Update to odulow per maintenance bronze
[o-du/phy.git] / fhi_lib / test / test_xran / c_plane_tests.cc
1 /******************************************************************************
2 *
3 *   Copyright (c) 2019 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18
19
20 #include "common.hpp"
21 #include "xran_lib_wrap.hpp"
22 #include "xran_common.h"
23 #include "xran_fh_o_du.h"
24 #include "ethdi.h"
25 #include "ethernet.h"
26 #include "xran_transport.h"
27 #include "xran_cp_api.h"
28
29 #include <stdint.h>
30
31 #define DELETE_ARRAY(x)     { if(x) { delete[] x; x = nullptr; } }
32
33 const std::string module_name = "C-Plane";
34
35 const uint8_t m_bitmask[] = { 0x00, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
36
37 extern "C"
38 {
39
40 /* wrapper function for performace tests to reset mbuf */
41 int xran_ut_prepare_cp(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params,
42                         uint8_t cc_id, uint8_t ant_id, uint8_t seq_id)
43 {
44     rte_pktmbuf_reset(mbuf);
45     return(xran_prepare_ctrl_pkt(mbuf, params, cc_id, ant_id, seq_id));
46 }
47
48
49 void cput_fh_rx_callback(void *pCallbackTag, xran_status_t status)
50 {
51     return;
52 }
53
54 void cput_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
55 {
56     rte_pause();
57 }
58
59 } /* extern "C" */
60
61
62
63 class C_plane: public KernelTests
64 {
65 private:
66     struct xran_section_gen_info *m_pSectGenInfo = NULL;
67     struct xran_section_gen_info *m_pSectResult = NULL;
68
69     struct sectinfo {
70         uint16_t    sectionId;
71         uint8_t     rb;
72         uint8_t     symInc;
73         uint16_t    startPrbc;
74         uint16_t    numPrbc;
75         uint16_t    reMask;
76         uint8_t     numSymbol;
77         uint16_t    beamId;
78         int         freqOffset;
79         std::vector<uint8_t> exts;
80         };
81
82     struct extcfginfo {
83         int         type;
84         std::string name;
85         union {
86             struct xran_sectionext1_info ext1;
87             struct xran_sectionext2_info ext2;
88             struct xran_sectionext3_info ext3;
89             struct xran_sectionext4_info ext4;
90             struct xran_sectionext5_info ext5;
91             } u;
92         };
93
94 protected:
95     int m_maxSections = 8;  /*  not used */
96     int m_numSections;
97
98     struct rte_mbuf *m_pTestBuffer;
99
100     struct xran_cp_gen_params m_params;
101     struct xran_recv_packet_info m_pktInfo;
102     struct xran_cp_gen_params m_result;
103
104     struct xran_sectionext1_info m_temp_ext1[XRAN_MAX_PRBS];
105
106     uint8_t     m_dir;
107     std::string m_dirStr;
108     uint8_t     m_sectionType;
109
110     uint8_t     m_ccId, m_antId;
111     uint8_t     m_seqId;
112     uint8_t     m_frameId, m_subframeId, m_slotId;
113     uint8_t     m_symStart;
114
115     uint8_t     m_iqWidth, m_compMethod;
116     uint8_t     m_filterIndex;
117     uint16_t    m_timeOffset;
118     uint8_t     m_fftSize;
119     uint8_t     m_scs;
120     uint16_t    m_cpLength;
121
122     struct sectinfo     *m_sections;
123     struct extcfginfo   *m_extcfgs;
124     int                 m_nextcfgs;
125
126     uint16_t  m_ext1_dst_len = 0;
127     int8_t   *m_p_ext1_dst   = nullptr;
128     int16_t  *m_p_bfw_iq_src = nullptr;
129
130     struct xran_sectionext1_info m_ext1;
131
132     int16_t m_bfwIQ[XRAN_MAX_BFW_N*2];
133
134
135     void SetUp() override
136     {
137         int i, j;
138
139         init_test("C_Plane");
140
141         m_dirStr        = get_input_parameter<std::string>("direction");
142
143         if(!m_dirStr.compare("DL")) m_dir = XRAN_DIR_DL;
144         else if(!m_dirStr.compare("UL")) m_dir = XRAN_DIR_UL;
145         else FAIL() << "Invalid direction!";
146
147         m_sectionType   = get_input_parameter<uint8_t>("section_type");
148         m_ccId          = get_input_parameter<uint8_t>("cc_id");
149         m_antId         = get_input_parameter<uint8_t>("ant_id");
150         m_seqId         = get_input_parameter<uint16_t>("seq_id");
151
152         m_frameId       = get_input_parameter<uint8_t>("frame_id");
153         m_subframeId    = get_input_parameter<uint8_t>("subframe_id");
154         m_slotId        = get_input_parameter<uint8_t>("slot_id");
155         m_symStart      = get_input_parameter<uint8_t>("symbol_start");
156         m_compMethod    = get_input_parameter<uint8_t>("comp_method");
157         m_iqWidth       = get_input_parameter<uint8_t>("iq_width");
158
159         switch(m_sectionType) {
160             case XRAN_CP_SECTIONTYPE_1:
161                 m_filterIndex = XRAN_FILTERINDEX_STANDARD;
162                 break;
163
164             case XRAN_CP_SECTIONTYPE_3:
165                 m_filterIndex   = get_input_parameter<uint8_t>("filter_index");
166                 m_timeOffset    = get_input_parameter<uint16_t>("time_offset");
167                 m_fftSize       = get_input_parameter<uint8_t>("fft_size");
168                 m_scs           = get_input_parameter<uint8_t>("scs");
169                 m_cpLength      = get_input_parameter<uint16_t>("cp_length");
170                 break;
171
172             default:
173                 FAIL() << "Invalid Section Type - " << m_sectionType << std::endl;
174             }
175
176         m_numSections   = get_input_subsection_size("sections");
177         ASSERT_FALSE(m_numSections == 0);
178
179         m_sections = new struct sectinfo [m_numSections];
180         for(i=0; i<m_numSections; i++) {
181             m_sections[i].sectionId = get_input_parameter<uint16_t>("sections", i, "sectionId");
182             m_sections[i].rb        = get_input_parameter<uint16_t>("sections", i, "rb");
183             m_sections[i].symInc    = get_input_parameter<uint16_t>("sections", i, "symInc");
184             m_sections[i].startPrbc = get_input_parameter<uint16_t>("sections", i, "startPrbc");
185             m_sections[i].numPrbc   = get_input_parameter<uint16_t>("sections", i, "numPrbc");
186             m_sections[i].reMask    = get_input_parameter<uint16_t>("sections", i, "reMask");
187             m_sections[i].numSymbol = get_input_parameter<uint16_t>("sections", i, "numSymbol");
188             m_sections[i].beamId    = get_input_parameter<uint16_t>("sections", i, "beamId");
189
190             switch(m_sectionType) {
191                 case XRAN_CP_SECTIONTYPE_3:
192                     m_sections[i].freqOffset    = get_input_parameter<uint16_t>("sections", i, "freqOffset");
193                     break;
194                 }
195
196             m_sections[i].exts      = get_input_parameter<std::vector<uint8_t>>("sections", i, "exts");
197             }
198
199         /* reading configurations of section extension */
200         m_nextcfgs = get_input_subsection_size("extensions");
201         if(m_nextcfgs) {
202             m_extcfgs = new struct extcfginfo [m_nextcfgs];
203
204             for(i=0; i < m_nextcfgs; i++) {
205                 std::vector<uint16_t> csf;
206                 std::vector<uint16_t> mcScaleReMask;
207                 std::vector<uint16_t> mcScaleOffset;
208
209                 m_extcfgs[i].type   = get_input_parameter<int>("extensions", i, "type");
210                 m_extcfgs[i].name   = get_input_parameter<std::string>("extensions", i, "name");
211
212                 switch(m_extcfgs[i].type) {
213                     case XRAN_CP_SECTIONEXTCMD_1:
214                         /* Skip section extension type 1 since it has separate function */
215                         std::cout << "### Skip Extension 1 configuration !!\n" << std::endl;
216                         continue;
217
218                     case XRAN_CP_SECTIONEXTCMD_2:
219                         m_extcfgs[i].u.ext2.bfAzPtWidth  = get_input_parameter<uint8_t>("extensions", i, "bfAzPtWidth") & 0x7;
220                         m_extcfgs[i].u.ext2.bfAzPt       = get_input_parameter<uint8_t>("extensions", i, "bfAzPt") & 0xf;
221                         m_extcfgs[i].u.ext2.bfZePtWidth  = get_input_parameter<uint8_t>("extensions", i, "bfZePtWidth") & 0x7;
222                         m_extcfgs[i].u.ext2.bfZePt       = get_input_parameter<uint8_t>("extensions", i, "bfZePt") & 0xf;
223                         m_extcfgs[i].u.ext2.bfAz3ddWidth = get_input_parameter<uint8_t>("extensions", i, "bfAz3ddWidth") & 0x7;
224                         m_extcfgs[i].u.ext2.bfAz3dd      = get_input_parameter<uint8_t>("extensions", i, "bfAz3dd") & 0xf;
225                         m_extcfgs[i].u.ext2.bfZe3ddWidth = get_input_parameter<uint8_t>("extensions", i, "bfZe3ddWidth") & 0x7;
226                         m_extcfgs[i].u.ext2.bfZe3dd      = get_input_parameter<uint8_t>("extensions", i, "bfZe3dd") & 0xf;
227                         m_extcfgs[i].u.ext2.bfAzSI       = get_input_parameter<uint8_t>("extensions", i, "bfAzSI") & 0x7;
228                         m_extcfgs[i].u.ext2.bfZeSI       = get_input_parameter<uint8_t>("extensions", i, "bfZeSI") & 0x7;
229                         break;
230
231                     case XRAN_CP_SECTIONEXTCMD_3:
232                         m_extcfgs[i].u.ext3.codebookIdx  = get_input_parameter<uint8_t> ("extensions", i, "codebookIdx");
233                         m_extcfgs[i].u.ext3.layerId      = get_input_parameter<uint8_t> ("extensions", i, "layerId") & 0xf;
234                         m_extcfgs[i].u.ext3.numLayers    = get_input_parameter<uint8_t> ("extensions", i, "numLayers") & 0xf;
235                         m_extcfgs[i].u.ext3.txScheme     = get_input_parameter<uint8_t> ("extensions", i, "txScheme") & 0xf;
236                         m_extcfgs[i].u.ext3.crsReMask    = get_input_parameter<uint16_t>("extensions", i, "crsReMask") & 0xfff;
237                         m_extcfgs[i].u.ext3.crsShift     = get_input_parameter<uint8_t> ("extensions", i, "crsShift") & 0x1;
238                         m_extcfgs[i].u.ext3.crsSymNum    = get_input_parameter<uint8_t> ("extensions", i, "crsSymNum") & 0xf;
239                         m_extcfgs[i].u.ext3.numAntPort   = get_input_parameter<uint16_t>("extensions", i, "numAntPort");
240                         m_extcfgs[i].u.ext3.beamIdAP1    = get_input_parameter<uint16_t>("extensions", i, "beamIdAP1");
241                         m_extcfgs[i].u.ext3.beamIdAP2    = get_input_parameter<uint16_t>("extensions", i, "beamIdAP2");
242                         m_extcfgs[i].u.ext3.beamIdAP3    = get_input_parameter<uint16_t>("extensions", i, "beamIdAP3");
243                         break;
244
245                     case XRAN_CP_SECTIONEXTCMD_4:
246                         m_extcfgs[i].u.ext4.csf          = get_input_parameter<uint8_t> ("extensions", i, "csf") & 0xf;
247                         m_extcfgs[i].u.ext4.modCompScaler= get_input_parameter<uint16_t>("extensions", i, "modCompScaler") & 0x7fff;
248                         break;
249
250                     case XRAN_CP_SECTIONEXTCMD_5:
251                         m_extcfgs[i].u.ext5.num_sets     = get_input_parameter<uint8_t>("extensions", i, "num_sets");
252                         if(m_extcfgs[i].u.ext5.num_sets > XRAN_MAX_MODCOMP_ADDPARMS)
253                             FAIL() << "Invalid number of sets in extension 5!";
254
255                         csf = get_input_parameter<std::vector<uint16_t>>("extensions", i, "csf");
256                         mcScaleReMask = get_input_parameter<std::vector<uint16_t>>("extensions", i, "mcScaleReMask");
257                         mcScaleOffset = get_input_parameter<std::vector<uint16_t>>("extensions", i, "mcScaleOffset");
258
259                         if(csf.size() != m_extcfgs[i].u.ext5.num_sets
260                                 || mcScaleReMask.size() != m_extcfgs[i].u.ext5.num_sets
261                                 || mcScaleOffset.size() != m_extcfgs[i].u.ext5.num_sets)
262                             FAIL() << "Invalid configuration in extension 5 - different size!";
263
264                         for(int ii=0; ii < m_extcfgs[i].u.ext5.num_sets; ii++) {
265                             m_extcfgs[i].u.ext5.mc[ii].csf           = csf[ii];
266                             m_extcfgs[i].u.ext5.mc[ii].mcScaleReMask = mcScaleReMask[ii];
267                             m_extcfgs[i].u.ext5.mc[ii].mcScaleOffset = mcScaleOffset[ii];
268                             }
269                         break;
270
271                     default:
272                        FAIL() << "Invalid Section Type Extension - " << m_extcfgs[i].type << std::endl;
273                        continue;
274                     } /* switch(m_extcfgs[i].type) */
275                 } /* for(i=0; i < m_nextcfgs; i++) */
276             }
277         else {
278             m_extcfgs = nullptr;
279             }
280
281         /* allocate and prepare required data storage */
282         m_pSectGenInfo      = new struct xran_section_gen_info [m_numSections];
283         ASSERT_NE(m_pSectGenInfo, nullptr);
284         m_params.sections   = m_pSectGenInfo;
285
286         m_pSectResult       = new struct xran_section_gen_info [m_numSections];
287         ASSERT_NE(m_pSectResult, nullptr);
288         m_result.sections   = m_pSectResult;
289
290         m_ext1_dst_len      = 9600;
291         m_p_ext1_dst        = new int8_t [m_ext1_dst_len];
292         m_p_bfw_iq_src      = new int16_t [9600/2];
293
294         /* allocating an mbuf for packet generatrion */
295         m_pTestBuffer       = xran_ethdi_mbuf_alloc();
296         ASSERT_FALSE(m_pTestBuffer == nullptr);
297     }
298
299     void TearDown() override
300     {
301         if(m_pTestBuffer != nullptr) {
302             rte_pktmbuf_free(m_pTestBuffer);
303             m_pTestBuffer = nullptr;
304             }
305
306         DELETE_ARRAY(m_extcfgs);
307         DELETE_ARRAY(m_sections);
308         DELETE_ARRAY(m_p_bfw_iq_src);
309         DELETE_ARRAY(m_p_ext1_dst);
310         DELETE_ARRAY(m_pSectGenInfo);
311         DELETE_ARRAY(m_pSectResult);
312     }
313
314     int prepare_sections(void);
315     int prepare_extensions(void);
316     void verify_sections(void);
317
318 };
319
320
321
322 int C_plane::prepare_extensions()
323 {
324     int i, numext, sect_num;
325     int ext_id;
326
327     for(sect_num=0; sect_num < m_numSections; sect_num++) {
328         numext = 0;
329
330         for(i=0; i < m_sections[sect_num].exts.size(); i++) {
331
332             ext_id = m_sections[sect_num].exts[i];
333             if(ext_id >= m_nextcfgs) {
334                 std::cout << "Invalid section extension configuration index - " << ext_id << " [max " << m_nextcfgs-1 << "]" << std::endl;
335                 return (-1);
336                 }
337
338             switch(m_extcfgs[ext_id].type) {
339                 case XRAN_CP_SECTIONEXTCMD_1:
340                     std::cout << "Skip Extension 1 !!" << std::endl;
341                     continue;
342                 case XRAN_CP_SECTIONEXTCMD_2:
343                     m_params.sections[sect_num].exData[numext].len  = sizeof(m_extcfgs[ext_id].u.ext2);
344                     m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext2;
345                     break;
346                 case XRAN_CP_SECTIONEXTCMD_3:
347                     m_params.sections[sect_num].exData[numext].len  = sizeof(m_extcfgs[ext_id].u.ext3);
348                     m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext3;
349                     break;
350                 case XRAN_CP_SECTIONEXTCMD_4:
351                     m_params.sections[sect_num].exData[numext].len  = sizeof(m_extcfgs[ext_id].u.ext4);
352                     m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext4;
353                     break;
354                 case XRAN_CP_SECTIONEXTCMD_5:
355                     m_params.sections[sect_num].exData[numext].len  = sizeof(m_extcfgs[ext_id].u.ext5);
356                     m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext5;
357                     break;
358                 default:
359                     std::cout << "Invalid Section Extension Type - " << (int)m_extcfgs[ext_id].type << std::endl;
360                     return (-1);
361                 } /* switch(m_extcfgs[ext_id].type) */
362
363             m_params.sections[sect_num].exData[numext].type = m_extcfgs[ext_id].type;
364             numext++;
365             } /* for(i=0; i < m_sections[sect_num].exts.size(); i++) */
366
367         if(numext) {
368             m_params.sections[sect_num].exDataSize  = numext;
369             m_params.sections[sect_num].info.ef     = 1;
370             }
371         else {
372             m_params.sections[sect_num].exDataSize  = 0;
373             m_params.sections[sect_num].info.ef     = 0;
374             }
375         } /* for(sect_num=0; sect_num < m_numSections; sect_num++) */
376
377     return (0);
378 }
379
380
381 int C_plane::prepare_sections(void)
382 {
383   int numsec;
384
385
386     /* Preparing input data for packet generation */
387     m_params.dir                  = m_dir;
388     m_params.sectionType          = m_sectionType;
389
390     m_params.hdr.filterIdx        = m_filterIndex;
391     m_params.hdr.frameId          = m_frameId;
392     m_params.hdr.subframeId       = m_subframeId;
393     m_params.hdr.slotId           = m_slotId;
394     m_params.hdr.startSymId       = m_symStart;
395     m_params.hdr.iqWidth          = XRAN_CONVERT_IQWIDTH(m_iqWidth);
396     m_params.hdr.compMeth         = m_compMethod;
397
398     switch(m_sectionType) {
399         case XRAN_CP_SECTIONTYPE_1:
400             break;
401
402         case XRAN_CP_SECTIONTYPE_3:
403             m_params.hdr.timeOffset   = m_timeOffset;
404             m_params.hdr.fftSize      = m_fftSize;
405             m_params.hdr.scs          = m_scs;
406             m_params.hdr.cpLength     = m_cpLength;
407             break;
408
409         default:
410             return (-1);
411         }
412
413     for(numsec=0; numsec < m_numSections; numsec++) {
414         m_params.sections[numsec].info.type         = m_params.sectionType;       // for database
415         m_params.sections[numsec].info.startSymId   = m_params.hdr.startSymId;    // for database
416         m_params.sections[numsec].info.iqWidth      = m_params.hdr.iqWidth;       // for database
417         m_params.sections[numsec].info.compMeth     = m_params.hdr.compMeth;      // for database
418         m_params.sections[numsec].info.id           = m_sections[numsec].sectionId;
419         m_params.sections[numsec].info.rb           = m_sections[numsec].rb;
420         m_params.sections[numsec].info.symInc       = m_sections[numsec].symInc;
421         m_params.sections[numsec].info.startPrbc    = m_sections[numsec].startPrbc;
422         m_params.sections[numsec].info.numPrbc      = m_sections[numsec].numPrbc;
423         m_params.sections[numsec].info.reMask       = m_sections[numsec].reMask;
424         m_params.sections[numsec].info.numSymbol    = m_sections[numsec].numSymbol;
425         m_params.sections[numsec].info.beamId       = m_sections[numsec].beamId;
426
427         switch(m_sectionType) {
428             case XRAN_CP_SECTIONTYPE_1:
429                 break;
430
431             case XRAN_CP_SECTIONTYPE_3:
432                 m_params.sections[numsec].info.freqOffset   = m_sections[numsec].freqOffset;
433                 break;
434
435             default:
436                 return (-1);
437             }
438         }
439
440     m_params.numSections        = numsec;
441
442     return (0);
443 }
444
445
446 void C_plane::verify_sections(void)
447 {
448   int i,j;
449
450     /* Verify the result */
451     EXPECT_TRUE(m_result.dir            == m_params.dir);
452     EXPECT_TRUE(m_result.sectionType    == m_params.sectionType);
453
454     EXPECT_TRUE(m_result.hdr.filterIdx  == m_params.hdr.filterIdx);
455     EXPECT_TRUE(m_result.hdr.frameId    == m_params.hdr.frameId);
456     EXPECT_TRUE(m_result.hdr.subframeId == m_params.hdr.subframeId);
457     EXPECT_TRUE(m_result.hdr.slotId     == m_params.hdr.slotId);
458     EXPECT_TRUE(m_result.hdr.startSymId == m_params.hdr.startSymId);
459     EXPECT_TRUE(m_result.hdr.iqWidth    == m_params.hdr.iqWidth);
460     EXPECT_TRUE(m_result.hdr.compMeth   == m_params.hdr.compMeth);
461
462     switch(m_sectionType) {
463         case XRAN_CP_SECTIONTYPE_1:
464             break;
465
466         case XRAN_CP_SECTIONTYPE_3:
467             EXPECT_TRUE(m_result.hdr.fftSize    == m_params.hdr.fftSize);
468             EXPECT_TRUE(m_result.hdr.scs        == m_params.hdr.scs);
469             EXPECT_TRUE(m_result.hdr.cpLength   == m_params.hdr.cpLength);
470             break;
471
472         default:
473             FAIL() << "Invalid Section Type - " << m_sectionType << "\n";
474         }
475
476     ASSERT_TRUE(m_result.numSections    == m_params.numSections);
477     for(i=0; i < m_result.numSections; i++) {
478         EXPECT_TRUE(m_result.sections[i].info.id        == m_params.sections[i].info.id);
479         EXPECT_TRUE(m_result.sections[i].info.rb        == m_params.sections[i].info.rb);
480         EXPECT_TRUE(m_result.sections[i].info.symInc    == m_params.sections[i].info.symInc);
481         EXPECT_TRUE(m_result.sections[i].info.startPrbc == m_params.sections[i].info.startPrbc);
482         if(m_params.sections[i].info.numPrbc > 255)
483             EXPECT_TRUE(m_result.sections[i].info.numPrbc == 0);
484         else
485             EXPECT_TRUE(m_result.sections[i].info.numPrbc == m_params.sections[i].info.numPrbc);
486         EXPECT_TRUE(m_result.sections[i].info.numSymbol == m_params.sections[i].info.numSymbol);
487         EXPECT_TRUE(m_result.sections[i].info.reMask    == m_params.sections[i].info.reMask);
488         EXPECT_TRUE(m_result.sections[i].info.beamId    == m_params.sections[i].info.beamId);
489         EXPECT_TRUE(m_result.sections[i].info.ef        == m_params.sections[i].info.ef);
490
491         switch(m_sectionType) {
492             case XRAN_CP_SECTIONTYPE_1:
493                 break;
494
495             case XRAN_CP_SECTIONTYPE_3:
496                 EXPECT_TRUE(m_result.sections[i].info.freqOffset  == m_params.sections[i].info.freqOffset);
497                 break;
498
499             default:
500                 FAIL() << "Invalid Section Type - " << m_sectionType << "\n";
501             }
502
503         if(m_params.sections[i].info.ef) {
504             //printf("[%d] %d ==  %d\n",i,  m_result.sections[i].exDataSize, m_params.sections[i].exDataSize);
505             EXPECT_TRUE(m_result.sections[i].exDataSize == m_params.sections[i].exDataSize);
506
507             for(j=0; j < m_params.sections[i].exDataSize; j++) {
508                 EXPECT_TRUE(m_result.sections[i].exData[j].type == m_params.sections[i].exData[j].type);
509
510                 switch(m_params.sections[i].exData[j].type) {
511                     case XRAN_CP_SECTIONEXTCMD_1:
512                         {
513                         struct xran_sectionext1_info *ext1_params, *ext1_result;
514                         int iq_size, parm_size, N;
515
516                         ext1_params = (struct xran_sectionext1_info *)m_params.sections[i].exData[j].data;
517                         ext1_result = (struct xran_sectionext1_info *)m_result.sections[i].exData[j].data;
518
519                         EXPECT_TRUE(ext1_result->bfwiqWidth  == ext1_params->bfwiqWidth);
520                         EXPECT_TRUE(ext1_result->bfwCompMeth == ext1_params->bfwCompMeth);
521
522                         N = ext1_params->bfwNumber;
523                         switch(ext1_params->bfwCompMeth) {
524                             case XRAN_BFWCOMPMETHOD_BLKFLOAT:
525                                 //printf("[%d, %d] %d ==  %d\n",i, j, ext1_result->bfwCompParam.exponent, ext1_params->bfwCompParam.exponent);
526                                 EXPECT_TRUE(ext1_result->bfwCompParam.exponent == ext1_params->bfwCompParam.exponent);
527                                 break;
528
529                             case XRAN_BFWCOMPMETHOD_BLKSCALE:
530                                 EXPECT_TRUE(ext1_result->bfwCompParam.blockScaler == ext1_params->bfwCompParam.blockScaler);
531                                 break;
532
533                             case XRAN_BFWCOMPMETHOD_ULAW:
534                                 EXPECT_TRUE(ext1_result->bfwCompParam.compBitWidthShift == ext1_params->bfwCompParam.compBitWidthShift);
535                                 break;
536
537                             case XRAN_BFWCOMPMETHOD_BEAMSPACE:
538                                 parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8;
539                                 EXPECT_TRUE(std::memcmp(ext1_result->bfwCompParam.activeBeamspaceCoeffMask, ext1_params->bfwCompParam.activeBeamspaceCoeffMask, parm_size));
540                                 break;
541                             }
542
543                         /* Get the number of BF weights */
544                         iq_size = N*ext1_params->bfwiqWidth*2;  // total in bits
545                         parm_size = iq_size>>3;                 // total in bytes (/8)
546                         if(iq_size%8) parm_size++;              // round up
547                         EXPECT_FALSE(std::memcmp(ext1_result->p_bfwIQ, ext1_params->p_bfwIQ, parm_size));
548                         }
549                         break;
550
551                     case XRAN_CP_SECTIONEXTCMD_2:
552                         {
553                         struct xran_sectionext2_info *ext2_params, *ext2_result;
554
555                         ext2_params = (struct xran_sectionext2_info *)m_params.sections[i].exData[j].data;
556                         ext2_result = (struct xran_sectionext2_info *)m_result.sections[i].exData[j].data;
557
558                         if(ext2_params->bfAzPtWidth) {
559                             EXPECT_TRUE(ext2_result->bfAzPtWidth    == ext2_params->bfAzPtWidth);
560                             EXPECT_TRUE(ext2_result->bfAzPt         == ext2_params->bfAzPt);
561                             }
562
563                         if(ext2_params->bfZePtWidth) {
564                             EXPECT_TRUE(ext2_result->bfZePtWidth    == ext2_params->bfZePtWidth);
565                             EXPECT_TRUE(ext2_result->bfZePt         == ext2_params->bfZePt);
566                             }
567                         if(ext2_params->bfAz3ddWidth) {
568                             EXPECT_TRUE(ext2_result->bfAz3ddWidth   == ext2_params->bfAz3ddWidth);
569                             EXPECT_TRUE(ext2_result->bfAz3dd        == ext2_params->bfAz3dd);
570                             }
571                         if(ext2_params->bfZe3ddWidth) {
572                             EXPECT_TRUE(ext2_result->bfZe3ddWidth   == ext2_params->bfZe3ddWidth);
573                             EXPECT_TRUE(ext2_result->bfZe3dd        == ext2_params->bfZe3dd);
574                             }
575
576                         EXPECT_TRUE(ext2_result->bfAzSI == ext2_params->bfAzSI);
577                         EXPECT_TRUE(ext2_result->bfZeSI == ext2_params->bfZeSI);
578                         }
579                         break;
580
581                     case XRAN_CP_SECTIONEXTCMD_3:
582                         {
583                         struct xran_sectionext3_info *ext3_params, *ext3_result;
584
585                         ext3_params = (struct xran_sectionext3_info *)m_params.sections[i].exData[j].data;
586                         ext3_result = (struct xran_sectionext3_info *)m_result.sections[i].exData[j].data;
587
588                         EXPECT_TRUE(ext3_result->layerId    == ext3_params->layerId);
589                         EXPECT_TRUE(ext3_result->codebookIdx== ext3_params->codebookIdx);
590                         EXPECT_TRUE(ext3_result->numLayers  == ext3_params->numLayers);
591
592                         if(ext3_params->layerId == XRAN_LAYERID_0
593                             || ext3_params->layerId == XRAN_LAYERID_TXD) {   /* first data layer */
594                             EXPECT_TRUE(ext3_result->txScheme   == ext3_params->txScheme);
595                             EXPECT_TRUE(ext3_result->crsReMask  == ext3_params->crsReMask);
596                             EXPECT_TRUE(ext3_result->crsShift   == ext3_params->crsShift);
597                             EXPECT_TRUE(ext3_result->crsSymNum  == ext3_params->crsSymNum);
598
599                             EXPECT_TRUE(ext3_result->numAntPort == ext3_params->numAntPort);
600
601                             EXPECT_TRUE(ext3_result->beamIdAP1  == ext3_params->beamIdAP1);
602
603                             if(ext3_params->numAntPort == 4) {
604                                 EXPECT_TRUE(ext3_result->beamIdAP2  == ext3_params->beamIdAP2);
605                                 EXPECT_TRUE(ext3_result->beamIdAP3  == ext3_params->beamIdAP3);
606                                 }
607                             }
608                         }
609                         break;
610
611                     case XRAN_CP_SECTIONEXTCMD_4:
612                         {
613                         struct xran_sectionext4_info *ext4_params, *ext4_result;
614
615                         ext4_params = (struct xran_sectionext4_info *)m_params.sections[i].exData[j].data;
616                         ext4_result = (struct xran_sectionext4_info *)m_result.sections[i].exData[j].data;
617
618                         EXPECT_TRUE(ext4_result->csf            == ext4_params->csf);
619                         EXPECT_TRUE(ext4_result->modCompScaler  == ext4_params->modCompScaler);
620                         }
621                         break;
622
623                     case XRAN_CP_SECTIONEXTCMD_5:
624                         {
625                         struct xran_sectionext5_info *ext5_params, *ext5_result;
626                         int idx;
627
628                         ext5_params = (struct xran_sectionext5_info *)m_params.sections[i].exData[j].data;
629                         ext5_result = (struct xran_sectionext5_info *)m_result.sections[i].exData[j].data;
630
631                         EXPECT_TRUE(ext5_result->num_sets == ext5_params->num_sets);
632                         for(idx=0; idx < ext5_params->num_sets; idx++) {
633                             EXPECT_TRUE(ext5_result->mc[idx].csf == ext5_params->mc[idx].csf);
634                             EXPECT_TRUE(ext5_result->mc[idx].mcScaleReMask == ext5_params->mc[idx].mcScaleReMask);
635                             EXPECT_TRUE(ext5_result->mc[idx].mcScaleOffset == ext5_params->mc[idx].mcScaleOffset);
636                             }
637                         }
638                         break;
639                     }
640                 }
641             }
642         }
643
644     return;
645 }
646
647
648 /***************************************************************************
649  * Functional Test cases
650  ***************************************************************************/
651
652 TEST_P(C_plane, Section_Ext1)
653 {
654     int i = 0, idRb;
655     int16_t *ptr = NULL;
656     int32_t nRbs = 36;
657     int32_t nAntElm = 64;
658     int8_t  iqWidth = 16;
659     int8_t  compMethod = XRAN_COMPMETHOD_NONE;
660     int8_t  *p_ext1_dst  = NULL;
661     int8_t  *bfw_payload = NULL;
662     int32_t expected_len = (3+1)*nRbs + nAntElm*nRbs*4;
663
664     int16_t  ext_len       = 9600;
665     int16_t  ext_sec_total = 0;
666     int8_t * ext_buf       = nullptr;
667     int8_t * ext_buf_init  = nullptr;
668
669     struct xran_section_gen_info* loc_pSectGenInfo = m_params.sections;
670     struct xran_sectionext1_info m_prep_ext1;
671     struct xran_cp_radioapp_section_ext1 *p_ext1;
672     struct rte_mbuf_ext_shared_info  share_data;
673     struct rte_mbuf *mbuf = NULL;
674
675     /* Configure section information */
676     if(prepare_sections() < 0) {
677         FAIL() << "Invalid Section configuration\n";
678     }
679
680     if(prepare_extensions() < 0) {
681         FAIL() << "Invalid Section extension configuration\n";
682     }
683
684     if(loc_pSectGenInfo->info.type == XRAN_CP_SECTIONTYPE_1) {
685             /* extType 1 only with Section 1 for now */
686
687         ext_buf  = ext_buf_init = (int8_t*) xran_malloc(ext_len);
688         if (ext_buf) {
689             ptr = m_p_bfw_iq_src;
690
691             for (idRb =0; idRb < nRbs*nAntElm*2; idRb++){
692                 ptr[idRb] = i;
693                 i++;
694             }
695
696             ext_buf += (RTE_PKTMBUF_HEADROOM +
697                        sizeof (struct xran_ecpri_hdr) +
698                        sizeof(struct xran_cp_radioapp_common_header) +
699                        sizeof(struct xran_cp_radioapp_section1));
700
701             ext_len -= (RTE_PKTMBUF_HEADROOM +
702                         sizeof(struct xran_ecpri_hdr) +
703                         sizeof(struct xran_cp_radioapp_common_header) +
704                         sizeof(struct xran_cp_radioapp_section1));
705
706             ext_sec_total = xran_cp_populate_section_ext_1((int8_t *)ext_buf,
707                                                  ext_len,
708                                                  m_p_bfw_iq_src,
709                                                  nRbs,
710                                                  nAntElm,
711                                                  iqWidth,
712                                                  compMethod);
713
714             ASSERT_TRUE(ext_sec_total == expected_len);
715             p_ext1_dst = ext_buf;
716
717             memset(&m_temp_ext1[0], 0, sizeof (struct xran_sectionext1_info)*XRAN_MAX_PRBS);
718
719             idRb = 0;
720             do {
721                 p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst;
722                 bfw_payload = (int8_t*)(p_ext1+1);
723                 p_ext1_dst += p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
724
725                 m_temp_ext1[idRb].bfwNumber      = nAntElm;
726                 m_temp_ext1[idRb].bfwiqWidth     = iqWidth;
727                 m_temp_ext1[idRb].bfwCompMeth    = compMethod;
728                 m_temp_ext1[idRb].p_bfwIQ               = (int16_t*)bfw_payload;
729                 m_temp_ext1[idRb].bfwIQ_sz              = p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
730
731                 loc_pSectGenInfo->exData[idRb].type = XRAN_CP_SECTIONEXTCMD_1;
732                 loc_pSectGenInfo->exData[idRb].len  = sizeof(m_temp_ext1[idRb]);
733                 loc_pSectGenInfo->exData[idRb].data = &m_temp_ext1[idRb];
734
735                 idRb++;
736             }while(p_ext1->ef != XRAN_EF_F_LAST);
737             ASSERT_TRUE(idRb == nRbs);
738
739             mbuf = xran_attach_cp_ext_buf(ext_buf_init, ext_buf, ext_sec_total, &share_data);
740
741             /* Update section information */
742             memset(&m_prep_ext1, 0, sizeof (struct xran_sectionext1_info));
743             m_prep_ext1.bfwNumber      = nAntElm;
744             m_prep_ext1.bfwiqWidth     = iqWidth;
745             m_prep_ext1.bfwCompMeth    = compMethod;
746             m_prep_ext1.p_bfwIQ        = (int16_t*)ext_buf;
747             m_prep_ext1.bfwIQ_sz       = ext_sec_total;
748
749
750             loc_pSectGenInfo->exData[0].type = XRAN_CP_SECTIONEXTCMD_1;
751             loc_pSectGenInfo->exData[0].len  = sizeof(m_prep_ext1);
752             loc_pSectGenInfo->exData[0].data = &m_prep_ext1;
753
754             loc_pSectGenInfo->info.ef       = 1;
755             loc_pSectGenInfo->exDataSize    = 1; /* append all extType1 as one shot
756                                                     (as generated via xran_cp_populate_section_ext_1)*/
757
758             m_params.numSections    = 1;
759
760             /* Generating C-Plane packet */
761             ASSERT_TRUE(xran_prepare_ctrl_pkt(/*m_pTestBuffer*/mbuf, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
762
763             /** to match O-RU parsing */
764             loc_pSectGenInfo->exDataSize = nRbs;
765             loc_pSectGenInfo->exData[0].len  = sizeof(m_temp_ext1[0]);
766             loc_pSectGenInfo->exData[0].data = &m_temp_ext1[0];
767
768             /* Parsing generated packet */
769             EXPECT_TRUE(xran_parse_cp_pkt(/*m_pTestBuffer*/mbuf, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
770         } else {
771             FAIL() << "xran_malloc failed\n";
772         }
773
774         /* Verify the result */
775         verify_sections();
776
777         if(ext_buf_init)
778             xran_free(ext_buf_init);
779     }
780 }
781
782 TEST_P(C_plane, Section_Ext1_9bit)
783 {
784     int i = 0, idRb;
785     int16_t *ptr = NULL;
786     int32_t nRbs = 36;
787     int32_t nAntElm = 64;
788     int8_t  iqWidth = 9;
789     int8_t  compMethod = XRAN_COMPMETHOD_BLKFLOAT;
790     int8_t  *p_ext1_dst  = NULL;
791     int8_t  *bfw_payload = NULL;
792     int32_t expected_len = ((nAntElm/16*4*iqWidth)+1)*nRbs + /* bfwCompParam + IQ = */
793                             sizeof(struct xran_cp_radioapp_section_ext1)*nRbs; /* ext1 Headers */
794
795     int16_t  ext_len       = 9600;
796     int16_t  ext_sec_total = 0;
797     int8_t * ext_buf       = nullptr;
798     int8_t * ext_buf_init  = nullptr;
799
800     struct xran_section_gen_info* loc_pSectGenInfo = m_params.sections;
801     struct xran_sectionext1_info m_prep_ext1;
802     struct xran_cp_radioapp_section_ext1 *p_ext1;
803     struct rte_mbuf_ext_shared_info  share_data;
804     struct rte_mbuf *mbuf = NULL;
805
806     /* Configure section information */
807     if(prepare_sections() < 0) {
808         FAIL() << "Invalid Section configuration\n";
809     }
810
811     if(prepare_extensions() < 0) {
812         FAIL() << "Invalid Section extension configuration\n";
813     }
814
815     if(loc_pSectGenInfo->info.type == XRAN_CP_SECTIONTYPE_1) {
816         /* extType 1 only with Section 1 for now */
817
818         ext_buf  = ext_buf_init = (int8_t*) xran_malloc(ext_len);
819         if (ext_buf) {
820             ptr = m_p_bfw_iq_src;
821
822             for (idRb =0; idRb < nRbs*nAntElm*2; idRb++){
823                 ptr[idRb] = i;
824                 i++;
825             }
826
827             ext_buf += (RTE_PKTMBUF_HEADROOM +
828                        sizeof (struct xran_ecpri_hdr) +
829                        sizeof(struct xran_cp_radioapp_common_header) +
830                        sizeof(struct xran_cp_radioapp_section1));
831
832             ext_len -= (RTE_PKTMBUF_HEADROOM +
833                         sizeof(struct xran_ecpri_hdr) +
834                         sizeof(struct xran_cp_radioapp_common_header) +
835                         sizeof(struct xran_cp_radioapp_section1));
836
837             ext_sec_total = xran_cp_populate_section_ext_1((int8_t *)ext_buf,
838                                                  ext_len,
839                                                  m_p_bfw_iq_src,
840                                                  nRbs,
841                                                  nAntElm,
842                                                  iqWidth,
843                                                  compMethod);
844
845             ASSERT_TRUE(ext_sec_total == expected_len);
846             p_ext1_dst = ext_buf;
847
848             memset(&m_temp_ext1[0], 0, sizeof (struct xran_sectionext1_info)*XRAN_MAX_PRBS);
849
850             idRb = 0;
851             do {
852                 p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst;
853                 bfw_payload = (int8_t*)(p_ext1+1);
854                 p_ext1_dst += p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
855
856                 m_temp_ext1[idRb].bfwNumber      = nAntElm;
857                 m_temp_ext1[idRb].bfwiqWidth     = iqWidth;
858                 m_temp_ext1[idRb].bfwCompMeth    = compMethod;
859
860                 m_temp_ext1[idRb].bfwCompParam.exponent = *bfw_payload++ & 0xF;
861
862                 m_temp_ext1[idRb].p_bfwIQ               = (int16_t*)bfw_payload;
863                 m_temp_ext1[idRb].bfwIQ_sz              = p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
864
865                 loc_pSectGenInfo->exData[idRb].type = XRAN_CP_SECTIONEXTCMD_1;
866                 loc_pSectGenInfo->exData[idRb].len  = sizeof(m_temp_ext1[idRb]);
867                 loc_pSectGenInfo->exData[idRb].data = &m_temp_ext1[idRb];
868
869                 idRb++;
870             }while(p_ext1->ef != XRAN_EF_F_LAST);
871             ASSERT_TRUE(idRb == nRbs);
872
873             mbuf = xran_attach_cp_ext_buf(ext_buf_init, ext_buf, ext_sec_total, &share_data);
874
875             /* Update section information */
876             memset(&m_prep_ext1, 0, sizeof (struct xran_sectionext1_info));
877             m_prep_ext1.bfwNumber      = nAntElm;
878             m_prep_ext1.bfwiqWidth     = iqWidth;
879             m_prep_ext1.bfwCompMeth    = compMethod;
880             m_prep_ext1.p_bfwIQ        = (int16_t*)ext_buf;
881             m_prep_ext1.bfwIQ_sz       = ext_sec_total;
882
883
884             loc_pSectGenInfo->exData[0].type = XRAN_CP_SECTIONEXTCMD_1;
885             loc_pSectGenInfo->exData[0].len  = sizeof(m_prep_ext1);
886             loc_pSectGenInfo->exData[0].data = &m_prep_ext1;
887
888             loc_pSectGenInfo->info.ef       = 1;
889             loc_pSectGenInfo->exDataSize    = 1; /* append all extType1 as one shot
890                                                     (as generated via xran_cp_populate_section_ext_1)*/
891
892             m_params.numSections    = 1;
893
894             /* Generating C-Plane packet */
895             ASSERT_TRUE(xran_prepare_ctrl_pkt(/*m_pTestBuffer*/mbuf, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
896
897             /** to match O-RU parsing */
898             loc_pSectGenInfo->exDataSize = nRbs;
899             loc_pSectGenInfo->exData[0].len  = sizeof(m_temp_ext1[0]);
900             loc_pSectGenInfo->exData[0].data = &m_temp_ext1[0];
901
902             /* Parsing generated packet */
903             EXPECT_TRUE(xran_parse_cp_pkt(/*m_pTestBuffer*/mbuf, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
904         } else {
905             FAIL() << "xran_malloc failed\n";
906         }
907
908         /* Verify the result */
909         verify_sections();
910
911         if(ext_buf_init)
912             xran_free(ext_buf_init);
913     }
914 }
915
916
917 TEST_P(C_plane, PacketGen)
918 {
919     /* Configure section information */
920     if(prepare_sections() < 0) {
921         FAIL() << "Invalid Section configuration\n";
922         }
923     if(prepare_extensions() < 0) {
924         FAIL() << "Invalid Section extension configuration\n";
925         }
926
927     /* Generating C-Plane packet */
928     ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
929
930     /* Parsing generated packet */
931     EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
932
933     /* Verify the result */
934     verify_sections();
935 }
936
937
938 TEST_P(C_plane, PacketGen_Ext)
939 {
940     /* Configure section information */
941     if(prepare_sections() < 0) {
942         FAIL() << "Invalid Section configuration\n";
943         }
944
945     /* Generating C-Plane packet */
946     ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
947
948     /* Parsing generated packet */
949     EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
950
951     /* Verify the result */
952     verify_sections();
953 }
954
955
956 /***************************************************************************
957  * Performance Test cases
958  ***************************************************************************/
959
960 TEST_P(C_plane, Perf)
961 {
962     /* Configure section information */
963     if(prepare_sections() < 0) {
964         FAIL() << "Invalid Section configuration\n";
965         }
966     if(prepare_extensions() < 0) {
967         FAIL() << "Invalid Section extension configuration\n";
968         }
969
970     /* using wrapper function to reset mbuf */
971     performance("C", module_name,
972             &xran_ut_prepare_cp, m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId);
973 }
974
975
976 TEST_P(C_plane, Perf_Ext)
977 {
978     /* Configure section information */
979     if(prepare_sections() < 0) {
980         FAIL() << "Invalid Section configuration\n";
981         }
982
983     /* using wrapper function to reset mbuf */
984     performance("C", module_name,
985             &xran_ut_prepare_cp, m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId);
986 }
987
988 INSTANTIATE_TEST_CASE_P(UnitTest, C_plane,
989         testing::ValuesIn(get_sequence(C_plane::get_number_of_cases("C_Plane"))));
990