+ ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(size);
+}
+
+
+/**
+ * @brief Build ECPRI header and returns added length
+ *
+ * @ingroup xran
+ *
+ * @param mbuf
+ * The pointer of the packet buffer to be parsed
+ * @param CC_ID
+ * Component Carrier ID for this C-Plane message
+ * @param Ant_ID
+ * Antenna ID(RU Port ID) for this C-Plane message
+ * @param seq_id
+ * Sequence ID for this C-Plane message
+ * @param ecpri_hdr
+ * The pointer to ECPRI header
+ * @return
+ * added payload size on success
+ * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
+ */
+int xran_build_ecpri_hdr(struct rte_mbuf *mbuf,
+ uint8_t CC_ID, uint8_t Ant_ID,
+ uint8_t seq_id,
+ struct xran_ecpri_hdr **ecpri_hdr)
+{
+ uint32_t payloadlen;
+ struct xran_ecpri_hdr *tmp;
+
+
+ tmp = (struct xran_ecpri_hdr *)rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
+ if(unlikely(tmp == NULL)) {
+ print_err("Fail to allocate the space for eCPRI hedaer!");
+ return (XRAN_STATUS_RESOURCE);
+ }
+
+ /* Fill common header */
+ tmp->cmnhdr.ecpri_ver = XRAN_ECPRI_VER;
+ tmp->cmnhdr.ecpri_resv = 0; // should be zero
+ tmp->cmnhdr.ecpri_concat = 0;
+ tmp->cmnhdr.ecpri_mesg_type = ECPRI_RT_CONTROL_DATA;
+ tmp->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);
+
+ /* TODO: Transport layer fragmentation is not supported */
+ tmp->ecpri_seq_id.seq_id = seq_id;
+ tmp->ecpri_seq_id.sub_seq_id = 0;
+ tmp->ecpri_seq_id.e_bit = 1;
+
+ /* Starts with eCPRI header size */
+ payloadlen = xran_get_ecpri_hdr_size();
+
+ *ecpri_hdr = tmp;
+
+ return (payloadlen);
+}
+
+/**
+ * @brief Parse ECPRI header
+ *
+ * @ingroup xran
+ *
+ * @param mbuf
+ * The pointer of the packet buffer to be parsed
+ * @param ecpri_hdr
+ * The pointer to ECPRI header
+ * @param pkt_info
+ * The pointer of sturcture to store the information from header
+ * @return
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PACKET if failed to parse the packet
+ */
+int xran_parse_ecpri_hdr(struct rte_mbuf *mbuf,
+ struct xran_ecpri_hdr **ecpri_hdr,
+ struct xran_recv_packet_info *pkt_info)
+{
+ int ret;
+
+
+ *ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);
+ if(*ecpri_hdr == NULL) {
+ print_err("Invalid packet - eCPRI hedaer!");
+ return (XRAN_STATUS_INVALID_PACKET);
+ }
+
+ /* Process eCPRI header */
+ ret = XRAN_STATUS_SUCCESS;
+ if((*ecpri_hdr)->cmnhdr.ecpri_ver != XRAN_ECPRI_VER) {
+ print_err("Invalid eCPRI version - %d", (*ecpri_hdr)->cmnhdr.ecpri_ver);
+ ret = XRAN_STATUS_INVALID_PACKET;
+ }
+ if((*ecpri_hdr)->cmnhdr.ecpri_resv != 0) {
+ print_err("Invalid reserved field - %d", (*ecpri_hdr)->cmnhdr.ecpri_resv);
+ ret = XRAN_STATUS_INVALID_PACKET;
+ }
+
+ if(pkt_info != NULL) {
+ /* store the information from header */
+ pkt_info->ecpri_version = (*ecpri_hdr)->cmnhdr.ecpri_ver;
+ pkt_info->msg_type = (enum ecpri_msg_type)(*ecpri_hdr)->cmnhdr.ecpri_mesg_type;
+ pkt_info->payload_len = rte_be_to_cpu_16((*ecpri_hdr)->cmnhdr.ecpri_payl_size);
+
+ pkt_info->seq_id = (*ecpri_hdr)->ecpri_seq_id.seq_id;
+ pkt_info->subseq_id = (*ecpri_hdr)->ecpri_seq_id.sub_seq_id;
+ pkt_info->ebit = (*ecpri_hdr)->ecpri_seq_id.e_bit;
+ xran_decompose_cid((*ecpri_hdr)->ecpri_xtc_id, &(pkt_info->eaxc));
+ }
+
+ return (ret);