1 /******************************************************************************
3 * Copyright (c) 2019 Intel.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 *******************************************************************************/
21 * @brief This file provides the API functions to build Control Plane Messages
22 * for XRAN Front Haul layer as defined in XRAN-FH.CUS.0-v02.01.
25 * @ingroup group_lte_source_xran
26 * @author Intel Corporation
30 #include <rte_branch_prediction.h>
32 #include "xran_common.h"
33 #include "xran_transport.h"
34 #include "xran_cp_api.h"
35 #include "xran_hash.h"
36 #include "xran_printf.h"
39 struct xran_sectioninfo_db {
42 #if defined(XRAN_CP_USES_HASHTABLE)
43 struct rte_hash *hash;
45 struct xran_section_info *list;
49 static struct xran_sectioninfo_db *sectiondb[XRAN_DIR_MAX];
51 int xran_cp_init_sectiondb(void *pHandle)
56 struct xran_sectioninfo_db *ptr;
60 #if !defined(PRACH_USES_SHARED_PORT)
61 num_eAxc = xran_get_num_eAxc(pHandle) * 2;
63 num_eAxc = xran_get_num_eAxc(pHandle);
66 for(i=0; i < XRAN_DIR_MAX; i++) {
67 size = (xran_get_num_cc(pHandle) * num_eAxc * sizeof(struct xran_sectioninfo_db));
68 print_log("Allocation Size for Section DB : %d (%dx%dx%ld)", size
69 , xran_get_num_cc(pHandle)
71 , sizeof(struct xran_sectioninfo_db));
72 sectiondb[i] = malloc(size);
74 if(sectiondb[i] == NULL) {
75 print_err("Allocation Failed for Section DB!");
76 return (-XRAN_ERRCODE_OUTOFMEMORY);
79 for(j=0; j < xran_get_num_cc(pHandle); j++) { // CC
80 for(k=0; k < num_eAxc; k++) { // antenna
81 ptr = sectiondb[i] + num_eAxc*j + k;
83 ptr->max_num = xran_get_max_sections(pHandle);
86 // allicate array to store section information
87 size = sizeof(struct xran_section_info)*xran_get_max_sections(pHandle);
88 print_log("Allocation Size for list : %d (%ldx%d)", size,
89 sizeof(struct xran_section_info),
90 xran_get_max_sections(pHandle));
91 ptr->list = malloc(size);
92 if(ptr-> list == NULL) {
93 print_err("Allocation Failed for Section DB!");
94 return (-XRAN_ERRCODE_OUTOFMEMORY);
97 #if defined(XRAN_CP_USES_HASHTABLE)
98 // Create hash table for section information
99 cid = rte_be_to_cpu_16(xran_compose_cid(xran_get_llscuid(pHandle), xran_get_sectorid(pHandle), j, k));
100 print_log("Creating hash for %04X", cid);
101 ptr->hash = xran_section_init_hash(i, cid, xran_get_max_sections(pHandle));
107 return (XRAN_ERRCODE_OK);
110 int xran_cp_free_sectiondb(void *pHandle)
114 struct xran_sectioninfo_db *ptr;
117 #if !defined(PRACH_USES_SHARED_PORT)
118 num_eAxc = xran_get_num_eAxc(pHandle) * 2;
120 num_eAxc = xran_get_num_eAxc(pHandle);
123 for(i=0; i < XRAN_DIR_MAX; i++) {
124 for(j=0; j < xran_get_num_cc(pHandle); j++) { // CC
125 for(k=0; k < num_eAxc; k++) { // antenna
126 ptr = sectiondb[i] + num_eAxc*j + k;
128 #if defined(XRAN_CP_USES_HASHTABLE)
129 xran_section_free_hash(ptr->hash);
131 if(ptr->list != NULL)
133 else print_err("list is NULL");
136 if(sectiondb[i] != NULL)
138 else print_err("sectiondb[%d] is NULL", i);
141 return (XRAN_ERRCODE_OK);
144 static struct xran_sectioninfo_db *xran_get_section_db(void *pHandle,
145 uint8_t dir, uint8_t cc_id, uint8_t ruport_id)
147 struct xran_sectioninfo_db *ptr;
150 if(unlikely(dir>=XRAN_DIR_MAX)) {
151 print_err("Invalid direction - %d", dir);
155 if(unlikely(cc_id >= xran_get_num_cc(pHandle))) {
156 print_err("Invalid CC id - %d", cc_id);
160 #if !defined(PRACH_USES_SHARED_PORT)
161 num_eAxc = xran_get_num_eAxc(pHandle) * 2;
163 num_eAxc = xran_get_num_eAxc(pHandle);
166 if(unlikely(ruport_id >= num_eAxc)) {
167 print_err("Invalid eAxC id - %d", ruport_id);
171 ptr = sectiondb[dir] + xran_get_num_eAxc(pHandle)*cc_id + ruport_id;
176 static struct xran_section_info *xran_get_section_info(struct xran_sectioninfo_db *ptr, uint16_t index)
178 if(unlikely(ptr == NULL))
181 if(unlikely(ptr->max_num < index)) {
182 print_err("Index is out of range - %d", index);
186 return(&(ptr->list[index]));
189 int xran_cp_add_section_info(void *pHandle,
190 uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
191 uint8_t subframe_id, uint8_t slot_id,
192 struct xran_section_info *info)
194 struct xran_sectioninfo_db *ptr;
195 struct xran_section_info *list;
197 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
198 if(unlikely(ptr == NULL)) {
199 return (-XRAN_ERRCODE_INVALIDPARAM);
202 if(unlikely(ptr->cur_index >= ptr->max_num)) {
203 print_err("No more space to add section information!");
204 return (-XRAN_ERRCODE_OUTOFMEMORY);
207 list = xran_get_section_info(ptr, ptr->cur_index);
209 rte_memcpy(list, info, sizeof(struct xran_section_info));
210 #if defined(XRAN_CP_USES_HASHTABLE)
211 xran_section_add_hash(ptr->hash, info->id, ptr->cur_index);
216 return (XRAN_ERRCODE_OK);
219 int xran_cp_add_multisection_info(void *pHandle,
220 uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
221 uint8_t subframe_id, uint8_t slot_id,
222 uint8_t num_sections, struct xran_section_gen_info *gen_info)
225 struct xran_sectioninfo_db *ptr;
226 struct xran_section_info *list;
228 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
229 if(unlikely(ptr == NULL)) {
230 return (-XRAN_ERRCODE_INVALIDPARAM);
233 if(unlikely(ptr->cur_index >= (ptr->max_num+num_sections))) {
234 print_err("No more space to add section information!");
235 return (-XRAN_ERRCODE_OUTOFMEMORY);
238 list = xran_get_section_info(ptr, ptr->cur_index);
240 for(i=0; i<num_sections; i++) {
241 rte_memcpy(&list[i], &gen_info[i].info, sizeof(struct xran_section_info));
242 #if defined(XRAN_CP_USES_HASHTABLE)
243 xran_section_add_hash(ptr->hash, gen_info[i].info.id, ptr->cur_index);
248 return (XRAN_ERRCODE_OK);
251 struct xran_section_info *xran_cp_find_section_info(void *pHandle,
252 uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
253 uint8_t subframe_id, uint8_t slot_id,
257 struct xran_sectioninfo_db *ptr;
260 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
261 if(unlikely(ptr == NULL))
264 #if defined(XRAN_CP_USES_HASHTABLE)
265 index = xran_section_lookup(ptr->hash, section_id);
266 if(unlikely(index > ptr->max_num)) {
267 print_err("Invalid index - %d", index);
272 print_dbg("No section ID in the list - %d", section_id);
276 return (xran_get_section_info(ptr, index));
278 for(index=0; index<ptr->cur_index; index++) {
279 if(ptr->list[index].id == section_id) {
280 print_dbg("Found section info %04X", section_id);
281 return (xran_get_section_info(ptr, index));
285 print_dbg("No section ID in the list - %d", section_id);
291 struct xran_section_info *xran_cp_iterate_section_info(void *pHandle,
292 uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
293 uint8_t subframe_id, uint8_t slot_id, uint32_t *next)
296 struct xran_sectioninfo_db *ptr;
299 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
300 if(unlikely(ptr == NULL))
303 #if defined(XRAN_CP_USES_HASHTABLE)
304 index = xran_section_iterate(ptr->hash, next);
305 if(unlikely(index > ptr->max_num)) {
306 print_err("Invalid index - %d", index);
311 print_dbg("No section ID in the list - %d", section_id);
315 return (xran_get_section_info(ptr, index));
318 if(*next < ptr->cur_index) {
320 return (xran_get_section_info(ptr, index));
323 print_dbg("No more sections in the list");
329 int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id)
332 struct xran_sectioninfo_db *ptr;
335 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
336 if(unlikely(ptr == NULL))
339 return (ptr->cur_index);
342 int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id)
344 struct xran_sectioninfo_db *ptr;
346 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id);
347 if(unlikely(ptr == NULL)) {
348 return (-XRAN_ERRCODE_INVALIDPARAM);
352 #if defined(XRAN_CP_USES_HASHTABLE)
353 xran_section_reset_hash(ptr->hash);
356 return (XRAN_ERRCODE_OK);
359 int xran_dump_sectiondb(void)
366 // Cyclic Prefix Length 5.4.4.14
367 // CP_length = cpLength * Ts * 2^u, Ts = 1/30.72MHz, if u is N/A, it shall be zero
368 #define CPLEN_TS (30720000)
369 inline uint16_t xran_get_cplength(int cpLength, int uval) // uval = -1 for N/A
371 return ((cpLength * ((uval<0)?0:(2<<uval))) / (CPLEN_TS));
374 // Frequency offset 5.4.5.11
375 // frequency_offset = freqOffset * SCS * 0.5
376 inline int32_t xran_get_freqoffset(int freqOffset, int scs)
378 return ((freqOffset * scs)>>1);
383 * @brief Fill the section body of type 0 in C-Plane packet
386 * A pointer to the section in the packet buffer
388 * A porinter to the information to generate a C-Plane packet
390 * 0 on success; non zero on failure
392 static int xran_prepare_section0(
393 struct xran_cp_radioapp_section0 *section,
394 struct xran_section_gen_info *params)
396 #if (XRAN_STRICT_PARM_CHECK)
397 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
398 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
399 return (-XRAN_ERRCODE_INVALIDPARAM);
403 section->hdr.sectionId = params->info.id;
404 section->hdr.rb = params->info.rb;
405 section->hdr.symInc = params->info.symInc;
406 section->hdr.startPrbc = params->info.startPrbc;
407 section->hdr.numPrbc = params->info.numPrbc;
409 section->hdr.u.s0.reMask = params->info.reMask;
410 section->hdr.u.s0.numSymbol = params->info.numSymbol;
411 section->hdr.u.s0.reserved = 0;
413 // for network byte order
414 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
416 return (XRAN_ERRCODE_OK);
419 * @brief Fill the section header of type 0 in C-Plane packet
422 * A pointer to the section header in the packet buffer
424 * A porinter to the information to generate a C-Plane packet
426 * 0 on success; non zero on failure
428 static int xran_prepare_section0_hdr(
429 struct xran_cp_radioapp_section0_header *s0hdr,
430 struct xran_cp_gen_params *params)
433 s0hdr->timeOffset = rte_cpu_to_be_16(params->hdr.timeOffset);
434 s0hdr->frameStructure.fftSize = params->hdr.fftSize;
435 s0hdr->frameStructure.uScs = params->hdr.scs;
436 s0hdr->cpLength = rte_cpu_to_be_16(params->hdr.cpLength);
439 return (XRAN_ERRCODE_OK);
443 * @brief Fill the section body of type 1 in C-Plane packet
444 * Extension is not supported.
447 * A pointer to the section header in the packet buffer
449 * A porinter to the information to generate a C-Plane packet
451 * 0 on success; non zero on failure
453 static int xran_prepare_section1(
454 struct xran_cp_radioapp_section1 *section,
455 struct xran_section_gen_info *params)
457 #if (XRAN_STRICT_PARM_CHECK)
458 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
459 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
460 return (-XRAN_ERRCODE_INVALIDPARAM);
464 section->hdr.sectionId = params->info.id;
465 section->hdr.rb = params->info.rb;
466 section->hdr.symInc = params->info.symInc;
467 section->hdr.startPrbc = params->info.startPrbc;
468 section->hdr.numPrbc = params->info.numPrbc;
470 section->hdr.u.s1.reMask = params->info.reMask;
471 section->hdr.u.s1.numSymbol = params->info.numSymbol;
472 section->hdr.u.s1.beamId = params->info.beamId;
474 if(params->info.ef) {
475 // TODO: need to handle extension
476 print_err("Extension is not supported!");
477 section->hdr.u.s1.ef = 0;
478 // section->hdr.u.s1.ef = params->info.ef;
481 section->hdr.u.s1.ef = 0;
483 // for network byte order
484 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
486 return (XRAN_ERRCODE_OK);
489 * @brief Fill the section header of type 1 in C-Plane packet
492 * A pointer to the section header in the packet buffer
494 * A porinter to the information to generate a C-Plane packet
496 * 0 on success; non zero on failure
498 static int xran_prepare_section1_hdr(
499 struct xran_cp_radioapp_section1_header *s1hdr,
500 struct xran_cp_gen_params *params)
502 s1hdr->udComp.udIqWidth = params->hdr.iqWidth;
503 s1hdr->udComp.udCompMeth = params->hdr.compMeth;
506 return (XRAN_ERRCODE_OK);
510 * @brief Fill the section body of type 3 in C-Plane packet
511 * Extension is not supported.
514 * A pointer to the section header in the packet buffer
516 * A porinter to the information to generate a C-Plane packet
518 * 0 on success; non zero on failure
520 static int xran_prepare_section3(
521 struct xran_cp_radioapp_section3 *section,
522 struct xran_section_gen_info *params)
524 #if (XRAN_STRICT_PARM_CHECK)
525 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
526 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
527 return (-XRAN_ERRCODE_INVALIDPARAM);
531 section->hdr.sectionId = params->info.id;
532 section->hdr.rb = params->info.rb;
533 section->hdr.symInc = params->info.symInc;
534 section->hdr.startPrbc = params->info.startPrbc;
535 section->hdr.numPrbc = params->info.numPrbc;
537 section->hdr.u.s3.reMask = params->info.reMask;
538 section->hdr.u.s3.numSymbol = params->info.numSymbol;
539 section->hdr.u.s3.beamId = params->info.beamId;
541 section->freqOffset = rte_cpu_to_be_32(params->info.freqOffset)>>8;
542 section->reserved = 0;
544 if(params->info.ef) {
545 // TODO: need to handle extension
546 print_err("Extension is not supported!");
547 section->hdr.u.s3.ef = 0;
548 // section->hdr.u.s3.ef = params->info.ef;
551 section->hdr.u.s3.ef = 0;
553 // for network byte order (header, 8 bytes)
554 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
556 return (XRAN_ERRCODE_OK);
559 * @brief Fill the section header of type 3 in C-Plane packet
562 * A pointer to the section header in the packet buffer
564 * A porinter to the information to generate a C-Plane packet
566 * 0 on success; non zero on failure
568 static int xran_prepare_section3_hdr(
569 struct xran_cp_radioapp_section3_header *s3hdr,
570 struct xran_cp_gen_params *params)
573 s3hdr->timeOffset = rte_cpu_to_be_16(params->hdr.timeOffset);
574 s3hdr->frameStructure.fftSize = params->hdr.fftSize;
575 s3hdr->frameStructure.uScs = params->hdr.scs;
576 s3hdr->cpLength = rte_cpu_to_be_16(params->hdr.cpLength);
577 s3hdr->udComp.udIqWidth = params->hdr.iqWidth;
578 s3hdr->udComp.udCompMeth = params->hdr.compMeth;
580 return (XRAN_ERRCODE_OK);
584 * @brief add sections to C-Plane packet
585 * Section type 1 and 3 are supported.
588 * A pointer to the packet buffer
590 * A porinter to the information to generate a C-Plane packet
592 * 0 on success; non zero on failure
594 int xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
600 int (*xran_prepare_section_func)(void *section, void *params);
604 switch(params->sectionType) {
605 case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
606 section_size = sizeof(struct xran_cp_radioapp_section0);
607 xran_prepare_section_func = (int (*)(void *, void *))xran_prepare_section0;
610 case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
611 section_size = sizeof(struct xran_cp_radioapp_section1);
612 xran_prepare_section_func = (int (*)(void *, void *))xran_prepare_section1;
615 case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
616 section_size = sizeof(struct xran_cp_radioapp_section3);
617 xran_prepare_section_func = (int (*)(void *, void *))xran_prepare_section3;
620 case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
621 case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
622 case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
625 xran_prepare_section_func = NULL;
626 print_err("Section Type %d is not supported!", params->sectionType);
627 return (-XRAN_ERRCODE_INVALIDPARAM);
630 if(unlikely(xran_prepare_section_func == NULL)) {
631 print_err("Section Type %d is not supported!", params->sectionType);
632 return (-XRAN_ERRCODE_INVALIDPARAM);
635 for(i=0; i<params->numSections; i++) {
636 section = rte_pktmbuf_append(mbuf, section_size);
637 if(section == NULL) {
638 print_err("Fail to allocate the space for section[%d]!", i);
639 return (-XRAN_ERRCODE_OUTOFMEMORY);
642 if(unlikely(xran_prepare_section_func((void *)section,
643 (void *)¶ms->sections[i]) < 0)) {
644 return (-XRAN_ERRCODE_INVALIDPARAM);
647 totalen += section_size;
654 * @brief fill the information of a radio application header in a C-Plane packet
657 * A pointer to the application header in the packet buffer
659 * A porinter to the information to generate a C-Plane packet
661 * 0 on success; non zero on failure
663 static inline int xran_prepare_radioapp_common_header(
664 struct xran_cp_radioapp_common_header *apphdr,
665 struct xran_cp_gen_params *params)
668 #if (XRAN_STRICT_PARM_CHECK)
669 if(unlikely(params->dir != XRAN_DIR_DL && params->dir != XRAN_DIR_UL)) {
670 print_err("Invalid direction!");
671 return (-XRAN_ERRCODE_INVALIDPARAM);
673 if(unlikely(params->hdr.slotId > XRAN_SLOTID_MAX)) {
674 print_err("Invalid Slot ID!");
675 return (-XRAN_ERRCODE_INVALIDPARAM);
677 if(unlikely(params->hdr.startSymId > XRAN_SYMBOLNUMBER_MAX)) {
678 print_err("Invalid Symbol ID!");
679 return (-XRAN_ERRCODE_INVALIDPARAM);
683 apphdr->dataDirection = params->dir;
684 apphdr->payloadVer = XRAN_PAYLOAD_VER;
685 apphdr->filterIndex = params->hdr.filterIdx;
686 apphdr->frameId = params->hdr.frameId;
687 apphdr->subframeId = params->hdr.subframeId;
688 apphdr->slotId = params->hdr.slotId;
689 apphdr->startSymbolId = params->hdr.startSymId;
690 apphdr->numOfSections = params->numSections;
691 apphdr->sectionType = params->sectionType;
693 // radio app header has common parts of 4bytes for all section types
694 *((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
696 return (XRAN_ERRCODE_OK);
700 * @brief add a radio application header in a C-Plane packet
703 * A pointer to the packet buffer
705 * A porinter to the information to generate a C-Plane packet
707 * 0 on success; non zero on failure
709 int xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
713 struct xran_cp_radioapp_common_header *apphdr;
714 int (*xran_prepare_radioapp_section_hdr_func)(void *hdr, void *params);
717 #if (XRAN_STRICT_PARM_CHECK)
718 if(unlikely(params->sectionType >= XRAN_CP_SECTIONTYPE_MAX)) {
719 print_err("Invalid Section Type - %d", params->sectionType);
720 return (-XRAN_ERRCODE_INVALIDPARAM);
724 switch(params->sectionType) {
725 case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
726 xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section0_hdr;
727 totalen = sizeof(struct xran_cp_radioapp_section0_header);
730 case XRAN_CP_SECTIONTYPE_1: // Most DL/UL Radio Channels
731 xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section1_hdr;
732 totalen = sizeof(struct xran_cp_radioapp_section1_header);
735 case XRAN_CP_SECTIONTYPE_3: // PRACH and Mixed-numerology Channels
736 xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section3_hdr;
737 totalen = sizeof(struct xran_cp_radioapp_section3_header);
740 case XRAN_CP_SECTIONTYPE_5: // UE scheduling information, not supported
741 case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
742 case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
744 print_err("Section Type %d is not supported!", params->sectionType);
745 xran_prepare_radioapp_section_hdr_func = NULL;
747 return (-XRAN_ERRCODE_INVALIDPARAM);
750 apphdr = (struct xran_cp_radioapp_common_header *)rte_pktmbuf_append(mbuf, totalen);
751 if(unlikely(apphdr == NULL)) {
752 print_err("Fail to reserve the space for radio application header!");
753 return (-XRAN_ERRCODE_OUTOFMEMORY);
756 ret = xran_prepare_radioapp_common_header(apphdr, params);
757 if(unlikely(ret < 0)) {
761 if(likely(xran_prepare_radioapp_section_hdr_func)) {
762 xran_prepare_radioapp_section_hdr_func(apphdr, params);
765 print_err("xran_prepare_radioapp_section_hdr_func is NULL!");
766 return (-XRAN_ERRCODE_INVALIDPARAM);
773 * @brief Create a C-Plane packet
774 * Transport layer fragmentation is not supported.
776 * @ingroup xran_cp_pkt
779 * A pointer to the packet buffer
781 * A porinter to the information to generate a C-Plane packet
783 * Component Carrier ID for this C-Plane message
785 * Antenna ID(RU Port ID) for this C-Plane message
787 * Sequence ID for this C-Plane message
789 * 0 on success; non zero on failure
791 int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
792 struct xran_cp_gen_params *params,
793 uint8_t CC_ID, uint8_t Ant_ID,
798 struct xran_ecpri_hdr *ecpri_hdr;
801 ecpri_hdr = (struct xran_ecpri_hdr *)rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
802 if(unlikely(ecpri_hdr == NULL)) {
803 print_err("Fail to allocate the space for eCPRI hedaer!");
804 return (-XRAN_ERRCODE_OUTOFMEMORY);
807 ecpri_hdr->ecpri_ver = XRAN_ECPRI_VER;
808 ecpri_hdr->ecpri_resv = 0; // should be zero
809 ecpri_hdr->ecpri_concat = 0;
810 ecpri_hdr->ecpri_mesg_type = ECPRI_RT_CONTROL_DATA;
811 ecpri_hdr->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);
812 ecpri_hdr->ecpri_seq_id.seq_id = seq_id;
814 /* TODO: Transport layer fragmentation is not supported */
815 ecpri_hdr->ecpri_seq_id.sub_seq_id = 0;
816 ecpri_hdr->ecpri_seq_id.e_bit = 1;
820 ret = xran_append_radioapp_header(mbuf, params);
826 ret = xran_append_control_section(mbuf, params);
832 // printf("Total Payload length = %d\n", payloadlen);
833 ecpri_hdr->ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
835 return (XRAN_ERRCODE_OK);
838 ///////////////////////////////////////
840 int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result)
842 struct xran_ecpri_hdr *ecpri_hdr;
843 struct xran_cp_radioapp_common_header *apphdr;
849 ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);
850 if(ecpri_hdr == NULL) {
851 print_err("Invalid packet - eCPRI hedaer!");
852 return (-XRAN_ERRCODE_INVALIDPACKET);
855 /* Process eCPRI header. */
856 if(ecpri_hdr->ecpri_ver != XRAN_ECPRI_VER) {
857 print_err("Invalid eCPRI version - %d", ecpri_hdr->ecpri_ver);
858 ret = -XRAN_ERRCODE_INVALIDPACKET;
861 if(ecpri_hdr->ecpri_resv != 0) {
862 print_err("Invalid reserved field - %d", ecpri_hdr->ecpri_resv);
863 ret = -XRAN_ERRCODE_INVALIDPACKET;
866 if(ecpri_hdr->ecpri_mesg_type != ECPRI_RT_CONTROL_DATA) {
867 print_err("Not C-Plane Message - %d", ecpri_hdr->ecpri_mesg_type);
868 ret = -XRAN_ERRCODE_INVALIDPACKET;
871 printf("[CPlane] [%04X:%03d-%3d-%d] len=%5d\n",
872 rte_be_to_cpu_16(ecpri_hdr->ecpri_xtc_id),
873 ecpri_hdr->ecpri_seq_id.seq_id, ecpri_hdr->ecpri_seq_id.sub_seq_id,
874 ecpri_hdr->ecpri_seq_id.e_bit,
875 rte_be_to_cpu_16(ecpri_hdr->ecpri_payl_size));
878 /* Process radio header. */
879 apphdr = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_ecpri_hdr));
881 print_err("Invalid packet - radio app hedaer!");
882 return (-XRAN_ERRCODE_INVALIDPACKET);
885 *((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
887 if(apphdr->payloadVer != XRAN_PAYLOAD_VER) {
888 print_err("Invalid Payload version - %d", apphdr->payloadVer);
889 ret = -XRAN_ERRCODE_INVALIDPACKET;
892 result->dir = apphdr->dataDirection;
893 result->hdr.filterIdx = apphdr->filterIndex;
894 result->hdr.frameId = apphdr->frameId;
895 result->hdr.subframeId = apphdr->subframeId;
896 result->hdr.slotId = apphdr->slotId;
897 result->hdr.startSymId = apphdr->startSymbolId;
898 result->sectionType = apphdr->sectionType;
899 result->numSections = apphdr->numOfSections;
901 switch(apphdr->sectionType) {
902 case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
904 struct xran_cp_radioapp_section0_header *hdr;
905 struct xran_cp_radioapp_section0 *section;
907 hdr = (struct xran_cp_radioapp_section0_header*)apphdr;
909 result->hdr.fftSize = rte_be_to_cpu_16(hdr->timeOffset);
910 result->hdr.scs = hdr->frameStructure.fftSize;
911 result->hdr.timeOffset = hdr->frameStructure.uScs;
912 result->hdr.cpLength = rte_be_to_cpu_16(hdr->cpLength);
913 //hdr->reserved; /* should be zero */
915 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0_header));
916 if(section == NULL) {
917 print_err("Invalid packet 0 - radio app hedaer!");
918 return (-XRAN_ERRCODE_INVALIDPACKET);
920 for(i=0; i<result->numSections; i++) {
921 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
923 result->sections[i].info.type = apphdr->sectionType;
924 result->sections[i].info.id = section->hdr.sectionId;
925 result->sections[i].info.rb = section->hdr.rb;
926 result->sections[i].info.symInc = section->hdr.symInc;
927 result->sections[i].info.startPrbc = section->hdr.startPrbc;
928 result->sections[i].info.numPrbc = section->hdr.numPrbc,
929 result->sections[i].info.numSymbol = section->hdr.u.s0.numSymbol;
930 result->sections[i].info.reMask = section->hdr.u.s0.reMask;
931 //section->hdr.u.s0.reserved; /* should be zero */
933 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0));
934 if(section == NULL) {
935 print_err("Invalid packet 0 - number of section [%d:%d]!",
936 result->numSections, i);
937 result->numSections = i;
938 ret = (-XRAN_ERRCODE_INVALIDPACKET);
945 case XRAN_CP_SECTIONTYPE_1: // Most DL/UL Radio Channels
947 struct xran_cp_radioapp_section1_header *hdr;
948 struct xran_cp_radioapp_section1 *section;
950 hdr = (struct xran_cp_radioapp_section1_header*)apphdr;
952 result->hdr.iqWidth = hdr->udComp.udIqWidth;
953 result->hdr.compMeth = hdr->udComp.udCompMeth;
955 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section1_header));
956 if(section == NULL) {
957 print_err("Invalid packet 1 - radio app hedaer!");
958 return (-XRAN_ERRCODE_INVALIDPACKET);
961 for(i=0; i<result->numSections; i++) {
962 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
964 result->sections[i].info.type = apphdr->sectionType;
965 result->sections[i].info.id = section->hdr.sectionId;
966 result->sections[i].info.rb = section->hdr.rb;
967 result->sections[i].info.symInc = section->hdr.symInc;
968 result->sections[i].info.startPrbc = section->hdr.startPrbc;
969 result->sections[i].info.numPrbc = section->hdr.numPrbc,
970 result->sections[i].info.numSymbol = section->hdr.u.s1.numSymbol;
971 result->sections[i].info.reMask = section->hdr.u.s1.reMask;
972 result->sections[i].info.beamId = section->hdr.u.s1.beamId;
973 result->sections[i].info.ef = section->hdr.u.s1.ef;
975 if(section->hdr.u.s1.ef) {
976 // TODO: handle section extension
981 section = (void *)rte_pktmbuf_adj(mbuf,
982 sizeof(struct xran_cp_radioapp_section1)+extlen);
983 if(section == NULL) {
984 print_err("Invalid packet 1 - number of section [%d:%d]!",
985 result->numSections, i);
986 result->numSections = i;
987 ret = (-XRAN_ERRCODE_INVALIDPACKET);
994 case XRAN_CP_SECTIONTYPE_3: // PRACH and Mixed-numerology Channels
996 struct xran_cp_radioapp_section3_header *hdr;
997 struct xran_cp_radioapp_section3 *section;
999 hdr = (struct xran_cp_radioapp_section3_header*)apphdr;
1001 result->hdr.timeOffset = rte_be_to_cpu_16(hdr->timeOffset);
1002 result->hdr.scs = hdr->frameStructure.uScs;
1003 result->hdr.fftSize = hdr->frameStructure.fftSize;
1004 result->hdr.cpLength = rte_be_to_cpu_16(hdr->cpLength);
1005 result->hdr.iqWidth = hdr->udComp.udIqWidth;
1006 result->hdr.compMeth = hdr->udComp.udCompMeth;
1008 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3_header));
1009 if(section == NULL) {
1010 print_err("Invalid packet 3 - radio app hedaer!");
1011 return (-XRAN_ERRCODE_INVALIDPACKET);
1014 for(i=0; i<result->numSections; i++) {
1015 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
1017 result->sections[i].info.type = apphdr->sectionType;
1018 result->sections[i].info.id = section->hdr.sectionId;
1019 result->sections[i].info.rb = section->hdr.rb;
1020 result->sections[i].info.symInc = section->hdr.symInc;
1021 result->sections[i].info.startPrbc = section->hdr.startPrbc;
1022 result->sections[i].info.numPrbc = section->hdr.numPrbc,
1023 result->sections[i].info.numSymbol = section->hdr.u.s3.numSymbol;
1024 result->sections[i].info.reMask = section->hdr.u.s3.reMask;
1025 result->sections[i].info.beamId = section->hdr.u.s3.beamId;
1026 result->sections[i].info.ef = section->hdr.u.s3.ef;
1027 result->sections[i].info.freqOffset = ((int32_t)rte_be_to_cpu_32(section->freqOffset))>>8;
1029 if(section->reserved) {
1030 print_err("Invalid packet 3 - section[%d:%d]", i, section->reserved);
1031 ret = -XRAN_ERRCODE_INVALIDPACKET;
1034 if(section->hdr.u.s3.ef) {
1035 // TODO: handle section extension
1040 section = (void *)rte_pktmbuf_adj(mbuf,
1041 sizeof(struct xran_cp_radioapp_section3)+extlen);
1042 if(section == NULL) {
1043 print_err("Invalid packet 3 - number of section [%d:%d]!",
1044 result->numSections, i);
1045 result->numSections = i;
1046 ret = (-XRAN_ERRCODE_INVALIDPACKET);
1053 case XRAN_CP_SECTIONTYPE_5: // UE scheduling information, not supported
1054 case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
1055 case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
1057 ret = -XRAN_ERRCODE_INVALIDPARAM;
1058 print_err("Non-supported Section Type - %d", apphdr->sectionType);
1062 printf("[CP-%s] [%3d:%2d:%2d] section%d[%d] startSym=%d filterIdx=%X IQwidth=%d CompMeth=%d\n",
1063 result->dir?"DL":"UL",
1064 result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
1065 result->sectionType, result->numSections,
1066 result->hdr.startSymId,
1067 result->hdr.filterIdx,
1068 result->hdr.iqWidth, result->hdr.compMeth);
1070 for(i=0; i<result->numSections; i++) {
1071 printf(" >> %3d:%04X| rb=%d symInc=%d numSym=%d startPrbc=%02X numPrbc=%d reMask=%03X beamId=%04X freqOffset=%d ef=%d\n",
1072 i, result->sections[i].info.id,
1073 result->sections[i].info.rb,
1074 result->sections[i].info.symInc, result->sections[i].info.numSymbol,
1075 result->sections[i].info.startPrbc, result->sections[i].info.numPrbc,
1076 result->sections[i].info.reMask,
1077 result->sections[i].info.beamId,
1078 result->sections[i].info.freqOffset,
1079 result->sections[i].info.ef);
1080 // result->sections[i].info.type