Files
openairinterface5g/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c
T
Rúben Soares Silva d9e3725a21 Unpack SRS report TLV not expecting padding to be present
Add a function pullx32 to pull x amount of bytes into uint32_t
Change the unpacking to pull only the needed bytes, and skip over the padding, when not Aerial
Change SRS.indication dumping function to also print the report TLV contents
Change SRS.indication unitary test to fill the last 4 byte block of the report TLV according to the length, with padding
2025-03-31 10:15:08 +01:00

2448 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;
}
int 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;
uint8_t *pReadPackedMessage = pMessageBuf;
AssertFatal(pMessageBuf != NULL && pUnpackedBuf != NULL, "P7 unpack supplied pointers are null");
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
AssertFatal(messageBufLen >= NFAPI_HEADER_LENGTH && unpackedBufLen >= sizeof(fapi_message_header_t),
"P5 unpack supplied message buffer is too small %d, %d\n",
messageBufLen,
unpackedBufLen);
if (fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &fapi_hdr, sizeof(fapi_message_header_t), 0) < 0) {
// failed to read the header
return -1;
}
pMessageHeader->message_length = fapi_hdr.message_length;
pMessageHeader->message_id = fapi_hdr.message_id;
if ((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
return -1;
}
// 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 -1;
}
return 0;
}
static uint8_t pack_nr_tx_beamforming_pdu(const nfapi_nr_tx_precoding_and_beamforming_t *beamforming_pdu,
uint8_t **ppWritePackedMsg,
uint8_t *end)
{ // Pack RX Beamforming PDU
if (!(push16(beamforming_pdu->num_prgs, ppWritePackedMsg, end) && push16(beamforming_pdu->prg_size, ppWritePackedMsg, end)
&& push8(beamforming_pdu->dig_bf_interfaces, ppWritePackedMsg, end))) {
return 0;
}
for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
if (!push16(beamforming_pdu->prgs_list[prg].pm_idx, ppWritePackedMsg, end)) {
return 0;
}
for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interfaces; digBFInterface++) {
if (!push16(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) {
return 0;
}
}
}
return 1;
}
static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
if (!(push16(value->bwp_size, ppWritePackedMsg, end) && push16(value->bwp_start, ppWritePackedMsg, end)
&& push8(value->subcarrier_spacing, ppWritePackedMsg, end) && push8(value->cyclic_prefix, ppWritePackedMsg, end)
&& push16(value->start_rb, ppWritePackedMsg, end) && push16(value->nr_of_rbs, ppWritePackedMsg, end)
&& push8(value->csi_type, ppWritePackedMsg, end) && push8(value->row, ppWritePackedMsg, end)
&& push16(value->freq_domain, ppWritePackedMsg, end) && push8(value->symb_l0, ppWritePackedMsg, end)
&& push8(value->symb_l1, ppWritePackedMsg, end) && push8(value->cdm_type, ppWritePackedMsg, end)
&& push8(value->freq_density, ppWritePackedMsg, end) && push16(value->scramb_id, ppWritePackedMsg, end)
&& push8(value->power_control_offset, ppWritePackedMsg, end)
&& push8(value->power_control_offset_ss, ppWritePackedMsg, end))) {
return 0;
}
// Precoding and beamforming
if(!pack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming,ppWritePackedMsg, end)) {
return 0;
}
return 1;
}
static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
if (!(push16(value->BWPSize, ppWritePackedMsg, end) && push16(value->BWPStart, ppWritePackedMsg, end)
&& push8(value->SubcarrierSpacing, ppWritePackedMsg, end) && push8(value->CyclicPrefix, ppWritePackedMsg, end)
&& push8(value->StartSymbolIndex, ppWritePackedMsg, end) && push8(value->DurationSymbols, ppWritePackedMsg, end)
&& pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end)
&& push8(value->CceRegMappingType, ppWritePackedMsg, end) && push8(value->RegBundleSize, ppWritePackedMsg, end)
&& push8(value->InterleaverSize, ppWritePackedMsg, end) && push8(value->CoreSetType, ppWritePackedMsg, end)
&& push16(value->ShiftIndex, ppWritePackedMsg, end) && push8(value->precoderGranularity, ppWritePackedMsg, end)
&& push16(value->numDlDci, ppWritePackedMsg, end))) {
return 0;
}
for (uint16_t i = 0; i < value->numDlDci; ++i) {
if (!(push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) && push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end)
&& push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end)
&& push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end)
&& push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end))) {
return 0;
}
// Precoding and beamforming
if(!pack_nr_tx_beamforming_pdu(&value->dci_pdu[i].precodingAndBeamforming,ppWritePackedMsg, end)) {
return 0;
}
// TX Power info
if (!(push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end)
&& push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
// DCI Payload fields
push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
// Pack DCI Payload
pack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end))) {
return 0;
}
}
return 1;
}
static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
if (!(push16(value->pduBitmap, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
&& push16(value->pduIndex, ppWritePackedMsg, end) && push16(value->BWPSize, ppWritePackedMsg, end)
&& push16(value->BWPStart, ppWritePackedMsg, end) && push8(value->SubcarrierSpacing, ppWritePackedMsg, end)
&& push8(value->CyclicPrefix, ppWritePackedMsg, end) && push8(value->NrOfCodewords, ppWritePackedMsg, end))) {
return 0;
}
for (int i = 0; i < value->NrOfCodewords; ++i) {
if (!(push16(value->targetCodeRate[i], ppWritePackedMsg, end) && push8(value->qamModOrder[i], ppWritePackedMsg, end)
&& push8(value->mcsIndex[i], ppWritePackedMsg, end) && push8(value->mcsTable[i], ppWritePackedMsg, end)
&& push8(value->rvIndex[i], ppWritePackedMsg, end) && push32(value->TBSize[i], ppWritePackedMsg, end))) {
return 0;
}
}
if (!(push16(value->dataScramblingId, ppWritePackedMsg, end) && push8(value->nrOfLayers, ppWritePackedMsg, end)
&& push8(value->transmissionScheme, ppWritePackedMsg, end) && push8(value->refPoint, ppWritePackedMsg, end)
&& push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) && push8(value->dmrsConfigType, ppWritePackedMsg, end)
&& push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) && push8(value->SCID, ppWritePackedMsg, end)
&& push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) && push16(value->dmrsPorts, ppWritePackedMsg, end)
&& push8(value->resourceAlloc, ppWritePackedMsg, end) && (int)pusharray8(value->rbBitmap, 36, 36, ppWritePackedMsg, end)
&& push16(value->rbStart, ppWritePackedMsg, end) && push16(value->rbSize, ppWritePackedMsg, end)
&& push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) && push8(value->StartSymbolIndex, ppWritePackedMsg, end)
&& push8(value->NrOfSymbols, ppWritePackedMsg, end))) {
return 0;
}
// Check pduBitMap bit 0 to add or not PTRS parameters
if (value->pduBitmap & 0b1) {
if (!(push8(value->PTRSPortIndex, ppWritePackedMsg, end) && push8(value->PTRSTimeDensity, ppWritePackedMsg, end)
&& push8(value->PTRSFreqDensity, ppWritePackedMsg, end) && push8(value->PTRSReOffset, ppWritePackedMsg, end)
&& push8(value->nEpreRatioOfPDSCHToPTRS, ppWritePackedMsg, end))) {
return 0;
}
}
// Precoding and beamforming
if(!pack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming,ppWritePackedMsg, end)) {
return 0;
}
if (!(push8(value->powerControlOffset, ppWritePackedMsg, end) && push8(value->powerControlOffsetSS, ppWritePackedMsg, end))) {
return 0;
}
// Check pduBitMap bit 1 to add or not CBG parameters
if (value->pduBitmap & 0b10) {
if (!(push8(value->isLastCbPresent, ppWritePackedMsg, end) && push8(value->isInlineTbCrc, ppWritePackedMsg, end)
&& push32(value->dlTbCrc, ppWritePackedMsg, end))) {
return 0;
}
}
#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 uint16_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;
}