+int xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int tti, int cc_id,
+ struct xran_prb_map *prbMapElem)
+{
+ struct xran_cp_gen_params params;
+ struct xran_section_gen_info sect_geninfo[XRAN_MAX_NUM_SECTIONS];
+ struct rte_mbuf *mbuf;
+ int ret = 0;
+ uint32_t i;
+ uint32_t nsection = prbMapElem->nPrbElm;
+ struct xran_prb_elm *pPrbMapElem = &prbMapElem->prbMap[0];
+ struct xran_prb_elm *pPrbMapElemPrev;
+ uint32_t slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
+ uint32_t subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
+ uint32_t frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
+ uint8_t seq_id = xran_get_cp_seqid(pHandle, XRAN_DIR_DL, cc_id, ru_port_id);
+
+ params.dir = dir;
+ params.sectionType = XRAN_CP_SECTIONTYPE_1; // Most DL/UL Radio Channels
+ params.hdr.filterIdx = XRAN_FILTERINDEX_STANDARD;
+ params.hdr.frameId = frame_id;
+ params.hdr.subframeId = subframe_id;
+ params.hdr.slotId = slot_id;
+ params.hdr.startSymId = pPrbMapElem->nStartSymb;
+ params.hdr.iqWidth = xran_get_conf_iqwidth(pHandle);
+ params.hdr.compMeth = pPrbMapElem->compMethod;
+
+ for (i=0; i<nsection; i++)
+ {
+ pPrbMapElem = &prbMapElem->prbMap[i];
+ sect_geninfo[i].info.type = params.sectionType; // for database
+ sect_geninfo[i].info.startSymId = params.hdr.startSymId; // for database
+ sect_geninfo[i].info.iqWidth = params.hdr.iqWidth; // for database
+ sect_geninfo[i].info.compMeth = params.hdr.compMeth; // for database
+ sect_geninfo[i].info.id = xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id);
+ sect_geninfo[i].info.rb = XRAN_RBIND_EVERY;
+ sect_geninfo[i].info.startPrbc = pPrbMapElem->nRBStart;
+ sect_geninfo[i].info.numPrbc = pPrbMapElem->nRBSize;
+ sect_geninfo[i].info.numSymbol = pPrbMapElem->numSymb;
+ sect_geninfo[i].info.reMask = 0xfff;
+ sect_geninfo[i].info.beamId = pPrbMapElem->nBeamIndex;
+ if (i==0)
+ sect_geninfo[i].info.symInc = XRAN_SYMBOLNUMBER_NOTINC;
+ else
+ {
+ pPrbMapElemPrev = &prbMapElem->prbMap[i-1];
+ if (pPrbMapElemPrev->nStartSymb == pPrbMapElem->nStartSymb)
+ {
+ sect_geninfo[i].info.symInc = XRAN_SYMBOLNUMBER_NOTINC;
+ if (pPrbMapElemPrev->numSymb != pPrbMapElem->numSymb)
+ print_err("section info error: previous numSymb %d not equal to current numSymb %d\n", pPrbMapElemPrev->numSymb, pPrbMapElem->numSymb);
+ }
+ else
+ {
+ sect_geninfo[i].info.symInc = XRAN_SYMBOLNUMBER_INC;
+ if (pPrbMapElem->nStartSymb != (pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb))
+ print_err("section info error: current startSym %d not equal to previous endSymb %d\n", pPrbMapElem->nStartSymb, pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb);
+ }
+ }
+
+ /* extension is not supported */
+ sect_geninfo[nsection].info.ef = 0;
+ sect_geninfo[nsection].exDataSize = 0;
+ //sect_geninfo[nsection].exData = NULL;
+ }
+ params.numSections = nsection;
+ params.sections = sect_geninfo;
+
+ mbuf = xran_ethdi_mbuf_alloc();
+ if(unlikely(mbuf == NULL)) {
+ print_err("Alloc fail!\n");
+ return (-1);
+ }
+
+ ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, ru_port_id, seq_id);
+ if(ret < 0) {
+ print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n",
+ frame_id, subframe_id, slot_id, dir);
+ } else {
+ /* add in the ethernet header */
+ struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));
+ xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
+ tx_counter++;
+ for(i=0; i<nsection; i++)
+ xran_cp_add_section_info(pHandle,
+ dir, cc_id, ru_port_id,
+ (slot_id + subframe_id*SLOTNUM_PER_SUBFRAME)%XRAN_MAX_SECTIONDB_CTX,
+ §_geninfo[i].info);
+ }
+
+ return ret;
+}
+#if 0
+int xran_cp_create_rbmap(int dir, int tti, int cc_id,
+ struct xran_flat_buffer *prbMapElem,
+ struct xran_cp_rbmap_list *rbMapList)
+{
+ struct xran_prb_map *prb_map;
+ int list_index = 0;
+ int sym_id;
+ int i, j;
+
+ prb_map = (struct xran_prb_map *)prbMapElm[0].pData;
+ cc_id = prb_map->cc_id;
+ tti = prb_map->tti_id;
+ dir = prb_map->dir;
+
+
+ list_index = -1;
+ for(sym_id = 0; sym_id < N_SYM_PER_SLOT; sym_id++) {
+ /* skip symbol, if not matched with given direction */
+ int type_sym = xran_fs_get_symbol_type(cc_id, tti, sym_id);
+ if(type_sym != XRAN_SYMBOL_TYPE_FDD && type_sym != dir)
+ continue;
+
+ /* retrieve the information of RB allocation */
+ prb_map = (struct xran_prb_map *)prbMapElem[sym_id].pData;
+ if(unlikely(prb_map == NULL)) {
+ print_err("RB allocation table is NULL! (tti:%d, cc:%d, sym_id:%d)", tti, cc_id, sym_id);
+ continue;
+ }
+
+ /* creating 2D mapping */
+ for(i=0; i < prb_map->nPrbElm; i++) {
+ if(list_index < 0) { /* create first entry */
+ list_index = 0;
+ rbMapList[list_index].grp_id = 0;
+ rbMapList[list_index].sym_start = sym_id; // prb_map->sym_id
+ rbMapList[list_index].sym_num = 1;
+ rbMapList[list_index].rb_start = prb_map->prbMap[i].nRBStart;
+ rbMapList[list_index].rb_num = prb_map->prbMap[i].nRBSize;
+ rbMapList[list_index].beam_id = prb_map->prbMap[i].nBeamIndex;
+ rbMapList[list_index].comp_meth = prb_map->prbMap[i].compMethod;
+ }
+ else {
+ /* find consecutive allocation from list */
+ for(j=0; j<list_index+1; j++) {
+ if(prb_map->prbMap[i].nRBStart != rbMapList[j].rb_start
+ || prb_map->prbMap[i].nRBSize != rbMapList[j].rb_num
+ || prb_map->prbMap[i].nBeamIndex != rbMapList[j].beam_id
+ || prb_map->prbMap[i].compMethod != rbMapList[j].comp_meth
+ || sym_id != (rbMapList[j].sym_start+rbMapList[j].sym_num)) {
+ /* move to next */
+ continue;
+ }
+ else {
+ /* consecutive allocation has been found */
+ rbMapList[j].sym_num++;
+ break;
+ }
+ }
+
+ if(j == list_index+1) { /* different allocation, create new entry */
+ list_index++;
+ rbMapList[list_index].grp_id = 0;
+ rbMapList[list_index].sym_start = sym_id; // prb_map->sym_id
+ rbMapList[list_index].sym_num = 1;
+ rbMapList[list_index].rb_start = prb_map->prbMap[i].nRBStart;
+ rbMapList[list_index].rb_num = prb_map->prbMap[i].nRBSize;
+ rbMapList[list_index].beam_id = prb_map->prbMap[i].nBeamIndex;
+ rbMapList[list_index].comp_meth = prb_map->prbMap[i].compMethod;
+ }
+ }
+ } /* for(i=0; i < prb_map->nPrbElm; i++) */
+ } /* for(sym_id = 0; sym_id < N_SYM_PER_SLOT; sym_id++) */
+
+ list_index++;
+
+#if 0
+ for(i=0; i<list_index; i++) {
+ printf("[%c:%d-%d] %d - symstart=%d, symnum=%d, rbstart=%d, rbnum=%d, beamid=%d, comp=%d\n",
+ dir?'U':'D', tti, cc_id, i,
+ rbMapList[i].sym_start, rbMapList[i].sym_num,
+ rbMapList[i].rb_start, rbMapList[i].rb_num,
+ rbMapList[i].beam_id, rbMapList[i].comp_meth);
+ }
+#endif
+ return (list_index);
+}
+#endif
+