From 9b8bc21d84b1d667e68374957c081af0550da696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Soares=20Silva?= Date: Thu, 1 Aug 2024 17:47:08 +0100 Subject: [PATCH] Move functions for packing/unpacking DL_TTI.request Add unitary test for DL_TTI.request ( test pack/unpack, free, copy and compare ) --- nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h | 4 + nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c | 516 ++++++++++++++++- .../open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h | 3 - nfapi/open-nFAPI/nfapi/src/nfapi_p7.c | 520 +----------------- nfapi/tests/p7/CMakeLists.txt | 4 +- nfapi/tests/p7/nr_fapi_dl_tti_request_test.c | 279 ++++++++++ 6 files changed, 773 insertions(+), 553 deletions(-) create mode 100644 nfapi/tests/p7/nr_fapi_dl_tti_request_test.c diff --git a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h index 465d341380..8909878f28 100644 --- a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h +++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h @@ -28,4 +28,8 @@ int fapi_nr_p7_message_unpack(void *pMessageBuf, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t *config); + +uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config); +uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config); + #endif // OPENAIRINTERFACE_NR_FAPI_P7_H diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c index 14d7833854..1aa5a0ed22 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c @@ -31,6 +31,10 @@ uint8_t fapi_nr_p7_message_body_pack(nfapi_nr_p7_message_header_t *header, // look for the specific message uint8_t result = 0; switch (header->message_id) { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + result = pack_dl_tti_request(header, ppWritePackedMsg, end, config); + break; + default: { if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) { if (config && config->pack_p7_vendor_extension) { @@ -88,6 +92,7 @@ int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packed NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); return -1; } + // Update the message length in the header pMessageHeader->message_length = packedMsgLen; @@ -109,45 +114,32 @@ int fapi_nr_p7_message_unpack(void *pMessageBuf, fapi_message_header_t fapi_hdr; uint8_t *pReadPackedMessage = pMessageBuf; - if (pMessageBuf == NULL || pUnpackedBuf == NULL) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n"); - return -1; - } - + AssertFatal(pMessageBuf != NULL && pUnpackedBuf != NULL, "P7 unpack supplied pointers are null"); uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen; + AssertFatal(messageBufLen >= NFAPI_HEADER_LENGTH && unpackedBufLen >= sizeof(fapi_message_header_t), + "P5 unpack supplied message buffer is too small %d, %d\n", + messageBufLen, + unpackedBufLen); - if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + + if (fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &fapi_hdr, sizeof(fapi_message_header_t), 0) < 0) { + // failed to read the header return -1; } - - - - // process the header - if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) - && pull32(&pReadPackedMessage, &pMessageHeader->message_length, end) - && pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) - && pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) - && pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n"); - return -1; - } - + pMessageHeader->message_length = fapi_hdr.message_length; + pMessageHeader->message_id = fapi_hdr.message_id; if ((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n"); return -1; } - /* - if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n"); - return -1; - } - */ - // look for the specific message switch (pMessageHeader->message_id) { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen)) + result = unpack_dl_tti_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + default: if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) { @@ -166,8 +158,474 @@ int fapi_nr_p7_message_unpack(void *pMessageBuf, } if (result == 0) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n"); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Unpack failed to unpack message\n"); return -1; } return 0; } + +static uint8_t pack_nr_tx_beamforming_pdu(const nfapi_nr_tx_precoding_and_beamforming_t *beamforming_pdu, + uint8_t **ppWritePackedMsg, + uint8_t *end) +{ // Pack RX Beamforming PDU + if (!(push16(beamforming_pdu->num_prgs, ppWritePackedMsg, end) && push16(beamforming_pdu->prg_size, ppWritePackedMsg, end) + && push8(beamforming_pdu->dig_bf_interfaces, ppWritePackedMsg, end))) { + return 0; + } + for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) { + if (!push16(beamforming_pdu->prgs_list[prg].pm_idx, ppWritePackedMsg, end)) { + return 0; + } + for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interfaces; digBFInterface++) { + if (!push16(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) { + return 0; + } + } + } + return 1; +} + +static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv; + if (!(push16(value->bwp_size, ppWritePackedMsg, end) && push16(value->bwp_start, ppWritePackedMsg, end) + && push8(value->subcarrier_spacing, ppWritePackedMsg, end) && push8(value->cyclic_prefix, ppWritePackedMsg, end) + && push16(value->start_rb, ppWritePackedMsg, end) && push16(value->nr_of_rbs, ppWritePackedMsg, end) + && push8(value->csi_type, ppWritePackedMsg, end) && push8(value->row, ppWritePackedMsg, end) + && push16(value->freq_domain, ppWritePackedMsg, end) && push8(value->symb_l0, ppWritePackedMsg, end) + && push8(value->symb_l1, ppWritePackedMsg, end) && push8(value->cdm_type, ppWritePackedMsg, end) + && push8(value->freq_density, ppWritePackedMsg, end) && push16(value->scramb_id, ppWritePackedMsg, end) + && push8(value->power_control_offset, ppWritePackedMsg, end) + && push8(value->power_control_offset_ss, ppWritePackedMsg, end))) { + return 0; + } + + // Precoding and beamforming + if(!pack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming,ppWritePackedMsg, end)) { + return 0; + } + return 1; +} + +static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv; + + if (!(push16(value->BWPSize, ppWritePackedMsg, end) && push16(value->BWPStart, ppWritePackedMsg, end) + && push8(value->SubcarrierSpacing, ppWritePackedMsg, end) && push8(value->CyclicPrefix, ppWritePackedMsg, end) + && push8(value->StartSymbolIndex, ppWritePackedMsg, end) && push8(value->DurationSymbols, ppWritePackedMsg, end) + && pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end) + && push8(value->CceRegMappingType, ppWritePackedMsg, end) && push8(value->RegBundleSize, ppWritePackedMsg, end) + && push8(value->InterleaverSize, ppWritePackedMsg, end) && push8(value->CoreSetType, ppWritePackedMsg, end) + && push16(value->ShiftIndex, ppWritePackedMsg, end) && push8(value->precoderGranularity, ppWritePackedMsg, end) + && push16(value->numDlDci, ppWritePackedMsg, end))) { + return 0; + } + + for (uint16_t i = 0; i < value->numDlDci; ++i) { + if (!(push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) && push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end) + && push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) + && push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end) + && push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end))) { + return 0; + } + // Precoding and beamforming + if(!pack_nr_tx_beamforming_pdu(&value->dci_pdu[i].precodingAndBeamforming,ppWritePackedMsg, end)) { + return 0; + } + // TX Power info + if (!(push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) + && push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) && + // DCI Payload fields + push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) && + // Pack DCI Payload + pack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end))) { + return 0; + } + } + return 1; +} + +static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv; + + if (!(push16(value->pduBitmap, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end) + && push16(value->pduIndex, ppWritePackedMsg, end) && push16(value->BWPSize, ppWritePackedMsg, end) + && push16(value->BWPStart, ppWritePackedMsg, end) && push8(value->SubcarrierSpacing, ppWritePackedMsg, end) + && push8(value->CyclicPrefix, ppWritePackedMsg, end) && push8(value->NrOfCodewords, ppWritePackedMsg, end))) { + return 0; + } + for (int i = 0; i < value->NrOfCodewords; ++i) { + if (!(push16(value->targetCodeRate[i], ppWritePackedMsg, end) && push8(value->qamModOrder[i], ppWritePackedMsg, end) + && push8(value->mcsIndex[i], ppWritePackedMsg, end) && push8(value->mcsTable[i], ppWritePackedMsg, end) + && push8(value->rvIndex[i], ppWritePackedMsg, end) && push32(value->TBSize[i], ppWritePackedMsg, end))) { + return 0; + } + } + + if (!(push16(value->dataScramblingId, ppWritePackedMsg, end) && push8(value->nrOfLayers, ppWritePackedMsg, end) + && push8(value->transmissionScheme, ppWritePackedMsg, end) && push8(value->refPoint, ppWritePackedMsg, end) + && push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) && push8(value->dmrsConfigType, ppWritePackedMsg, end) + && push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) && push8(value->SCID, ppWritePackedMsg, end) + && push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) && push16(value->dmrsPorts, ppWritePackedMsg, end) + && push8(value->resourceAlloc, ppWritePackedMsg, end) && (int)pusharray8(value->rbBitmap, 36, 36, ppWritePackedMsg, end) + && push16(value->rbStart, ppWritePackedMsg, end) && push16(value->rbSize, ppWritePackedMsg, end) + && push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) && push8(value->StartSymbolIndex, ppWritePackedMsg, end) + && push8(value->NrOfSymbols, ppWritePackedMsg, end))) { + return 0; + } + + // Check pduBitMap bit 0 to add or not PTRS parameters + if (value->pduBitmap & 0b1) { + if (!(push8(value->PTRSPortIndex, ppWritePackedMsg, end) && push8(value->PTRSTimeDensity, ppWritePackedMsg, end) + && push8(value->PTRSFreqDensity, ppWritePackedMsg, end) && push8(value->PTRSReOffset, ppWritePackedMsg, end) + && push8(value->nEpreRatioOfPDSCHToPTRS, ppWritePackedMsg, end))) { + return 0; + } + } + + // Precoding and beamforming + if(!pack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming,ppWritePackedMsg, end)) { + return 0; + } + + if (!(push8(value->powerControlOffset, ppWritePackedMsg, end) && push8(value->powerControlOffsetSS, ppWritePackedMsg, end))) { + return 0; + } + + // Check pduBitMap bit 1 to add or not CBG parameters + if (value->pduBitmap & 0b10) { + if (!(push8(value->isLastCbPresent, ppWritePackedMsg, end) && push8(value->isInlineTbCrc, ppWritePackedMsg, end) + && push32(value->dlTbCrc, ppWritePackedMsg, end))) { + return 0; + } + } + + if (!push8(value->maintenance_parms_v3.ldpcBaseGraph, ppWritePackedMsg, end) + || !push32(value->maintenance_parms_v3.tbSizeLbrmBytes, ppWritePackedMsg, end)) + return 0; + + return 1; +} + +static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing ssb. \n"); + nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv; + + if (!(push16(value->PhysCellId, ppWritePackedMsg, end) && push8(value->BetaPss, ppWritePackedMsg, end) + && push8(value->SsbBlockIndex, ppWritePackedMsg, end) && push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end) + && push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end) + && push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end) + && push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end) + && push8(0, ppWritePackedMsg, end))) { + return 0; + } + // Precoding and beamforming + if(!pack_nr_tx_beamforming_pdu(&value->precoding_and_beamforming,ppWritePackedMsg, end)) { + return 0; + } + return 1; +} + +static uint8_t pack_dl_tti_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)tlv; + uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg; + if (!push16(value->PDUType, ppWritePackedMsg, end)) + return 0; + uint8_t *pPackedLengthField = *ppWritePackedMsg; + if (!push16(value->PDUSize, ppWritePackedMsg, end)) + return 0; + + // first match the pdu type, then call the respective function + switch (value->PDUType) { + case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: { + if (!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15, ppWritePackedMsg, end))) + return 0; + } break; + + case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: { + if (!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15, ppWritePackedMsg, end))) + return 0; + } break; + + case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: { + if (!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppWritePackedMsg, end))) + return 0; + } break; + + case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: { + if (!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15, ppWritePackedMsg, end))) + return 0; + } break; + + default: { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType); + } break; + } + // pack proper size + uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg; + uint16_t packedMsgLen = msgEnd - msgHead; + value->PDUSize = packedMsgLen; + return push16(value->PDUSize, &pPackedLengthField, end); +} + +uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) +{ + nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg; + + if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end) + && push8(pNfapiMsg->dl_tti_request_body.nPDUs, ppWritePackedMsg, end) + && push8(pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end))) { + return 0; + } + for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) { + if (!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i], ppWritePackedMsg, end)) { + return 0; + } + } + + for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) { + if (!push8(pNfapiMsg->dl_tti_request_body.nUe[i], ppWritePackedMsg, end)) + return 0; + for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) { + if (!(push32(pNfapiMsg->dl_tti_request_body.PduIdx[i][j], ppWritePackedMsg, end))) { + return 0; + } + } + } + return 1; +} + +static uint8_t unpack_nr_tx_beamforming_pdu(nfapi_nr_tx_precoding_and_beamforming_t *beamforming_pdu, uint8_t **ppReadPackedMsg, uint8_t *end) +{ // Unpack RX Beamforming PDU + if (!(pull16(ppReadPackedMsg, &beamforming_pdu->num_prgs, end) && pull16(ppReadPackedMsg, &beamforming_pdu->prg_size, end) + && pull8(ppReadPackedMsg, &beamforming_pdu->dig_bf_interfaces, end))) { + return 0; + } + for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) { + if (!(pull16(ppReadPackedMsg, &beamforming_pdu->prgs_list[prg].pm_idx, end))) { + return 0; + } + for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interfaces; digBFInterface++) { + if (!pull16(ppReadPackedMsg, &beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, end)) { + return 0; + } + } + } + return 1; +} + +static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv; + + if (!(pull16(ppReadPackedMsg, &value->BWPSize, end) && pull16(ppReadPackedMsg, &value->BWPStart, end) + && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) && pull8(ppReadPackedMsg, &value->CyclicPrefix, end) + && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) && pull8(ppReadPackedMsg, &value->DurationSymbols, end) + && pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end) + && pull8(ppReadPackedMsg, &value->CceRegMappingType, end) && pull8(ppReadPackedMsg, &value->RegBundleSize, end) + && pull8(ppReadPackedMsg, &value->InterleaverSize, end) && pull8(ppReadPackedMsg, &value->CoreSetType, end) + && pull16(ppReadPackedMsg, &value->ShiftIndex, end) && pull8(ppReadPackedMsg, &value->precoderGranularity, end) + && pull16(ppReadPackedMsg, &value->numDlDci, end))) { + return 0; + } + + for (uint16_t i = 0; i < value->numDlDci; ++i) { + if (!(pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end) + && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end) + && pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end) + && pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end))) { + return 0; + } + + // Preocding and Beamforming + if(!unpack_nr_tx_beamforming_pdu(&value->dci_pdu[i].precodingAndBeamforming, ppReadPackedMsg, end)) { + return 0; + } + + if (!(pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end) + && pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end) + && pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end) + && unpack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppReadPackedMsg, end))) { + return 0; + } + } + return 1; +} + +static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv; + + if (!(pull16(ppReadPackedMsg, &value->pduBitmap, end) && pull16(ppReadPackedMsg, &value->rnti, end) + && pull16(ppReadPackedMsg, &value->pduIndex, end) && pull16(ppReadPackedMsg, &value->BWPSize, end) + && pull16(ppReadPackedMsg, &value->BWPStart, end) && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) + && pull8(ppReadPackedMsg, &value->CyclicPrefix, end) && pull8(ppReadPackedMsg, &value->NrOfCodewords, end))) { + return 0; + } + for (int i = 0; i < value->NrOfCodewords; ++i) { + if (!(pull16(ppReadPackedMsg, &value->targetCodeRate[i], end) && pull8(ppReadPackedMsg, &value->qamModOrder[i], end) + && pull8(ppReadPackedMsg, &value->mcsIndex[i], end) && pull8(ppReadPackedMsg, &value->mcsTable[i], end) + && pull8(ppReadPackedMsg, &value->rvIndex[i], end) && pull32(ppReadPackedMsg, &value->TBSize[i], end))) { + return 0; + } + } + + if (!(pull16(ppReadPackedMsg, &value->dataScramblingId, end) && pull8(ppReadPackedMsg, &value->nrOfLayers, end) + && pull8(ppReadPackedMsg, &value->transmissionScheme, end) && pull8(ppReadPackedMsg, &value->refPoint, end) + && pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) && pull8(ppReadPackedMsg, &value->dmrsConfigType, end) + && pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) && pull8(ppReadPackedMsg, &value->SCID, end) + && pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) && pull16(ppReadPackedMsg, &value->dmrsPorts, end) + && pull8(ppReadPackedMsg, &value->resourceAlloc, end) && pullarray8(ppReadPackedMsg, &value->rbBitmap[0], 36, 36, end) + && pull16(ppReadPackedMsg, &value->rbStart, end) && pull16(ppReadPackedMsg, &value->rbSize, end) + && pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) + && pull8(ppReadPackedMsg, &value->NrOfSymbols, end))) { + return 0; + } + // Check pduBitMap bit 0 to pull PTRS parameters or not + if (value->pduBitmap & 0b1) { + if (!(pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) && pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end) + && pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) && pull8(ppReadPackedMsg, &value->PTRSReOffset, end) + && pull8(ppReadPackedMsg, &value->nEpreRatioOfPDSCHToPTRS, end))) { + return 0; + } + } + + // Preocding and Beamforming + if(!unpack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming, ppReadPackedMsg, end)) { + return 0; + } + + // Tx power info + if (!(pull8(ppReadPackedMsg, &value->powerControlOffset, end) && pull8(ppReadPackedMsg, &value->powerControlOffsetSS, end))) { + return 0; + } + + // Check pduBitMap bit 1 to pull CBG parameters or not + if (value->pduBitmap & 0b10) { + if (!(pull8(ppReadPackedMsg, &value->isLastCbPresent, end) && pull8(ppReadPackedMsg, &value->isInlineTbCrc, end) + && pull32(ppReadPackedMsg, &value->dlTbCrc, end))) { + return 0; + } + } + + if (!pull8(ppReadPackedMsg, &value->maintenance_parms_v3.ldpcBaseGraph, end) + || !pull32(ppReadPackedMsg, &value->maintenance_parms_v3.tbSizeLbrmBytes, end)) + return 0; + + return 1; +} + +static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv; + if (!(pull16(ppReadPackedMsg, &value->bwp_size, end) && pull16(ppReadPackedMsg, &value->bwp_start, end) + && pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &value->cyclic_prefix, end) + && pull16(ppReadPackedMsg, &value->start_rb, end) && pull16(ppReadPackedMsg, &value->nr_of_rbs, end) + && pull8(ppReadPackedMsg, &value->csi_type, end) && pull8(ppReadPackedMsg, &value->row, end) + && pull16(ppReadPackedMsg, &value->freq_domain, end) && pull8(ppReadPackedMsg, &value->symb_l0, end) + && pull8(ppReadPackedMsg, &value->symb_l1, end) && pull8(ppReadPackedMsg, &value->cdm_type, end) + && pull8(ppReadPackedMsg, &value->freq_density, end) && pull16(ppReadPackedMsg, &value->scramb_id, end) + && pull8(ppReadPackedMsg, &value->power_control_offset, end) + && pull8(ppReadPackedMsg, &value->power_control_offset_ss, end))) { + return 0; + } + + // Preocding and Beamforming + if(!unpack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming, ppReadPackedMsg, end)) { + return 0; + } + + return 1; +} + +static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Unpacking ssb. \n"); + uint8_t byte3, byte2, byte1, byte0; + nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv; + + if (!(pull16(ppReadPackedMsg, &value->PhysCellId, end) && pull8(ppReadPackedMsg, &value->BetaPss, end) + && pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) && pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end) + && pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) && pull8(ppReadPackedMsg, &value->bchPayloadFlag, end) + && pull8(ppReadPackedMsg, &byte3, end) && pull8(ppReadPackedMsg, &byte2, end) && pull8(ppReadPackedMsg, &byte1, end) + && pull8(ppReadPackedMsg, &byte0, end))) { // this should be always 0, bchpayload is 24 bits + return 0; + } + // rebuild the bchPayload + value->bchPayload = byte3 << 16 | byte2 << 8 | byte1; + + // Preocding and Beamforming + if(!unpack_nr_tx_beamforming_pdu(&value->precoding_and_beamforming, ppReadPackedMsg, end)) { + return 0; + } + return 1; +} + +static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) +{ + nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)msg; + + if (!(pull16(ppReadPackedMsg, &value->PDUType, end) && pull16(ppReadPackedMsg, (uint16_t *)&value->PDUSize, end))) + return 0; + + // first match the pdu type, then call the respective function + switch (value->PDUType) { + case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: { + if (!(unpack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15, ppReadPackedMsg, end))) + return 0; + } break; + + case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: { + if (!(unpack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15, ppReadPackedMsg, end))) + return 0; + } break; + + case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: { + if (!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppReadPackedMsg, end))) + return 0; + } break; + + case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: { + if (!(unpack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15, ppReadPackedMsg, end))) + return 0; + } break; + + default: { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType); + } break; + } + + return 1; +} + +uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) +{ + nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg; + pNfapiMsg->vendor_extension = NULL; + if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) + && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end) + && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end))) { + return 0; + } + for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) { + if (!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i])) + return 0; + } + + for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) { + if (!pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nUe[i], end)) { + return 0; + } + for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) { + if (!pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.PduIdx[i][j], end)) { + return 0; + } + } + } + + return 1; +} diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h b/nfapi/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h index c7624a2315..fcc3575e9e 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h @@ -46,9 +46,6 @@ uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, nfapi_nr_srs_indication_t *pNfapiMsg, nfapi_p7_codec_config_t *config); -uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config); - -uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config); uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config); diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index 23647ce0f7..bd85c756ed 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -40,6 +40,7 @@ #include "nfapi_nr_interface_scf.h" #include "nr_nfapi_p7.h" #include "nr_fapi.h" +#include "nr_fapi_p7.h" extern int nfapi_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMsg, void *user_data); extern int nfapi_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, void *user_data); @@ -234,201 +235,6 @@ static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t *value, uint8_t **ppW return 1; } -static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv; - if (!(push16(value->bwp_size, ppWritePackedMsg, end) && push16(value->bwp_start, ppWritePackedMsg, end) - && push8(value->subcarrier_spacing, ppWritePackedMsg, end) && push8(value->cyclic_prefix, ppWritePackedMsg, end) - && push16(value->start_rb, ppWritePackedMsg, end) && push16(value->nr_of_rbs, ppWritePackedMsg, end) - && push8(value->csi_type, ppWritePackedMsg, end) && push8(value->row, ppWritePackedMsg, end) - && push16(value->freq_domain, ppWritePackedMsg, end) && push8(value->symb_l0, ppWritePackedMsg, end) - && push8(value->symb_l1, ppWritePackedMsg, end) && push8(value->cdm_type, ppWritePackedMsg, end) - && push8(value->freq_density, ppWritePackedMsg, end) && push16(value->scramb_id, ppWritePackedMsg, end) - && push8(value->power_control_offset, ppWritePackedMsg, end) - && push8(value->power_control_offset_ss, ppWritePackedMsg, end))) { - return 0; - } - - // Precoding and Beamforming - if (!(push16(value->precodingAndBeamforming.num_prgs, ppWritePackedMsg, end) - && push16(value->precodingAndBeamforming.prg_size, ppWritePackedMsg, end) - && push8(value->precodingAndBeamforming.dig_bf_interfaces, ppWritePackedMsg, end))) { - return 0; - } - for (int prg = 0; prg < value->precodingAndBeamforming.num_prgs; prg++) { - if (!push16(value->precodingAndBeamforming.prgs_list[prg].pm_idx, ppWritePackedMsg, end)) { - return 0; - } - for (int digInt = 0; digInt < value->precodingAndBeamforming.dig_bf_interfaces; digInt++) { - if (!push16(value->precodingAndBeamforming.prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, ppWritePackedMsg, end)) { - return 0; - } - } - } - return 1; -} - -static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv; - - if (!(push16(value->BWPSize, ppWritePackedMsg, end) && push16(value->BWPStart, ppWritePackedMsg, end) - && push8(value->SubcarrierSpacing, ppWritePackedMsg, end) && push8(value->CyclicPrefix, ppWritePackedMsg, end) - && push8(value->StartSymbolIndex, ppWritePackedMsg, end) && push8(value->DurationSymbols, ppWritePackedMsg, end) - && pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end) - && push8(value->CceRegMappingType, ppWritePackedMsg, end) && push8(value->RegBundleSize, ppWritePackedMsg, end) - && push8(value->InterleaverSize, ppWritePackedMsg, end) && push8(value->CoreSetType, ppWritePackedMsg, end) - && push16(value->ShiftIndex, ppWritePackedMsg, end) && push8(value->precoderGranularity, ppWritePackedMsg, end) - && push16(value->numDlDci, ppWritePackedMsg, end))) { - return 0; - } - - for (uint16_t i = 0; i < value->numDlDci; ++i) { - if (!(push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) && push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end) - && push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) - && push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end) - && push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end))) { - return 0; - } - // Precoding and beamforming - // TODO get these values from elsewhere and delete the hardcoded ones - value->dci_pdu[i].precodingAndBeamforming.num_prgs = 0; - value->dci_pdu[i].precodingAndBeamforming.prg_size = 0; // 1 PRG of max size for analogue beamforming - value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces = 0; - value->dci_pdu[i].precodingAndBeamforming.prgs_list[0].pm_idx = 0; - value->dci_pdu[i].precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0; - if (!(push16(value->dci_pdu[i].precodingAndBeamforming.num_prgs, ppWritePackedMsg, end) - && push16(value->dci_pdu[i].precodingAndBeamforming.prg_size, ppWritePackedMsg, end) - && push8(value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, ppWritePackedMsg, end))) { - return 0; - } - for (int prg = 0; prg < value->dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) { - if (!push16(value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx, ppWritePackedMsg, end)) { - return 0; - } - for (int digInt = 0; digInt < value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces; digInt++) { - if (!push16(value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, - ppWritePackedMsg, - end)) { - return 0; - } - } - } - // TX Power info - if (!(push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) - && push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) && - // DCI Payload fields - push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) && - // Pack DCI Payload - pack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end))) { - return 0; - } - } - return 1; -} - -static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv; - - if (!(push16(value->pduBitmap, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end) - && push16(value->pduIndex, ppWritePackedMsg, end) && push16(value->BWPSize, ppWritePackedMsg, end) - && push16(value->BWPStart, ppWritePackedMsg, end) && push8(value->SubcarrierSpacing, ppWritePackedMsg, end) - && push8(value->CyclicPrefix, ppWritePackedMsg, end) && push8(value->NrOfCodewords, ppWritePackedMsg, end))) { - return 0; - } - for (int i = 0; i < value->NrOfCodewords; ++i) { - if (!(push16(value->targetCodeRate[i], ppWritePackedMsg, end) && push8(value->qamModOrder[i], ppWritePackedMsg, end) - && push8(value->mcsIndex[i], ppWritePackedMsg, end) && push8(value->mcsTable[i], ppWritePackedMsg, end) - && push8(value->rvIndex[i], ppWritePackedMsg, end) && push32(value->TBSize[i], ppWritePackedMsg, end))) { - return 0; - } - } - - if (!(push16(value->dataScramblingId, ppWritePackedMsg, end) && push8(value->nrOfLayers, ppWritePackedMsg, end) - && push8(value->transmissionScheme, ppWritePackedMsg, end) && push8(value->refPoint, ppWritePackedMsg, end) - && push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) && push8(value->dmrsConfigType, ppWritePackedMsg, end) - && push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) && push8(value->SCID, ppWritePackedMsg, end) - && push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) && push16(value->dmrsPorts, ppWritePackedMsg, end) - && push8(value->resourceAlloc, ppWritePackedMsg, end) && (int)pusharray8(value->rbBitmap, 36, 36, ppWritePackedMsg, end) - && push16(value->rbStart, ppWritePackedMsg, end) && push16(value->rbSize, ppWritePackedMsg, end) - && push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) && push8(value->StartSymbolIndex, ppWritePackedMsg, end) - && push8(value->NrOfSymbols, ppWritePackedMsg, end))) { - return 0; - } - - // Check pduBitMap bit 0 to add or not PTRS parameters - if (value->pduBitmap & 0b1) { - if (!(push8(value->PTRSPortIndex, ppWritePackedMsg, end) && push8(value->PTRSTimeDensity, ppWritePackedMsg, end) - && push8(value->PTRSFreqDensity, ppWritePackedMsg, end) && push8(value->PTRSReOffset, ppWritePackedMsg, end) - && push8(value->nEpreRatioOfPDSCHToPTRS, ppWritePackedMsg, end))) { - return 0; - } - } - - if (!(push16(value->precodingAndBeamforming.num_prgs, ppWritePackedMsg, end) - && push16(value->precodingAndBeamforming.prg_size, ppWritePackedMsg, end) - && push8(value->precodingAndBeamforming.dig_bf_interfaces, ppWritePackedMsg, end))) { - return 0; - } - for (int i = 0; i < value->precodingAndBeamforming.num_prgs; ++i) { - if (!push16(value->precodingAndBeamforming.prgs_list[i].pm_idx, ppWritePackedMsg, end)) { - return 0; - } - for (int k = 0; k < value->precodingAndBeamforming.dig_bf_interfaces; ++k) { - if (!push16(value->precodingAndBeamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, ppWritePackedMsg, end)) { - return 0; - } - } - } - - if (!(push8(value->powerControlOffset, ppWritePackedMsg, end) && push8(value->powerControlOffsetSS, ppWritePackedMsg, end))) { - return 0; - } - - // Check pduBitMap bit 1 to add or not CBG parameters - if (value->pduBitmap & 0b10) { - if (!(push8(value->isLastCbPresent, ppWritePackedMsg, end) && push8(value->isInlineTbCrc, ppWritePackedMsg, end) - && push32(value->dlTbCrc, ppWritePackedMsg, end))) { - return 0; - } - } - - if (!push8(value->maintenance_parms_v3.ldpcBaseGraph, ppWritePackedMsg, end) - || !push32(value->maintenance_parms_v3.tbSizeLbrmBytes, ppWritePackedMsg, end)) - return 0; - - return 1; -} - -static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing ssb. \n"); - nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv; - - if (!(push16(value->PhysCellId, ppWritePackedMsg, end) && push8(value->BetaPss, ppWritePackedMsg, end) - && push8(value->SsbBlockIndex, ppWritePackedMsg, end) && push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end) - && push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end) - && push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end) - && push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end) - && push8(0, ppWritePackedMsg, end) - && push16(value->precoding_and_beamforming.num_prgs, ppWritePackedMsg, end) - && push16(value->precoding_and_beamforming.prg_size, ppWritePackedMsg, end) - && push8(value->precoding_and_beamforming.dig_bf_interfaces, ppWritePackedMsg, end))) { - return 0; - } - for (int i = 0; i < value->precoding_and_beamforming.num_prgs; ++i) { - if (!push16(value->precoding_and_beamforming.prgs_list[i].pm_idx, ppWritePackedMsg, end)) { - return 0; - } - for (int k = 0; k < value->precoding_and_beamforming.dig_bf_interfaces; ++k) { - if (!push16(value->precoding_and_beamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, ppWritePackedMsg, end)) { - return 0; - } - } - } - return 1; -} static uint8_t pack_dl_config_dci_dl_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_dl_config_dci_dl_pdu_rel13_t *value = (nfapi_dl_config_dci_dl_pdu_rel13_t *)tlv; @@ -710,49 +516,6 @@ static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppWrit push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end)); } -static uint8_t pack_dl_tti_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)tlv; - uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg; - if (!push16(value->PDUType, ppWritePackedMsg, end)) - return 0; - uint8_t *pPackedLengthField = *ppWritePackedMsg; - if (!push16(value->PDUSize, ppWritePackedMsg, end)) - return 0; - - // first match the pdu type, then call the respective function - switch (value->PDUType) { - case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: { - if (!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppWritePackedMsg, end))) - return 0; - } break; - - case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: { - if (!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15, ppWritePackedMsg, end))) - return 0; - } break; - - case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: { - if (!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15, ppWritePackedMsg, end))) - return 0; - } break; - - case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: { - if (!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15, ppWritePackedMsg, end))) - return 0; - } break; - - default: { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType); - } break; - } - // pack proper size - uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg; - uint16_t packedMsgLen = msgEnd - msgHead; - value->PDUSize = packedMsgLen; - return push16(value->PDUSize, &pPackedLengthField, end); -} - static uint8_t pack_dl_config_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_dl_config_request_body_t *value = (nfapi_dl_config_request_body_t *)tlv; @@ -893,34 +656,6 @@ static uint8_t pack_dl_config_request_body_value(void *tlv, uint8_t **ppWritePac return 1; } -uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) -{ - nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg; - - if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end) - && push8(pNfapiMsg->dl_tti_request_body.nPDUs, ppWritePackedMsg, end) - && push8(pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end))) { - return 0; - } - for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) { - if (!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i], ppWritePackedMsg, end)) - return 0; - } - - for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) { - if (!push8(pNfapiMsg->dl_tti_request_body.nUe[i], ppWritePackedMsg, end)) - return 0; - for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) { - if (!(push32(pNfapiMsg->dl_tti_request_body.PduIdx[i][j], ppWritePackedMsg, end))) { - return 0; - } - } - return 0; - } - - return 1; -} - static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) { nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t *)msg; //return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && @@ -3994,186 +3729,6 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu // Unpack routines // NR: -static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv; - uint16_t num_prgs = 0, prg_size = 0; - uint8_t dig_bf_interfaces = 0; - return (pull16(ppReadPackedMsg, &value->bwp_size, end) && pull16(ppReadPackedMsg, &value->bwp_start, end) - && pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &value->cyclic_prefix, end) - && pull16(ppReadPackedMsg, &value->start_rb, end) && pull16(ppReadPackedMsg, &value->nr_of_rbs, end) - && pull8(ppReadPackedMsg, &value->csi_type, end) && pull8(ppReadPackedMsg, &value->row, end) - && pull16(ppReadPackedMsg, &value->freq_domain, end) && pull8(ppReadPackedMsg, &value->symb_l0, end) - && pull8(ppReadPackedMsg, &value->symb_l1, end) && pull8(ppReadPackedMsg, &value->cdm_type, end) - && pull8(ppReadPackedMsg, &value->freq_density, end) && pull16(ppReadPackedMsg, &value->scramb_id, end) - && pull8(ppReadPackedMsg, &value->power_control_offset, end) - && pull8(ppReadPackedMsg, &value->power_control_offset_ss, end) && - // Precoding and Beamforming hardcoded to 0 - pull16(ppReadPackedMsg, &num_prgs, end) && pull16(ppReadPackedMsg, &prg_size, end) - && pull8(ppReadPackedMsg, &dig_bf_interfaces, end)); -} - -static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv; - - if (!(pull16(ppReadPackedMsg, &value->BWPSize, end) && pull16(ppReadPackedMsg, &value->BWPStart, end) - && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) && pull8(ppReadPackedMsg, &value->CyclicPrefix, end) - && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) && pull8(ppReadPackedMsg, &value->DurationSymbols, end) - && pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end) - && pull8(ppReadPackedMsg, &value->CceRegMappingType, end) && pull8(ppReadPackedMsg, &value->RegBundleSize, end) - && pull8(ppReadPackedMsg, &value->InterleaverSize, end) && pull8(ppReadPackedMsg, &value->CoreSetType, end) - && pull16(ppReadPackedMsg, &value->ShiftIndex, end) && pull8(ppReadPackedMsg, &value->precoderGranularity, end) - && pull16(ppReadPackedMsg, &value->numDlDci, end))) { - return 0; - } - - for (uint16_t i = 0; i < value->numDlDci; ++i) { - if (!(pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end) - && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end) - && pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end) - && pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end) - && pull16(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.num_prgs, end) - && pull16(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.prg_size, end) - && pull8(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, end))) { - return 0; - } - for (int prg = 0; prg < value->dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) { - if (!pull16(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx, end)) { - return 0; - } - for (int digInt = 0; digInt < value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces; digInt++) { - if (!pull16(ppReadPackedMsg, - &value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, - end)) { - return 0; - } - } - } - if (!(pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end) - && pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end) - && pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end) - && unpack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppReadPackedMsg, end))) { - return 0; - } - } - // TODO: resolve the packaging of array (currently sending a single element) - return 1; -} - -static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv; - // TODO: resolve the packaging of array (currently sending a single element) - - if (!(pull16(ppReadPackedMsg, &value->pduBitmap, end) && pull16(ppReadPackedMsg, &value->rnti, end) - && pull16(ppReadPackedMsg, &value->pduIndex, end) && pull16(ppReadPackedMsg, &value->BWPSize, end) - && pull16(ppReadPackedMsg, &value->BWPStart, end) && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) - && pull8(ppReadPackedMsg, &value->CyclicPrefix, end) && pull8(ppReadPackedMsg, &value->NrOfCodewords, end))) { - return 0; - } - for (int i = 0; i < value->NrOfCodewords; ++i) { - if (!(pull16(ppReadPackedMsg, &value->targetCodeRate[i], end) && pull8(ppReadPackedMsg, &value->qamModOrder[i], end) - && pull8(ppReadPackedMsg, &value->mcsIndex[i], end) && pull8(ppReadPackedMsg, &value->mcsTable[i], end) - && pull8(ppReadPackedMsg, &value->rvIndex[i], end) && pull32(ppReadPackedMsg, &value->TBSize[i], end))) { - return 0; - } - } - - if (!(pull16(ppReadPackedMsg, &value->dataScramblingId, end) && pull8(ppReadPackedMsg, &value->nrOfLayers, end) - && pull8(ppReadPackedMsg, &value->transmissionScheme, end) && pull8(ppReadPackedMsg, &value->refPoint, end) - && pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) && pull8(ppReadPackedMsg, &value->dmrsConfigType, end) - && pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) && pull8(ppReadPackedMsg, &value->SCID, end) - && pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) && pull16(ppReadPackedMsg, &value->dmrsPorts, end) - && pull8(ppReadPackedMsg, &value->resourceAlloc, end) && pullarray8(ppReadPackedMsg, &value->rbBitmap[0], 36, 36, end) - && pull16(ppReadPackedMsg, &value->rbStart, end) && pull16(ppReadPackedMsg, &value->rbSize, end) - && pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) - && pull8(ppReadPackedMsg, &value->NrOfSymbols, end))) { - return 0; - } - // Check pduBitMap bit 0 to pull PTRS parameters or not - if (value->pduBitmap & 0b1) { - if (!(pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) && pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end) - && pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) && pull8(ppReadPackedMsg, &value->PTRSReOffset, end) - && pull8(ppReadPackedMsg, &value->nEpreRatioOfPDSCHToPTRS, end))) { - return 0; - } - } - - if (!(pull16(ppReadPackedMsg, &value->precodingAndBeamforming.num_prgs, end) - && pull16(ppReadPackedMsg, &value->precodingAndBeamforming.prg_size, end) - && pull8(ppReadPackedMsg, &value->precodingAndBeamforming.dig_bf_interfaces, end))) { - return 0; - } - - for (int i = 0; i < value->precodingAndBeamforming.num_prgs; ++i) { - if (!pull16(ppReadPackedMsg, &value->precodingAndBeamforming.prgs_list[i].pm_idx, end)) { - return 0; - } - for (int k = 0; k < value->precodingAndBeamforming.dig_bf_interfaces; ++k) { - if (!pull16(ppReadPackedMsg, &value->precodingAndBeamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, end)) { - return 0; - } - } - } - // Tx power info - if (!(pull8(ppReadPackedMsg, &value->powerControlOffset, end) && pull8(ppReadPackedMsg, &value->powerControlOffsetSS, end))) { - return 0; - } - - // Check pduBitMap bit 1 to pull CBG parameters or not - if (value->pduBitmap & 0b10) { - if (!(pull8(ppReadPackedMsg, &value->isLastCbPresent, end) && pull8(ppReadPackedMsg, &value->isInlineTbCrc, end) - && pull32(ppReadPackedMsg, &value->dlTbCrc, end))) { - return 0; - } - } - - if (!pull8(ppReadPackedMsg, &value->maintenance_parms_v3.ldpcBaseGraph, end) - || !pull32(ppReadPackedMsg, &value->maintenance_parms_v3.tbSizeLbrmBytes, end)) - return 0; - - return 1; -} - -static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Unpacking ssb. \n"); - uint8_t byte3, byte2, byte1, byte0; - nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv; - - if (!(pull16(ppReadPackedMsg, &value->PhysCellId, end) && pull8(ppReadPackedMsg, &value->BetaPss, end) - && pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) && pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end) - && pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) && pull8(ppReadPackedMsg, &value->bchPayloadFlag, end) - && pull8(ppReadPackedMsg, &byte3, end) && pull8(ppReadPackedMsg, &byte2, end) && pull8(ppReadPackedMsg, &byte1, end) - && pull8(ppReadPackedMsg, &byte0, end))) { // this should be always 0, bchpayload is 24 bits - return 0; - } - // rebuild the bchpayload - value->bchPayload = byte3; - value->bchPayload = value->bchPayload << 8; - value->bchPayload |= byte2; - value->bchPayload = value->bchPayload << 8; - value->bchPayload |= byte1; - - if (!(pull16(ppReadPackedMsg, &value->precoding_and_beamforming.num_prgs, end) - && pull16(ppReadPackedMsg, &value->precoding_and_beamforming.prg_size, end) - && pull8(ppReadPackedMsg, &value->precoding_and_beamforming.dig_bf_interfaces, end))) { - return 0; - } - - for (int i = 0; i < value->precoding_and_beamforming.num_prgs; ++i) { - if (!pull16(ppReadPackedMsg, &value->precoding_and_beamforming.prgs_list[i].pm_idx, end)) { - return 0; - } - for (int k = 0; k < value->precoding_and_beamforming.dig_bf_interfaces; ++k) { - if (!pull16(ppReadPackedMsg, &value->precoding_and_beamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, end)) { - return 0; - } - } - } - return 1; -} // LTE: static uint8_t unpack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) { @@ -4564,50 +4119,6 @@ static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppRe } -static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) { - nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)msg; - - if(!(pull16(ppReadPackedMsg, &value->PDUType, end) && - pull16(ppReadPackedMsg, (uint16_t *) &value->PDUSize, end))) - return 0; - - // first match the pdu type, then call the respective function - switch(value->PDUType) { - case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: { - if(!(unpack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppReadPackedMsg,end))) - return 0; - } - break; - - case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: { - if(!(unpack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppReadPackedMsg,end))) - return 0; - } - break; - - case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: { - if (!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppReadPackedMsg, end))) - return 0; - } break; - - case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: { - if(!(unpack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppReadPackedMsg,end))) - return 0; - } - break; - - default: { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType ); - } - break; - } - - return 1; -} - - - - static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) { nfapi_dl_config_request_body_t *value = (nfapi_dl_config_request_body_t *)tlv; @@ -4776,35 +4287,6 @@ static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPa return 1; } -uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) -{ - nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg; - - if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) - && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end) - && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end))) { - return 0; - } - for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) { - if (!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i])) - return 0; - } - - int arr[12]; - if (!pullarray8(ppReadPackedMsg, pNfapiMsg->dl_tti_request_body.nUe, 256, pNfapiMsg->dl_tti_request_body.nGroup, end)) { - return 0; - } - for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) { - for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) { - arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j]; - } - - if (!(pullarrays32(ppReadPackedMsg, arr, 12, pNfapiMsg->dl_tti_request_body.nUe[i], end))) - return 0; - } - - return 1; -} static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) { diff --git a/nfapi/tests/p7/CMakeLists.txt b/nfapi/tests/p7/CMakeLists.txt index 7cf1958693..1ceef08bfd 100644 --- a/nfapi/tests/p7/CMakeLists.txt +++ b/nfapi/tests/p7/CMakeLists.txt @@ -1,8 +1,8 @@ set(Test_Labels fapi p7) -set(_fapi_p7_messages "dci_inversion") +set(_fapi_p7_messages "dci_inversion;dl_tti_request") foreach (fapi_p7_message IN LISTS _fapi_p7_messages) add_executable(nr_fapi_${fapi_p7_message}_test nr_fapi_${fapi_p7_message}_test.c) - target_link_libraries(nr_fapi_${fapi_p7_message}_test PUBLIC nr_fapi_p5) + target_link_libraries(nr_fapi_${fapi_p7_message}_test PUBLIC nr_fapi_p7) target_link_libraries(nr_fapi_${fapi_p7_message}_test PRIVATE pthread UTIL ${T_LIB} minimal_lib) add_dependencies(tests nr_fapi_${fapi_p7_message}_test) diff --git a/nfapi/tests/p7/nr_fapi_dl_tti_request_test.c b/nfapi/tests/p7/nr_fapi_dl_tti_request_test.c new file mode 100644 index 0000000000..2cc95260f0 --- /dev/null +++ b/nfapi/tests/p7/nr_fapi_dl_tti_request_test.c @@ -0,0 +1,279 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#include "dci_payload_utils.h" +#include "nr_fapi_p7.h" +#include "nr_fapi_p7_utils.h" + +static void fill_dl_tti_request_beamforming(nfapi_nr_tx_precoding_and_beamforming_t *precodingAndBeamforming) +{ + precodingAndBeamforming->num_prgs = rand16_range(1, NFAPI_MAX_NUM_PRGS); + precodingAndBeamforming->prg_size = rand16_range(1, 275); + precodingAndBeamforming->dig_bf_interfaces = rand8_range(0,NFAPI_MAX_NUM_BG_IF); + for (int prg = 0; prg < precodingAndBeamforming->num_prgs; ++prg) { + precodingAndBeamforming->prgs_list[prg].pm_idx = rand16(); + for (int dbf_if = 0; dbf_if < precodingAndBeamforming->dig_bf_interfaces; ++dbf_if) { + precodingAndBeamforming->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx = rand16(); + } + } +} + +static void fill_dl_tti_request_pdcch_pdu(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdu) +{ + pdu->BWPSize = rand16(); + pdu->BWPStart = rand16(); + pdu->SubcarrierSpacing = rand8(); + pdu->CyclicPrefix = rand8(); + pdu->StartSymbolIndex = rand8(); + pdu->DurationSymbols = rand8(); + for (int fdr_idx = 0; fdr_idx < 6; ++fdr_idx) { + pdu->FreqDomainResource[fdr_idx] = rand8(); + } + pdu->CceRegMappingType = rand8(); + pdu->RegBundleSize = rand8(); + pdu->InterleaverSize = rand8(); + pdu->CoreSetType = rand8(); + pdu->ShiftIndex = rand8(); + pdu->precoderGranularity = rand8(); + pdu->numDlDci = rand8_range(1, MAX_DCI_CORESET); + for (int dl_dci = 0; dl_dci < pdu->numDlDci; ++dl_dci) { + pdu->dci_pdu[dl_dci].RNTI = rand16(); + pdu->dci_pdu[dl_dci].ScramblingId = rand16(); + pdu->dci_pdu[dl_dci].ScramblingRNTI = rand16(); + pdu->dci_pdu[dl_dci].CceIndex = rand8(); + pdu->dci_pdu[dl_dci].AggregationLevel = rand8(); + fill_dl_tti_request_beamforming(&pdu->dci_pdu[dl_dci].precodingAndBeamforming); + pdu->dci_pdu[dl_dci].beta_PDCCH_1_0 = rand8(); + pdu->dci_pdu[dl_dci].powerControlOffsetSS = rand8(); + pdu->dci_pdu[dl_dci].PayloadSizeBits = rand16_range(0, DCI_PAYLOAD_BYTE_LEN * 8); + generate_payload(pdu->dci_pdu[dl_dci].PayloadSizeBits, pdu->dci_pdu[dl_dci].Payload); + } +} + +static void fill_dl_tti_request_pdsch_pdu(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdu) +{ + pdu->pduBitmap = rand16_range(0, 2); + pdu->rnti = rand16(); + pdu->pduIndex = rand16(); + pdu->BWPSize = rand16_range(1, 275); + pdu->BWPStart = rand16_range(0, 274); + pdu->SubcarrierSpacing = rand8_range(0, 4); + pdu->CyclicPrefix = rand8_range(0, 1); + pdu->NrOfCodewords = rand8_range(1, 2); + for (int cw = 0; cw < pdu->NrOfCodewords; ++cw) { + pdu->targetCodeRate[cw] = rand16(); + pdu->qamModOrder[cw] = rand8(); + pdu->mcsIndex[cw] = rand8(); + pdu->mcsTable[cw] = rand8_range(0, 2); + pdu->rvIndex[cw] = rand8_range(0, 3); + pdu->TBSize[cw] = rand16(); + } + pdu->dataScramblingId = rand16(); + pdu->nrOfLayers = rand8_range(1, 8); + pdu->transmissionScheme = rand8_range(0, 8); + pdu->refPoint = rand8_range(0, 1); + // dlDmrsSymbPos is a bitmap occupying the 14 LSB + pdu->dlDmrsSymbPos = rand16_range(0, 0x3FFF); + pdu->dmrsConfigType = rand8_range(0, 1); + pdu->dlDmrsScramblingId = rand16(); + pdu->SCID = rand8_range(0, 1); + pdu->numDmrsCdmGrpsNoData = rand8_range(1, 3); + // dmrsPorts is a bitmap occupying the 11 LSB + pdu->dmrsPorts = rand16_range(0, 0x7FF); + pdu->resourceAlloc = rand8_range(0, 1); + for (int i = 0; i < 36; ++i) { + pdu->rbBitmap[i] = rand8(); + } + pdu->rbStart = rand16_range(0, 274); + pdu->rbSize = rand16_range(1, 275); + pdu->VRBtoPRBMapping = rand8_range(0, 2); + pdu->StartSymbolIndex = rand8_range(0, 13); + pdu->NrOfSymbols = rand8_range(1, 14); + + if (pdu->pduBitmap & 0b1) { + // PTRSPortIndex is a bitmap occupying the 6 LSB + pdu->PTRSPortIndex = rand8_range(0, 0x3F); + pdu->PTRSTimeDensity = rand8_range(0, 2); + pdu->PTRSFreqDensity = rand8_range(0, 1); + pdu->PTRSReOffset = rand8_range(0, 3); + pdu->nEpreRatioOfPDSCHToPTRS = rand8_range(0, 3); + } + fill_dl_tti_request_beamforming(&pdu->precodingAndBeamforming); + pdu->powerControlOffset = rand8_range(0, 23); + pdu->powerControlOffsetSS = rand8_range(0, 3); + // Check pduBitMap bit 1 to add or not CBG parameters + if (pdu->pduBitmap & 0b10) { + pdu->isLastCbPresent = rand8_range(0, 1); + pdu->isInlineTbCrc = rand8_range(0, 1); + pdu->dlTbCrc = rand32(); + } + pdu->maintenance_parms_v3.ldpcBaseGraph = rand8(); + pdu->maintenance_parms_v3.tbSizeLbrmBytes = rand32(); +} + +static void fill_dl_tti_request_csi_rs_pdu(nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *pdu) +{ + pdu->bwp_size = rand16_range(1, 275); + pdu->bwp_start = rand16_range(0, 274); + pdu->subcarrier_spacing = rand8_range(0, 4); + pdu->cyclic_prefix = rand8_range(0, 1); + pdu->start_rb = rand16_range(0, 274); + pdu->nr_of_rbs = rand16_range(0, pdu->bwp_size); + pdu->csi_type = rand8_range(0, 2); + pdu->row = rand8_range(1, 18); + // freq_domain is a bitmap up to 12 LSB, depending on row value [TS38.211, sec 7.4.1.5.3] + // row = 1 -> b0 to b3 + // row = 2 -> b0 to b11 + // row = 4 -> b0 to b2 + // other rows -> b0 to b5 + switch (pdu->row) { + case 1: // 4 bits + pdu->freq_domain = rand16_range(0, 0xF); + break; + case 2: // 12 bits + pdu->freq_domain = rand16_range(0, 0xFFF); + break; + case 4: // 3 bits + pdu->freq_domain = rand16_range(0, 7); + break; + default: // 6 bits + pdu->freq_domain = rand16_range(0, 0x3F); + break; + } + pdu->symb_l0 = rand8_range(0, 13); + pdu->symb_l1 = rand8_range(2, 12); + pdu->cdm_type = rand8_range(0, 3); + pdu->scramb_id = rand16_range(0, 1023); + pdu->power_control_offset = rand8_range(0, 23); + pdu->power_control_offset_ss = rand8_range(0, 3); + fill_dl_tti_request_beamforming(&pdu->precodingAndBeamforming); +} + +static void fill_dl_tti_request_ssb_pdu(nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu) +{ + pdu->PhysCellId = rand16_range(0, 1007); + pdu->BetaPss = rand8_range(0, 1); + pdu->SsbBlockIndex = rand8_range(0, 63); + pdu->SsbSubcarrierOffset = rand8_range(0, 31); + pdu->ssbOffsetPointA = rand16_range(0, 2199); + pdu->bchPayloadFlag = rand8_range(0, 2); + pdu->bchPayload = rand24(); + fill_dl_tti_request_beamforming(&pdu->precoding_and_beamforming); +} + +static void fill_dl_tti_request(nfapi_nr_dl_tti_request_t *msg) +{ + msg->SFN = rand16_range(0, 1023); + msg->Slot = rand16_range(0, 159); + int available_PDUs = rand8_range(4, 16); // Minimum 4 PDUs in order to test at least one of each + msg->dl_tti_request_body.nPDUs = available_PDUs; + msg->dl_tti_request_body.nGroup = rand8(); + + int pdu = 0; + int num_PDCCH = rand8_range(1, available_PDUs - 3); + + available_PDUs -= num_PDCCH; + int num_PDSCH = rand8_range(1, available_PDUs - 2); + + available_PDUs -= num_PDSCH; + int num_CSI_RS = rand8_range(1, available_PDUs - 1); + + available_PDUs -= num_CSI_RS; + int num_SSB = available_PDUs; + + for (int i = 0; i < num_PDCCH; ++pdu, ++i) { + msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUSize = rand16(); + fill_dl_tti_request_pdcch_pdu(&msg->dl_tti_request_body.dl_tti_pdu_list[pdu].pdcch_pdu.pdcch_pdu_rel15); + } + + for (int i = 0; i < num_PDSCH; ++pdu, ++i) { + msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; + msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUSize = rand16(); + fill_dl_tti_request_pdsch_pdu(&msg->dl_tti_request_body.dl_tti_pdu_list[pdu].pdsch_pdu.pdsch_pdu_rel15); + } + + for (int i = 0; i < num_CSI_RS; ++pdu, ++i) { + msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUType = NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE; + msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUSize = rand16(); + fill_dl_tti_request_csi_rs_pdu(&msg->dl_tti_request_body.dl_tti_pdu_list[pdu].csi_rs_pdu.csi_rs_pdu_rel15); + } + + for (int i = 0; i < num_SSB; ++pdu, ++i) { + msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE; + msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUSize = rand16(); + fill_dl_tti_request_ssb_pdu(&msg->dl_tti_request_body.dl_tti_pdu_list[pdu].ssb_pdu.ssb_pdu_rel15); + } +} + +static void test_pack_unpack(nfapi_nr_dl_tti_request_t *req) +{ + uint8_t msg_buf[1024 * 1024 * 6]; + // first test the packing procedure + int pack_result = fapi_nr_p7_message_pack(req, msg_buf, sizeof(msg_buf), NULL); + + DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH); + // update req message_length value with value calculated in message_pack procedure + req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH; + // test the unpacking of the header + // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK + fapi_message_header_t header; + uint32_t header_buffer_size = NFAPI_HEADER_LENGTH; + uint8_t header_buffer[header_buffer_size]; + for (int idx = 0; idx < header_buffer_size; idx++) { + header_buffer[idx] = msg_buf[idx]; + } + uint8_t *pReadPackedMessage = header_buffer; + int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0); + DevAssert(unpack_header_result >= 0); + DevAssert(header.message_id == req->header.message_id); + DevAssert(header.message_length == req->header.message_length); + // test the unpacking and compare with initial message + nfapi_nr_dl_tti_request_t unpacked_req = {0}; + int unpack_result = + fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0); + DevAssert(unpack_result >= 0); + DevAssert(eq_dl_tti_request(&unpacked_req, req)); + free_dl_tti_request(&unpacked_req); +} + +static void test_copy(const nfapi_nr_dl_tti_request_t *msg) +{ + // Test copy function + nfapi_nr_dl_tti_request_t copy = {0}; + copy_dl_tti_request(msg, ©); + DevAssert(eq_dl_tti_request(msg, ©)); + free_dl_tti_request(©); +} + +int main(int n, char *v[]) +{ + fapi_test_init(); + + nfapi_nr_dl_tti_request_t req = {.header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST}; + // Fill DL_TTI request + fill_dl_tti_request(&req); + // Perform tests + test_pack_unpack(&req); + test_copy(&req); + // All tests successful! + free_dl_tti_request(&req); + return 0; +}