provide follow features implementation:
[o-du/phy.git] / fhi_lib / lib / src / xran_up_api.c
index 3fb5ba9..d748e2c 100644 (file)
-/******************************************************************************
-*
-*   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.
-*
-*******************************************************************************/
-
-/**
- * @brief This file provides the implementation of User Plane Messages APIs.
- *
- * @file xran_up_api.c
- * @ingroup group_lte_source_xran
- * @author Intel Corporation
- *
- **/
-#include <inttypes.h>
-
-#include <rte_memcpy.h>
-#include <rte_mbuf.h>
-
-#include "xran_fh_o_du.h"
-#include "xran_transport.h"
-#include "xran_up_api.h"
-#include "xran_printf.h"
-#include "xran_mlog_lnx.h"
-
-extern uint32_t xran_lib_ota_tti;
-
-/**
- * @brief Builds eCPRI header in xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet
- * @param iq_data_num_bytes Number of bytes in IQ data buffer
- * @param iq_data_offset Number of elements already sent
- * @return int int 0 on success, non zero on failure
- */
-static int build_ecpri_hdr(struct rte_mbuf *mbuf,
-    const uint32_t iq_data_num_bytes,
-    const uint32_t iq_data_offset,
-    uint8_t alignment)
-{
-    struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)
-        rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
-
-    uint16_t iq_samples_bytes_in_mbuf = rte_pktmbuf_tailroom(mbuf) -
-        sizeof(struct radio_app_common_hdr) - sizeof(struct data_section_hdr);
-
-    iq_samples_bytes_in_mbuf -= (iq_samples_bytes_in_mbuf % alignment);
-
-    if (NULL == ecpri_hdr)
-        return 1;
-
-    ecpri_hdr->cmnhdr.ecpri_ver = XRAN_ECPRI_VER;
-    ecpri_hdr->cmnhdr.ecpri_resv = 0;
-    ecpri_hdr->cmnhdr.ecpri_concat = 0;
-    ecpri_hdr->cmnhdr.ecpri_mesg_type = ECPRI_IQ_DATA;
-
-    if (iq_data_offset + iq_samples_bytes_in_mbuf > iq_data_num_bytes) {
-        ecpri_hdr->cmnhdr.ecpri_payl_size =
-            rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
-                sizeof(struct data_section_hdr) +
-                (iq_data_num_bytes - iq_data_offset) +
-                xran_get_ecpri_hdr_size());
-        ecpri_hdr->ecpri_seq_id.e_bit = 1;  /* last segment */
-    } else {
-        ecpri_hdr->cmnhdr.ecpri_payl_size =
-            rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
-                sizeof(struct data_section_hdr) +
-                iq_samples_bytes_in_mbuf +
-                xran_get_ecpri_hdr_size());
-        ecpri_hdr->ecpri_seq_id.e_bit = 0;
-    }
-
-//    ecpri_hdr->ecpri_xtc_id = 0;    /* currently not used */
-    ecpri_hdr->ecpri_seq_id.seq_id = 0;
-    ecpri_hdr->ecpri_seq_id.sub_seq_id = iq_data_offset /
-        iq_samples_bytes_in_mbuf;
-
-    return 0;
-}
-
-/**
- * @brief Builds eCPRI header in xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet
- * @param ecpri_mesg_type eCPRI message type
- * @param payl_size the size in bytes of the payload part of eCPRI message
- * @param CC_ID Component Carrier ID for ecpriRtcid/ecpriPcid
- * @param Ant_ID Antenna ID for ecpriRtcid/ecpriPcid
- * @param seq_id Message identifier for eCPRI message
- * @return int int 0 on success, non zero on failure
- */
-static int xran_build_ecpri_hdr_ex(struct rte_mbuf *mbuf,
-                              uint8_t ecpri_mesg_type,
-                              int payl_size,
-                              uint8_t CC_ID,
-                              uint8_t Ant_ID,
-                              uint8_t seq_id)
-{
-    char *pChar = rte_pktmbuf_mtod(mbuf, char*);
-    struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)(pChar + sizeof(struct ether_hdr));
-
-    if (NULL == ecpri_hdr)
-        return 1;
-
-    ecpri_hdr->cmnhdr.ecpri_ver       = XRAN_ECPRI_VER;
-    ecpri_hdr->cmnhdr.ecpri_resv      = 0;     // should be zero
-    ecpri_hdr->cmnhdr.ecpri_concat    = 0;
-    ecpri_hdr->cmnhdr.ecpri_mesg_type = ecpri_mesg_type;
-    ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(payl_size
-                                    + sizeof(struct data_section_hdr)
-                                    + sizeof(struct radio_app_common_hdr)
-                                    + xran_get_ecpri_hdr_size());
-
-    /* one to one lls-CU to RU only and band sector is the same */
-    ecpri_hdr->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);
-
-    ecpri_hdr->ecpri_seq_id.seq_id = seq_id;
-
-    /* no transport layer fragmentation supported */
-    ecpri_hdr->ecpri_seq_id.sub_seq_id  = 0;
-    ecpri_hdr->ecpri_seq_id.e_bit       = 1;
-
-    return 0;
-}
-
-
-/**
- * @brief Builds application layer of xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet
- * @param app_hdr_input Radio App common header structure to be set in mbuf
- *                      packet.
- * @return int 0 on success, non zero on failure
- */
-static int build_application_layer(
-    struct rte_mbuf *mbuf,
-    const struct radio_app_common_hdr *app_hdr_input)
-{
-    char *pChar = rte_pktmbuf_mtod(mbuf, char*);
-    struct radio_app_common_hdr *app_hdr = (struct radio_app_common_hdr *)(pChar + sizeof(struct ether_hdr)
-        + sizeof (struct xran_ecpri_hdr));
-
-    if (NULL == app_hdr)
-        return 1;
-
-    rte_memcpy(app_hdr, app_hdr_input, sizeof(struct radio_app_common_hdr));
-
-    return 0;
-}
-
-/**
- * @brief Builds section header in xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet
- * @param sec_hdr Section header structure to be set in mbuf packet
- * @return int 0 on success, non zero on failure
- */
-static int build_section_hdr(
-    struct rte_mbuf *mbuf,
-    const struct data_section_hdr *sec_hdr)
-{
-    char *pChar = rte_pktmbuf_mtod(mbuf, char*);
-    struct data_section_hdr *section_hdr = (struct data_section_hdr *)
-        (pChar + sizeof(struct ether_hdr) + sizeof (struct xran_ecpri_hdr) + sizeof(struct radio_app_common_hdr));
-
-    if (NULL == section_hdr)
-        return 1;
-
-    rte_memcpy(section_hdr, sec_hdr, sizeof(struct data_section_hdr));
-
-    return 0;
-}
-/**
- * @brief Function for appending IQ samples data to the mbuf.
- *
- * @param mbuf Initialized rte_mbuf packet.
- * @param iq_data_start Address of the first element in IQ data array.
- * @param iq_data_num_bytes Size of the IQ data array.
- * @param iq_data_offset IQ data btyes already sent.
- * @return uint16_t Bytes that have been appended to the packet.
- */
-static uint16_t append_iq_samples_ex(
-    struct rte_mbuf *mbuf,
-    const void *iq_data_start,
-    const uint32_t iq_data_num_bytes,
-    enum xran_input_byte_order iq_buf_byte_order,
-    uint32_t do_copy)
-{
-    char *pChar = rte_pktmbuf_mtod(mbuf, char*);
-    void *iq_sam_buf  = (pChar + sizeof(struct ether_hdr) + sizeof (struct xran_ecpri_hdr)
-                        + sizeof(struct radio_app_common_hdr)
-                        + sizeof(struct data_section_hdr));
-
-    if (iq_sam_buf == NULL){
-        print_err("iq_sam_buf == NULL\n");
-        return 0;
-    }
-    if(iq_buf_byte_order == XRAN_CPU_LE_BYTE_ORDER){
-        int idx = 0;
-        uint16_t *psrc = (uint16_t *)iq_data_start;
-        uint16_t *pdst = (uint16_t *)iq_sam_buf;
-        /* CPU byte order (le) of IQ to network byte order (be) */
-        for (idx = 0; idx < iq_data_num_bytes/sizeof(int16_t); idx++){
-            pdst[idx]  =  (psrc[idx]>>8) | (psrc[idx]<<8); //rte_cpu_to_be_16(psrc[idx]);
-        }
-    }else if(iq_buf_byte_order == XRAN_NE_BE_BYTE_ORDER){
-        if(do_copy)
-           rte_memcpy(iq_sam_buf, (uint8_t *)iq_data_start,  iq_data_num_bytes);
-    }
-
-    return iq_data_num_bytes;
-}
-
-/**
- * @brief Function for appending IQ samples data to the mbuf.
- *
- * @param mbuf Initialized rte_mbuf packet.
- * @param iq_data_start Address of the first element in IQ data array.
- * @param iq_data_num_bytes Size of the IQ data array.
- * @param iq_data_offset IQ data btyes already sent.
- * @return uint16_t Bytes that have been appended to the packet.
- */
-static uint16_t append_iq_samples(
-    struct rte_mbuf *mbuf,
-    const void *iq_data_start,
-    const uint32_t iq_data_num_bytes,
-    const uint32_t iq_data_offset,
-    const uint8_t alignment)
-{
-    uint16_t iq_bytes_to_send = 0;
-    uint16_t free_space_in_pkt = rte_pktmbuf_tailroom(mbuf);
-
-    if (free_space_in_pkt > iq_data_num_bytes - iq_data_offset)
-        iq_bytes_to_send = iq_data_num_bytes - iq_data_offset;
-    else
-        iq_bytes_to_send = free_space_in_pkt;
-
-    /* don't cut off an iq in half */
-    iq_bytes_to_send -= iq_bytes_to_send % alignment;
-
-    void *iq_sam_buf = (void *)rte_pktmbuf_append(mbuf, iq_bytes_to_send);
-
-    rte_memcpy(iq_sam_buf, (uint8_t *)iq_data_start + iq_data_offset,
-            iq_bytes_to_send);
-
-    return iq_bytes_to_send;
-}
-
-/**
- * @brief Builds compression header in xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet
- * @param compression_hdr Section compression header structure
- *                to be set in mbuf packet
- * @return int 0 on success, non zero on failure
- */
-static int build_compression_hdr(
-    struct rte_mbuf *mbuf,
-    const struct data_section_compression_hdr *compr_hdr)
-{
-    struct data_section_compression_hdr *compression_hdr =
-        (struct data_section_compression_hdr *)
-        rte_pktmbuf_append(mbuf, sizeof(*compression_hdr));
-
-    if (NULL == compression_hdr)
-        return 1;
-
-    rte_memcpy(compression_hdr, compr_hdr, sizeof(*compression_hdr));
-
-    return 0;
-}
-
-/**
- * @brief Appends compression parameter in xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet
- * @param ud_comp_paramr Compression param to be set in mbuf packet
- * @return int 0 on success, non zero on failure
- */
-static int append_comp_param(struct rte_mbuf *mbuf, union compression_params *ud_comp_param)
-{
-    union compression_params *compr_param =
-        (union compression_params *)rte_pktmbuf_append(mbuf, sizeof(union compression_params));
-
-    if (NULL == compr_param)
-        return 1;
-
-    rte_memcpy(compr_param, ud_comp_param, sizeof(union compression_params));
-
-    return 0;
-}
-
-/**
- * @brief Function for starting preparion of IQ samples portions
- *        to be sent in xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet.
- * @param iq_data_start Address of the first element in IQ data array.
- * @param iq_data_num_bytes Size of the IQ data array.
- * @param iq_data_offset IQ data bytes already sent.
- * @param alignment Size of IQ data alignment.
- * @param pkt_gen_params Struct with parameters used for building packet
- * @return int Number of bytes that have been appended
-               to the packet within a single data section appended.
- */
-int xran_prepare_iq_symbol_portion(
-    struct rte_mbuf *mbuf,
-    const void *iq_data_start,
-    const uint32_t iq_data_num_bytes,
-    uint32_t *iq_data_offset,
-    uint8_t alignment,
-    struct xran_up_pkt_gen_params *params,
-    int sub_seq_id)
-{
-    uint8_t i = 0;
-    uint16_t iq_sam_bytes_sent = 0;
-
-    if (build_ecpri_hdr(mbuf, iq_data_num_bytes, *iq_data_offset, alignment))
-        return 0;
-
-    if (build_application_layer(mbuf, &(params->app_params)) != 0)
-        return 0;
-
-    if (build_section_hdr(mbuf, &(params->sec_hdr)) != 0)
-        return 0;
-
-    if(params->compr_hdr_param.ud_comp_hdr.ud_comp_meth != XRAN_COMPMETHOD_NONE) {
-        if (build_compression_hdr(mbuf, &(params->compr_hdr_param)) !=0)
-            return 0;
-
-        if(append_comp_param(mbuf, &(params->compr_param)) !=0)
-            return 0;
-        }
-
-    return append_iq_samples(mbuf, iq_data_start, iq_data_num_bytes,
-           (*iq_data_offset), alignment);
-}
-
-/**
- * @brief Function for extracting all IQ samples from xRAN packet
- *        holding a single data section
- * @param iq_data_start Address of the first element in IQ data array.
- * @param symb_id Symbol ID to be extracted from ecpri header
- * @param seq_id  Sequence ID to be extracted from radio header
- * @return int Size of remaining mbuf filled with IQ samples
-               zero on failure
- */
-int xran_extract_iq_samples(struct rte_mbuf *mbuf,
-    void **iq_data_start,
-    uint8_t *CC_ID,
-    uint8_t *Ant_ID,
-    uint8_t *frame_id,
-    uint8_t *subframe_id,
-    uint8_t *slot_id,
-    uint8_t *symb_id,
-    struct ecpri_seq_id *seq_id,
-    uint16_t *num_prbu,
-    uint16_t *start_prbu,
-    uint16_t *sym_inc,
-    uint16_t *rb,
-    uint16_t *sect_id)
-{
-#if XRAN_MLOG_VAR
-    uint32_t mlogVar[10];
-    uint32_t mlogVarCnt = 0;
-#endif
-    struct xran_eaxc_info result;
-
-    if (NULL == mbuf)
-        return 0;
-    if (NULL == iq_data_start)
-        return 0;
-
-    /* Process eCPRI header. */
-    const struct xran_ecpri_hdr *ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);
-    if (ecpri_hdr == NULL)
-        return 0;
-
-    if (seq_id)
-        *seq_id = ecpri_hdr->ecpri_seq_id;
-
-    xran_decompose_cid((uint16_t)ecpri_hdr->ecpri_xtc_id, &result);
-
-    *CC_ID  = result.ccId;
-    *Ant_ID = result.ruPortId;
-
-    /* Process radio header. */
-    struct radio_app_common_hdr *radio_hdr =
-        (void *)rte_pktmbuf_adj(mbuf, sizeof(*ecpri_hdr));
-    if (radio_hdr == NULL)
-        return 0;       /* packet too short */
-
-    radio_hdr->sf_slot_sym.value = rte_be_to_cpu_16(radio_hdr->sf_slot_sym.value);
-
-    if (frame_id)
-        *frame_id    = radio_hdr->frame_id;
-
-    if (subframe_id)
-        *subframe_id = radio_hdr->sf_slot_sym.subframe_id;
-
-    if (slot_id)
-        *slot_id     = radio_hdr->sf_slot_sym.slot_id;
-
-    if (symb_id)
-        *symb_id = radio_hdr->sf_slot_sym.symb_id;
-
-    /* Process data section hdr */
-    struct data_section_hdr *data_hdr =
-        (void *)rte_pktmbuf_adj(mbuf, sizeof(*radio_hdr));
-    if (data_hdr == NULL)
-        return 0;       /* packet too short */
-
-    /* cpu byte order */
-    data_hdr->fields.all_bits  = rte_be_to_cpu_32(data_hdr->fields.all_bits);
-
-    *num_prbu   = data_hdr->fields.num_prbu;
-    *start_prbu = data_hdr->fields.start_prbu;
-    *sym_inc    = data_hdr->fields.sym_inc;
-    *rb         = data_hdr->fields.rb;
-    *sect_id    = data_hdr->fields.sect_id;
-
-#ifdef COMPRESSION
-    const struct data_section_compression_hdr *data_compr_hdr =
-        (void *) rte_pktmbuf_adj(mbuf, sizeof(*data_hdr));
-
-    const uint8_t *compr_param =
-        (void *)rte_pktmbuf_adj(mbuf, sizeof(*data_compr_hdr));
-
-    *iq_data_start = rte_pktmbuf_adj(mbuf, sizeof(*compr_param));
-
-#else
-    *iq_data_start = rte_pktmbuf_adj(mbuf, sizeof(*data_hdr));
-#endif
-    if (*iq_data_start == NULL)
-        return 0;
-
-#if XRAN_MLOG_VAR
-    mlogVar[mlogVarCnt++] = 0xBBBBBBBB;
-    mlogVar[mlogVarCnt++] = xran_lib_ota_tti;
-    mlogVar[mlogVarCnt++] = radio_hdr->frame_id;
-    mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.subframe_id;
-    mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.slot_id;
-    mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.symb_id;
-    mlogVar[mlogVarCnt++] = data_hdr->fields.sect_id;
-    mlogVar[mlogVarCnt++] = data_hdr->fields.start_prbu;
-    mlogVar[mlogVarCnt++] = data_hdr->fields.num_prbu;
-    mlogVar[mlogVarCnt++] = rte_pktmbuf_pkt_len(mbuf);
-    MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
-#endif
-
-    return rte_pktmbuf_pkt_len(mbuf);
-}
-
-/**
- * @brief Function for starting preparion of IQ samples portions
- *        to be sent in xRAN packet
- *
- * @param mbuf Initialized rte_mbuf packet.
- * @param iq_data_start Address of the first element in IQ data array.
- * @param iq_data_num_bytes Size of the IQ data array.
- * @param iq_data_offset IQ data bytes already sent.
- * @param alignment Size of IQ data alignment.
- * @param pkt_gen_params Struct with parameters used for building packet
- * @return int Number of bytes that have been appended
-               to the packet within all appended sections.
- */
-int xran_prepare_iq_symbol_portion_no_comp(
-                        struct rte_mbuf *mbuf,
-                        const void *iq_data_start,
-                        const enum xran_input_byte_order iq_buf_byte_order,
-                        const uint32_t iq_data_num_bytes,
-                        struct xran_up_pkt_gen_no_compression_params *params,
-                        uint8_t CC_ID,
-                        uint8_t Ant_ID,
-                        uint8_t seq_id,
-                        uint32_t do_copy)
-{
-    if(xran_build_ecpri_hdr_ex(mbuf,
-                           ECPRI_IQ_DATA,
-                           iq_data_num_bytes,
-                           CC_ID,
-                           Ant_ID,
-                           seq_id)){
-        print_err("xran_build_ecpri_hdr_ex return 0\n");
-        return 0;
-    }
-
-    if (build_application_layer(mbuf, &(params->app_params)) != 0){
-        print_err("build_application_layer return != 0\n");
-        return 0;
-    }
-
-    if (build_section_hdr(mbuf, &(params->sec_hdr)) != 0){
-        print_err("build_section_hdr return != 0\n");
-        return 0;
-    }
-
-    return append_iq_samples_ex(mbuf, iq_data_start, iq_data_num_bytes, iq_buf_byte_order, do_copy);
-}
-
+/******************************************************************************\r
+*\r
+*   Copyright (c) 2019 Intel.\r
+*\r
+*   Licensed under the Apache License, Version 2.0 (the "License");\r
+*   you may not use this file except in compliance with the License.\r
+*   You may obtain a copy of the License at\r
+*\r
+*       http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+*   Unless required by applicable law or agreed to in writing, software\r
+*   distributed under the License is distributed on an "AS IS" BASIS,\r
+*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+*   See the License for the specific language governing permissions and\r
+*   limitations under the License.\r
+*\r
+*******************************************************************************/\r
+\r
+/**\r
+ * @brief This file provides the implementation of User Plane Messages APIs.\r
+ *\r
+ * @file xran_up_api.c\r
+ * @ingroup group_lte_source_xran\r
+ * @author Intel Corporation\r
+ *\r
+ **/\r
+#include <inttypes.h>\r
+\r
+#include <rte_memcpy.h>\r
+#include <rte_mbuf.h>\r
+\r
+#include "xran_fh_o_du.h"\r
+#include "xran_transport.h"\r
+#include "xran_up_api.h"\r
+#include "xran_printf.h"\r
+#include "xran_mlog_lnx.h"\r
+\r
+extern uint32_t xran_lib_ota_tti;\r
+\r
+/**\r
+ * @brief Builds eCPRI header in xRAN packet\r
+ *\r
+ * @param mbuf Initialized rte_mbuf packet\r
+ * @param iq_data_num_bytes Number of bytes in IQ data buffer\r
+ * @param iq_data_offset Number of elements already sent\r
+ * @return int int 0 on success, non zero on failure\r
+ */\r
+static int build_ecpri_hdr(struct rte_mbuf *mbuf,\r
+    const uint32_t iq_data_num_bytes,\r
+    const uint32_t iq_data_offset,\r
+    uint8_t alignment)\r
+{\r
+    struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)\r
+        rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));\r
+\r
+    uint16_t iq_samples_bytes_in_mbuf = rte_pktmbuf_tailroom(mbuf) -\r
+        sizeof(struct radio_app_common_hdr) - sizeof(struct data_section_hdr);\r
+\r
+    iq_samples_bytes_in_mbuf -= (iq_samples_bytes_in_mbuf % alignment);\r
+\r
+    if (NULL == ecpri_hdr)\r
+        return 1;\r
+\r
+    ecpri_hdr->cmnhdr.ecpri_ver = XRAN_ECPRI_VER;\r
+    ecpri_hdr->cmnhdr.ecpri_resv = 0;\r
+    ecpri_hdr->cmnhdr.ecpri_concat = 0;\r
+    ecpri_hdr->cmnhdr.ecpri_mesg_type = ECPRI_IQ_DATA;\r
+\r
+    if (iq_data_offset + iq_samples_bytes_in_mbuf > iq_data_num_bytes) {\r
+        ecpri_hdr->cmnhdr.ecpri_payl_size =\r
+            rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +\r
+                sizeof(struct data_section_hdr) +\r
+                (iq_data_num_bytes - iq_data_offset) +\r
+                xran_get_ecpri_hdr_size());\r
+        ecpri_hdr->ecpri_seq_id.e_bit = 1;  /* last segment */\r
+    } else {\r
+        ecpri_hdr->cmnhdr.ecpri_payl_size =\r
+            rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +\r
+                sizeof(struct data_section_hdr) +\r
+                iq_samples_bytes_in_mbuf +\r
+                xran_get_ecpri_hdr_size());\r
+        ecpri_hdr->ecpri_seq_id.e_bit = 0;\r
+    }\r
+\r
+//    ecpri_hdr->ecpri_xtc_id = 0;    /* currently not used */\r
+    ecpri_hdr->ecpri_seq_id.seq_id = 0;\r
+    ecpri_hdr->ecpri_seq_id.sub_seq_id = iq_data_offset /\r
+        iq_samples_bytes_in_mbuf;\r
+\r
+    return 0;\r
+}\r
+\r
+/**\r
+ * @brief Builds eCPRI header in xRAN packet\r
+ *\r
+ * @param mbuf Initialized rte_mbuf packet\r
+ * @param ecpri_mesg_type eCPRI message type\r
+ * @param payl_size the size in bytes of the payload part of eCPRI message\r
+ * @param CC_ID Component Carrier ID for ecpriRtcid/ecpriPcid\r
+ * @param Ant_ID Antenna ID for ecpriRtcid/ecpriPcid\r
+ * @param seq_id Message identifier for eCPRI message\r
+ * @param comp_meth Compression method\r
+ * @return int int 0 on success, non zero on failure\r
+ */\r
+static int xran_build_ecpri_hdr_ex(struct rte_mbuf *mbuf,\r
+                              uint8_t ecpri_mesg_type,\r
+                              int payl_size,\r
+                              uint8_t CC_ID,\r
+                              uint8_t Ant_ID,\r
+                              uint8_t seq_id,\r
+                              uint8_t comp_meth)\r
+{\r
+    char *pChar = rte_pktmbuf_mtod(mbuf, char*);\r
+    struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)(pChar + sizeof(struct ether_hdr));\r
+    uint16_t    ecpri_payl_size = payl_size\r
+                                + sizeof(struct data_section_hdr)\r
+                                + sizeof(struct radio_app_common_hdr)\r
+                                + xran_get_ecpri_hdr_size();\r
+\r
+    if (comp_meth != XRAN_COMPMETHOD_NONE)\r
+        ecpri_payl_size += sizeof(struct data_section_compression_hdr);\r
+\r
+    if (NULL == ecpri_hdr)\r
+        return 1;\r
+\r
+    ecpri_hdr->cmnhdr.ecpri_ver       = XRAN_ECPRI_VER;\r
+    ecpri_hdr->cmnhdr.ecpri_resv      = 0;     // should be zero\r
+    ecpri_hdr->cmnhdr.ecpri_concat    = 0;\r
+    ecpri_hdr->cmnhdr.ecpri_mesg_type = ecpri_mesg_type;\r
+    ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(ecpri_payl_size);\r
+\r
+    /* one to one lls-CU to RU only and band sector is the same */\r
+    ecpri_hdr->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);\r
+\r
+    ecpri_hdr->ecpri_seq_id.seq_id = seq_id;\r
+\r
+    /* no transport layer fragmentation supported */\r
+    ecpri_hdr->ecpri_seq_id.sub_seq_id  = 0;\r
+    ecpri_hdr->ecpri_seq_id.e_bit       = 1;\r
+\r
+    return 0;\r
+}\r
+\r
+\r
+/**\r
+ * @brief Builds application layer of xRAN packet\r
+ *\r
+ * @param mbuf Initialized rte_mbuf packet\r
+ * @param app_hdr_input Radio App common header structure to be set in mbuf\r
+ *                      packet.\r
+ * @return int 0 on success, non zero on failure\r
+ */\r
+static int build_application_layer(\r
+    struct rte_mbuf *mbuf,\r
+    const struct radio_app_common_hdr *app_hdr_input)\r
+{\r
+    char *pChar = rte_pktmbuf_mtod(mbuf, char*);\r
+    struct radio_app_common_hdr *app_hdr = (struct radio_app_common_hdr *)(pChar + sizeof(struct ether_hdr)\r
+        + sizeof (struct xran_ecpri_hdr));\r
+\r
+    if (NULL == app_hdr)\r
+        return 1;\r
+\r
+    rte_memcpy(app_hdr, app_hdr_input, sizeof(struct radio_app_common_hdr));\r
+\r
+    return 0;\r
+}\r
+\r
+/**\r
+ * @brief Builds section header in xRAN packet\r
+ *\r
+ * @param mbuf Initialized rte_mbuf packet\r
+ * @param sec_hdr Section header structure to be set in mbuf packet\r
+ * @return int 0 on success, non zero on failure\r
+ */\r
+static int build_section_hdr(\r
+    struct rte_mbuf *mbuf,\r
+    const struct data_section_hdr *sec_hdr)\r
+{\r
+    char *pChar = rte_pktmbuf_mtod(mbuf, char*);\r
+    struct data_section_hdr *section_hdr = (struct data_section_hdr *)\r
+        (pChar + sizeof(struct ether_hdr) + sizeof (struct xran_ecpri_hdr) + sizeof(struct radio_app_common_hdr));\r
+\r
+    if (NULL == section_hdr)\r
+        return 1;\r
+\r
+    rte_memcpy(section_hdr, sec_hdr, sizeof(struct data_section_hdr));\r
+\r
+    return 0;\r
+}\r
+/**\r
+ * @brief Function for appending IQ samples data to the mbuf.\r
+ *\r
+ * @param mbuf Initialized rte_mbuf packet.\r
+ * @param iq_data_start Address of the first element in IQ data array.\r
+ * @param iq_data_num_bytes Size of the IQ data array.\r
+ * @param iq_data_offset IQ data btyes already sent.\r
+ * @return uint16_t Bytes that have been appended to the packet.\r
+ */\r
+static uint16_t append_iq_samples_ex(\r
+    struct rte_mbuf *mbuf,\r
+    const void *iq_data_start,\r
+    const uint32_t iq_data_num_bytes,\r
+    enum xran_input_byte_order iq_buf_byte_order,\r
+    uint32_t do_copy)\r
+{\r
+    char *pChar = rte_pktmbuf_mtod(mbuf, char*);\r
+    void *iq_sam_buf  = (pChar + sizeof(struct ether_hdr) + sizeof (struct xran_ecpri_hdr)\r
+                        + sizeof(struct radio_app_common_hdr)\r
+                        + sizeof(struct data_section_hdr));\r
+\r
+    if (iq_sam_buf == NULL){\r
+        print_err("iq_sam_buf == NULL\n");\r
+        return 0;\r
+    }\r
+    if(iq_buf_byte_order == XRAN_CPU_LE_BYTE_ORDER){\r
+        int idx = 0;\r
+        uint16_t *psrc = (uint16_t *)iq_data_start;\r
+        uint16_t *pdst = (uint16_t *)iq_sam_buf;\r
+        /* CPU byte order (le) of IQ to network byte order (be) */\r
+        for (idx = 0; idx < iq_data_num_bytes/sizeof(int16_t); idx++){\r
+            pdst[idx]  =  (psrc[idx]>>8) | (psrc[idx]<<8); //rte_cpu_to_be_16(psrc[idx]);\r
+        }\r
+    }\r
+\r
+#if 0\r
+    /* do not expect to do copy anymore */\r
+    else if(iq_buf_byte_order == XRAN_NE_BE_BYTE_ORDER){\r
+        if(do_copy) {\r
+           rte_memcpy(iq_sam_buf, (uint8_t *)iq_data_start,  iq_data_num_bytes);\r
+        }\r
+    }\r
+#endif\r
+\r
+    return iq_data_num_bytes;\r
+}\r
+\r
+/**\r
+ * @brief Function for appending IQ samples data to the mbuf.\r
+ *\r
+ * @param mbuf Initialized rte_mbuf packet.\r
+ * @param iq_data_start Address of the first element in IQ data array.\r
+ * @param iq_data_num_bytes Size of the IQ data array.\r
+ * @param iq_data_offset IQ data btyes already sent.\r
+ * @return uint16_t Bytes that have been appended to the packet.\r
+ */\r
+static uint16_t append_iq_samples(\r
+    struct rte_mbuf *mbuf,\r
+    const void *iq_data_start,\r
+    const uint32_t iq_data_num_bytes,\r
+    const uint32_t iq_data_offset,\r
+    const uint8_t alignment)\r
+{\r
+    uint16_t iq_bytes_to_send = 0;\r
+    uint16_t free_space_in_pkt = rte_pktmbuf_tailroom(mbuf);\r
+\r
+    if (free_space_in_pkt > iq_data_num_bytes - iq_data_offset)\r
+        iq_bytes_to_send = iq_data_num_bytes - iq_data_offset;\r
+    else\r
+        iq_bytes_to_send = free_space_in_pkt;\r
+\r
+    /* don't cut off an iq in half */\r
+    iq_bytes_to_send -= iq_bytes_to_send % alignment;\r
+\r
+    void *iq_sam_buf = (void *)rte_pktmbuf_append(mbuf, iq_bytes_to_send);\r
+\r
+    rte_memcpy(iq_sam_buf, (uint8_t *)iq_data_start + iq_data_offset,\r
+            iq_bytes_to_send);\r
+\r
+    return iq_bytes_to_send;\r
+}\r
+\r
+/**\r
+ * @brief Builds compression header in xRAN packet\r
+ *\r
+ * @param mbuf Initialized rte_mbuf packet\r
+ * @param compression_hdr Section compression header structure\r
+ *                to be set in mbuf packet\r
+ * @return int 0 on success, non zero on failure\r
+ */\r
+static int build_compression_hdr(\r
+    struct rte_mbuf *mbuf,\r
+    const struct data_section_compression_hdr *compr_hdr)\r
+{\r
+    char *pChar = rte_pktmbuf_mtod(mbuf, char*);\r
+    struct data_section_compression_hdr *compression_hdr = (struct data_section_compression_hdr *)\r
+        (pChar + sizeof(struct ether_hdr) + sizeof (struct xran_ecpri_hdr) + sizeof(struct radio_app_common_hdr)\r
+        + sizeof(struct data_section_hdr));\r
+\r
+    if (NULL == compression_hdr)\r
+        return 1;\r
+\r
+    rte_memcpy(compression_hdr, compr_hdr, sizeof(*compression_hdr));\r
+\r
+    return 0;\r
+}\r
+\r
+/**\r
+ * @brief Appends compression parameter in xRAN packet\r
+ *\r
+ * @param mbuf Initialized rte_mbuf packet\r
+ * @param ud_comp_paramr Compression param to be set in mbuf packet\r
+ * @return int 0 on success, non zero on failure\r
+ */\r
+static int append_comp_param(struct rte_mbuf *mbuf, union compression_params *ud_comp_param)\r
+{\r
+    union compression_params *compr_param =\r
+        (union compression_params *)rte_pktmbuf_append(mbuf, sizeof(union compression_params));\r
+\r
+    if (NULL == compr_param)\r
+        return 1;\r
+\r
+    rte_memcpy(compr_param, ud_comp_param, sizeof(union compression_params));\r
+\r
+    return 0;\r
+}\r
+\r
+/**\r
+ * @brief Function for extracting all IQ samples from xRAN packet\r
+ *        holding a single data section\r
+ * @param iq_data_start Address of the first element in IQ data array.\r
+ * @param symb_id Symbol ID to be extracted from ecpri header\r
+ * @param seq_id  Sequence ID to be extracted from radio header\r
+ * @return int Size of remaining mbuf filled with IQ samples\r
+               zero on failure\r
+ */\r
+int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,\r
+    void **iq_data_start,\r
+    uint8_t *CC_ID,\r
+    uint8_t *Ant_ID,\r
+    uint8_t *frame_id,\r
+    uint8_t *subframe_id,\r
+    uint8_t *slot_id,\r
+    uint8_t *symb_id,\r
+    struct ecpri_seq_id *seq_id,\r
+    uint16_t *num_prbu,\r
+    uint16_t *start_prbu,\r
+    uint16_t *sym_inc,\r
+    uint16_t *rb,\r
+    uint16_t *sect_id,\r
+    int8_t   expect_comp,\r
+    uint8_t *compMeth,\r
+    uint8_t *iqWidth)\r
+{\r
+#if XRAN_MLOG_VAR\r
+    uint32_t mlogVar[10];\r
+    uint32_t mlogVarCnt = 0;\r
+#endif\r
+    struct xran_eaxc_info result;\r
+\r
+    if (NULL == mbuf)\r
+        return 0;\r
+    if (NULL == iq_data_start)\r
+        return 0;\r
+\r
+    /* Process eCPRI header. */\r
+    const struct xran_ecpri_hdr *ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);\r
+    if (ecpri_hdr == NULL)\r
+        return 0;\r
+\r
+    if (seq_id)\r
+        *seq_id = ecpri_hdr->ecpri_seq_id;\r
+\r
+    xran_decompose_cid((uint16_t)ecpri_hdr->ecpri_xtc_id, &result);\r
+\r
+    *CC_ID  = result.ccId;\r
+    *Ant_ID = result.ruPortId;\r
+\r
+    /* Process radio header. */\r
+    struct radio_app_common_hdr *radio_hdr =\r
+        (void *)rte_pktmbuf_adj(mbuf, sizeof(*ecpri_hdr));\r
+    if (radio_hdr == NULL)\r
+        return 0;       /* packet too short */\r
+\r
+    radio_hdr->sf_slot_sym.value = rte_be_to_cpu_16(radio_hdr->sf_slot_sym.value);\r
+\r
+    if (frame_id)\r
+        *frame_id    = radio_hdr->frame_id;\r
+\r
+    if (subframe_id)\r
+        *subframe_id = radio_hdr->sf_slot_sym.subframe_id;\r
+\r
+    if (slot_id)\r
+        *slot_id     = radio_hdr->sf_slot_sym.slot_id;\r
+\r
+    if (symb_id)\r
+        *symb_id = radio_hdr->sf_slot_sym.symb_id;\r
+\r
+    /* Process data section hdr */\r
+    struct data_section_hdr *data_hdr =\r
+        (void *)rte_pktmbuf_adj(mbuf, sizeof(*radio_hdr));\r
+    if (data_hdr == NULL)\r
+        return 0;       /* packet too short */\r
+\r
+    /* cpu byte order */\r
+    data_hdr->fields.all_bits  = rte_be_to_cpu_32(data_hdr->fields.all_bits);\r
+\r
+    *num_prbu   = data_hdr->fields.num_prbu;\r
+    *start_prbu = data_hdr->fields.start_prbu;\r
+    *sym_inc    = data_hdr->fields.sym_inc;\r
+    *rb         = data_hdr->fields.rb;\r
+    *sect_id    = data_hdr->fields.sect_id;\r
+\r
+    if(expect_comp) {\r
+        const struct data_section_compression_hdr *data_compr_hdr =\r
+            (void *) rte_pktmbuf_adj(mbuf, sizeof(*data_hdr));\r
+\r
+        if (data_compr_hdr == NULL)\r
+            return 0;\r
+\r
+        *compMeth = data_compr_hdr->ud_comp_hdr.ud_comp_meth;\r
+        *iqWidth =  data_compr_hdr->ud_comp_hdr.ud_iq_width;\r
+\r
+        const uint8_t *compr_param =\r
+            (void *)rte_pktmbuf_adj(mbuf, sizeof(*data_compr_hdr));\r
+\r
+            *iq_data_start = (void *)compr_param; /*rte_pktmbuf_adj(mbuf, sizeof(*compr_param))*/;\r
+    } else {\r
+        *iq_data_start = rte_pktmbuf_adj(mbuf, sizeof(*data_hdr));\r
+    }\r
+\r
+    if (*iq_data_start == NULL)\r
+        return 0;\r
+\r
+#if XRAN_MLOG_VAR\r
+    mlogVar[mlogVarCnt++] = 0xBBBBBBBB;\r
+    mlogVar[mlogVarCnt++] = xran_lib_ota_tti;\r
+    mlogVar[mlogVarCnt++] = radio_hdr->frame_id;\r
+    mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.subframe_id;\r
+    mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.slot_id;\r
+    mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.symb_id;\r
+    mlogVar[mlogVarCnt++] = data_hdr->fields.sect_id;\r
+    mlogVar[mlogVarCnt++] = data_hdr->fields.start_prbu;\r
+    mlogVar[mlogVarCnt++] = data_hdr->fields.num_prbu;\r
+    mlogVar[mlogVarCnt++] = rte_pktmbuf_pkt_len(mbuf);\r
+    MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());\r
+#endif\r
+\r
+    return rte_pktmbuf_pkt_len(mbuf);\r
+}\r
+\r
+/**\r
+ * @brief Function for starting preparion of IQ samples portions\r
+ *        to be sent in xRAN packet\r
+ *\r
+ * @param mbuf Initialized rte_mbuf packet.\r
+ * @param iq_data_start Address of the first element in IQ data array.\r
+ * @param iq_data_num_bytes Size of the IQ data array.\r
+ * @param iq_data_offset IQ data bytes already sent.\r
+ * @param alignment Size of IQ data alignment.\r
+ * @param pkt_gen_params Struct with parameters used for building packet\r
+ * @return int Number of bytes that have been appended\r
+               to the packet within all appended sections.\r
+ */\r
+int32_t xran_prepare_iq_symbol_portion(\r
+                        struct rte_mbuf *mbuf,\r
+                        const void *iq_data_start,\r
+                        const enum xran_input_byte_order iq_buf_byte_order,\r
+                        const uint32_t iq_data_num_bytes,\r
+                        struct xran_up_pkt_gen_params *params,\r
+                        uint8_t CC_ID,\r
+                        uint8_t Ant_ID,\r
+                        uint8_t seq_id,\r
+                        uint32_t do_copy)\r
+{\r
+    if(xran_build_ecpri_hdr_ex(mbuf,\r
+                           ECPRI_IQ_DATA,\r
+                           iq_data_num_bytes,\r
+                           CC_ID,\r
+                           Ant_ID,\r
+                           seq_id,\r
+                           params->compr_hdr_param.ud_comp_hdr.ud_comp_meth)){\r
+        print_err("xran_build_ecpri_hdr_ex return 0\n");\r
+        return 0;\r
+    }\r
+\r
+    if (build_application_layer(mbuf, &(params->app_params)) != 0){\r
+        print_err("build_application_layer return != 0\n");\r
+        return 0;\r
+    }\r
+\r
+    if (build_section_hdr(mbuf, &(params->sec_hdr)) != 0){\r
+        print_err("build_section_hdr return != 0\n");\r
+        return 0;\r
+    }\r
+\r
+\r
+    if(params->compr_hdr_param.ud_comp_hdr.ud_comp_meth != XRAN_COMPMETHOD_NONE) {\r
+        if (build_compression_hdr(mbuf, &(params->compr_hdr_param)) !=0)\r
+            return 0;\r
+\r
+         /* payload expected to start with udCompParam */\r
+\r
+        /*if(append_comp_param(mbuf, &(params->compr_param)) !=0)\r
+            return 0;*/\r
+    }\r
+\r
+\r
+    return append_iq_samples_ex(mbuf, iq_data_start, iq_data_num_bytes, iq_buf_byte_order, do_copy);\r
+}\r
+\r