X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=o-du%2Fphy.git;a=blobdiff_plain;f=fhi_lib%2Ftest%2Ftest_xran%2Fc_plane_tests.cc;h=8319306727d5dafe7f226ee070722f5408cd76f5;hp=891880dd86fbc9e5a51a577e551c210a59bbab40;hb=2fbf70096f64af622da983e88c5a64e90ad9bdbd;hpb=9e108bb6d4caf2f6d4e920c640882fa49c15684c diff --git a/fhi_lib/test/test_xran/c_plane_tests.cc b/fhi_lib/test/test_xran/c_plane_tests.cc index 891880d..8319306 100644 --- a/fhi_lib/test/test_xran/c_plane_tests.cc +++ b/fhi_lib/test/test_xran/c_plane_tests.cc @@ -1,793 +1,793 @@ -/****************************************************************************** -* -* Copyright (c) 2019 Intel. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*******************************************************************************/ - - -#include "common.hpp" -#include "xran_lib_wrap.hpp" -#include "xran_common.h" -#include "xran_fh_o_du.h" -#include "ethdi.h" -#include "ethernet.h" -#include "xran_transport.h" -#include "xran_cp_api.h" - -#include - - -const std::string module_name = "C-Plane"; - -const uint8_t m_bitmask[] = { 0x00, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; - -extern "C" -{ - -/* wrapper function for performace tests to reset mbuf */ -int xran_ut_prepare_cp(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params, - uint8_t cc_id, uint8_t ant_id, uint8_t seq_id) -{ - rte_pktmbuf_reset(mbuf); - return(xran_prepare_ctrl_pkt(mbuf, params, cc_id, ant_id, seq_id)); -} - - -void cput_fh_rx_callback(void *pCallbackTag, xran_status_t status) -{ - return; -} - -void cput_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status) -{ - rte_pause(); -} - -} /* extern "C" */ - - - -class C_plane: public KernelTests -{ -private: - struct xran_section_gen_info *m_pSectGenInfo = NULL; - struct xran_section_gen_info *m_pSectResult = NULL; - - -protected: - int m_maxSections = 8; /* not used */ - int m_numSections; - - struct rte_mbuf *m_pTestBuffer; - - struct xran_cp_gen_params m_params; - struct xran_recv_packet_info m_pktInfo; - struct xran_cp_gen_params m_result; - - uint8_t m_dir; - std::string m_dirStr; - uint8_t m_sectionType; - - uint8_t m_ccId, m_antId; - uint8_t m_seqId; - uint8_t m_frameId, m_subframeId, m_slotId; - uint8_t m_symStart, m_symNum; - uint16_t *m_prbStart = NULL, *m_prbNum = NULL; - - uint8_t m_iqWidth, m_compMethod; - uint16_t m_beamId; - uint16_t m_reMask = 0xfff; - uint16_t m_sectionId; - uint8_t m_filterIndex; - uint16_t m_timeOffset; - uint8_t m_fftSize; - uint8_t m_scs; - uint16_t m_cpLength; - int m_freqOffset; - - uint16_t m_ext1_dst_len = 0; - int8_t *m_p_ext1_dst = NULL; - int16_t *m_p_bfw_iq_src = NULL; - - struct xran_sectionext1_info m_ext1; - struct xran_sectionext2_info m_ext2; - struct xran_sectionext4_info m_ext4; - struct xran_sectionext5_info m_ext5; - - int16_t m_bfwIQ[XRAN_MAX_BFW_N*2]; - - - void SetUp() override - { - int i, j; - - init_test("C_Plane"); - - m_numSections = get_input_parameter("num_sections"); - ASSERT_FALSE(m_numSections == 0); - - m_dirStr = get_input_parameter("direction"); - - if(!m_dirStr.compare("DL")) m_dir = XRAN_DIR_DL; - else if(!m_dirStr.compare("UL")) m_dir = XRAN_DIR_UL; - else FAIL() << "Invalid direction!"; - - m_sectionType = get_input_parameter("section_type"); - m_ccId = get_input_parameter("cc_id"); - m_antId = get_input_parameter("ant_id"); - m_seqId = get_input_parameter("seq_id"); - - m_frameId = get_input_parameter("frame_id"); - m_subframeId = get_input_parameter("subframe_id"); - m_slotId = get_input_parameter("slot_id"); - m_symStart = get_input_parameter("symbol_start"); - m_compMethod = get_input_parameter("comp_method"); - m_iqWidth = get_input_parameter("iq_width"); - - m_sectionId = get_input_parameter("section_id"); - m_symNum = get_input_parameter("symbol_num"); - m_beamId = get_input_parameter("beam_id"); - - /* reading configurations of start prb and the number of prbs */ - std::vector prbstart = get_input_parameter>("prb_start"); - std::vector prbnum = get_input_parameter>("prb_num"); - /* number of sections and the pair of start/number of prb shall be matched */ - ASSERT_TRUE((m_numSections == prbstart.size()) - && (m_numSections == prbnum.size()) - && (prbstart.size() == prbnum.size())); - - m_prbStart = new uint16_t [m_numSections]; - m_prbNum = new uint16_t [m_numSections]; - for(i=0; i < m_numSections; i++) { - m_prbStart[i] = prbstart[i]; - m_prbNum[i] = prbnum[i]; - } - - switch(m_sectionType) { - case XRAN_CP_SECTIONTYPE_1: - m_filterIndex = XRAN_FILTERINDEX_STANDARD; - break; - - case XRAN_CP_SECTIONTYPE_3: - m_filterIndex = get_input_parameter("filter_index"); - m_timeOffset = get_input_parameter("time_offset"); - m_fftSize = get_input_parameter("fft_size"); - m_scs = get_input_parameter("scs"); - m_cpLength = get_input_parameter("cp_length"); - m_freqOffset = get_input_parameter("freq_offset"); - break; - - default: - FAIL() << "Invalid Section Type - " << m_sectionType << "\n"; - } - - /* allocate and prepare required data storage */ - m_pSectGenInfo = new struct xran_section_gen_info [m_numSections]; - ASSERT_NE(m_pSectGenInfo, nullptr); - m_params.sections = m_pSectGenInfo; - - m_pSectResult = new struct xran_section_gen_info [m_numSections]; - ASSERT_NE(m_pSectResult, nullptr); - m_result.sections = m_pSectResult; - - m_ext1_dst_len = 9600; - m_p_ext1_dst = new int8_t [m_ext1_dst_len]; - m_p_bfw_iq_src = new int16_t [9600/2]; - - /* allocating an mbuf for packet generatrion */ - m_pTestBuffer = xran_ethdi_mbuf_alloc(); - - ASSERT_FALSE(m_pTestBuffer == NULL); - } - - void TearDown() override - { - int i, j; - - if(m_pTestBuffer != NULL) - rte_pktmbuf_free(m_pTestBuffer); - - if(m_prbStart) - delete[] m_prbStart; - if(m_prbNum) - delete[] m_prbNum; - - if(m_p_bfw_iq_src) - delete[] m_p_bfw_iq_src; - - if(m_p_ext1_dst) - delete[] m_p_ext1_dst; - - if(m_pSectGenInfo) - delete[] m_pSectGenInfo; - - if(m_pSectResult) { - delete[] m_pSectResult; - } - - } - - int prepare_sections(bool extflag); - int prepare_extensions(int sect_num); - void verify_sections(void); - -}; - - - -int C_plane::prepare_extensions(int sect_num) -{ - int i, numext; - int N; - - - N = 8; - - // extension 1 - m_ext1.bfwNumber = 4*N; // 4 ant, 8 UEs - m_ext1.bfwiqWidth = 16; - m_ext1.bfwCompMeth = XRAN_BFWCOMPMETHOD_NONE; - /* XRAN_BFWCOMPMETHOD_BLKFLOAT - * XRAN_BFWCOMPMETHOD_BLKSCALE - * XRAN_BFWCOMPMETHOD_ULAW - * XRAN_BFWCOMPMETHOD_BEAMSPACE - */ - m_ext1.p_bfwIQ = m_bfwIQ; - - switch (m_ext1.bfwCompMeth) { - case XRAN_BFWCOMPMETHOD_BLKFLOAT: - m_ext1.bfwCompParam.exponent = 0xa; - break; - case XRAN_BFWCOMPMETHOD_BLKSCALE: - m_ext1.bfwCompParam.blockScaler = 0xa5; - break; - case XRAN_BFWCOMPMETHOD_ULAW: - m_ext1.bfwCompParam.compBitWidthShift = 0x55; - case XRAN_BFWCOMPMETHOD_BEAMSPACE: - for(i=0; ibfwiqWidth == ext1_params->bfwiqWidth); - EXPECT_TRUE(ext1_result->bfwCompMeth == ext1_params->bfwCompMeth); - - N = ext1_params->bfwNumber; - switch(ext1_params->bfwCompMeth) { - case XRAN_BFWCOMPMETHOD_BLKFLOAT: - EXPECT_TRUE(ext1_result->bfwCompParam.exponent == ext1_params->bfwCompParam.exponent); - break; - - case XRAN_BFWCOMPMETHOD_BLKSCALE: - EXPECT_TRUE(ext1_result->bfwCompParam.blockScaler == ext1_params->bfwCompParam.blockScaler); - break; - - case XRAN_BFWCOMPMETHOD_ULAW: - EXPECT_TRUE(ext1_result->bfwCompParam.compBitWidthShift == ext1_params->bfwCompParam.compBitWidthShift); - break; - - case XRAN_BFWCOMPMETHOD_BEAMSPACE: - parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8; - EXPECT_TRUE(std::memcmp(ext1_result->bfwCompParam.activeBeamspaceCoeffMask, ext1_params->bfwCompParam.activeBeamspaceCoeffMask, parm_size)); - break; - } - - /* Get the number of BF weights */ - iq_size = N*ext1_params->bfwiqWidth*2; // total in bits - parm_size = iq_size>>3; // total in bytes (/8) - if(iq_size%8) parm_size++; // round up - EXPECT_TRUE(std::memcmp(ext1_result->p_bfwIQ, ext1_params->p_bfwIQ, parm_size)); - - } - break; - - case XRAN_CP_SECTIONEXTCMD_2: - { - struct xran_sectionext2_info *ext2_params, *ext2_result; - - ext2_params = (struct xran_sectionext2_info *)m_params.sections[i].exData[j].data; - ext2_result = (struct xran_sectionext2_info *)m_result.sections[i].exData[j].data; - - if(ext2_params->bfAzPtWidth) { - EXPECT_TRUE(ext2_result->bfAzPtWidth == ext2_params->bfAzPtWidth); - EXPECT_TRUE(ext2_result->bfAzPt == ext2_params->bfAzPt); - } - - if(ext2_params->bfZePtWidth) { - EXPECT_TRUE(ext2_result->bfZePtWidth == ext2_params->bfZePtWidth); - EXPECT_TRUE(ext2_result->bfZePt == ext2_params->bfZePt); - } - if(ext2_params->bfAz3ddWidth) { - EXPECT_TRUE(ext2_result->bfAz3ddWidth == ext2_params->bfAz3ddWidth); - EXPECT_TRUE(ext2_result->bfAz3dd == ext2_params->bfAz3dd); - } - if(ext2_params->bfZe3ddWidth) { - EXPECT_TRUE(ext2_result->bfZe3ddWidth == ext2_params->bfZe3ddWidth); - EXPECT_TRUE(ext2_result->bfZe3dd == ext2_params->bfZe3dd); - } - - EXPECT_TRUE(ext2_result->bfAzSI == ext2_params->bfAzSI); - EXPECT_TRUE(ext2_result->bfZeSI == ext2_params->bfZeSI); - } - break; - - case XRAN_CP_SECTIONEXTCMD_4: - { - struct xran_sectionext4_info *ext4_params, *ext4_result; - - ext4_params = (struct xran_sectionext4_info *)m_params.sections[i].exData[j].data; - ext4_result = (struct xran_sectionext4_info *)m_result.sections[i].exData[j].data; - - EXPECT_TRUE(ext4_result->csf == ext4_params->csf); - EXPECT_TRUE(ext4_result->modCompScaler == ext4_params->modCompScaler); - } - break; - case XRAN_CP_SECTIONEXTCMD_5: - { - struct xran_sectionext5_info *ext5_params, *ext5_result; - int idx; - - ext5_params = (struct xran_sectionext5_info *)m_params.sections[i].exData[j].data; - ext5_result = (struct xran_sectionext5_info *)m_result.sections[i].exData[j].data; - - EXPECT_TRUE(ext5_result->num_sets == ext5_params->num_sets); - for(idx=0; idx < ext5_params->num_sets; idx++) { - EXPECT_TRUE(ext5_result->mc[idx].csf == ext5_params->mc[idx].csf); - EXPECT_TRUE(ext5_result->mc[idx].mcScaleReMask == ext5_params->mc[idx].mcScaleReMask); - EXPECT_TRUE(ext5_result->mc[idx].mcScaleOffset == ext5_params->mc[idx].mcScaleOffset); - } - } - break; - } - } - } - } - - return; -} - - -/*************************************************************************** - * Functional Test cases - ***************************************************************************/ - -TEST_P(C_plane, Section_Ext1) -{ - int i = 0, idRb; - int32_t len = 0; - int16_t *ptr = NULL; - int32_t nRbs = 36; - int32_t nAntElm = 32; - int8_t iqWidth = 16; - int8_t compMethod = XRAN_COMPMETHOD_NONE; - int8_t *p_ext1_dst = NULL; - int16_t *bfw_payload = NULL; - int32_t expected_len = (3+1)*nRbs + nAntElm*nRbs*4; - - struct xran_section_gen_info* loc_pSectGenInfo = m_params.sections; - struct xran_sectionext1_info m_ext1; - struct xran_cp_radioapp_section_ext1 *p_ext1; - - /* Configure section information */ - if(prepare_sections(false) < 0) { - FAIL() << "Invalid Section configuration\n"; - } - ptr = m_p_bfw_iq_src; - - for (idRb =0; idRb < nRbs*nAntElm*2; idRb++){ - ptr[idRb] = i; - i++; - } - - len = xran_cp_populate_section_ext_1(m_p_ext1_dst, - m_ext1_dst_len, - m_p_bfw_iq_src, - nRbs, - nAntElm, - iqWidth, - compMethod); - - ASSERT_TRUE(len == expected_len); - - p_ext1_dst = m_p_ext1_dst; - idRb = 0; - do { - p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst; - bfw_payload = (int16_t*)(p_ext1+1); - p_ext1_dst += p_ext1->extLen*XRAN_SECTIONEXT_ALIGN; - idRb++; - }while(p_ext1->ef != XRAN_EF_F_LAST); - - ASSERT_TRUE(idRb == nRbs); - - /* Update section information */ - memset(&m_ext1, 0, sizeof (struct xran_sectionext1_info)); - m_ext1.bfwNumber = nAntElm; - m_ext1.bfwiqWidth = iqWidth; - m_ext1.bfwCompMeth = compMethod; - m_ext1.p_bfwIQ = (int16_t*)m_p_ext1_dst; - m_ext1.bfwIQ_sz = len; - - loc_pSectGenInfo->exData[0].type = XRAN_CP_SECTIONEXTCMD_1; - loc_pSectGenInfo->exData[0].len = sizeof(m_ext1); - loc_pSectGenInfo->exData[0].data = &m_ext1; - - loc_pSectGenInfo->info.ef = 1; - loc_pSectGenInfo->exDataSize = 1; - - m_params.numSections = 1; - - /* Generating C-Plane packet */ - ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS); - - /* Parsing generated packet */ - EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS); - - /* Verify the result */ - //verify_sections(); -} - -TEST_P(C_plane, Section_Ext1_9bit) -{ - int i = 0, idRb; - int32_t len = 0; - int16_t *ptr = NULL; - int32_t nRbs = 36; - int32_t nAntElm = 32; - int8_t iqWidth = 9; - int8_t compMethod = XRAN_COMPMETHOD_BLKFLOAT; - int8_t *p_ext1_dst = NULL; - int16_t *bfw_payload = NULL; - int32_t expected_len = ((nAntElm/16*4*iqWidth)+1)*nRbs + /* bfwCompParam + IQ = */ - sizeof(struct xran_cp_radioapp_section_ext1)*nRbs; /* ext1 Headers */ - - struct xran_section_gen_info* loc_pSectGenInfo = m_params.sections; - struct xran_sectionext1_info m_ext1; - struct xran_cp_radioapp_section_ext1 *p_ext1; - - /* Configure section information */ - if(prepare_sections(false) < 0) { - FAIL() << "Invalid Section configuration\n"; - } - ptr = m_p_bfw_iq_src; - - for (idRb =0; idRb < nRbs*nAntElm*2; idRb++){ - ptr[idRb] = i; - i++; - } - - len = xran_cp_populate_section_ext_1(m_p_ext1_dst, - m_ext1_dst_len, - m_p_bfw_iq_src, - nRbs, - nAntElm, - iqWidth, - compMethod); - - ASSERT_TRUE(len == expected_len); - - p_ext1_dst = m_p_ext1_dst; - idRb = 0; - do { - p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst; - bfw_payload = (int16_t*)(p_ext1+1); - p_ext1_dst += p_ext1->extLen*XRAN_SECTIONEXT_ALIGN; - idRb++; - }while(p_ext1->ef != XRAN_EF_F_LAST); - - ASSERT_TRUE(idRb == nRbs); - - /* Update section information */ - memset(&m_ext1, 0, sizeof (struct xran_sectionext1_info)); - m_ext1.bfwNumber = nAntElm; - m_ext1.bfwiqWidth = iqWidth; - m_ext1.bfwCompMeth = compMethod; - m_ext1.p_bfwIQ = (int16_t*)m_p_ext1_dst; - m_ext1.bfwIQ_sz = len; - - loc_pSectGenInfo->exData[0].type = XRAN_CP_SECTIONEXTCMD_1; - loc_pSectGenInfo->exData[0].len = sizeof(m_ext1); - loc_pSectGenInfo->exData[0].data = &m_ext1; - - loc_pSectGenInfo->info.ef = 1; - loc_pSectGenInfo->exDataSize = 1; - - m_params.numSections = 1; - - /* Generating C-Plane packet */ - ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS); - - /* Parsing generated packet */ - EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS); - - /* Verify the result */ - //verify_sections(); -} - - - -TEST_P(C_plane, PacketGen) -{ - int i; - - - /* Configure section information */ - if(prepare_sections(false) < 0) { - FAIL() << "Invalid Section configuration\n"; - } - - /* Generating C-Plane packet */ - ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS); - - /* Parsing generated packet */ - EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS); - - /* Verify the result */ - verify_sections(); -} - - -TEST_P(C_plane, PacketGen_Ext) -{ - int i; - - - /* Configure section information */ - if(prepare_sections(true) < 0) { - FAIL() << "Invalid Section configuration\n"; - } - - /* Generating C-Plane packet */ - ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS); - - /* Parsing generated packet */ - EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS); - - /* Verify the result */ - verify_sections(); -} - - -/*************************************************************************** - * Performance Test cases - ***************************************************************************/ -TEST_P(C_plane, Perf) -{ - /* Configure section information */ - if(prepare_sections(false) < 0) { - FAIL() << "Invalid Section configuration\n"; - } - - /* using wrapper function to reset mbuf */ - performance("C", module_name, - &xran_ut_prepare_cp, m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId); -} - -TEST_P(C_plane, Perf_Ext) -{ - /* Configure section information */ - if(prepare_sections(true) < 0) { - FAIL() << "Invalid Section configuration\n"; - } - - /* using wrapper function to reset mbuf */ - performance("C", module_name, - &xran_ut_prepare_cp, m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId); -} - - -INSTANTIATE_TEST_CASE_P(UnitTest, C_plane, - testing::ValuesIn(get_sequence(C_plane::get_number_of_cases("C_Plane")))); - +/****************************************************************************** +* +* Copyright (c) 2019 Intel. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*******************************************************************************/ + + +#include "common.hpp" +#include "xran_lib_wrap.hpp" +#include "xran_common.h" +#include "xran_fh_o_du.h" +#include "ethdi.h" +#include "ethernet.h" +#include "xran_transport.h" +#include "xran_cp_api.h" + +#include + + +const std::string module_name = "C-Plane"; + +const uint8_t m_bitmask[] = { 0x00, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; + +extern "C" +{ + +/* wrapper function for performace tests to reset mbuf */ +int xran_ut_prepare_cp(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params, + uint8_t cc_id, uint8_t ant_id, uint8_t seq_id) +{ + rte_pktmbuf_reset(mbuf); + return(xran_prepare_ctrl_pkt(mbuf, params, cc_id, ant_id, seq_id)); +} + + +void cput_fh_rx_callback(void *pCallbackTag, xran_status_t status) +{ + return; +} + +void cput_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status) +{ + rte_pause(); +} + +} /* extern "C" */ + + + +class C_plane: public KernelTests +{ +private: + struct xran_section_gen_info *m_pSectGenInfo = NULL; + struct xran_section_gen_info *m_pSectResult = NULL; + + +protected: + int m_maxSections = 8; /* not used */ + int m_numSections; + + struct rte_mbuf *m_pTestBuffer; + + struct xran_cp_gen_params m_params; + struct xran_recv_packet_info m_pktInfo; + struct xran_cp_gen_params m_result; + + uint8_t m_dir; + std::string m_dirStr; + uint8_t m_sectionType; + + uint8_t m_ccId, m_antId; + uint8_t m_seqId; + uint8_t m_frameId, m_subframeId, m_slotId; + uint8_t m_symStart, m_symNum; + uint16_t *m_prbStart = NULL, *m_prbNum = NULL; + + uint8_t m_iqWidth, m_compMethod; + uint16_t m_beamId; + uint16_t m_reMask = 0xfff; + uint16_t m_sectionId; + uint8_t m_filterIndex; + uint16_t m_timeOffset; + uint8_t m_fftSize; + uint8_t m_scs; + uint16_t m_cpLength; + int m_freqOffset; + + uint16_t m_ext1_dst_len = 0; + int8_t *m_p_ext1_dst = NULL; + int16_t *m_p_bfw_iq_src = NULL; + + struct xran_sectionext1_info m_ext1; + struct xran_sectionext2_info m_ext2; + struct xran_sectionext4_info m_ext4; + struct xran_sectionext5_info m_ext5; + + int16_t m_bfwIQ[XRAN_MAX_BFW_N*2]; + + + void SetUp() override + { + int i, j; + + init_test("C_Plane"); + + m_numSections = get_input_parameter("num_sections"); + ASSERT_FALSE(m_numSections == 0); + + m_dirStr = get_input_parameter("direction"); + + if(!m_dirStr.compare("DL")) m_dir = XRAN_DIR_DL; + else if(!m_dirStr.compare("UL")) m_dir = XRAN_DIR_UL; + else FAIL() << "Invalid direction!"; + + m_sectionType = get_input_parameter("section_type"); + m_ccId = get_input_parameter("cc_id"); + m_antId = get_input_parameter("ant_id"); + m_seqId = get_input_parameter("seq_id"); + + m_frameId = get_input_parameter("frame_id"); + m_subframeId = get_input_parameter("subframe_id"); + m_slotId = get_input_parameter("slot_id"); + m_symStart = get_input_parameter("symbol_start"); + m_compMethod = get_input_parameter("comp_method"); + m_iqWidth = get_input_parameter("iq_width"); + + m_sectionId = get_input_parameter("section_id"); + m_symNum = get_input_parameter("symbol_num"); + m_beamId = get_input_parameter("beam_id"); + + /* reading configurations of start prb and the number of prbs */ + std::vector prbstart = get_input_parameter>("prb_start"); + std::vector prbnum = get_input_parameter>("prb_num"); + /* number of sections and the pair of start/number of prb shall be matched */ + ASSERT_TRUE((m_numSections == prbstart.size()) + && (m_numSections == prbnum.size()) + && (prbstart.size() == prbnum.size())); + + m_prbStart = new uint16_t [m_numSections]; + m_prbNum = new uint16_t [m_numSections]; + for(i=0; i < m_numSections; i++) { + m_prbStart[i] = prbstart[i]; + m_prbNum[i] = prbnum[i]; + } + + switch(m_sectionType) { + case XRAN_CP_SECTIONTYPE_1: + m_filterIndex = XRAN_FILTERINDEX_STANDARD; + break; + + case XRAN_CP_SECTIONTYPE_3: + m_filterIndex = get_input_parameter("filter_index"); + m_timeOffset = get_input_parameter("time_offset"); + m_fftSize = get_input_parameter("fft_size"); + m_scs = get_input_parameter("scs"); + m_cpLength = get_input_parameter("cp_length"); + m_freqOffset = get_input_parameter("freq_offset"); + break; + + default: + FAIL() << "Invalid Section Type - " << m_sectionType << "\n"; + } + + /* allocate and prepare required data storage */ + m_pSectGenInfo = new struct xran_section_gen_info [m_numSections]; + ASSERT_NE(m_pSectGenInfo, nullptr); + m_params.sections = m_pSectGenInfo; + + m_pSectResult = new struct xran_section_gen_info [m_numSections]; + ASSERT_NE(m_pSectResult, nullptr); + m_result.sections = m_pSectResult; + + m_ext1_dst_len = 9600; + m_p_ext1_dst = new int8_t [m_ext1_dst_len]; + m_p_bfw_iq_src = new int16_t [9600/2]; + + /* allocating an mbuf for packet generatrion */ + m_pTestBuffer = xran_ethdi_mbuf_alloc(); + + ASSERT_FALSE(m_pTestBuffer == NULL); + } + + void TearDown() override + { + int i, j; + + if(m_pTestBuffer != NULL) + rte_pktmbuf_free(m_pTestBuffer); + + if(m_prbStart) + delete[] m_prbStart; + if(m_prbNum) + delete[] m_prbNum; + + if(m_p_bfw_iq_src) + delete[] m_p_bfw_iq_src; + + if(m_p_ext1_dst) + delete[] m_p_ext1_dst; + + if(m_pSectGenInfo) + delete[] m_pSectGenInfo; + + if(m_pSectResult) { + delete[] m_pSectResult; + } + + } + + int prepare_sections(bool extflag); + int prepare_extensions(int sect_num); + void verify_sections(void); + +}; + + + +int C_plane::prepare_extensions(int sect_num) +{ + int i, numext; + int N; + + + N = 8; + + // extension 1 + m_ext1.bfwNumber = 4*N; // 4 ant, 8 UEs + m_ext1.bfwiqWidth = 16; + m_ext1.bfwCompMeth = XRAN_BFWCOMPMETHOD_NONE; + /* XRAN_BFWCOMPMETHOD_BLKFLOAT + * XRAN_BFWCOMPMETHOD_BLKSCALE + * XRAN_BFWCOMPMETHOD_ULAW + * XRAN_BFWCOMPMETHOD_BEAMSPACE + */ + m_ext1.p_bfwIQ = m_bfwIQ; + + switch (m_ext1.bfwCompMeth) { + case XRAN_BFWCOMPMETHOD_BLKFLOAT: + m_ext1.bfwCompParam.exponent = 0xa; + break; + case XRAN_BFWCOMPMETHOD_BLKSCALE: + m_ext1.bfwCompParam.blockScaler = 0xa5; + break; + case XRAN_BFWCOMPMETHOD_ULAW: + m_ext1.bfwCompParam.compBitWidthShift = 0x55; + case XRAN_BFWCOMPMETHOD_BEAMSPACE: + for(i=0; ibfwiqWidth == ext1_params->bfwiqWidth); + EXPECT_TRUE(ext1_result->bfwCompMeth == ext1_params->bfwCompMeth); + + N = ext1_params->bfwNumber; + switch(ext1_params->bfwCompMeth) { + case XRAN_BFWCOMPMETHOD_BLKFLOAT: + EXPECT_TRUE(ext1_result->bfwCompParam.exponent == ext1_params->bfwCompParam.exponent); + break; + + case XRAN_BFWCOMPMETHOD_BLKSCALE: + EXPECT_TRUE(ext1_result->bfwCompParam.blockScaler == ext1_params->bfwCompParam.blockScaler); + break; + + case XRAN_BFWCOMPMETHOD_ULAW: + EXPECT_TRUE(ext1_result->bfwCompParam.compBitWidthShift == ext1_params->bfwCompParam.compBitWidthShift); + break; + + case XRAN_BFWCOMPMETHOD_BEAMSPACE: + parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8; + EXPECT_TRUE(std::memcmp(ext1_result->bfwCompParam.activeBeamspaceCoeffMask, ext1_params->bfwCompParam.activeBeamspaceCoeffMask, parm_size)); + break; + } + + /* Get the number of BF weights */ + iq_size = N*ext1_params->bfwiqWidth*2; // total in bits + parm_size = iq_size>>3; // total in bytes (/8) + if(iq_size%8) parm_size++; // round up + EXPECT_TRUE(std::memcmp(ext1_result->p_bfwIQ, ext1_params->p_bfwIQ, parm_size)); + + } + break; + + case XRAN_CP_SECTIONEXTCMD_2: + { + struct xran_sectionext2_info *ext2_params, *ext2_result; + + ext2_params = (struct xran_sectionext2_info *)m_params.sections[i].exData[j].data; + ext2_result = (struct xran_sectionext2_info *)m_result.sections[i].exData[j].data; + + if(ext2_params->bfAzPtWidth) { + EXPECT_TRUE(ext2_result->bfAzPtWidth == ext2_params->bfAzPtWidth); + EXPECT_TRUE(ext2_result->bfAzPt == ext2_params->bfAzPt); + } + + if(ext2_params->bfZePtWidth) { + EXPECT_TRUE(ext2_result->bfZePtWidth == ext2_params->bfZePtWidth); + EXPECT_TRUE(ext2_result->bfZePt == ext2_params->bfZePt); + } + if(ext2_params->bfAz3ddWidth) { + EXPECT_TRUE(ext2_result->bfAz3ddWidth == ext2_params->bfAz3ddWidth); + EXPECT_TRUE(ext2_result->bfAz3dd == ext2_params->bfAz3dd); + } + if(ext2_params->bfZe3ddWidth) { + EXPECT_TRUE(ext2_result->bfZe3ddWidth == ext2_params->bfZe3ddWidth); + EXPECT_TRUE(ext2_result->bfZe3dd == ext2_params->bfZe3dd); + } + + EXPECT_TRUE(ext2_result->bfAzSI == ext2_params->bfAzSI); + EXPECT_TRUE(ext2_result->bfZeSI == ext2_params->bfZeSI); + } + break; + + case XRAN_CP_SECTIONEXTCMD_4: + { + struct xran_sectionext4_info *ext4_params, *ext4_result; + + ext4_params = (struct xran_sectionext4_info *)m_params.sections[i].exData[j].data; + ext4_result = (struct xran_sectionext4_info *)m_result.sections[i].exData[j].data; + + EXPECT_TRUE(ext4_result->csf == ext4_params->csf); + EXPECT_TRUE(ext4_result->modCompScaler == ext4_params->modCompScaler); + } + break; + case XRAN_CP_SECTIONEXTCMD_5: + { + struct xran_sectionext5_info *ext5_params, *ext5_result; + int idx; + + ext5_params = (struct xran_sectionext5_info *)m_params.sections[i].exData[j].data; + ext5_result = (struct xran_sectionext5_info *)m_result.sections[i].exData[j].data; + + EXPECT_TRUE(ext5_result->num_sets == ext5_params->num_sets); + for(idx=0; idx < ext5_params->num_sets; idx++) { + EXPECT_TRUE(ext5_result->mc[idx].csf == ext5_params->mc[idx].csf); + EXPECT_TRUE(ext5_result->mc[idx].mcScaleReMask == ext5_params->mc[idx].mcScaleReMask); + EXPECT_TRUE(ext5_result->mc[idx].mcScaleOffset == ext5_params->mc[idx].mcScaleOffset); + } + } + break; + } + } + } + } + + return; +} + + +/*************************************************************************** + * Functional Test cases + ***************************************************************************/ + +TEST_P(C_plane, Section_Ext1) +{ + int i = 0, idRb; + int32_t len = 0; + int16_t *ptr = NULL; + int32_t nRbs = 36; + int32_t nAntElm = 32; + int8_t iqWidth = 16; + int8_t compMethod = XRAN_COMPMETHOD_NONE; + int8_t *p_ext1_dst = NULL; + int16_t *bfw_payload = NULL; + int32_t expected_len = (3+1)*nRbs + nAntElm*nRbs*4; + + struct xran_section_gen_info* loc_pSectGenInfo = m_params.sections; + struct xran_sectionext1_info m_ext1; + struct xran_cp_radioapp_section_ext1 *p_ext1; + + /* Configure section information */ + if(prepare_sections(false) < 0) { + FAIL() << "Invalid Section configuration\n"; + } + ptr = m_p_bfw_iq_src; + + for (idRb =0; idRb < nRbs*nAntElm*2; idRb++){ + ptr[idRb] = i; + i++; + } + + len = xran_cp_populate_section_ext_1(m_p_ext1_dst, + m_ext1_dst_len, + m_p_bfw_iq_src, + nRbs, + nAntElm, + iqWidth, + compMethod); + + ASSERT_TRUE(len == expected_len); + + p_ext1_dst = m_p_ext1_dst; + idRb = 0; + do { + p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst; + bfw_payload = (int16_t*)(p_ext1+1); + p_ext1_dst += p_ext1->extLen*XRAN_SECTIONEXT_ALIGN; + idRb++; + }while(p_ext1->ef != XRAN_EF_F_LAST); + + ASSERT_TRUE(idRb == nRbs); + + /* Update section information */ + memset(&m_ext1, 0, sizeof (struct xran_sectionext1_info)); + m_ext1.bfwNumber = nAntElm; + m_ext1.bfwiqWidth = iqWidth; + m_ext1.bfwCompMeth = compMethod; + m_ext1.p_bfwIQ = (int16_t*)m_p_ext1_dst; + m_ext1.bfwIQ_sz = len; + + loc_pSectGenInfo->exData[0].type = XRAN_CP_SECTIONEXTCMD_1; + loc_pSectGenInfo->exData[0].len = sizeof(m_ext1); + loc_pSectGenInfo->exData[0].data = &m_ext1; + + loc_pSectGenInfo->info.ef = 1; + loc_pSectGenInfo->exDataSize = 1; + + m_params.numSections = 1; + + /* Generating C-Plane packet */ + ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS); + + /* Parsing generated packet */ + EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS); + + /* Verify the result */ + //verify_sections(); +} + +TEST_P(C_plane, Section_Ext1_9bit) +{ + int i = 0, idRb; + int32_t len = 0; + int16_t *ptr = NULL; + int32_t nRbs = 36; + int32_t nAntElm = 32; + int8_t iqWidth = 9; + int8_t compMethod = XRAN_COMPMETHOD_BLKFLOAT; + int8_t *p_ext1_dst = NULL; + int16_t *bfw_payload = NULL; + int32_t expected_len = ((nAntElm/16*4*iqWidth)+1)*nRbs + /* bfwCompParam + IQ = */ + sizeof(struct xran_cp_radioapp_section_ext1)*nRbs; /* ext1 Headers */ + + struct xran_section_gen_info* loc_pSectGenInfo = m_params.sections; + struct xran_sectionext1_info m_ext1; + struct xran_cp_radioapp_section_ext1 *p_ext1; + + /* Configure section information */ + if(prepare_sections(false) < 0) { + FAIL() << "Invalid Section configuration\n"; + } + ptr = m_p_bfw_iq_src; + + for (idRb =0; idRb < nRbs*nAntElm*2; idRb++){ + ptr[idRb] = i; + i++; + } + + len = xran_cp_populate_section_ext_1(m_p_ext1_dst, + m_ext1_dst_len, + m_p_bfw_iq_src, + nRbs, + nAntElm, + iqWidth, + compMethod); + + ASSERT_TRUE(len == expected_len); + + p_ext1_dst = m_p_ext1_dst; + idRb = 0; + do { + p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst; + bfw_payload = (int16_t*)(p_ext1+1); + p_ext1_dst += p_ext1->extLen*XRAN_SECTIONEXT_ALIGN; + idRb++; + }while(p_ext1->ef != XRAN_EF_F_LAST); + + ASSERT_TRUE(idRb == nRbs); + + /* Update section information */ + memset(&m_ext1, 0, sizeof (struct xran_sectionext1_info)); + m_ext1.bfwNumber = nAntElm; + m_ext1.bfwiqWidth = iqWidth; + m_ext1.bfwCompMeth = compMethod; + m_ext1.p_bfwIQ = (int16_t*)m_p_ext1_dst; + m_ext1.bfwIQ_sz = len; + + loc_pSectGenInfo->exData[0].type = XRAN_CP_SECTIONEXTCMD_1; + loc_pSectGenInfo->exData[0].len = sizeof(m_ext1); + loc_pSectGenInfo->exData[0].data = &m_ext1; + + loc_pSectGenInfo->info.ef = 1; + loc_pSectGenInfo->exDataSize = 1; + + m_params.numSections = 1; + + /* Generating C-Plane packet */ + ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS); + + /* Parsing generated packet */ + EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS); + + /* Verify the result */ + //verify_sections(); +} + + + +TEST_P(C_plane, PacketGen) +{ + int i; + + + /* Configure section information */ + if(prepare_sections(false) < 0) { + FAIL() << "Invalid Section configuration\n"; + } + + /* Generating C-Plane packet */ + ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS); + + /* Parsing generated packet */ + EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS); + + /* Verify the result */ + verify_sections(); +} + + +TEST_P(C_plane, PacketGen_Ext) +{ + int i; + + + /* Configure section information */ + if(prepare_sections(true) < 0) { + FAIL() << "Invalid Section configuration\n"; + } + + /* Generating C-Plane packet */ + ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS); + + /* Parsing generated packet */ + EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS); + + /* Verify the result */ + verify_sections(); +} + + +/*************************************************************************** + * Performance Test cases + ***************************************************************************/ +TEST_P(C_plane, Perf) +{ + /* Configure section information */ + if(prepare_sections(false) < 0) { + FAIL() << "Invalid Section configuration\n"; + } + + /* using wrapper function to reset mbuf */ + performance("C", module_name, + &xran_ut_prepare_cp, m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId); +} + +TEST_P(C_plane, Perf_Ext) +{ + /* Configure section information */ + if(prepare_sections(true) < 0) { + FAIL() << "Invalid Section configuration\n"; + } + + /* using wrapper function to reset mbuf */ + performance("C", module_name, + &xran_ut_prepare_cp, m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId); +} + + +INSTANTIATE_TEST_CASE_P(UnitTest, C_plane, + testing::ValuesIn(get_sequence(C_plane::get_number_of_cases("C_Plane")))); +