Files
openairinterface5g/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c
T
Florian Kaltenberger 9ba2e7ca5b Revert "Removed TRP-scheme byte from UL BF PDU to Interop with Aerial 25-1 (FAPI 10.02)"
This commit broke compatibility with Aerial when compiled with -DSCF_FAPI_10_04_SRS=ON. It was decided that this should become the default.

This reverts commit 8beb382277.
2025-09-10 13:34:27 +02:00

2447 lines
106 KiB
C

/*
* 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 "nr_fapi.h"
#include "nr_fapi_p7.h"
#include "nr_nfapi_p7.h"
#include "debug.h"
uint8_t fapi_nr_p7_message_body_pack(nfapi_nr_p7_message_header_t *header,
uint8_t **ppWritePackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config)
{
// 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;
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
result = pack_ul_tti_request(header, ppWritePackedMsg, end, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
result = pack_nr_slot_indication(header, ppWritePackedMsg, end, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
result = pack_ul_dci_request(header, ppWritePackedMsg, end, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
result = pack_tx_data_request(header, ppWritePackedMsg, end, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
result = pack_nr_rx_data_indication(header, ppWritePackedMsg, end, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
result = pack_nr_crc_indication(header, ppWritePackedMsg, end, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
result = pack_nr_uci_indication(header, ppWritePackedMsg, end, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
result = pack_nr_srs_indication(header, ppWritePackedMsg, end, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
result = pack_nr_rach_indication(header, ppWritePackedMsg, end, config);
break;
#ifdef ENABLE_AERIAL
case NFAPI_NR_PHY_MSG_TYPE_VENDOR_EXT_SLOT_RESPONSE:
result = pack_nr_slot_indication(header, ppWritePackedMsg, end, config);
break;
#endif
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) {
result = (config->pack_p7_vendor_extension)(header, ppWritePackedMsg, end, config);
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, header->message_id);
}
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
if (result == 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
}
return result;
}
int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config)
{
if (pMessageBuf == NULL || pPackedBuf == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
return -1;
}
nfapi_nr_p7_message_header_t *pMessageHeader = pMessageBuf;
uint8_t *pWritePackedMessage = pPackedBuf;
uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
uint8_t *pPackedLengthField = &pWritePackedMessage[4];
uint8_t *pPacketBodyField = &pWritePackedMessage[8];
uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
const uint8_t result = fapi_nr_p7_message_body_pack(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config);
AssertFatal(result > 0, "fapi_nr_p7_message_body_pack error packing message body %d\n", result);
// PHY API message header
// Number of messages [0]
// Opaque handle [1]
// PHY API Message structure
// Message type ID [2,3]
// Message Length [4,5,6,7]
// Message Body [8,...]
if (!(push8(1, &pWritePackedMessage, pPackMessageEnd) && push8(0, &pWritePackedMessage, pPackMessageEnd)
&& push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd))) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
return -1;
}
// check for a valid message length
uintptr_t msgHead = (uintptr_t)pPacketBodyFieldStart;
uintptr_t msgEnd = (uintptr_t)pPacketBodyField;
uint32_t packedMsgLen = msgEnd - msgHead;
if (packedMsgLen > packedBufLen) {
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;
// Update the message length in the header
if (!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd))
return -1;
return packedMsgLen;
}
bool fapi_nr_p7_message_unpack(void *pMessageBuf,
uint32_t messageBufLen,
void *pUnpackedBuf,
uint32_t unpackedBufLen,
nfapi_p7_codec_config_t *config)
{
int result = 0;
nfapi_nr_p7_message_header_t *pMessageHeader = (nfapi_nr_p7_message_header_t *)pUnpackedBuf;
fapi_message_header_t fapi_hdr;
AssertFatal(pMessageBuf != NULL && pUnpackedBuf != NULL, "P7 unpack supplied pointers are null");
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 (!fapi_nr_message_header_unpack(pMessageBuf, NFAPI_HEADER_LENGTH, &fapi_hdr, sizeof(fapi_message_header_t), 0)) {
// failed to read the header
return false;
}
uint8_t *pReadPackedMessage = pMessageBuf + NFAPI_HEADER_LENGTH;
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
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 false;
}
// 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;
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen))
result = unpack_ul_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION, unpackedBufLen)) {
nfapi_nr_slot_indication_scf_t *msg = (nfapi_nr_slot_indication_scf_t *)pMessageHeader;
result = unpack_nr_slot_indication(&pReadPackedMessage, end, msg, config);
}
break;
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen))
result = unpack_ul_dci_request(&pReadPackedMessage, end, pMessageHeader, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen))
result = unpack_tx_data_request(&pReadPackedMessage, end, pMessageHeader, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION, unpackedBufLen)) {
result = unpack_nr_rx_data_indication(&pReadPackedMessage, end, pMessageHeader, config);
}
break;
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION, unpackedBufLen)) {
result = unpack_nr_crc_indication(&pReadPackedMessage, end, pMessageHeader, config);
}
break;
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION, unpackedBufLen)) {
result = unpack_nr_uci_indication(&pReadPackedMessage, end, pMessageHeader, config);
}
break;
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION, unpackedBufLen)) {
result = unpack_nr_srs_indication(&pReadPackedMessage, end, pMessageHeader, config);
}
break;
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION, unpackedBufLen)) {
result = unpack_nr_rach_indication(&pReadPackedMessage, end, pMessageHeader, config);
}
break;
default:
if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
if (config && config->unpack_p7_vendor_extension) {
result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"%s VE NFAPI message ID %d. No ve decoder provided\n",
__FUNCTION__,
pMessageHeader->message_id);
}
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
}
break;
}
if (result == 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Unpack failed to unpack message\n");
return false;
}
return true;
}
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;
}
}
#ifndef ENABLE_AERIAL
if (!push8(value->maintenance_parms_v3.ldpcBaseGraph, ppWritePackedMsg, end)
|| !push32(value->maintenance_parms_v3.tbSizeLbrmBytes, ppWritePackedMsg, end))
return 0;
#endif
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;
}
}
#ifndef ENABLE_AERIAL
if (!pull8(ppReadPackedMsg, &value->maintenance_parms_v3.ldpcBaseGraph, end)
|| !pull32(ppReadPackedMsg, &value->maintenance_parms_v3.tbSizeLbrmBytes, end))
return 0;
#endif
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;
}
// Pack fns for ul_tti PDUS
static uint8_t pack_nr_rx_beamforming_pdu(const nfapi_nr_ul_beamforming_t *beamforming_pdu,
uint8_t **ppWritePackedMsg,
uint8_t *end)
{ // Pack RX Beamforming PDU
if (!(push8(beamforming_pdu->trp_scheme, ppWritePackedMsg, end) && push16(beamforming_pdu->num_prgs, ppWritePackedMsg, end)
&& push16(beamforming_pdu->prg_size, ppWritePackedMsg, end)
&& push8(beamforming_pdu->dig_bf_interface, ppWritePackedMsg, end))) {
return 0;
}
for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interface; 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_ul_tti_request_prach_pdu(const nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
{
if (!(push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) && push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end)
&& push8(prach_pdu->prach_format, ppWritePackedMsg, end) && push8(prach_pdu->num_ra, ppWritePackedMsg, end)
&& push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) && push16(prach_pdu->num_cs, ppWritePackedMsg, end))) {
return 0;
}
return pack_nr_rx_beamforming_pdu(&prach_pdu->beamforming, ppWritePackedMsg, end);
}
static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
{
if (!(push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) && push16(pusch_pdu->rnti, ppWritePackedMsg, end)
&& push32(pusch_pdu->handle, ppWritePackedMsg, end) && push16(pusch_pdu->bwp_size, ppWritePackedMsg, end)
&& push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) && push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end)
&& push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) && push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end)
&& push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && push8(pusch_pdu->mcs_index, ppWritePackedMsg, end)
&& push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end)
&& push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end)
&& push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end)
&& push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end)
&& push16(pusch_pdu->pusch_identity, ppWritePackedMsg, end) && push8(pusch_pdu->scid, ppWritePackedMsg, end)
&& push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end)
&& push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) && push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end)
&& pusharray8(pusch_pdu->rb_bitmap, 36, 36, ppWritePackedMsg, end) && push16(pusch_pdu->rb_start, ppWritePackedMsg, end)
&& push16(pusch_pdu->rb_size, ppWritePackedMsg, end) && push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end)
&& push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end)
&& push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end)
&& push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end)
&& push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) && push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end))) {
return 0;
}
// Pack Optional Data only included if indicated in pduBitmap
// Check if PUSCH_PDU_BITMAP_PUSCH_DATA bit is set
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_DATA) {
// pack optional TLVs
if (!(push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_data.new_data_indicator, ppWritePackedMsg, end)
&& push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end)
&& push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end))) {
return 0;
}
const uint16_t cb_len = (pusch_pdu->pusch_data.num_cb + 7) / 8;
if (!pusharray8(pusch_pdu->pusch_data.cb_present_and_position, cb_len, cb_len, ppWritePackedMsg, end)) {
return 0;
}
}
// Check if PUSCH_PDU_BITMAP_PUSCH_UCI bit is set
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_UCI) {
if (!(push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end)
&& push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end)
&& push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end))) {
return 0;
}
}
// Check if PUSCH_PDU_BITMAP_PUSCH_PTRS bit is set
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
if (!push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end)) {
return 0;
}
for (int i = 0; i < pusch_pdu->pusch_ptrs.num_ptrs_ports; ++i) {
if (!(push16(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_port_index, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_dmrs_port, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_re_offset, ppWritePackedMsg, end))) {
return 0;
}
}
if (!(push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end)
&& push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end))) {
return 0;
}
}
// Check if PUSCH_PDU_BITMAP_DFTS_OFDM bit is set
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_DFTS_OFDM) {
if (!(push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end)
&& push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end)
&& push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end)
&& push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end))) {
return 0;
}
}
// Pack RX Beamforming PDU
if (!(pack_nr_rx_beamforming_pdu(&pusch_pdu->beamforming, ppWritePackedMsg, end))) {
return 0;
}
#ifndef ENABLE_AERIAL
if (!(push8(pusch_pdu->maintenance_parms_v3.ldpcBaseGraph, ppWritePackedMsg, end)
&& push32(pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes, ppWritePackedMsg, end)))
return 0;
#endif
return 1;
}
static uint8_t pack_ul_tti_request_pucch_pdu(const nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
{
if (!(push16(pucch_pdu->rnti, ppWritePackedMsg, end) && push32(pucch_pdu->handle, ppWritePackedMsg, end)
&& push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) && push16(pucch_pdu->bwp_start, ppWritePackedMsg, end)
&& push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) && push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end)
&& push8(pucch_pdu->format_type, ppWritePackedMsg, end) && push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end)
&& push8(pucch_pdu->pi_2bpsk, ppWritePackedMsg, end) && push16(pucch_pdu->prb_start, ppWritePackedMsg, end)
&& push16(pucch_pdu->prb_size, ppWritePackedMsg, end) && push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end)
&& push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) && push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end)
&& push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) && push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end)
&& push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) && push16(pucch_pdu->hopping_id, ppWritePackedMsg, end)
&& push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end)
&& push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end)
&& push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) && push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end)
&& push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) && push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end)
&& push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end)
&& push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) && push8(pucch_pdu->sr_flag, ppWritePackedMsg, end)
&& push16(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) && push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end)
&& push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end))) {
return 0;
}
return pack_nr_rx_beamforming_pdu(&pucch_pdu->beamforming, ppWritePackedMsg, end);
}
static uint8_t pack_ul_tti_request_srs_parameters_v4(nfapi_v4_srs_parameters_t *srsParameters,
const uint8_t num_symbols,
uint8_t **ppWritePackedMsg,
uint8_t *end)
{
if (!(push16(srsParameters->srs_bandwidth_size, ppWritePackedMsg, end))) {
return 0;
}
for (int symbol_idx = 0; symbol_idx < num_symbols; ++symbol_idx) {
const nfapi_v4_srs_parameters_symbols_t *symbol = &srsParameters->symbol_list[symbol_idx];
if (!(push16(symbol->srs_bandwidth_start, ppWritePackedMsg, end) && push8(symbol->sequence_group, ppWritePackedMsg, end)
&& push8(symbol->sequence_number, ppWritePackedMsg, end))) {
return 0;
}
}
#ifdef ENABLE_AERIAL
// For Aerial, we always pack/unpack the 4 reported symbols, not only the ones indicated by num_symbols
for (int symbol_idx = num_symbols; symbol_idx < 4; ++symbol_idx) {
if (!(push16(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end))) {
return 0;
}
}
#endif // ENABLE_AERIAL
const uint8_t nUsage = __builtin_popcount(srsParameters->usage);
if (!(push32(srsParameters->usage, ppWritePackedMsg, end)
&& pusharray8(srsParameters->report_type, 4, nUsage, ppWritePackedMsg, end)
&& push8(srsParameters->singular_Value_representation, ppWritePackedMsg, end)
&& push8(srsParameters->iq_representation, ppWritePackedMsg, end) && push16(srsParameters->prg_size, ppWritePackedMsg, end)
&& push8(srsParameters->num_total_ue_antennas, ppWritePackedMsg, end)
&& push32(srsParameters->ue_antennas_in_this_srs_resource_set, ppWritePackedMsg, end)
&& push32(srsParameters->sampled_ue_antennas, ppWritePackedMsg, end)
&& push8(srsParameters->report_scope, ppWritePackedMsg, end)
&& push8(srsParameters->num_ul_spatial_streams_ports, ppWritePackedMsg, end)
&& pusharray8(srsParameters->Ul_spatial_stream_ports,
256,
srsParameters->num_ul_spatial_streams_ports,
ppWritePackedMsg,
end))) {
return 0;
}
return 1;
}
static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
{
if (!(push16(srs_pdu->rnti, ppWritePackedMsg, end) && push32(srs_pdu->handle, ppWritePackedMsg, end)
&& push16(srs_pdu->bwp_size, ppWritePackedMsg, end) && push16(srs_pdu->bwp_start, ppWritePackedMsg, end)
&& push8(srs_pdu->subcarrier_spacing, ppWritePackedMsg, end) && push8(srs_pdu->cyclic_prefix, ppWritePackedMsg, end)
&& push8(srs_pdu->num_ant_ports, ppWritePackedMsg, end) && push8(srs_pdu->num_symbols, ppWritePackedMsg, end)
&& push8(srs_pdu->num_repetitions, ppWritePackedMsg, end) && push8(srs_pdu->time_start_position, ppWritePackedMsg, end)
&& push8(srs_pdu->config_index, ppWritePackedMsg, end) && push16(srs_pdu->sequence_id, ppWritePackedMsg, end)
&& push8(srs_pdu->bandwidth_index, ppWritePackedMsg, end) && push8(srs_pdu->comb_size, ppWritePackedMsg, end)
&& push8(srs_pdu->comb_offset, ppWritePackedMsg, end) && push8(srs_pdu->cyclic_shift, ppWritePackedMsg, end)
&& push8(srs_pdu->frequency_position, ppWritePackedMsg, end) && push16(srs_pdu->frequency_shift, ppWritePackedMsg, end)
&& push8(srs_pdu->frequency_hopping, ppWritePackedMsg, end)
&& push8(srs_pdu->group_or_sequence_hopping, ppWritePackedMsg, end) && push8(srs_pdu->resource_type, ppWritePackedMsg, end)
&& push16(srs_pdu->t_srs, ppWritePackedMsg, end) && push16(srs_pdu->t_offset, ppWritePackedMsg, end))) {
return 0;
}
if(!(pack_nr_rx_beamforming_pdu(&srs_pdu->beamforming, ppWritePackedMsg, end))){
return 0;
}
if(!(pack_ul_tti_request_srs_parameters_v4(&srs_pdu->srs_parameters_v4, 1 << srs_pdu->num_symbols, ppWritePackedMsg, end))){
return 0;
}
return 1;
}
static uint8_t pack_ul_tti_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_ul_tti_request_number_of_pdus_t *value = (nfapi_nr_ul_tti_request_number_of_pdus_t *)tlv;
uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
if (!push16(value->pdu_type, ppWritePackedMsg, end)) {
return 0;
}
uint8_t *pPackedLengthField = *ppWritePackedMsg;
if (!push16(value->pdu_size, ppWritePackedMsg, end))
return 0;
// pack PDUs
// first match the pdu type, then call the respective function
switch (value->pdu_type) {
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
if (!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end))
return 0;
} break;
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
if (!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end))
return 0;
} break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
if (!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end))
return 0;
} break;
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
if (!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end))
return 0;
} break;
default: {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type);
} break;
}
// pack proper size
uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
uint16_t packedMsgLen = msgEnd - msgHead;
value->pdu_size = packedMsgLen;
return push16(value->pdu_size, &pPackedLengthField, end);
}
static uint8_t pack_ul_tti_groups_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_ul_tti_request_number_of_groups_t *value = (nfapi_nr_ul_tti_request_number_of_groups_t *)tlv;
if (!push8(value->n_ue, ppWritePackedMsg, end))
return 0;
for (int i = 0; i < value->n_ue; i++) {
if (!push8(value->ue_list[i].pdu_idx, ppWritePackedMsg, end))
return 0;
}
return 1;
}
uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
pNfapiMsg->n_ulcch = 0;
pNfapiMsg->n_ulsch = 0;
for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
switch (pNfapiMsg->pdus_list[i].pdu_type) {
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
pNfapiMsg->n_ulcch++;
} break;
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
pNfapiMsg->n_ulsch++;
} break;
default:
break;
}
}
if (!push16(pNfapiMsg->SFN, ppWritePackedMsg, end))
return 0;
if (!push16(pNfapiMsg->Slot, ppWritePackedMsg, end))
return 0;
if (!push8(pNfapiMsg->n_pdus, ppWritePackedMsg, end))
return 0;
if (!push8(pNfapiMsg->rach_present, ppWritePackedMsg, end))
return 0;
if (!push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end))
return 0;
if (!push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end))
return 0;
if (!push8(pNfapiMsg->n_group, ppWritePackedMsg, end))
return 0;
for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
if (!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end))
return 0;
}
for (int i = 0; i < pNfapiMsg->n_group; i++) {
if (!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end))
return 0;
}
return 1;
}
static uint8_t unpack_nr_rx_beamforming_pdu(nfapi_nr_ul_beamforming_t *beamforming_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
{ // Unpack RX Beamforming PDU
if (!(pull8(ppReadPackedMsg, &beamforming_pdu->trp_scheme, end) && pull16(ppReadPackedMsg, &beamforming_pdu->num_prgs, end)
&& pull16(ppReadPackedMsg, &beamforming_pdu->prg_size, end)
&& pull8(ppReadPackedMsg, &beamforming_pdu->dig_bf_interface, end))) {
return 0;
}
for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interface; 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_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
{
if (!(pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) && pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end)
&& pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) && pull8(ppReadPackedMsg, &prach_pdu->num_ra, end)
&& pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) && pull16(ppReadPackedMsg, &prach_pdu->num_cs, end))) {
return 0;
}
return unpack_nr_rx_beamforming_pdu(&prach_pdu->beamforming, ppReadPackedMsg, end);
}
static uint8_t unpack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
{
if (!(pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) && pull16(ppReadPackedMsg, &pusch_pdu->rnti, end)
&& pull32(ppReadPackedMsg, &pusch_pdu->handle, end) && pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) && pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) && pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->pusch_identity, end) && pull8(ppReadPackedMsg, &pusch_pdu->scid, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) && pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end)
&& pullarray8(ppReadPackedMsg, pusch_pdu->rb_bitmap, 36, 36, end) && pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end) && pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) && pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end)))
return 0;
// Unpack Optional Data only included if indicated in pduBitmap
// Check if PUSCH_PDU_BITMAP_PUSCH_DATA bit is set
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_DATA) {
// pack optional TLVs
if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.new_data_indicator, end)
&& pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end))) {
return 0;
}
const uint8_t cb_len = (pusch_pdu->pusch_data.num_cb + 7) / 8;
if (!pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position, cb_len, cb_len, end)) {
return 0;
}
}
// Check if PUSCH_PDU_BITMAP_PUSCH_UCI bit is set
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_UCI) {
if (!(pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end))) {
return 0;
}
}
// Check if PUSCH_PDU_BITMAP_PUSCH_PTRS bit is set
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end))) {
return 0;
}
pusch_pdu->pusch_ptrs.ptrs_ports_list = calloc(pusch_pdu->pusch_ptrs.num_ptrs_ports, sizeof(nfapi_nr_ptrs_ports_t));
for (int ptrs_port = 0; ptrs_port < pusch_pdu->pusch_ptrs.num_ptrs_ports; ++ptrs_port) {
if (!(pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list[ptrs_port].ptrs_port_index, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list[ptrs_port].ptrs_dmrs_port, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list[ptrs_port].ptrs_re_offset, end))) {
return 0;
}
}
if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end))) {
return 0;
}
}
// Check if PUSCH_PDU_BITMAP_DFTS_OFDM bit is set
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_DFTS_OFDM) {
if (!(pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end)
&& pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end)
&& pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end))) {
return 0;
}
}
if (!(unpack_nr_rx_beamforming_pdu(&pusch_pdu->beamforming, ppReadPackedMsg, end))) {
return 0;
}
#ifndef ENABLE_AERIAL
if (!(pull8(ppReadPackedMsg, &pusch_pdu->maintenance_parms_v3.ldpcBaseGraph, end)
&& pull32(ppReadPackedMsg, &pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes, end)))
return 0;
#endif
return 1;
}
static uint8_t unpack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
{
if (!(pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) && pull32(ppReadPackedMsg, &pucch_pdu->handle, end)
&& pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) && pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end)
&& pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end)
&& pull8(ppReadPackedMsg, &pucch_pdu->format_type, end) && pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end)
&& pull8(ppReadPackedMsg, &pucch_pdu->pi_2bpsk, end) && pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end)
&& pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end) && pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end)
&& pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end) && pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end)
&& pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end) && pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end)
&& pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end) && pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end)
&& pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end)
&& pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end)
&& pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end) && pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end)
&& pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end) && pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end)
&& pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end)
&& pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) && pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end)
&& pull16(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) && pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end)
&& pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end))) {
return 0;
}
return unpack_nr_rx_beamforming_pdu(&pucch_pdu->beamforming, ppReadPackedMsg, end);
}
static uint8_t unpack_ul_tti_request_srs_parameters_v4(nfapi_v4_srs_parameters_t *srsParameters,
const uint8_t num_symbols,
uint8_t **ppReadPackedMsg,
uint8_t *end)
{
if (!(pull16(ppReadPackedMsg, &srsParameters->srs_bandwidth_size, end))) {
return 0;
}
for (int symbol_idx = 0; symbol_idx < num_symbols; ++symbol_idx) {
nfapi_v4_srs_parameters_symbols_t *symbol = &srsParameters->symbol_list[symbol_idx];
if (!(pull16(ppReadPackedMsg, &symbol->srs_bandwidth_start, end) && pull8(ppReadPackedMsg, &symbol->sequence_group, end)
&& pull8(ppReadPackedMsg, &symbol->sequence_number, end))) {
return 0;
}
}
#ifdef ENABLE_AERIAL
// For Aerial, we always pack/unpack the 4 reported symbols, not only the ones indicated by num_symbols
for (int symbol_idx = num_symbols; symbol_idx < 4; ++symbol_idx) {
nfapi_v4_srs_parameters_symbols_t *symbol = &srsParameters->symbol_list[symbol_idx];
if (!(pull16(ppReadPackedMsg, &symbol->srs_bandwidth_start, end) && pull8(ppReadPackedMsg, &symbol->sequence_group, end)
&& pull8(ppReadPackedMsg, &symbol->sequence_number, end))) {
return 0;
}
}
#endif // ENABLE_AERIAL
if (!(pull32(ppReadPackedMsg, &srsParameters->usage, end))) {
return 0;
}
const uint8_t nUsage = __builtin_popcount(srsParameters->usage);
if (!(pullarray8(ppReadPackedMsg, &srsParameters->report_type[0], 4, nUsage, end)
&& pull8(ppReadPackedMsg, &srsParameters->singular_Value_representation, end)
&& pull8(ppReadPackedMsg, &srsParameters->iq_representation, end) && pull16(ppReadPackedMsg, &srsParameters->prg_size, end)
&& pull8(ppReadPackedMsg, &srsParameters->num_total_ue_antennas, end)
&& pull32(ppReadPackedMsg, &srsParameters->ue_antennas_in_this_srs_resource_set, end)
&& pull32(ppReadPackedMsg, &srsParameters->sampled_ue_antennas, end)
&& pull8(ppReadPackedMsg, &srsParameters->report_scope, end)
&& pull8(ppReadPackedMsg, &srsParameters->num_ul_spatial_streams_ports, end)
&& pullarray8(ppReadPackedMsg,
&srsParameters->Ul_spatial_stream_ports[0],
256,
srsParameters->num_ul_spatial_streams_ports,
end))) {
return 0;
}
return 1;
}
static uint8_t unpack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
{
if (!(pull16(ppReadPackedMsg, &srs_pdu->rnti, end) && pull32(ppReadPackedMsg, &srs_pdu->handle, end)
&& pull16(ppReadPackedMsg, &srs_pdu->bwp_size, end) && pull16(ppReadPackedMsg, &srs_pdu->bwp_start, end)
&& pull8(ppReadPackedMsg, &srs_pdu->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &srs_pdu->cyclic_prefix, end)
&& pull8(ppReadPackedMsg, &srs_pdu->num_ant_ports, end) && pull8(ppReadPackedMsg, &srs_pdu->num_symbols, end)
&& pull8(ppReadPackedMsg, &srs_pdu->num_repetitions, end) && pull8(ppReadPackedMsg, &srs_pdu->time_start_position, end)
&& pull8(ppReadPackedMsg, &srs_pdu->config_index, end) && pull16(ppReadPackedMsg, &srs_pdu->sequence_id, end)
&& pull8(ppReadPackedMsg, &srs_pdu->bandwidth_index, end) && pull8(ppReadPackedMsg, &srs_pdu->comb_size, end)
&& pull8(ppReadPackedMsg, &srs_pdu->comb_offset, end) && pull8(ppReadPackedMsg, &srs_pdu->cyclic_shift, end)
&& pull8(ppReadPackedMsg, &srs_pdu->frequency_position, end) && pull16(ppReadPackedMsg, &srs_pdu->frequency_shift, end)
&& pull8(ppReadPackedMsg, &srs_pdu->frequency_hopping, end)
&& pull8(ppReadPackedMsg, &srs_pdu->group_or_sequence_hopping, end) && pull8(ppReadPackedMsg, &srs_pdu->resource_type, end)
&& pull16(ppReadPackedMsg, &srs_pdu->t_srs, end) && pull16(ppReadPackedMsg, &srs_pdu->t_offset, end))) {
return 0;
}
if (!(unpack_nr_rx_beamforming_pdu(&srs_pdu->beamforming, ppReadPackedMsg, end))) {
return 0;
}
if (!(unpack_ul_tti_request_srs_parameters_v4(&srs_pdu->srs_parameters_v4, 1 << srs_pdu->num_symbols, ppReadPackedMsg, end))) {
return 0;
}
return 1;
}
static uint8_t unpack_ul_tti_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
{
nfapi_nr_ul_tti_request_number_of_pdus_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_pdus_t *)msg;
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) && pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end)))
return 0;
// first natch the pdu type, then call the respective function
switch (pNfapiMsg->pdu_type) {
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
if (!unpack_ul_tti_request_prach_pdu(&pNfapiMsg->prach_pdu, ppReadPackedMsg, end))
return 0;
} break;
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
if (!unpack_ul_tti_request_pusch_pdu(&pNfapiMsg->pusch_pdu, ppReadPackedMsg, end))
return 0;
} break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
if (!unpack_ul_tti_request_pucch_pdu(&pNfapiMsg->pucch_pdu, ppReadPackedMsg, end))
return 0;
} break;
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
if (!unpack_ul_tti_request_srs_pdu(&pNfapiMsg->srs_pdu, ppReadPackedMsg, end))
return 0;
} break;
default: {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", pNfapiMsg->pdu_type);
} break;
}
return 1;
}
static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
{
nfapi_nr_ul_tti_request_number_of_groups_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_groups_t *)msg;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ue, end))
return 0;
for (int i = 0; i < pNfapiMsg->n_ue; i++) {
if (!pull8(ppReadPackedMsg, &pNfapiMsg->ue_list[i].pdu_idx, end))
return 0;
}
return 1;
}
uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
if (!pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end))
return 0;
if (!pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end))
return 0;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end))
return 0;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end))
return 0;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end))
return 0;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end))
return 0;
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end))
return 0;
for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
if (!unpack_ul_tti_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdus_list[i]))
return 0;
}
for (int i = 0; i < pNfapiMsg->n_group; i++) {
if (!unpack_ul_tti_groups_list_value(ppReadPackedMsg, end, &pNfapiMsg->groups_list[i]))
return 0;
}
return 1;
}
uint8_t pack_nr_slot_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_nr_slot_indication_scf_t *pNfapiMsg = (nfapi_nr_slot_indication_scf_t *)msg;
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)))
return 0;
return 1;
}
uint8_t unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_nr_slot_indication_scf_t *msg,
nfapi_p7_codec_config_t *config)
{
nfapi_nr_slot_indication_scf_t *pNfapiMsg = (nfapi_nr_slot_indication_scf_t *)msg;
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)))
return 0;
return 1;
}
static uint8_t pack_ul_dci_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_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) && push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end)
&& push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end)
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end)
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end)
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end)
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end)
&& pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end)
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end)
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end)
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end)
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end)
&& push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end)
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, ppWritePackedMsg, end)
&& push16(value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end))) {
return 0;
}
for (int i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
nfapi_nr_dl_dci_pdu_t *dci_pdu = &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i];
if (!(push16(dci_pdu->RNTI, ppWritePackedMsg, end) && push16(dci_pdu->ScramblingId, ppWritePackedMsg, end)
&& push16(dci_pdu->ScramblingRNTI, ppWritePackedMsg, end) && push8(dci_pdu->CceIndex, ppWritePackedMsg, end)
&& push8(dci_pdu->AggregationLevel, ppWritePackedMsg, end))) {
return 0;
}
// Precoding and Beamforming
nfapi_nr_tx_precoding_and_beamforming_t *beamforming = &dci_pdu->precodingAndBeamforming;
if (!(push16(beamforming->num_prgs, ppWritePackedMsg, end) && push16(beamforming->prg_size, ppWritePackedMsg, end)
&& push8(beamforming->dig_bf_interfaces, ppWritePackedMsg, end))) {
return 0;
}
for (int prg = 0; prg < beamforming->num_prgs; prg++) {
if (!push16(beamforming->prgs_list[prg].pm_idx, ppWritePackedMsg, end)) {
return 0;
}
for (int digInt = 0; digInt < beamforming->dig_bf_interfaces; digInt++) {
if (!push16(beamforming->prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, ppWritePackedMsg, end)) {
return 0;
}
}
}
if (!(push8(dci_pdu->beta_PDCCH_1_0, ppWritePackedMsg, end) && push8(dci_pdu->powerControlOffsetSS, ppWritePackedMsg, end) &&
// DCI Payload fields
push16(dci_pdu->PayloadSizeBits, ppWritePackedMsg, end) &&
// Pack DCI Payload
pack_dci_payload(dci_pdu->Payload, dci_pdu->PayloadSizeBits, ppWritePackedMsg, end))) {
return 0;
}
}
// 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_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
&& push8(pNfapiMsg->numPdus, ppWritePackedMsg, end)))
return 0;
for (int i = 0; i < pNfapiMsg->numPdus; i++) {
if (!pack_ul_dci_pdu_list_value(&pNfapiMsg->ul_dci_pdu_list[i], ppWritePackedMsg, end))
return 0;
}
return 1;
}
static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
{
nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)msg;
if (!(pull16(ppReadPackedMsg, &value->PDUType, end) && pull16(ppReadPackedMsg, &value->PDUSize, end)
&& pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end)
&& pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end)
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end)
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end)
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end)
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end)
&& pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end)
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end)
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end)
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end)
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end)
&& pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end)
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end)
&& pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end))) {
return 0;
}
for (uint16_t i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
nfapi_nr_dl_dci_pdu_t *dci_pdu = &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i];
if (!(pull16(ppReadPackedMsg, &dci_pdu->RNTI, end) && pull16(ppReadPackedMsg, &dci_pdu->ScramblingId, end)
&& pull16(ppReadPackedMsg, &dci_pdu->ScramblingRNTI, end) && pull8(ppReadPackedMsg, &dci_pdu->CceIndex, end)
&& pull8(ppReadPackedMsg, &dci_pdu->AggregationLevel, end))) {
return 0;
}
// Precoding and Beamforming
nfapi_nr_tx_precoding_and_beamforming_t *beamforming = &dci_pdu->precodingAndBeamforming;
if (!(pull16(ppReadPackedMsg, &beamforming->num_prgs, end) && pull16(ppReadPackedMsg, &beamforming->prg_size, end)
&& pull8(ppReadPackedMsg, &beamforming->dig_bf_interfaces, end))) {
return 0;
}
for (int prg = 0; prg < beamforming->num_prgs; prg++) {
if (!pull16(ppReadPackedMsg, &beamforming->prgs_list[prg].pm_idx, end)) {
return 0;
}
for (int digInt = 0; digInt < beamforming->dig_bf_interfaces; digInt++) {
if (!pull16(ppReadPackedMsg, &beamforming->prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, end)) {
return 0;
}
}
}
if (!(pull8(ppReadPackedMsg, &dci_pdu->beta_PDCCH_1_0, end) && pull8(ppReadPackedMsg, &dci_pdu->powerControlOffsetSS, end)
&& pull16(ppReadPackedMsg, &dci_pdu->PayloadSizeBits, end)
&& unpack_dci_payload(dci_pdu->Payload, dci_pdu->PayloadSizeBits, ppReadPackedMsg, end))) {
return 0;
}
}
return 1;
}
uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
&& pull8(ppReadPackedMsg, &pNfapiMsg->numPdus, end)))
return 0;
for (int i = 0; i < pNfapiMsg->numPdus; i++) {
if (!unpack_ul_dci_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->ul_dci_pdu_list[i]))
return 0;
}
return 1;
}
static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, uint32_t *payload_offset)
{
nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv;
if (!(push32(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end)
&& push32(value->num_TLV, ppWritePackedMsg, end)))
return 0;
for (int i = 0; i < value->num_TLV; ++i) {
if (!push16(value->TLVs[i].tag, ppWritePackedMsg, end))
return 0;
#ifdef ENABLE_AERIAL
if (!push16(value->TLVs[i].length, ppWritePackedMsg, end))
return 0;
#else
if (!push32(value->TLVs[i].length, ppWritePackedMsg, end))
return 0;
#endif
const uint32_t byte_len = (value->TLVs[i].length + 3) / 4;
switch (value->TLVs[i].tag) {
case 0: {
if (!pusharray32(value->TLVs[i].value.direct, byte_len, byte_len, ppWritePackedMsg, end)) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
return 0;
}
break;
}
case 1: {
if (!pusharray32(value->TLVs[i].value.ptr, byte_len, byte_len, ppWritePackedMsg, end)) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
return 0;
}
break;
}
case 2: {
// Currently Tag = 2 is only used for Aerial
if (!push32(*payload_offset, ppWritePackedMsg, end)) {
return 0;
}
*payload_offset += value->TLVs[i].length;
break;
}
default: {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag);
break;
}
}
}
return 1;
}
uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
&& push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end)))
return 0;
uint32_t payload_offset = 0;
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
if (!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end, &payload_offset)) {
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n",
__FUNCTION__,
__LINE__,
i,
pNfapiMsg->pdu_list[i].PDU_length,
pNfapiMsg->pdu_list[i].PDU_index);
return 0;
}
}
return 1;
}
static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
{
nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg;
if (!(pull32(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) && pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end)
&& pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end)))
return 0;
for (int i = 0; i < pNfapiMsg->num_TLV; ++i) {
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end) && pull32(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end)))
return 0;
const uint32_t byte_len = (pNfapiMsg->TLVs[i].length + 3) / 4;
if (pNfapiMsg->TLVs[i].tag == 1) {
pNfapiMsg->TLVs[i].value.ptr = calloc(byte_len, sizeof(uint32_t));
}
switch (pNfapiMsg->TLVs[i].tag) {
case 0: {
if (!pullarray32(ppReadPackedMsg,
pNfapiMsg->TLVs[i].value.direct,
sizeof(pNfapiMsg->TLVs[i].value.direct) / sizeof(uint32_t),
byte_len,
end))
return 0;
break;
}
case 1: {
if (!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.ptr, byte_len, byte_len, end))
return 0;
break;
}
default: {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", pNfapiMsg->TLVs[i].tag);
return 0;
}
}
}
return 1;
}
uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
&& pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end)))
return 0;
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) {
return 0;
}
}
return 1;
}
static uint8_t pack_nr_rx_data_indication_body(const nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
{
if (!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
&& push8(value->harq_id, ppWritePackedMsg, end) && push32(value->pdu_length, ppWritePackedMsg, end)
&& push8(value->ul_cqi, ppWritePackedMsg, end) && push16(value->timing_advance, ppWritePackedMsg, end)
&& push16(value->rssi, ppWritePackedMsg, end)))
return 0;
if (pusharray8(value->pdu, value->pdu_length, value->pdu_length, ppWritePackedMsg, end) == 0)
return 0;
return 1;
}
uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t *)msg;
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
&& push16(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)))
return 0;
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
if (!pack_nr_rx_data_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
return 0;
}
return 1;
}
static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config)
{
if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
&& pull8(ppReadPackedMsg, &value->harq_id, end) && pull32(ppReadPackedMsg, &value->pdu_length, end)
&& pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
&& pull16(ppReadPackedMsg, &value->rssi, end)))
return 0;
const uint32_t length = value->pdu_length;
value->pdu = calloc(length, sizeof(*value->pdu));
if (pullarray8(ppReadPackedMsg, value->pdu, length, length, end) == 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__);
return 0;
}
return 1;
}
uint8_t unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t *)msg;
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
&& pull16(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end)))
return 0;
if (pNfapiMsg->number_of_pdus > 0) {
pNfapiMsg->pdu_list = calloc(pNfapiMsg->number_of_pdus, sizeof(*pNfapiMsg->pdu_list));
}
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
if (!unpack_nr_rx_data_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config))
return 0;
}
return 1;
}
static uint8_t pack_nr_crc_indication_body(const nfapi_nr_crc_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
{
if (!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
&& push8(value->harq_id, ppWritePackedMsg, end) && push8(value->tb_crc_status, ppWritePackedMsg, end)
&& push16(value->num_cb, ppWritePackedMsg, end))) {
return 0;
}
if (value->num_cb != 0) {
const uint16_t cb_len = (value->num_cb / 8) + 1; // length is ceil(NumCb/8)
if (!pusharray8(value->cb_crc_status, cb_len, cb_len, ppWritePackedMsg,
end)) {
return 0;
}
}
if (!(push8(value->ul_cqi, ppWritePackedMsg, end) && push16(value->timing_advance, ppWritePackedMsg, end)
&& push16(value->rssi, ppWritePackedMsg, end))) {
return 0;
}
return 1;
}
uint8_t pack_nr_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t *)msg;
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
&& push16(pNfapiMsg->number_crcs, ppWritePackedMsg, end)))
return 0;
for (int i = 0; i < pNfapiMsg->number_crcs; i++) {
if (!pack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppWritePackedMsg, end))
return 0;
}
return 1;
}
uint8_t unpack_nr_crc_indication_body(nfapi_nr_crc_t *value, uint8_t **ppReadPackedMsg, uint8_t *end)
{
if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
&& pull8(ppReadPackedMsg, &value->harq_id, end) && pull8(ppReadPackedMsg, &value->tb_crc_status, end)
&& pull16(ppReadPackedMsg, &value->num_cb, end))) {
return 0;
}
if (value->num_cb != 0) {
const uint16_t cb_len = (value->num_cb / 8) + 1; // length is ceil(NumCb/8)
value->cb_crc_status = calloc(cb_len, sizeof(uint8_t));
if (!pullarray8(ppReadPackedMsg, value->cb_crc_status, cb_len, cb_len, end)) {
return 0;
}
}
if (!(pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
&& pull16(ppReadPackedMsg, &value->rssi, end))) {
return 0;
}
return 1;
}
uint8_t unpack_nr_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t *)msg;
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
&& pull16(ppReadPackedMsg, &pNfapiMsg->number_crcs, end)))
return 0;
if (pNfapiMsg->number_crcs > 0) {
pNfapiMsg->crc_list = calloc(pNfapiMsg->number_crcs, sizeof(*pNfapiMsg->crc_list));
}
for (int i = 0; i < pNfapiMsg->number_crcs; i++) {
if (!unpack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppReadPackedMsg, end))
return 0;
}
return 1;
}
static uint8_t pack_nr_uci_pusch(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_uci_pusch_pdu_t *value = (nfapi_nr_uci_pusch_pdu_t *)tlv;
if (!push8(value->pduBitmap, ppWritePackedMsg, end))
return 0;
if (!push32(value->handle, ppWritePackedMsg, end))
return 0;
if (!push16(value->rnti, ppWritePackedMsg, end))
return 0;
if (!push8(value->ul_cqi, ppWritePackedMsg, end))
return 0;
if (!push16(value->timing_advance, ppWritePackedMsg, end))
return 0;
if (!push16(value->rssi, ppWritePackedMsg, end))
return 0;
// Bit 0 not used in PUSCH PDU
if ((value->pduBitmap >> 1) & 0x01) { // HARQ
if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
return 0;
if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
return 0;
const uint16_t harq_len = (value->harq.harq_bit_len / 8) + 1;
if (!pusharray8(value->harq.harq_payload, harq_len, harq_len, ppWritePackedMsg, end))
return 0;
}
if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
return 0;
if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
return 0;
const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
if (!pusharray8(value->csi_part1.csi_part1_payload, csi_len, csi_len, ppWritePackedMsg, end))
return 0;
}
if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
return 0;
if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
return 0;
const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
if (!pusharray8(value->csi_part2.csi_part2_payload, csi_len, csi_len, ppWritePackedMsg, end))
return 0;
}
return 1;
}
static uint8_t pack_nr_uci_pucch_0_1(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_uci_pucch_pdu_format_0_1_t *value = (nfapi_nr_uci_pucch_pdu_format_0_1_t *)tlv;
if (!push8(value->pduBitmap, ppWritePackedMsg, end))
return 0;
if (!push32(value->handle, ppWritePackedMsg, end))
return 0;
if (!push16(value->rnti, ppWritePackedMsg, end))
return 0;
if (!push8(value->pucch_format, ppWritePackedMsg, end))
return 0;
if (!push8(value->ul_cqi, ppWritePackedMsg, end))
return 0;
if (!push16(value->timing_advance, ppWritePackedMsg, end))
return 0;
if (!push16(value->rssi, ppWritePackedMsg, end))
return 0;
if (value->pduBitmap & 0x01) { // SR
if (!push8(value->sr.sr_indication, ppWritePackedMsg, end))
return 0;
if (!push8(value->sr.sr_confidence_level, ppWritePackedMsg, end))
return 0;
}
if (((value->pduBitmap >> 1) & 0x01)) { // HARQ
if (!push8(value->harq.num_harq, ppWritePackedMsg, end))
return 0;
if (!push8(value->harq.harq_confidence_level, ppWritePackedMsg, end))
return 0;
for (int i = 0; i < value->harq.num_harq; i++) {
if (!push8(value->harq.harq_list[i].harq_value, ppWritePackedMsg, end))
return 0;
}
}
return 1;
}
static uint8_t pack_nr_uci_pucch_2_3_4(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *value = (nfapi_nr_uci_pucch_pdu_format_2_3_4_t *)tlv;
if (!push8(value->pduBitmap, ppWritePackedMsg, end))
return 0;
if (!push32(value->handle, ppWritePackedMsg, end))
return 0;
if (!push16(value->rnti, ppWritePackedMsg, end))
return 0;
if (!push8(value->pucch_format, ppWritePackedMsg, end))
return 0;
if (!push8(value->ul_cqi, ppWritePackedMsg, end))
return 0;
if (!push16(value->timing_advance, ppWritePackedMsg, end))
return 0;
if (!push16(value->rssi, ppWritePackedMsg, end))
return 0;
if (value->pduBitmap & 0x01) { // SR
if (!push16(value->sr.sr_bit_len, ppWritePackedMsg, end))
return 0;
const uint16_t sr_len = value->sr.sr_bit_len / 8 + 1;
if (!pusharray8(value->sr.sr_payload, sr_len, sr_len, ppWritePackedMsg, end))
return 0;
}
if ((value->pduBitmap >> 1) & 0x01) { // HARQ
if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
return 0;
if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
return 0;
const uint16_t harq_len = value->harq.harq_bit_len / 8 + 1;
if (!pusharray8(value->harq.harq_payload, harq_len, harq_len, ppWritePackedMsg, end))
return 0;
}
if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
return 0;
if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
return 0;
const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
if (!pusharray8(value->csi_part1.csi_part1_payload, csi_len, csi_len, ppWritePackedMsg, end))
return 0;
}
if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
return 0;
if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
return 0;
const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
if (!pusharray8(value->csi_part2.csi_part2_payload, csi_len, csi_len, ppWritePackedMsg, end))
return 0;
}
return 1;
}
static uint8_t pack_nr_uci_indication_body(nfapi_nr_uci_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
{
if (!push16(value->pdu_type, ppWritePackedMsg, end))
return 0;
if (!push16(value->pdu_size, ppWritePackedMsg, end))
return 0;
switch (value->pdu_type) {
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
if (!pack_nr_uci_pusch(&value->pusch_pdu, ppWritePackedMsg, end)) {
return 0;
}
break;
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
if (!pack_nr_uci_pucch_0_1(&value->pucch_pdu_format_0_1, ppWritePackedMsg, end)) {
return 0;
}
break;
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
if (!pack_nr_uci_pucch_2_3_4(&value->pucch_pdu_format_2_3_4, ppWritePackedMsg, end)) {
return 0;
}
break;
default:
NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected UCI.indication PDU type %d\n", value->pdu_type);
return 0;
}
return 1;
}
uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t *)msg;
if (!push16(pNfapiMsg->sfn, ppWritePackedMsg, end))
return 0;
if (!push16(pNfapiMsg->slot, ppWritePackedMsg, end))
return 0;
if (!push16(pNfapiMsg->num_ucis, ppWritePackedMsg, end))
return 0;
for (int i = 0; i < pNfapiMsg->num_ucis; i++) {
if (!pack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppWritePackedMsg, end))
return 0;
}
return 1;
}
static uint8_t unpack_nr_uci_pusch(nfapi_nr_uci_pusch_pdu_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config)
{
if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
return 0;
if (!pull32(ppReadPackedMsg, &value->handle, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->rnti, end))
return 0;
if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->rssi, end))
return 0;
// Bit 0 not used in PUSCH PDU
if ((value->pduBitmap >> 1) & 0x01) { // HARQ
if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
return 0;
const uint16_t harq_len = value->harq.harq_bit_len / 8 + 1;
value->harq.harq_payload = calloc(harq_len, sizeof(*value->harq.harq_payload));
if (value->harq.harq_payload == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
return 0;
}
if (!pullarray8(ppReadPackedMsg, value->harq.harq_payload, harq_len, harq_len, end))
return 0;
}
if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
return 0;
const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
value->csi_part1.csi_part1_payload = calloc(csi_len, sizeof(*value->csi_part1.csi_part1_payload));
if (value->csi_part1.csi_part1_payload == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n", __FUNCTION__);
return 0;
}
if (!pullarray8(ppReadPackedMsg, value->csi_part1.csi_part1_payload, csi_len, csi_len, end))
return 0;
}
if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
return 0;
const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
value->csi_part2.csi_part2_payload = calloc(csi_len, sizeof(*value->csi_part2.csi_part2_payload));
if (value->csi_part2.csi_part2_payload == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n", __FUNCTION__);
return 0;
}
if (!pullarray8(ppReadPackedMsg, value->csi_part2.csi_part2_payload, csi_len, csi_len, end))
return 0;
}
return 1;
}
static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config)
{
if (!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && pull32(ppReadPackedMsg, &value->handle, end)
&& pull16(ppReadPackedMsg, &value->rnti, end) && pull8(ppReadPackedMsg, &value->pucch_format, end)
&& pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
&& pull16(ppReadPackedMsg, &value->rssi, end)))
return 0;
if (value->pduBitmap & 0x01) { // SR
if (!(pull8(ppReadPackedMsg, &value->sr.sr_indication, end) && pull8(ppReadPackedMsg, &value->sr.sr_confidence_level, end)))
return 0;
}
if (((value->pduBitmap >> 1) & 0x01)) { // HARQ
if (!(pull8(ppReadPackedMsg, &value->harq.num_harq, end) && pull8(ppReadPackedMsg, &value->harq.harq_confidence_level, end)))
return 0;
if (value->harq.num_harq > 0) {
for (int i = 0; i < value->harq.num_harq; i++) {
if (!pull8(ppReadPackedMsg, &value->harq.harq_list[i].harq_value, end)) {
return 0;
}
}
}
}
return 1;
}
static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config)
{
if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
return 0;
if (!pull32(ppReadPackedMsg, &value->handle, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->rnti, end))
return 0;
if (!pull8(ppReadPackedMsg, &value->pucch_format, end))
return 0;
if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->rssi, end))
return 0;
if (value->pduBitmap & 0x01) { // SR
if (!pull16(ppReadPackedMsg, &value->sr.sr_bit_len, end))
return 0;
const uint16_t sr_len = value->sr.sr_bit_len / 8 + 1;
value->sr.sr_payload = calloc(sr_len, sizeof(*value->sr.sr_payload));
if (value->sr.sr_payload == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->sr.sr_payload\n", __FUNCTION__);
return 0;
}
if (!pullarray8(ppReadPackedMsg, value->sr.sr_payload, sr_len, sr_len, end))
return 0;
}
if ((value->pduBitmap >> 1) & 0x01) { // HARQ
if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
return 0;
const uint16_t harq_len = value->harq.harq_bit_len / 8 + 1;
value->harq.harq_payload = calloc(harq_len, sizeof(*value->harq.harq_payload));
if (value->harq.harq_payload == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
return 0;
}
if (!pullarray8(ppReadPackedMsg, value->harq.harq_payload, harq_len, harq_len, end))
return 0;
}
if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
return 0;
const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
value->csi_part1.csi_part1_payload = calloc(csi_len, sizeof(*value->csi_part1.csi_part1_payload));
if (value->csi_part1.csi_part1_payload == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n", __FUNCTION__);
return 0;
}
if (!pullarray8(ppReadPackedMsg, value->csi_part1.csi_part1_payload, csi_len, csi_len, end))
return 0;
}
if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
return 0;
const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
value->csi_part2.csi_part2_payload = calloc(csi_len, sizeof(*value->csi_part2.csi_part2_payload));
if (value->csi_part2.csi_part2_payload == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n", __FUNCTION__);
return 0;
}
if (!pullarray8(ppReadPackedMsg, value->csi_part2.csi_part2_payload, csi_len, csi_len, end))
return 0;
}
return 1;
}
static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config)
{
if (!pull16(ppReadPackedMsg, &value->pdu_type, end))
return 0;
if (!pull16(ppReadPackedMsg, &value->pdu_size, end))
return 0;
switch (value->pdu_type) {
case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
nfapi_nr_uci_pusch_pdu_t *uci_pdu = &value->pusch_pdu;
if (!unpack_nr_uci_pusch(uci_pdu, ppReadPackedMsg, end, config))
return 0;
break;
}
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1;
if (!unpack_nr_uci_pucch_0_1(uci_pdu, ppReadPackedMsg, end, config))
return 0;
break;
}
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4;
if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end, config))
return 0;
break;
}
default:
NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected UCI.indication PDU type %d\n", value->pdu_type);
break;
}
return 1;
}
uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t *)msg;
if (!pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end))
return 0;
if (!pull16(ppReadPackedMsg, &pNfapiMsg->slot, end))
return 0;
if (!pull16(ppReadPackedMsg, &pNfapiMsg->num_ucis, end))
return 0;
pNfapiMsg->uci_list = calloc(pNfapiMsg->num_ucis, sizeof(*pNfapiMsg->uci_list));
for (int i = 0; i < pNfapiMsg->num_ucis; i++) {
if (!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config))
return 0;
}
return 1;
}
static uint8_t pack_nr_srs_report_tlv(const nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
if(!(push16(report_tlv->tag, ppWritePackedMsg, end) &&
push32(report_tlv->length, ppWritePackedMsg, end))) {
return 0;
}
for (int i = 0; i < (report_tlv->length + 3) / 4; i++) {
if (!push32(report_tlv->value[i], ppWritePackedMsg, end)) {
return 0;
}
}
return 1;
}
static uint8_t pack_nr_srs_indication_body(const nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) {
if(!(push32(value->handle, ppWritePackedMsg, end) &&
push16(value->rnti, ppWritePackedMsg, end) &&
push16(value->timing_advance_offset, ppWritePackedMsg, end) &&
pushs16(value->timing_advance_offset_nsec, ppWritePackedMsg, end) &&
push8(value->srs_usage, ppWritePackedMsg, end) &&
push8(value->report_type, ppWritePackedMsg, end))) {
return 0;
}
if (!pack_nr_srs_report_tlv(&value->report_tlv, ppWritePackedMsg, end)) {
return 0;
}
return 1;
}
uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t *)msg;
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
&& push16(pNfapiMsg->control_length, ppWritePackedMsg, end) && push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end))) {
return 0;
}
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
if (!pack_nr_srs_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end)) {
return 0;
}
}
return 1;
}
uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
{
#ifndef ENABLE_AERIAL
for (int i = 0; i < (report_tlv->length + 3) / 4; i++) {
if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
return 0;
}
}
#else
const int16_t last_idx = ((report_tlv->length + 3) / 4) - 1;
for (int i = 0; i < last_idx; i++) {
if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
return 0;
}
}
// Pull last bytes according to how much padding it would need to be 32-bit aligned
const uint8_t padding = get_tlv_padding(report_tlv->length);
pullx32(4 - padding, ppReadPackedMsg, &report_tlv->value[last_idx], end);
#endif
return 1;
}
static uint8_t unpack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
if(!(pull16(ppReadPackedMsg, &report_tlv->tag, end) &&
pull32(ppReadPackedMsg, &report_tlv->length, end))) {
return 0;
}
#ifndef ENABLE_AERIAL
if (!unpack_nr_srs_report_tlv_value(report_tlv, ppReadPackedMsg, end)) {
return 0;
}
#endif
return 1;
}
static uint8_t unpack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppReadPackedMsg, uint8_t *end) {
if(!(pull32(ppReadPackedMsg, &value->handle, end) &&
pull16(ppReadPackedMsg, &value->rnti, end) &&
pull16(ppReadPackedMsg, &value->timing_advance_offset, end) &&
pulls16(ppReadPackedMsg, &value->timing_advance_offset_nsec, end) &&
pull8(ppReadPackedMsg, &value->srs_usage, end) &&
pull8(ppReadPackedMsg, &value->report_type, end))) {
return 0;
}
if (!unpack_nr_srs_report_tlv(&value->report_tlv, ppReadPackedMsg, end)) {
return 0;
}
return 1;
}
uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t *)msg;
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
&& pull16(ppReadPackedMsg, &pNfapiMsg->control_length, end) && pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
return 0;
}
pNfapiMsg->pdu_list = calloc(pNfapiMsg->number_of_pdus, sizeof(*pNfapiMsg->pdu_list));
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
if (!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end)) {
return 0;
}
}
return 1;
}
static uint8_t pack_nr_rach_indication_body(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_prach_indication_pdu_t *value = (nfapi_nr_prach_indication_pdu_t *)tlv;
if (!(push16(value->phy_cell_id, ppWritePackedMsg, end) && push8(value->symbol_index, ppWritePackedMsg, end)
&& push8(value->slot_index, ppWritePackedMsg, end) && push8(value->freq_index, ppWritePackedMsg, end)
&& push8(value->avg_rssi, ppWritePackedMsg, end) && push8(value->avg_snr, ppWritePackedMsg, end)
&& push8(value->num_preamble, ppWritePackedMsg, end)))
return 0;
for (int i = 0; i < value->num_preamble; i++) {
if (!(push8(value->preamble_list[i].preamble_index, ppWritePackedMsg, end)
&& push16(value->preamble_list[i].timing_advance, ppWritePackedMsg, end)
&& push32(value->preamble_list[i].preamble_pwr, ppWritePackedMsg, end)))
return 0;
}
return 1;
}
uint8_t pack_nr_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t *)msg;
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
&& push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)))
return 0;
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
if (!pack_nr_rach_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
return 0;
}
return 1;
}
static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t *value,
uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config)
{
if (!(pull16(ppReadPackedMsg, &value->phy_cell_id, end) && pull8(ppReadPackedMsg, &value->symbol_index, end)
&& pull8(ppReadPackedMsg, &value->slot_index, end) && pull8(ppReadPackedMsg, &value->freq_index, end)
&& pull8(ppReadPackedMsg, &value->avg_rssi, end) && pull8(ppReadPackedMsg, &value->avg_snr, end)
&& pull8(ppReadPackedMsg, &value->num_preamble, end))) {
return 0;
}
for (int i = 0; i < value->num_preamble; i++) {
nfapi_nr_prach_indication_preamble_t *preamble = &(value->preamble_list[i]);
if (!(pull8(ppReadPackedMsg, &preamble->preamble_index, end) && pull16(ppReadPackedMsg, &preamble->timing_advance, end)
&& pull32(ppReadPackedMsg, &preamble->preamble_pwr, end))) {
return 0;
}
}
return 1;
}
uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t *)msg;
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
&& pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
return 0;
}
if (pNfapiMsg->number_of_pdus > 0) {
pNfapiMsg->pdu_list = calloc(pNfapiMsg->number_of_pdus, sizeof(*pNfapiMsg->pdu_list));
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
if (!unpack_nr_rach_indication_body(&(pNfapiMsg->pdu_list[i]), ppReadPackedMsg, end, config))
return 0;
}
}
return 1;
}