* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / test / test_xran / prach_functional.cc
1 /******************************************************************************
2 *
3 *   Copyright (c) 2020 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18
19
20 #include "common.hpp"
21 #include "xran_common.h"
22 #include "xran_fh_o_du.h"
23 #include "ethernet.h"
24 #include "xran_transport.h"
25 #include "xran_cp_api.h"
26
27 #include <stdint.h>
28
29
30 const std::string module_name = "Prach_test";
31
32
33 class PrachCheck : public KernelTests
34 {
35 private:
36     struct xran_section_recv_info *m_pSectResult = NULL;  /*Not used*/
37
38 protected:
39     struct xran_fh_config *m_xranConf;
40     struct xran_device_ctx m_xran_dev_ctx;
41     struct xran_prach_config *m_pPRACHConfig;
42     struct xran_ru_config *m_pRUConfig;
43         struct xran_prach_cp_config *m_pPrachCPConfig;
44
45     struct xran_section_gen_info *m_pSectGenInfo = NULL;
46     int m_maxSections = 8;  /*  not used */
47     int lastsymbol;
48
49     struct rte_mbuf *m_pTestBuffer;
50
51     struct xran_cp_gen_params m_params;
52     struct xran_recv_packet_info m_pktInfo;
53     struct xran_cp_gen_params m_result;
54
55     uint8_t     m_dir;
56     std::string m_dirStr;
57     uint8_t     m_sectionType;
58
59     uint8_t     m_ccId, m_antId;
60     uint8_t     m_seqId;
61     uint8_t     m_frameId, m_subframeId, m_slotId;
62     uint8_t     m_symStart, m_symNum;
63     uint16_t    *m_prbStart = NULL, *m_prbNum = NULL;
64
65     uint8_t     m_iqWidth, m_compMethod;
66     uint16_t    m_beamId;
67     uint16_t    m_reMask = 0xfff;
68     uint16_t    m_sectionId;
69     uint8_t     m_filterIndex;
70     //uint16_t    m_timeOffset;
71     uint8_t     m_fftSize;
72
73     //define reference values
74     uint8_t     m_startSymId;
75     uint8_t     m_x;
76     uint8_t        m_filterIdx;
77     uint16_t       m_startPrbc;
78     uint8_t        m_numPrbc;
79     uint8_t        m_numSymbol;
80     uint16_t       m_timeOffset;
81     int32_t        m_freqOffset;
82     uint8_t       m_nrofPrachInSlot;
83     uint8_t        m_occassionsInPrachSlot;
84     uint8_t        m_y[XRAN_PRACH_CANDIDATE_Y];
85     uint8_t     m_isPRACHslot[XRAN_PRACH_CANDIDATE_SLOT];
86     int         m_prach_start_symbol;
87     int            m_prach_last_symbol;
88     uint8_t     m_SlotNrNum;
89     uint16_t    m_m_params_timeOffset;
90     uint16_t    m_id;
91
92     void SetUp() override
93     {
94         init_test("prach_functional");
95         memset(&m_xran_dev_ctx, 0, sizeof(struct xran_device_ctx));
96         //modify
97         m_xranConf = &m_xran_dev_ctx.fh_cfg;
98
99         m_pPRACHConfig = &m_xranConf->prach_conf;
100         m_pRUConfig = &m_xranConf->ru_conf;
101         m_pPrachCPConfig = &m_xran_dev_ctx.PrachCPConfig;
102         //initialize input parameters
103         m_xran_dev_ctx.dssPeriod = get_input_parameter<uint8_t>("dssperiod");
104         m_xranConf->frame_conf.nNumerology = get_input_parameter<uint8_t>("Numerology");
105         m_xranConf->frame_conf.nFrameDuplexType = get_input_parameter<uint8_t>("FrameDuplexType");
106         m_xranConf->log_level = get_input_parameter<uint32_t>("loglevel");
107         m_pPRACHConfig->nPrachConfIdx = get_input_parameter<uint8_t>("PrachConfIdx");
108         m_pPRACHConfig->nPrachFreqStart = get_input_parameter<uint16_t>("PrachFreqStart");
109         m_pPRACHConfig->nPrachFreqOffset = get_input_parameter<int32_t>("PrachFreqOffset");
110         m_pPRACHConfig->nPrachSubcSpacing = get_input_parameter<uint8_t>("PrachSubcSpacing");
111
112         m_pRUConfig->iqWidth = get_input_parameter<uint8_t>("iqWidth");
113         m_pRUConfig->compMeth = get_input_parameter<uint8_t>("compMeth");
114         m_pRUConfig->fftSize = get_input_parameter<uint8_t>("fftSize");
115
116         m_frameId = get_input_parameter<uint8_t>("frameId");
117         m_subframeId = get_input_parameter<uint8_t>("subframeId");
118         m_slotId = get_input_parameter<uint8_t>("slotId");
119         m_beamId = get_input_parameter<uint16_t>("beamId");
120         m_ccId = get_input_parameter<uint8_t>("ccId");
121         m_antId = get_input_parameter<uint8_t>("antId");
122
123         //initialize reference output
124         m_startSymId = get_reference_parameter<uint8_t>("startSymId");
125         m_x = get_reference_parameter<uint8_t>("x_value");
126
127         m_filterIdx = get_reference_parameter<uint8_t>("filterIdx");
128         m_startPrbc = get_reference_parameter<uint16_t>("startPrbc");
129         m_numPrbc = get_reference_parameter<uint8_t>("numPrbc");
130         m_timeOffset = get_reference_parameter<uint16_t>("timeOffset");
131         m_freqOffset = get_reference_parameter<uint32_t>("freqOffset");
132         m_nrofPrachInSlot = get_reference_parameter<uint8_t>("nrofPrachInSlot");
133         m_m_params_timeOffset = get_reference_parameter<uint16_t>("m_params_timeOffset");
134         m_id = get_reference_parameter<uint16_t>("id");
135         std::vector<uint8_t> y_vec = get_reference_parameter<std::vector<uint8_t>>("y_value");
136         for(int i=0; i < XRAN_PRACH_CANDIDATE_Y; i++) {
137             m_y[i] = y_vec[i];
138             }
139
140         m_numSymbol = get_reference_parameter<uint8_t>("numSymbol");
141         m_occassionsInPrachSlot = get_reference_parameter<uint8_t>("occassionsInPrachSlot");
142
143         std::vector<uint8_t> index_vec = get_reference_parameter<std::vector<uint8_t>>("isPRACHslot");
144         m_SlotNrNum = get_reference_parameter<uint8_t>("SlotNrNum");
145         for(int i = 0; i < XRAN_PRACH_CANDIDATE_SLOT; i++){
146             m_isPRACHslot[i]=0;
147             }
148         for(int i=0; i<m_SlotNrNum;i++){
149             m_isPRACHslot[index_vec[i]]=1;
150             }
151
152
153         m_prach_start_symbol = get_reference_parameter<int>("prach_start_symbol");
154         m_prach_last_symbol = get_reference_parameter<int>("prach_last_symbol");
155
156         /* allocate and prepare required data storage */
157         m_pSectGenInfo = new struct xran_section_gen_info[8];
158         ASSERT_NE(m_pSectGenInfo, nullptr);
159         m_params.sections = m_pSectGenInfo;
160         m_params.sections[0].info = new struct xran_section_info;
161
162         /* allocating an mbuf for packet generatrion */
163         m_pTestBuffer = (struct rte_mbuf*)rte_pktmbuf_alloc(_eth_mbuf_pool);
164         ASSERT_FALSE(m_pTestBuffer == NULL);
165
166     }
167
168     void TearDown() override
169     {
170         if(m_pTestBuffer != NULL)
171             rte_pktmbuf_free(m_pTestBuffer);
172         if(m_pSectGenInfo)
173             delete[] m_pSectGenInfo;
174         return;
175     }
176 };
177
178
179 TEST_P(PrachCheck, PrachPacketGen)//TestCaseName   TestName
180 {
181     int ret;
182     int32_t i;
183     void *pHandle = NULL;
184
185     /* Preparing input data for prach config */
186     ret = xran_init_prach(m_xranConf, &m_xran_dev_ctx, XRAN_RAN_5GNR);
187     ASSERT_TRUE(ret == XRAN_STATUS_SUCCESS);
188
189     /* Verify the result */
190     EXPECT_EQ(m_pPrachCPConfig->filterIdx, m_filterIdx);
191     EXPECT_EQ(m_pPrachCPConfig->startSymId, m_startSymId);
192     EXPECT_EQ(m_pPrachCPConfig->startPrbc, m_startPrbc);
193     EXPECT_EQ(m_pPrachCPConfig->numPrbc, m_numPrbc);
194     EXPECT_EQ(m_pPrachCPConfig->timeOffset, m_timeOffset);
195     EXPECT_EQ(m_pPrachCPConfig->freqOffset, m_freqOffset);
196     EXPECT_EQ(m_pPrachCPConfig->x, m_x);
197     EXPECT_EQ(m_pPrachCPConfig->nrofPrachInSlot, m_nrofPrachInSlot);
198     EXPECT_EQ(m_pPrachCPConfig->y[0], m_y[0]);
199     EXPECT_EQ(m_pPrachCPConfig->y[1], m_y[1]);
200     EXPECT_EQ(m_pPrachCPConfig->numSymbol, m_numSymbol);
201     EXPECT_EQ(m_pPrachCPConfig->occassionsInPrachSlot, m_occassionsInPrachSlot);
202     for (i = 0; i < XRAN_PRACH_CANDIDATE_SLOT; i++){
203         EXPECT_EQ(m_pPrachCPConfig->isPRACHslot[i], m_isPRACHslot[i]);
204     }
205     for (i = 0; i < XRAN_MAX_SECTOR_NR; i++){
206         EXPECT_EQ(m_xran_dev_ctx.prach_start_symbol[i], m_prach_start_symbol);
207         EXPECT_EQ(m_xran_dev_ctx.prach_last_symbol[i], m_prach_last_symbol);
208     }
209
210     ret = xran_open(pHandle, m_xranConf);
211     ASSERT_TRUE(ret == XRAN_STATUS_SUCCESS);
212
213     ret = generate_cpmsg_prach(&m_xran_dev_ctx, &m_params, m_pSectGenInfo, m_pTestBuffer, &m_xran_dev_ctx,
214         m_frameId, m_subframeId, m_slotId, 0,
215         m_beamId, m_ccId, m_antId, 0, 0);
216     ASSERT_TRUE(ret == XRAN_STATUS_SUCCESS);
217     /* Verify the result */
218     EXPECT_EQ(m_params.sectionType, XRAN_CP_SECTIONTYPE_3);
219     EXPECT_EQ(m_params.dir, XRAN_DIR_UL);
220     EXPECT_EQ(m_params.hdr.filterIdx, m_filterIdx);
221     EXPECT_EQ(m_params.hdr.frameId, m_frameId);
222     EXPECT_EQ(m_params.hdr.subframeId, m_subframeId);
223     EXPECT_EQ(m_params.hdr.slotId, m_slotId);
224     EXPECT_EQ(m_params.hdr.startSymId, m_startSymId);
225     EXPECT_EQ(m_params.hdr.iqWidth, (m_pRUConfig->iqWidth==16)?0:m_pRUConfig->iqWidth);
226     EXPECT_EQ(m_params.hdr.compMeth,m_pRUConfig->compMeth );
227     EXPECT_EQ(m_params.hdr.timeOffset, m_m_params_timeOffset);
228     EXPECT_EQ(m_params.hdr.fftSize,m_pRUConfig->fftSize);
229     EXPECT_EQ(m_params.hdr.scs, m_pPRACHConfig->nPrachSubcSpacing);
230     EXPECT_EQ(m_params.hdr.cpLength, 0);
231     EXPECT_EQ(m_params.numSections, 1);
232
233     EXPECT_EQ(m_params.sections[0].info->type, XRAN_CP_SECTIONTYPE_3);
234     EXPECT_EQ(m_params.sections[0].info->startSymId, m_startSymId);
235     EXPECT_EQ(m_params.sections[0].info->iqWidth, (m_pRUConfig->iqWidth==16)?0:m_pRUConfig->iqWidth);
236     EXPECT_EQ(m_params.sections[0].info->compMeth, m_pRUConfig->compMeth);
237
238     EXPECT_EQ(m_params.sections[0].info->id, m_id);
239     EXPECT_EQ(m_params.sections[0].info->rb, XRAN_RBIND_EVERY);
240     EXPECT_EQ(m_params.sections[0].info->symInc, XRAN_SYMBOLNUMBER_NOTINC);
241     EXPECT_EQ(m_params.sections[0].info->startPrbc, m_startPrbc);
242     EXPECT_EQ(m_params.sections[0].info->numPrbc, m_numPrbc);
243     EXPECT_EQ(m_params.sections[0].info->numSymbol, m_numSymbol);
244     EXPECT_EQ(m_params.sections[0].info->reMask, 0xfff);
245     EXPECT_EQ(m_params.sections[0].info->beamId, m_beamId);
246     EXPECT_EQ(m_params.sections[0].info->freqOffset, m_freqOffset);
247     EXPECT_EQ(m_xran_dev_ctx.prach_last_symbol[m_ccId], m_prach_last_symbol);
248     EXPECT_EQ(m_params.sections[0].info->ef, 0);
249     EXPECT_EQ(m_params.sections[0].exDataSize, 0);
250
251     if(m_params.sections[0].info != NULL)
252         delete[] m_params.sections[0].info;
253 }
254
255
256 INSTANTIATE_TEST_CASE_P(UnitTest, PrachCheck,
257         testing::ValuesIn(get_sequence(PrachCheck::get_number_of_cases("prach_functional"))));
258