This commit broke compatibility with Aerial when compiled with -DSCF_FAPI_10_04_SRS=ON. It was decided that this should become the default.
This reverts commit 8beb382277.
2447 lines
106 KiB
C
2447 lines
106 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
#include "nr_fapi.h"
|
|
#include "nr_fapi_p7.h"
|
|
#include "nr_nfapi_p7.h"
|
|
#include "debug.h"
|
|
|
|
uint8_t fapi_nr_p7_message_body_pack(nfapi_nr_p7_message_header_t *header,
|
|
uint8_t **ppWritePackedMsg,
|
|
uint8_t *end,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
// look for the specific message
|
|
uint8_t result = 0;
|
|
switch (header->message_id) {
|
|
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
|
result = pack_dl_tti_request(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
|
result = pack_ul_tti_request(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
|
|
result = pack_nr_slot_indication(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
|
result = pack_ul_dci_request(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
|
result = pack_tx_data_request(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
|
|
result = pack_nr_rx_data_indication(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
|
result = pack_nr_crc_indication(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
|
|
result = pack_nr_uci_indication(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
|
|
result = pack_nr_srs_indication(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
|
|
result = pack_nr_rach_indication(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
#ifdef ENABLE_AERIAL
|
|
case NFAPI_NR_PHY_MSG_TYPE_VENDOR_EXT_SLOT_RESPONSE:
|
|
result = pack_nr_slot_indication(header, ppWritePackedMsg, end, config);
|
|
break;
|
|
#endif
|
|
default: {
|
|
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
|
|
if (config && config->pack_p7_vendor_extension) {
|
|
result = (config->pack_p7_vendor_extension)(header, ppWritePackedMsg, end, config);
|
|
} else {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, header->message_id);
|
|
}
|
|
} else {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
|
|
}
|
|
} break;
|
|
}
|
|
|
|
if (result == 0) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config)
|
|
{
|
|
if (pMessageBuf == NULL || pPackedBuf == NULL) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
|
|
return -1;
|
|
}
|
|
|
|
nfapi_nr_p7_message_header_t *pMessageHeader = pMessageBuf;
|
|
uint8_t *pWritePackedMessage = pPackedBuf;
|
|
uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
|
|
uint8_t *pPackedLengthField = &pWritePackedMessage[4];
|
|
uint8_t *pPacketBodyField = &pWritePackedMessage[8];
|
|
uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
|
|
|
|
const uint8_t result = fapi_nr_p7_message_body_pack(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config);
|
|
AssertFatal(result > 0, "fapi_nr_p7_message_body_pack error packing message body %d\n", result);
|
|
|
|
// PHY API message header
|
|
// Number of messages [0]
|
|
// Opaque handle [1]
|
|
// PHY API Message structure
|
|
// Message type ID [2,3]
|
|
// Message Length [4,5,6,7]
|
|
// Message Body [8,...]
|
|
if (!(push8(1, &pWritePackedMessage, pPackMessageEnd) && push8(0, &pWritePackedMessage, pPackMessageEnd)
|
|
&& push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd))) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
|
|
return -1;
|
|
}
|
|
|
|
// check for a valid message length
|
|
uintptr_t msgHead = (uintptr_t)pPacketBodyFieldStart;
|
|
uintptr_t msgEnd = (uintptr_t)pPacketBodyField;
|
|
uint32_t packedMsgLen = msgEnd - msgHead;
|
|
if (packedMsgLen > packedBufLen) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
|
|
return -1;
|
|
}
|
|
|
|
// Update the message length in the header
|
|
pMessageHeader->message_length = packedMsgLen;
|
|
|
|
// Update the message length in the header
|
|
if (!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd))
|
|
return -1;
|
|
|
|
return packedMsgLen;
|
|
}
|
|
|
|
bool fapi_nr_p7_message_unpack(void *pMessageBuf,
|
|
uint32_t messageBufLen,
|
|
void *pUnpackedBuf,
|
|
uint32_t unpackedBufLen,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
int result = 0;
|
|
nfapi_nr_p7_message_header_t *pMessageHeader = (nfapi_nr_p7_message_header_t *)pUnpackedBuf;
|
|
fapi_message_header_t fapi_hdr;
|
|
AssertFatal(pMessageBuf != NULL && pUnpackedBuf != NULL, "P7 unpack supplied pointers are null");
|
|
|
|
AssertFatal(messageBufLen >= NFAPI_HEADER_LENGTH && unpackedBufLen >= sizeof(fapi_message_header_t),
|
|
"P5 unpack supplied message buffer is too small %d, %d\n",
|
|
messageBufLen,
|
|
unpackedBufLen);
|
|
|
|
if (!fapi_nr_message_header_unpack(pMessageBuf, NFAPI_HEADER_LENGTH, &fapi_hdr, sizeof(fapi_message_header_t), 0)) {
|
|
// failed to read the header
|
|
return false;
|
|
}
|
|
uint8_t *pReadPackedMessage = pMessageBuf + NFAPI_HEADER_LENGTH;
|
|
uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
|
|
pMessageHeader->message_length = fapi_hdr.message_length;
|
|
pMessageHeader->message_id = fapi_hdr.message_id;
|
|
if ((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
|
|
return false;
|
|
}
|
|
|
|
// look for the specific message
|
|
switch (pMessageHeader->message_id) {
|
|
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen))
|
|
result = unpack_dl_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen))
|
|
result = unpack_ul_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION, unpackedBufLen)) {
|
|
nfapi_nr_slot_indication_scf_t *msg = (nfapi_nr_slot_indication_scf_t *)pMessageHeader;
|
|
result = unpack_nr_slot_indication(&pReadPackedMessage, end, msg, config);
|
|
}
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen))
|
|
result = unpack_ul_dci_request(&pReadPackedMessage, end, pMessageHeader, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen))
|
|
result = unpack_tx_data_request(&pReadPackedMessage, end, pMessageHeader, config);
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION, unpackedBufLen)) {
|
|
result = unpack_nr_rx_data_indication(&pReadPackedMessage, end, pMessageHeader, config);
|
|
}
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION, unpackedBufLen)) {
|
|
result = unpack_nr_crc_indication(&pReadPackedMessage, end, pMessageHeader, config);
|
|
}
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION, unpackedBufLen)) {
|
|
result = unpack_nr_uci_indication(&pReadPackedMessage, end, pMessageHeader, config);
|
|
}
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION, unpackedBufLen)) {
|
|
result = unpack_nr_srs_indication(&pReadPackedMessage, end, pMessageHeader, config);
|
|
}
|
|
break;
|
|
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
|
|
if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION, unpackedBufLen)) {
|
|
result = unpack_nr_rach_indication(&pReadPackedMessage, end, pMessageHeader, config);
|
|
}
|
|
break;
|
|
default:
|
|
|
|
if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
|
|
if (config && config->unpack_p7_vendor_extension) {
|
|
result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
|
|
} else {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR,
|
|
"%s VE NFAPI message ID %d. No ve decoder provided\n",
|
|
__FUNCTION__,
|
|
pMessageHeader->message_id);
|
|
}
|
|
} else {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (result == 0) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Unpack failed to unpack message\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static uint8_t pack_nr_tx_beamforming_pdu(const nfapi_nr_tx_precoding_and_beamforming_t *beamforming_pdu,
|
|
uint8_t **ppWritePackedMsg,
|
|
uint8_t *end)
|
|
{ // Pack RX Beamforming PDU
|
|
if (!(push16(beamforming_pdu->num_prgs, ppWritePackedMsg, end) && push16(beamforming_pdu->prg_size, ppWritePackedMsg, end)
|
|
&& push8(beamforming_pdu->dig_bf_interfaces, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
|
|
if (!push16(beamforming_pdu->prgs_list[prg].pm_idx, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interfaces; digBFInterface++) {
|
|
if (!push16(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
|
|
if (!(push16(value->bwp_size, ppWritePackedMsg, end) && push16(value->bwp_start, ppWritePackedMsg, end)
|
|
&& push8(value->subcarrier_spacing, ppWritePackedMsg, end) && push8(value->cyclic_prefix, ppWritePackedMsg, end)
|
|
&& push16(value->start_rb, ppWritePackedMsg, end) && push16(value->nr_of_rbs, ppWritePackedMsg, end)
|
|
&& push8(value->csi_type, ppWritePackedMsg, end) && push8(value->row, ppWritePackedMsg, end)
|
|
&& push16(value->freq_domain, ppWritePackedMsg, end) && push8(value->symb_l0, ppWritePackedMsg, end)
|
|
&& push8(value->symb_l1, ppWritePackedMsg, end) && push8(value->cdm_type, ppWritePackedMsg, end)
|
|
&& push8(value->freq_density, ppWritePackedMsg, end) && push16(value->scramb_id, ppWritePackedMsg, end)
|
|
&& push8(value->power_control_offset, ppWritePackedMsg, end)
|
|
&& push8(value->power_control_offset_ss, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
// Precoding and beamforming
|
|
if(!pack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming,ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
|
|
|
|
if (!(push16(value->BWPSize, ppWritePackedMsg, end) && push16(value->BWPStart, ppWritePackedMsg, end)
|
|
&& push8(value->SubcarrierSpacing, ppWritePackedMsg, end) && push8(value->CyclicPrefix, ppWritePackedMsg, end)
|
|
&& push8(value->StartSymbolIndex, ppWritePackedMsg, end) && push8(value->DurationSymbols, ppWritePackedMsg, end)
|
|
&& pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end)
|
|
&& push8(value->CceRegMappingType, ppWritePackedMsg, end) && push8(value->RegBundleSize, ppWritePackedMsg, end)
|
|
&& push8(value->InterleaverSize, ppWritePackedMsg, end) && push8(value->CoreSetType, ppWritePackedMsg, end)
|
|
&& push16(value->ShiftIndex, ppWritePackedMsg, end) && push8(value->precoderGranularity, ppWritePackedMsg, end)
|
|
&& push16(value->numDlDci, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
for (uint16_t i = 0; i < value->numDlDci; ++i) {
|
|
if (!(push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) && push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end)
|
|
&& push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end)
|
|
&& push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end)
|
|
&& push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
// Precoding and beamforming
|
|
if(!pack_nr_tx_beamforming_pdu(&value->dci_pdu[i].precodingAndBeamforming,ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
// TX Power info
|
|
if (!(push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end)
|
|
&& push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
|
|
// DCI Payload fields
|
|
push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
|
|
// Pack DCI Payload
|
|
pack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
|
|
|
|
if (!(push16(value->pduBitmap, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
|
|
&& push16(value->pduIndex, ppWritePackedMsg, end) && push16(value->BWPSize, ppWritePackedMsg, end)
|
|
&& push16(value->BWPStart, ppWritePackedMsg, end) && push8(value->SubcarrierSpacing, ppWritePackedMsg, end)
|
|
&& push8(value->CyclicPrefix, ppWritePackedMsg, end) && push8(value->NrOfCodewords, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
for (int i = 0; i < value->NrOfCodewords; ++i) {
|
|
if (!(push16(value->targetCodeRate[i], ppWritePackedMsg, end) && push8(value->qamModOrder[i], ppWritePackedMsg, end)
|
|
&& push8(value->mcsIndex[i], ppWritePackedMsg, end) && push8(value->mcsTable[i], ppWritePackedMsg, end)
|
|
&& push8(value->rvIndex[i], ppWritePackedMsg, end) && push32(value->TBSize[i], ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (!(push16(value->dataScramblingId, ppWritePackedMsg, end) && push8(value->nrOfLayers, ppWritePackedMsg, end)
|
|
&& push8(value->transmissionScheme, ppWritePackedMsg, end) && push8(value->refPoint, ppWritePackedMsg, end)
|
|
&& push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) && push8(value->dmrsConfigType, ppWritePackedMsg, end)
|
|
&& push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) && push8(value->SCID, ppWritePackedMsg, end)
|
|
&& push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) && push16(value->dmrsPorts, ppWritePackedMsg, end)
|
|
&& push8(value->resourceAlloc, ppWritePackedMsg, end) && (int)pusharray8(value->rbBitmap, 36, 36, ppWritePackedMsg, end)
|
|
&& push16(value->rbStart, ppWritePackedMsg, end) && push16(value->rbSize, ppWritePackedMsg, end)
|
|
&& push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) && push8(value->StartSymbolIndex, ppWritePackedMsg, end)
|
|
&& push8(value->NrOfSymbols, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
// Check pduBitMap bit 0 to add or not PTRS parameters
|
|
if (value->pduBitmap & 0b1) {
|
|
if (!(push8(value->PTRSPortIndex, ppWritePackedMsg, end) && push8(value->PTRSTimeDensity, ppWritePackedMsg, end)
|
|
&& push8(value->PTRSFreqDensity, ppWritePackedMsg, end) && push8(value->PTRSReOffset, ppWritePackedMsg, end)
|
|
&& push8(value->nEpreRatioOfPDSCHToPTRS, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Precoding and beamforming
|
|
if(!pack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming,ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
|
|
if (!(push8(value->powerControlOffset, ppWritePackedMsg, end) && push8(value->powerControlOffsetSS, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
// Check pduBitMap bit 1 to add or not CBG parameters
|
|
if (value->pduBitmap & 0b10) {
|
|
if (!(push8(value->isLastCbPresent, ppWritePackedMsg, end) && push8(value->isInlineTbCrc, ppWritePackedMsg, end)
|
|
&& push32(value->dlTbCrc, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
#ifndef ENABLE_AERIAL
|
|
if (!push8(value->maintenance_parms_v3.ldpcBaseGraph, ppWritePackedMsg, end)
|
|
|| !push32(value->maintenance_parms_v3.tbSizeLbrmBytes, ppWritePackedMsg, end))
|
|
return 0;
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing ssb. \n");
|
|
nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
|
|
|
|
if (!(push16(value->PhysCellId, ppWritePackedMsg, end) && push8(value->BetaPss, ppWritePackedMsg, end)
|
|
&& push8(value->SsbBlockIndex, ppWritePackedMsg, end) && push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end)
|
|
&& push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end)
|
|
&& push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end)
|
|
&& push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end)
|
|
&& push8(0, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
// Precoding and beamforming
|
|
if(!pack_nr_tx_beamforming_pdu(&value->precoding_and_beamforming,ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_dl_tti_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)tlv;
|
|
uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
|
|
if (!push16(value->PDUType, ppWritePackedMsg, end))
|
|
return 0;
|
|
uint8_t *pPackedLengthField = *ppWritePackedMsg;
|
|
if (!push16(value->PDUSize, ppWritePackedMsg, end))
|
|
return 0;
|
|
|
|
// first match the pdu type, then call the respective function
|
|
switch (value->PDUType) {
|
|
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: {
|
|
if (!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15, ppWritePackedMsg, end)))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: {
|
|
if (!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15, ppWritePackedMsg, end)))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: {
|
|
if (!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppWritePackedMsg, end)))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: {
|
|
if (!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15, ppWritePackedMsg, end)))
|
|
return 0;
|
|
} break;
|
|
|
|
default: {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType);
|
|
} break;
|
|
}
|
|
// pack proper size
|
|
uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
|
|
uint16_t packedMsgLen = msgEnd - msgHead;
|
|
value->PDUSize = packedMsgLen;
|
|
return push16(value->PDUSize, &pPackedLengthField, end);
|
|
}
|
|
|
|
uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
|
|
|
|
if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
|
|
&& push8(pNfapiMsg->dl_tti_request_body.nPDUs, ppWritePackedMsg, end)
|
|
&& push8(pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
|
|
if (!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i], ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) {
|
|
if (!push8(pNfapiMsg->dl_tti_request_body.nUe[i], ppWritePackedMsg, end))
|
|
return 0;
|
|
for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
|
|
if (!(push32(pNfapiMsg->dl_tti_request_body.PduIdx[i][j], ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_tx_beamforming_pdu(nfapi_nr_tx_precoding_and_beamforming_t *beamforming_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{ // Unpack RX Beamforming PDU
|
|
if (!(pull16(ppReadPackedMsg, &beamforming_pdu->num_prgs, end) && pull16(ppReadPackedMsg, &beamforming_pdu->prg_size, end)
|
|
&& pull8(ppReadPackedMsg, &beamforming_pdu->dig_bf_interfaces, end))) {
|
|
return 0;
|
|
}
|
|
for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
|
|
if (!(pull16(ppReadPackedMsg, &beamforming_pdu->prgs_list[prg].pm_idx, end))) {
|
|
return 0;
|
|
}
|
|
for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interfaces; digBFInterface++) {
|
|
if (!pull16(ppReadPackedMsg, &beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &value->BWPSize, end) && pull16(ppReadPackedMsg, &value->BWPStart, end)
|
|
&& pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) && pull8(ppReadPackedMsg, &value->CyclicPrefix, end)
|
|
&& pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) && pull8(ppReadPackedMsg, &value->DurationSymbols, end)
|
|
&& pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end)
|
|
&& pull8(ppReadPackedMsg, &value->CceRegMappingType, end) && pull8(ppReadPackedMsg, &value->RegBundleSize, end)
|
|
&& pull8(ppReadPackedMsg, &value->InterleaverSize, end) && pull8(ppReadPackedMsg, &value->CoreSetType, end)
|
|
&& pull16(ppReadPackedMsg, &value->ShiftIndex, end) && pull8(ppReadPackedMsg, &value->precoderGranularity, end)
|
|
&& pull16(ppReadPackedMsg, &value->numDlDci, end))) {
|
|
return 0;
|
|
}
|
|
|
|
for (uint16_t i = 0; i < value->numDlDci; ++i) {
|
|
if (!(pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end)
|
|
&& pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end)
|
|
&& pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end)
|
|
&& pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end))) {
|
|
return 0;
|
|
}
|
|
|
|
// Preocding and Beamforming
|
|
if(!unpack_nr_tx_beamforming_pdu(&value->dci_pdu[i].precodingAndBeamforming, ppReadPackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
|
|
if (!(pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end)
|
|
&& pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end)
|
|
&& pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end)
|
|
&& unpack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppReadPackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &value->pduBitmap, end) && pull16(ppReadPackedMsg, &value->rnti, end)
|
|
&& pull16(ppReadPackedMsg, &value->pduIndex, end) && pull16(ppReadPackedMsg, &value->BWPSize, end)
|
|
&& pull16(ppReadPackedMsg, &value->BWPStart, end) && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end)
|
|
&& pull8(ppReadPackedMsg, &value->CyclicPrefix, end) && pull8(ppReadPackedMsg, &value->NrOfCodewords, end))) {
|
|
return 0;
|
|
}
|
|
for (int i = 0; i < value->NrOfCodewords; ++i) {
|
|
if (!(pull16(ppReadPackedMsg, &value->targetCodeRate[i], end) && pull8(ppReadPackedMsg, &value->qamModOrder[i], end)
|
|
&& pull8(ppReadPackedMsg, &value->mcsIndex[i], end) && pull8(ppReadPackedMsg, &value->mcsTable[i], end)
|
|
&& pull8(ppReadPackedMsg, &value->rvIndex[i], end) && pull32(ppReadPackedMsg, &value->TBSize[i], end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (!(pull16(ppReadPackedMsg, &value->dataScramblingId, end) && pull8(ppReadPackedMsg, &value->nrOfLayers, end)
|
|
&& pull8(ppReadPackedMsg, &value->transmissionScheme, end) && pull8(ppReadPackedMsg, &value->refPoint, end)
|
|
&& pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) && pull8(ppReadPackedMsg, &value->dmrsConfigType, end)
|
|
&& pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) && pull8(ppReadPackedMsg, &value->SCID, end)
|
|
&& pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) && pull16(ppReadPackedMsg, &value->dmrsPorts, end)
|
|
&& pull8(ppReadPackedMsg, &value->resourceAlloc, end) && pullarray8(ppReadPackedMsg, &value->rbBitmap[0], 36, 36, end)
|
|
&& pull16(ppReadPackedMsg, &value->rbStart, end) && pull16(ppReadPackedMsg, &value->rbSize, end)
|
|
&& pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end)
|
|
&& pull8(ppReadPackedMsg, &value->NrOfSymbols, end))) {
|
|
return 0;
|
|
}
|
|
// Check pduBitMap bit 0 to pull PTRS parameters or not
|
|
if (value->pduBitmap & 0b1) {
|
|
if (!(pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) && pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end)
|
|
&& pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) && pull8(ppReadPackedMsg, &value->PTRSReOffset, end)
|
|
&& pull8(ppReadPackedMsg, &value->nEpreRatioOfPDSCHToPTRS, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Preocding and Beamforming
|
|
if(!unpack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming, ppReadPackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
|
|
// Tx power info
|
|
if (!(pull8(ppReadPackedMsg, &value->powerControlOffset, end) && pull8(ppReadPackedMsg, &value->powerControlOffsetSS, end))) {
|
|
return 0;
|
|
}
|
|
|
|
// Check pduBitMap bit 1 to pull CBG parameters or not
|
|
if (value->pduBitmap & 0b10) {
|
|
if (!(pull8(ppReadPackedMsg, &value->isLastCbPresent, end) && pull8(ppReadPackedMsg, &value->isInlineTbCrc, end)
|
|
&& pull32(ppReadPackedMsg, &value->dlTbCrc, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
#ifndef ENABLE_AERIAL
|
|
if (!pull8(ppReadPackedMsg, &value->maintenance_parms_v3.ldpcBaseGraph, end)
|
|
|| !pull32(ppReadPackedMsg, &value->maintenance_parms_v3.tbSizeLbrmBytes, end))
|
|
return 0;
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
|
|
if (!(pull16(ppReadPackedMsg, &value->bwp_size, end) && pull16(ppReadPackedMsg, &value->bwp_start, end)
|
|
&& pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &value->cyclic_prefix, end)
|
|
&& pull16(ppReadPackedMsg, &value->start_rb, end) && pull16(ppReadPackedMsg, &value->nr_of_rbs, end)
|
|
&& pull8(ppReadPackedMsg, &value->csi_type, end) && pull8(ppReadPackedMsg, &value->row, end)
|
|
&& pull16(ppReadPackedMsg, &value->freq_domain, end) && pull8(ppReadPackedMsg, &value->symb_l0, end)
|
|
&& pull8(ppReadPackedMsg, &value->symb_l1, end) && pull8(ppReadPackedMsg, &value->cdm_type, end)
|
|
&& pull8(ppReadPackedMsg, &value->freq_density, end) && pull16(ppReadPackedMsg, &value->scramb_id, end)
|
|
&& pull8(ppReadPackedMsg, &value->power_control_offset, end)
|
|
&& pull8(ppReadPackedMsg, &value->power_control_offset_ss, end))) {
|
|
return 0;
|
|
}
|
|
|
|
// Preocding and Beamforming
|
|
if(!unpack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming, ppReadPackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Unpacking ssb. \n");
|
|
uint8_t byte3, byte2, byte1, byte0;
|
|
nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &value->PhysCellId, end) && pull8(ppReadPackedMsg, &value->BetaPss, end)
|
|
&& pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) && pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end)
|
|
&& pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) && pull8(ppReadPackedMsg, &value->bchPayloadFlag, end)
|
|
&& pull8(ppReadPackedMsg, &byte3, end) && pull8(ppReadPackedMsg, &byte2, end) && pull8(ppReadPackedMsg, &byte1, end)
|
|
&& pull8(ppReadPackedMsg, &byte0, end))) { // this should be always 0, bchpayload is 24 bits
|
|
return 0;
|
|
}
|
|
// rebuild the bchPayload
|
|
value->bchPayload = byte3 << 16 | byte2 << 8 | byte1;
|
|
|
|
// Preocding and Beamforming
|
|
if(!unpack_nr_tx_beamforming_pdu(&value->precoding_and_beamforming, ppReadPackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
|
|
{
|
|
nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)msg;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &value->PDUType, end) && pull16(ppReadPackedMsg, (uint16_t *)&value->PDUSize, end)))
|
|
return 0;
|
|
|
|
// first match the pdu type, then call the respective function
|
|
switch (value->PDUType) {
|
|
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: {
|
|
if (!(unpack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15, ppReadPackedMsg, end)))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: {
|
|
if (!(unpack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15, ppReadPackedMsg, end)))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: {
|
|
if (!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppReadPackedMsg, end)))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: {
|
|
if (!(unpack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15, ppReadPackedMsg, end)))
|
|
return 0;
|
|
} break;
|
|
|
|
default: {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType);
|
|
} break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
|
|
pNfapiMsg->vendor_extension = NULL;
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
|
|
&& pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end)
|
|
&& pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end))) {
|
|
return 0;
|
|
}
|
|
for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
|
|
if (!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i]))
|
|
return 0;
|
|
}
|
|
|
|
for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) {
|
|
if (!pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nUe[i], end)) {
|
|
return 0;
|
|
}
|
|
for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
|
|
if (!pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.PduIdx[i][j], end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
// Pack fns for ul_tti PDUS
|
|
|
|
static uint8_t pack_nr_rx_beamforming_pdu(const nfapi_nr_ul_beamforming_t *beamforming_pdu,
|
|
uint8_t **ppWritePackedMsg,
|
|
uint8_t *end)
|
|
{ // Pack RX Beamforming PDU
|
|
if (!(push8(beamforming_pdu->trp_scheme, ppWritePackedMsg, end) && push16(beamforming_pdu->num_prgs, ppWritePackedMsg, end)
|
|
&& push16(beamforming_pdu->prg_size, ppWritePackedMsg, end)
|
|
&& push8(beamforming_pdu->dig_bf_interface, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
|
|
for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interface; digBFInterface++) {
|
|
if (!push16(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_ul_tti_request_prach_pdu(const nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
if (!(push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) && push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end)
|
|
&& push8(prach_pdu->prach_format, ppWritePackedMsg, end) && push8(prach_pdu->num_ra, ppWritePackedMsg, end)
|
|
&& push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) && push16(prach_pdu->num_cs, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
return pack_nr_rx_beamforming_pdu(&prach_pdu->beamforming, ppWritePackedMsg, end);
|
|
}
|
|
|
|
static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
if (!(push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) && push16(pusch_pdu->rnti, ppWritePackedMsg, end)
|
|
&& push32(pusch_pdu->handle, ppWritePackedMsg, end) && push16(pusch_pdu->bwp_size, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) && push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) && push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && push8(pusch_pdu->mcs_index, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->pusch_identity, ppWritePackedMsg, end) && push8(pusch_pdu->scid, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) && push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end)
|
|
&& pusharray8(pusch_pdu->rb_bitmap, 36, 36, ppWritePackedMsg, end) && push16(pusch_pdu->rb_start, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->rb_size, ppWritePackedMsg, end) && push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) && push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
// Pack Optional Data only included if indicated in pduBitmap
|
|
// Check if PUSCH_PDU_BITMAP_PUSCH_DATA bit is set
|
|
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_DATA) {
|
|
// pack optional TLVs
|
|
if (!(push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_data.new_data_indicator, ppWritePackedMsg, end)
|
|
&& push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
const uint16_t cb_len = (pusch_pdu->pusch_data.num_cb + 7) / 8;
|
|
if (!pusharray8(pusch_pdu->pusch_data.cb_present_and_position, cb_len, cb_len, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Check if PUSCH_PDU_BITMAP_PUSCH_UCI bit is set
|
|
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_UCI) {
|
|
if (!(push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Check if PUSCH_PDU_BITMAP_PUSCH_PTRS bit is set
|
|
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
|
if (!push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
for (int i = 0; i < pusch_pdu->pusch_ptrs.num_ptrs_ports; ++i) {
|
|
if (!(push16(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_port_index, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_dmrs_port, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_re_offset, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (!(push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Check if PUSCH_PDU_BITMAP_DFTS_OFDM bit is set
|
|
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_DFTS_OFDM) {
|
|
if (!(push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end)
|
|
&& push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end)
|
|
&& push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Pack RX Beamforming PDU
|
|
if (!(pack_nr_rx_beamforming_pdu(&pusch_pdu->beamforming, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
#ifndef ENABLE_AERIAL
|
|
if (!(push8(pusch_pdu->maintenance_parms_v3.ldpcBaseGraph, ppWritePackedMsg, end)
|
|
&& push32(pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes, ppWritePackedMsg, end)))
|
|
return 0;
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_ul_tti_request_pucch_pdu(const nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
if (!(push16(pucch_pdu->rnti, ppWritePackedMsg, end) && push32(pucch_pdu->handle, ppWritePackedMsg, end)
|
|
&& push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) && push16(pucch_pdu->bwp_start, ppWritePackedMsg, end)
|
|
&& push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) && push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end)
|
|
&& push8(pucch_pdu->format_type, ppWritePackedMsg, end) && push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end)
|
|
&& push8(pucch_pdu->pi_2bpsk, ppWritePackedMsg, end) && push16(pucch_pdu->prb_start, ppWritePackedMsg, end)
|
|
&& push16(pucch_pdu->prb_size, ppWritePackedMsg, end) && push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end)
|
|
&& push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) && push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end)
|
|
&& push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) && push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end)
|
|
&& push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) && push16(pucch_pdu->hopping_id, ppWritePackedMsg, end)
|
|
&& push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end)
|
|
&& push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end)
|
|
&& push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) && push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end)
|
|
&& push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) && push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end)
|
|
&& push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end)
|
|
&& push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) && push8(pucch_pdu->sr_flag, ppWritePackedMsg, end)
|
|
&& push16(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) && push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end)
|
|
&& push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
return pack_nr_rx_beamforming_pdu(&pucch_pdu->beamforming, ppWritePackedMsg, end);
|
|
}
|
|
|
|
static uint8_t pack_ul_tti_request_srs_parameters_v4(nfapi_v4_srs_parameters_t *srsParameters,
|
|
const uint8_t num_symbols,
|
|
uint8_t **ppWritePackedMsg,
|
|
uint8_t *end)
|
|
{
|
|
if (!(push16(srsParameters->srs_bandwidth_size, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
for (int symbol_idx = 0; symbol_idx < num_symbols; ++symbol_idx) {
|
|
const nfapi_v4_srs_parameters_symbols_t *symbol = &srsParameters->symbol_list[symbol_idx];
|
|
if (!(push16(symbol->srs_bandwidth_start, ppWritePackedMsg, end) && push8(symbol->sequence_group, ppWritePackedMsg, end)
|
|
&& push8(symbol->sequence_number, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
#ifdef ENABLE_AERIAL
|
|
// For Aerial, we always pack/unpack the 4 reported symbols, not only the ones indicated by num_symbols
|
|
for (int symbol_idx = num_symbols; symbol_idx < 4; ++symbol_idx) {
|
|
if (!(push16(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
#endif // ENABLE_AERIAL
|
|
const uint8_t nUsage = __builtin_popcount(srsParameters->usage);
|
|
if (!(push32(srsParameters->usage, ppWritePackedMsg, end)
|
|
&& pusharray8(srsParameters->report_type, 4, nUsage, ppWritePackedMsg, end)
|
|
&& push8(srsParameters->singular_Value_representation, ppWritePackedMsg, end)
|
|
&& push8(srsParameters->iq_representation, ppWritePackedMsg, end) && push16(srsParameters->prg_size, ppWritePackedMsg, end)
|
|
&& push8(srsParameters->num_total_ue_antennas, ppWritePackedMsg, end)
|
|
&& push32(srsParameters->ue_antennas_in_this_srs_resource_set, ppWritePackedMsg, end)
|
|
&& push32(srsParameters->sampled_ue_antennas, ppWritePackedMsg, end)
|
|
&& push8(srsParameters->report_scope, ppWritePackedMsg, end)
|
|
&& push8(srsParameters->num_ul_spatial_streams_ports, ppWritePackedMsg, end)
|
|
&& pusharray8(srsParameters->Ul_spatial_stream_ports,
|
|
256,
|
|
srsParameters->num_ul_spatial_streams_ports,
|
|
ppWritePackedMsg,
|
|
end))) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
if (!(push16(srs_pdu->rnti, ppWritePackedMsg, end) && push32(srs_pdu->handle, ppWritePackedMsg, end)
|
|
&& push16(srs_pdu->bwp_size, ppWritePackedMsg, end) && push16(srs_pdu->bwp_start, ppWritePackedMsg, end)
|
|
&& push8(srs_pdu->subcarrier_spacing, ppWritePackedMsg, end) && push8(srs_pdu->cyclic_prefix, ppWritePackedMsg, end)
|
|
&& push8(srs_pdu->num_ant_ports, ppWritePackedMsg, end) && push8(srs_pdu->num_symbols, ppWritePackedMsg, end)
|
|
&& push8(srs_pdu->num_repetitions, ppWritePackedMsg, end) && push8(srs_pdu->time_start_position, ppWritePackedMsg, end)
|
|
&& push8(srs_pdu->config_index, ppWritePackedMsg, end) && push16(srs_pdu->sequence_id, ppWritePackedMsg, end)
|
|
&& push8(srs_pdu->bandwidth_index, ppWritePackedMsg, end) && push8(srs_pdu->comb_size, ppWritePackedMsg, end)
|
|
&& push8(srs_pdu->comb_offset, ppWritePackedMsg, end) && push8(srs_pdu->cyclic_shift, ppWritePackedMsg, end)
|
|
&& push8(srs_pdu->frequency_position, ppWritePackedMsg, end) && push16(srs_pdu->frequency_shift, ppWritePackedMsg, end)
|
|
&& push8(srs_pdu->frequency_hopping, ppWritePackedMsg, end)
|
|
&& push8(srs_pdu->group_or_sequence_hopping, ppWritePackedMsg, end) && push8(srs_pdu->resource_type, ppWritePackedMsg, end)
|
|
&& push16(srs_pdu->t_srs, ppWritePackedMsg, end) && push16(srs_pdu->t_offset, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
if(!(pack_nr_rx_beamforming_pdu(&srs_pdu->beamforming, ppWritePackedMsg, end))){
|
|
return 0;
|
|
}
|
|
|
|
if(!(pack_ul_tti_request_srs_parameters_v4(&srs_pdu->srs_parameters_v4, 1 << srs_pdu->num_symbols, ppWritePackedMsg, end))){
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_ul_tti_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_ul_tti_request_number_of_pdus_t *value = (nfapi_nr_ul_tti_request_number_of_pdus_t *)tlv;
|
|
uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
|
|
if (!push16(value->pdu_type, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
uint8_t *pPackedLengthField = *ppWritePackedMsg;
|
|
|
|
if (!push16(value->pdu_size, ppWritePackedMsg, end))
|
|
return 0;
|
|
// pack PDUs
|
|
// first match the pdu type, then call the respective function
|
|
switch (value->pdu_type) {
|
|
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
|
|
if (!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
|
|
if (!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
|
|
if (!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
|
|
if (!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end))
|
|
return 0;
|
|
} break;
|
|
|
|
default: {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type);
|
|
} break;
|
|
}
|
|
|
|
// pack proper size
|
|
uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
|
|
uint16_t packedMsgLen = msgEnd - msgHead;
|
|
value->pdu_size = packedMsgLen;
|
|
return push16(value->pdu_size, &pPackedLengthField, end);
|
|
}
|
|
|
|
static uint8_t pack_ul_tti_groups_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_ul_tti_request_number_of_groups_t *value = (nfapi_nr_ul_tti_request_number_of_groups_t *)tlv;
|
|
|
|
if (!push8(value->n_ue, ppWritePackedMsg, end))
|
|
return 0;
|
|
|
|
for (int i = 0; i < value->n_ue; i++) {
|
|
if (!push8(value->ue_list[i].pdu_idx, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
|
|
pNfapiMsg->n_ulcch = 0;
|
|
pNfapiMsg->n_ulsch = 0;
|
|
for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
|
|
switch (pNfapiMsg->pdus_list[i].pdu_type) {
|
|
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
|
|
pNfapiMsg->n_ulcch++;
|
|
} break;
|
|
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
|
|
pNfapiMsg->n_ulsch++;
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (!push16(pNfapiMsg->SFN, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(pNfapiMsg->Slot, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(pNfapiMsg->n_pdus, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(pNfapiMsg->rach_present, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(pNfapiMsg->n_group, ppWritePackedMsg, end))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
|
|
if (!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
for (int i = 0; i < pNfapiMsg->n_group; i++) {
|
|
if (!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_rx_beamforming_pdu(nfapi_nr_ul_beamforming_t *beamforming_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{ // Unpack RX Beamforming PDU
|
|
if (!(pull8(ppReadPackedMsg, &beamforming_pdu->trp_scheme, end) && pull16(ppReadPackedMsg, &beamforming_pdu->num_prgs, end)
|
|
&& pull16(ppReadPackedMsg, &beamforming_pdu->prg_size, end)
|
|
&& pull8(ppReadPackedMsg, &beamforming_pdu->dig_bf_interface, end))) {
|
|
return 0;
|
|
}
|
|
for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
|
|
for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interface; digBFInterface++) {
|
|
if (!pull16(ppReadPackedMsg, &beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
if (!(pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) && pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end)
|
|
&& pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) && pull8(ppReadPackedMsg, &prach_pdu->num_ra, end)
|
|
&& pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) && pull16(ppReadPackedMsg, &prach_pdu->num_cs, end))) {
|
|
return 0;
|
|
}
|
|
|
|
return unpack_nr_rx_beamforming_pdu(&prach_pdu->beamforming, ppReadPackedMsg, end);
|
|
}
|
|
|
|
static uint8_t unpack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
if (!(pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) && pull16(ppReadPackedMsg, &pusch_pdu->rnti, end)
|
|
&& pull32(ppReadPackedMsg, &pusch_pdu->handle, end) && pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) && pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) && pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->pusch_identity, end) && pull8(ppReadPackedMsg, &pusch_pdu->scid, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) && pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end)
|
|
&& pullarray8(ppReadPackedMsg, pusch_pdu->rb_bitmap, 36, 36, end) && pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end) && pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) && pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end)))
|
|
return 0;
|
|
|
|
// Unpack Optional Data only included if indicated in pduBitmap
|
|
// Check if PUSCH_PDU_BITMAP_PUSCH_DATA bit is set
|
|
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_DATA) {
|
|
// pack optional TLVs
|
|
if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.new_data_indicator, end)
|
|
&& pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end))) {
|
|
return 0;
|
|
}
|
|
const uint8_t cb_len = (pusch_pdu->pusch_data.num_cb + 7) / 8;
|
|
if (!pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position, cb_len, cb_len, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
// Check if PUSCH_PDU_BITMAP_PUSCH_UCI bit is set
|
|
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_UCI) {
|
|
if (!(pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Check if PUSCH_PDU_BITMAP_PUSCH_PTRS bit is set
|
|
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
|
if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end))) {
|
|
return 0;
|
|
}
|
|
pusch_pdu->pusch_ptrs.ptrs_ports_list = calloc(pusch_pdu->pusch_ptrs.num_ptrs_ports, sizeof(nfapi_nr_ptrs_ports_t));
|
|
for (int ptrs_port = 0; ptrs_port < pusch_pdu->pusch_ptrs.num_ptrs_ports; ++ptrs_port) {
|
|
if (!(pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list[ptrs_port].ptrs_port_index, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list[ptrs_port].ptrs_dmrs_port, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list[ptrs_port].ptrs_re_offset, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Check if PUSCH_PDU_BITMAP_DFTS_OFDM bit is set
|
|
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_DFTS_OFDM) {
|
|
if (!(pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end)
|
|
&& pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end)
|
|
&& pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (!(unpack_nr_rx_beamforming_pdu(&pusch_pdu->beamforming, ppReadPackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
#ifndef ENABLE_AERIAL
|
|
if (!(pull8(ppReadPackedMsg, &pusch_pdu->maintenance_parms_v3.ldpcBaseGraph, end)
|
|
&& pull32(ppReadPackedMsg, &pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes, end)))
|
|
return 0;
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
if (!(pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) && pull32(ppReadPackedMsg, &pucch_pdu->handle, end)
|
|
&& pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) && pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end)
|
|
&& pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end)
|
|
&& pull8(ppReadPackedMsg, &pucch_pdu->format_type, end) && pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end)
|
|
&& pull8(ppReadPackedMsg, &pucch_pdu->pi_2bpsk, end) && pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end)
|
|
&& pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end) && pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end)
|
|
&& pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end) && pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end)
|
|
&& pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end) && pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end)
|
|
&& pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end) && pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end)
|
|
&& pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end)
|
|
&& pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end)
|
|
&& pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end) && pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end)
|
|
&& pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end) && pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end)
|
|
&& pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end)
|
|
&& pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) && pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end)
|
|
&& pull16(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) && pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end)
|
|
&& pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end))) {
|
|
return 0;
|
|
}
|
|
return unpack_nr_rx_beamforming_pdu(&pucch_pdu->beamforming, ppReadPackedMsg, end);
|
|
}
|
|
|
|
static uint8_t unpack_ul_tti_request_srs_parameters_v4(nfapi_v4_srs_parameters_t *srsParameters,
|
|
const uint8_t num_symbols,
|
|
uint8_t **ppReadPackedMsg,
|
|
uint8_t *end)
|
|
{
|
|
if (!(pull16(ppReadPackedMsg, &srsParameters->srs_bandwidth_size, end))) {
|
|
return 0;
|
|
}
|
|
|
|
for (int symbol_idx = 0; symbol_idx < num_symbols; ++symbol_idx) {
|
|
nfapi_v4_srs_parameters_symbols_t *symbol = &srsParameters->symbol_list[symbol_idx];
|
|
if (!(pull16(ppReadPackedMsg, &symbol->srs_bandwidth_start, end) && pull8(ppReadPackedMsg, &symbol->sequence_group, end)
|
|
&& pull8(ppReadPackedMsg, &symbol->sequence_number, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
#ifdef ENABLE_AERIAL
|
|
// For Aerial, we always pack/unpack the 4 reported symbols, not only the ones indicated by num_symbols
|
|
for (int symbol_idx = num_symbols; symbol_idx < 4; ++symbol_idx) {
|
|
nfapi_v4_srs_parameters_symbols_t *symbol = &srsParameters->symbol_list[symbol_idx];
|
|
if (!(pull16(ppReadPackedMsg, &symbol->srs_bandwidth_start, end) && pull8(ppReadPackedMsg, &symbol->sequence_group, end)
|
|
&& pull8(ppReadPackedMsg, &symbol->sequence_number, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
#endif // ENABLE_AERIAL
|
|
|
|
if (!(pull32(ppReadPackedMsg, &srsParameters->usage, end))) {
|
|
return 0;
|
|
}
|
|
const uint8_t nUsage = __builtin_popcount(srsParameters->usage);
|
|
if (!(pullarray8(ppReadPackedMsg, &srsParameters->report_type[0], 4, nUsage, end)
|
|
&& pull8(ppReadPackedMsg, &srsParameters->singular_Value_representation, end)
|
|
&& pull8(ppReadPackedMsg, &srsParameters->iq_representation, end) && pull16(ppReadPackedMsg, &srsParameters->prg_size, end)
|
|
&& pull8(ppReadPackedMsg, &srsParameters->num_total_ue_antennas, end)
|
|
&& pull32(ppReadPackedMsg, &srsParameters->ue_antennas_in_this_srs_resource_set, end)
|
|
&& pull32(ppReadPackedMsg, &srsParameters->sampled_ue_antennas, end)
|
|
&& pull8(ppReadPackedMsg, &srsParameters->report_scope, end)
|
|
&& pull8(ppReadPackedMsg, &srsParameters->num_ul_spatial_streams_ports, end)
|
|
&& pullarray8(ppReadPackedMsg,
|
|
&srsParameters->Ul_spatial_stream_ports[0],
|
|
256,
|
|
srsParameters->num_ul_spatial_streams_ports,
|
|
end))) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
if (!(pull16(ppReadPackedMsg, &srs_pdu->rnti, end) && pull32(ppReadPackedMsg, &srs_pdu->handle, end)
|
|
&& pull16(ppReadPackedMsg, &srs_pdu->bwp_size, end) && pull16(ppReadPackedMsg, &srs_pdu->bwp_start, end)
|
|
&& pull8(ppReadPackedMsg, &srs_pdu->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &srs_pdu->cyclic_prefix, end)
|
|
&& pull8(ppReadPackedMsg, &srs_pdu->num_ant_ports, end) && pull8(ppReadPackedMsg, &srs_pdu->num_symbols, end)
|
|
&& pull8(ppReadPackedMsg, &srs_pdu->num_repetitions, end) && pull8(ppReadPackedMsg, &srs_pdu->time_start_position, end)
|
|
&& pull8(ppReadPackedMsg, &srs_pdu->config_index, end) && pull16(ppReadPackedMsg, &srs_pdu->sequence_id, end)
|
|
&& pull8(ppReadPackedMsg, &srs_pdu->bandwidth_index, end) && pull8(ppReadPackedMsg, &srs_pdu->comb_size, end)
|
|
&& pull8(ppReadPackedMsg, &srs_pdu->comb_offset, end) && pull8(ppReadPackedMsg, &srs_pdu->cyclic_shift, end)
|
|
&& pull8(ppReadPackedMsg, &srs_pdu->frequency_position, end) && pull16(ppReadPackedMsg, &srs_pdu->frequency_shift, end)
|
|
&& pull8(ppReadPackedMsg, &srs_pdu->frequency_hopping, end)
|
|
&& pull8(ppReadPackedMsg, &srs_pdu->group_or_sequence_hopping, end) && pull8(ppReadPackedMsg, &srs_pdu->resource_type, end)
|
|
&& pull16(ppReadPackedMsg, &srs_pdu->t_srs, end) && pull16(ppReadPackedMsg, &srs_pdu->t_offset, end))) {
|
|
return 0;
|
|
}
|
|
|
|
if (!(unpack_nr_rx_beamforming_pdu(&srs_pdu->beamforming, ppReadPackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
if (!(unpack_ul_tti_request_srs_parameters_v4(&srs_pdu->srs_parameters_v4, 1 << srs_pdu->num_symbols, ppReadPackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_ul_tti_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
|
|
{
|
|
nfapi_nr_ul_tti_request_number_of_pdus_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_pdus_t *)msg;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) && pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end)))
|
|
return 0;
|
|
|
|
// first natch the pdu type, then call the respective function
|
|
switch (pNfapiMsg->pdu_type) {
|
|
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
|
|
if (!unpack_ul_tti_request_prach_pdu(&pNfapiMsg->prach_pdu, ppReadPackedMsg, end))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
|
|
if (!unpack_ul_tti_request_pusch_pdu(&pNfapiMsg->pusch_pdu, ppReadPackedMsg, end))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
|
|
if (!unpack_ul_tti_request_pucch_pdu(&pNfapiMsg->pucch_pdu, ppReadPackedMsg, end))
|
|
return 0;
|
|
} break;
|
|
|
|
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
|
|
if (!unpack_ul_tti_request_srs_pdu(&pNfapiMsg->srs_pdu, ppReadPackedMsg, end))
|
|
return 0;
|
|
} break;
|
|
|
|
default: {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", pNfapiMsg->pdu_type);
|
|
} break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
|
|
{
|
|
nfapi_nr_ul_tti_request_number_of_groups_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_groups_t *)msg;
|
|
|
|
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ue, end))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->n_ue; i++) {
|
|
if (!pull8(ppReadPackedMsg, &pNfapiMsg->ue_list[i].pdu_idx, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
|
|
|
|
if (!pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end))
|
|
return 0;
|
|
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end))
|
|
return 0;
|
|
if (!pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end))
|
|
return 0;
|
|
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end))
|
|
return 0;
|
|
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end))
|
|
return 0;
|
|
if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end))
|
|
return 0;
|
|
for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
|
|
if (!unpack_ul_tti_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdus_list[i]))
|
|
return 0;
|
|
}
|
|
|
|
for (int i = 0; i < pNfapiMsg->n_group; i++) {
|
|
if (!unpack_ul_tti_groups_list_value(ppReadPackedMsg, end, &pNfapiMsg->groups_list[i]))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t pack_nr_slot_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_slot_indication_scf_t *pNfapiMsg = (nfapi_nr_slot_indication_scf_t *)msg;
|
|
|
|
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
|
|
uint8_t *end,
|
|
nfapi_nr_slot_indication_scf_t *msg,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_slot_indication_scf_t *pNfapiMsg = (nfapi_nr_slot_indication_scf_t *)msg;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_ul_dci_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)tlv;
|
|
uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
|
|
if (!push16(value->PDUType, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
uint8_t *pPackedLengthField = *ppWritePackedMsg;
|
|
if (!(push16(value->PDUSize, ppWritePackedMsg, end) && push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end)
|
|
&& push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end)
|
|
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end)
|
|
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end)
|
|
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end)
|
|
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end)
|
|
&& pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end)
|
|
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end)
|
|
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end)
|
|
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end)
|
|
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end)
|
|
&& push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end)
|
|
&& push8(value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, ppWritePackedMsg, end)
|
|
&& push16(value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
for (int i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
|
|
nfapi_nr_dl_dci_pdu_t *dci_pdu = &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i];
|
|
if (!(push16(dci_pdu->RNTI, ppWritePackedMsg, end) && push16(dci_pdu->ScramblingId, ppWritePackedMsg, end)
|
|
&& push16(dci_pdu->ScramblingRNTI, ppWritePackedMsg, end) && push8(dci_pdu->CceIndex, ppWritePackedMsg, end)
|
|
&& push8(dci_pdu->AggregationLevel, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
// Precoding and Beamforming
|
|
nfapi_nr_tx_precoding_and_beamforming_t *beamforming = &dci_pdu->precodingAndBeamforming;
|
|
if (!(push16(beamforming->num_prgs, ppWritePackedMsg, end) && push16(beamforming->prg_size, ppWritePackedMsg, end)
|
|
&& push8(beamforming->dig_bf_interfaces, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
for (int prg = 0; prg < beamforming->num_prgs; prg++) {
|
|
if (!push16(beamforming->prgs_list[prg].pm_idx, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
for (int digInt = 0; digInt < beamforming->dig_bf_interfaces; digInt++) {
|
|
if (!push16(beamforming->prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
if (!(push8(dci_pdu->beta_PDCCH_1_0, ppWritePackedMsg, end) && push8(dci_pdu->powerControlOffsetSS, ppWritePackedMsg, end) &&
|
|
// DCI Payload fields
|
|
push16(dci_pdu->PayloadSizeBits, ppWritePackedMsg, end) &&
|
|
// Pack DCI Payload
|
|
pack_dci_payload(dci_pdu->Payload, dci_pdu->PayloadSizeBits, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// pack proper size
|
|
uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
|
|
uint16_t packedMsgLen = msgEnd - msgHead;
|
|
value->PDUSize = packedMsgLen;
|
|
return push16(value->PDUSize, &pPackedLengthField, end);
|
|
}
|
|
|
|
uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
|
|
|
|
if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
|
|
&& push8(pNfapiMsg->numPdus, ppWritePackedMsg, end)))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->numPdus; i++) {
|
|
if (!pack_ul_dci_pdu_list_value(&pNfapiMsg->ul_dci_pdu_list[i], ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
|
|
{
|
|
nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)msg;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &value->PDUType, end) && pull16(ppReadPackedMsg, &value->PDUSize, end)
|
|
&& pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end)
|
|
&& pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end)
|
|
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end)
|
|
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end)
|
|
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end)
|
|
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end)
|
|
&& pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end)
|
|
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end)
|
|
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end)
|
|
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end)
|
|
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end)
|
|
&& pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end)
|
|
&& pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end)
|
|
&& pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end))) {
|
|
return 0;
|
|
}
|
|
|
|
for (uint16_t i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
|
|
nfapi_nr_dl_dci_pdu_t *dci_pdu = &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i];
|
|
if (!(pull16(ppReadPackedMsg, &dci_pdu->RNTI, end) && pull16(ppReadPackedMsg, &dci_pdu->ScramblingId, end)
|
|
&& pull16(ppReadPackedMsg, &dci_pdu->ScramblingRNTI, end) && pull8(ppReadPackedMsg, &dci_pdu->CceIndex, end)
|
|
&& pull8(ppReadPackedMsg, &dci_pdu->AggregationLevel, end))) {
|
|
return 0;
|
|
}
|
|
// Precoding and Beamforming
|
|
nfapi_nr_tx_precoding_and_beamforming_t *beamforming = &dci_pdu->precodingAndBeamforming;
|
|
if (!(pull16(ppReadPackedMsg, &beamforming->num_prgs, end) && pull16(ppReadPackedMsg, &beamforming->prg_size, end)
|
|
&& pull8(ppReadPackedMsg, &beamforming->dig_bf_interfaces, end))) {
|
|
return 0;
|
|
}
|
|
|
|
for (int prg = 0; prg < beamforming->num_prgs; prg++) {
|
|
if (!pull16(ppReadPackedMsg, &beamforming->prgs_list[prg].pm_idx, end)) {
|
|
return 0;
|
|
}
|
|
for (int digInt = 0; digInt < beamforming->dig_bf_interfaces; digInt++) {
|
|
if (!pull16(ppReadPackedMsg, &beamforming->prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
if (!(pull8(ppReadPackedMsg, &dci_pdu->beta_PDCCH_1_0, end) && pull8(ppReadPackedMsg, &dci_pdu->powerControlOffsetSS, end)
|
|
&& pull16(ppReadPackedMsg, &dci_pdu->PayloadSizeBits, end)
|
|
&& unpack_dci_payload(dci_pdu->Payload, dci_pdu->PayloadSizeBits, ppReadPackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
|
|
&& pull8(ppReadPackedMsg, &pNfapiMsg->numPdus, end)))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->numPdus; i++) {
|
|
if (!unpack_ul_dci_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->ul_dci_pdu_list[i]))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, uint32_t *payload_offset)
|
|
{
|
|
nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv;
|
|
if (!(push32(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end)
|
|
&& push32(value->num_TLV, ppWritePackedMsg, end)))
|
|
return 0;
|
|
|
|
for (int i = 0; i < value->num_TLV; ++i) {
|
|
if (!push16(value->TLVs[i].tag, ppWritePackedMsg, end))
|
|
return 0;
|
|
#ifdef ENABLE_AERIAL
|
|
if (!push16(value->TLVs[i].length, ppWritePackedMsg, end))
|
|
return 0;
|
|
#else
|
|
if (!push32(value->TLVs[i].length, ppWritePackedMsg, end))
|
|
return 0;
|
|
#endif
|
|
const uint32_t byte_len = (value->TLVs[i].length + 3) / 4;
|
|
switch (value->TLVs[i].tag) {
|
|
case 0: {
|
|
if (!pusharray32(value->TLVs[i].value.direct, byte_len, byte_len, ppWritePackedMsg, end)) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
|
|
return 0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 1: {
|
|
if (!pusharray32(value->TLVs[i].value.ptr, byte_len, byte_len, ppWritePackedMsg, end)) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
|
|
return 0;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case 2: {
|
|
// Currently Tag = 2 is only used for Aerial
|
|
if (!push32(*payload_offset, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
*payload_offset += value->TLVs[i].length;
|
|
break;
|
|
}
|
|
default: {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
|
|
|
|
if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
|
|
&& push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end)))
|
|
return 0;
|
|
uint32_t payload_offset = 0;
|
|
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
|
|
if (!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end, &payload_offset)) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR,
|
|
"%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n",
|
|
__FUNCTION__,
|
|
__LINE__,
|
|
i,
|
|
pNfapiMsg->pdu_list[i].PDU_length,
|
|
pNfapiMsg->pdu_list[i].PDU_index);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
|
|
{
|
|
nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg;
|
|
|
|
if (!(pull32(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) && pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end)
|
|
&& pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end)))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->num_TLV; ++i) {
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end) && pull32(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end)))
|
|
return 0;
|
|
const uint32_t byte_len = (pNfapiMsg->TLVs[i].length + 3) / 4;
|
|
if (pNfapiMsg->TLVs[i].tag == 1) {
|
|
pNfapiMsg->TLVs[i].value.ptr = calloc(byte_len, sizeof(uint32_t));
|
|
}
|
|
switch (pNfapiMsg->TLVs[i].tag) {
|
|
case 0: {
|
|
if (!pullarray32(ppReadPackedMsg,
|
|
pNfapiMsg->TLVs[i].value.direct,
|
|
sizeof(pNfapiMsg->TLVs[i].value.direct) / sizeof(uint32_t),
|
|
byte_len,
|
|
end))
|
|
return 0;
|
|
|
|
break;
|
|
}
|
|
|
|
case 1: {
|
|
if (!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.ptr, byte_len, byte_len, end))
|
|
return 0;
|
|
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", pNfapiMsg->TLVs[i].tag);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
|
|
&& pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end)))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
|
|
if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_nr_rx_data_indication_body(const nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
if (!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
|
|
&& push8(value->harq_id, ppWritePackedMsg, end) && push32(value->pdu_length, ppWritePackedMsg, end)
|
|
&& push8(value->ul_cqi, ppWritePackedMsg, end) && push16(value->timing_advance, ppWritePackedMsg, end)
|
|
&& push16(value->rssi, ppWritePackedMsg, end)))
|
|
return 0;
|
|
|
|
if (pusharray8(value->pdu, value->pdu_length, value->pdu_length, ppWritePackedMsg, end) == 0)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t *)msg;
|
|
|
|
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
|
|
&& push16(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
|
|
if (!pack_nr_rx_data_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value,
|
|
uint8_t **ppReadPackedMsg,
|
|
uint8_t *end,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
|
|
&& pull8(ppReadPackedMsg, &value->harq_id, end) && pull32(ppReadPackedMsg, &value->pdu_length, end)
|
|
&& pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
|
|
&& pull16(ppReadPackedMsg, &value->rssi, end)))
|
|
return 0;
|
|
|
|
const uint32_t length = value->pdu_length;
|
|
value->pdu = calloc(length, sizeof(*value->pdu));
|
|
if (pullarray8(ppReadPackedMsg, value->pdu, length, length, end) == 0) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t *)msg;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
|
|
&& pull16(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end)))
|
|
return 0;
|
|
|
|
if (pNfapiMsg->number_of_pdus > 0) {
|
|
pNfapiMsg->pdu_list = calloc(pNfapiMsg->number_of_pdus, sizeof(*pNfapiMsg->pdu_list));
|
|
}
|
|
|
|
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
|
|
if (!unpack_nr_rx_data_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_nr_crc_indication_body(const nfapi_nr_crc_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
if (!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
|
|
&& push8(value->harq_id, ppWritePackedMsg, end) && push8(value->tb_crc_status, ppWritePackedMsg, end)
|
|
&& push16(value->num_cb, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
if (value->num_cb != 0) {
|
|
const uint16_t cb_len = (value->num_cb / 8) + 1; // length is ceil(NumCb/8)
|
|
if (!pusharray8(value->cb_crc_status, cb_len, cb_len, ppWritePackedMsg,
|
|
end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
if (!(push8(value->ul_cqi, ppWritePackedMsg, end) && push16(value->timing_advance, ppWritePackedMsg, end)
|
|
&& push16(value->rssi, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
uint8_t pack_nr_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t *)msg;
|
|
|
|
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
|
|
&& push16(pNfapiMsg->number_crcs, ppWritePackedMsg, end)))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->number_crcs; i++) {
|
|
if (!pack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_nr_crc_indication_body(nfapi_nr_crc_t *value, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
|
|
&& pull8(ppReadPackedMsg, &value->harq_id, end) && pull8(ppReadPackedMsg, &value->tb_crc_status, end)
|
|
&& pull16(ppReadPackedMsg, &value->num_cb, end))) {
|
|
return 0;
|
|
}
|
|
if (value->num_cb != 0) {
|
|
const uint16_t cb_len = (value->num_cb / 8) + 1; // length is ceil(NumCb/8)
|
|
value->cb_crc_status = calloc(cb_len, sizeof(uint8_t));
|
|
if (!pullarray8(ppReadPackedMsg, value->cb_crc_status, cb_len, cb_len, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
if (!(pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
|
|
&& pull16(ppReadPackedMsg, &value->rssi, end))) {
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_nr_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t *)msg;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
|
|
&& pull16(ppReadPackedMsg, &pNfapiMsg->number_crcs, end)))
|
|
return 0;
|
|
|
|
if (pNfapiMsg->number_crcs > 0) {
|
|
pNfapiMsg->crc_list = calloc(pNfapiMsg->number_crcs, sizeof(*pNfapiMsg->crc_list));
|
|
}
|
|
|
|
for (int i = 0; i < pNfapiMsg->number_crcs; i++) {
|
|
if (!unpack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppReadPackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_nr_uci_pusch(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_uci_pusch_pdu_t *value = (nfapi_nr_uci_pusch_pdu_t *)tlv;
|
|
|
|
if (!push8(value->pduBitmap, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push32(value->handle, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->rnti, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(value->ul_cqi, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->timing_advance, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->rssi, ppWritePackedMsg, end))
|
|
return 0;
|
|
|
|
// Bit 0 not used in PUSCH PDU
|
|
if ((value->pduBitmap >> 1) & 0x01) { // HARQ
|
|
if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
const uint16_t harq_len = (value->harq.harq_bit_len / 8) + 1;
|
|
if (!pusharray8(value->harq.harq_payload, harq_len, harq_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
|
|
if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
|
|
if (!pusharray8(value->csi_part1.csi_part1_payload, csi_len, csi_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
|
|
if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
|
|
if (!pusharray8(value->csi_part2.csi_part2_payload, csi_len, csi_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_nr_uci_pucch_0_1(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_uci_pucch_pdu_format_0_1_t *value = (nfapi_nr_uci_pucch_pdu_format_0_1_t *)tlv;
|
|
|
|
if (!push8(value->pduBitmap, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push32(value->handle, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->rnti, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(value->pucch_format, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(value->ul_cqi, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->timing_advance, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->rssi, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (value->pduBitmap & 0x01) { // SR
|
|
if (!push8(value->sr.sr_indication, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(value->sr.sr_confidence_level, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
if (((value->pduBitmap >> 1) & 0x01)) { // HARQ
|
|
if (!push8(value->harq.num_harq, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(value->harq.harq_confidence_level, ppWritePackedMsg, end))
|
|
return 0;
|
|
for (int i = 0; i < value->harq.num_harq; i++) {
|
|
if (!push8(value->harq.harq_list[i].harq_value, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_nr_uci_pucch_2_3_4(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *value = (nfapi_nr_uci_pucch_pdu_format_2_3_4_t *)tlv;
|
|
|
|
if (!push8(value->pduBitmap, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push32(value->handle, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->rnti, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(value->pucch_format, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push8(value->ul_cqi, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->timing_advance, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->rssi, ppWritePackedMsg, end))
|
|
return 0;
|
|
|
|
if (value->pduBitmap & 0x01) { // SR
|
|
if (!push16(value->sr.sr_bit_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
const uint16_t sr_len = value->sr.sr_bit_len / 8 + 1;
|
|
if (!pusharray8(value->sr.sr_payload, sr_len, sr_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 1) & 0x01) { // HARQ
|
|
if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
const uint16_t harq_len = value->harq.harq_bit_len / 8 + 1;
|
|
if (!pusharray8(value->harq.harq_payload, harq_len, harq_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
|
|
if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
|
|
if (!pusharray8(value->csi_part1.csi_part1_payload, csi_len, csi_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
|
|
if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
|
|
if (!pusharray8(value->csi_part2.csi_part2_payload, csi_len, csi_len, ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_nr_uci_indication_body(nfapi_nr_uci_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
if (!push16(value->pdu_type, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(value->pdu_size, ppWritePackedMsg, end))
|
|
return 0;
|
|
|
|
switch (value->pdu_type) {
|
|
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
|
|
if (!pack_nr_uci_pusch(&value->pusch_pdu, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
|
|
if (!pack_nr_uci_pucch_0_1(&value->pucch_pdu_format_0_1, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
|
|
if (!pack_nr_uci_pucch_2_3_4(&value->pucch_pdu_format_2_3_4, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
break;
|
|
default:
|
|
NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected UCI.indication PDU type %d\n", value->pdu_type);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t *)msg;
|
|
|
|
if (!push16(pNfapiMsg->sfn, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(pNfapiMsg->slot, ppWritePackedMsg, end))
|
|
return 0;
|
|
if (!push16(pNfapiMsg->num_ucis, ppWritePackedMsg, end))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->num_ucis; i++) {
|
|
if (!pack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_uci_pusch(nfapi_nr_uci_pusch_pdu_t *value,
|
|
uint8_t **ppReadPackedMsg,
|
|
uint8_t *end,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
|
|
return 0;
|
|
if (!pull32(ppReadPackedMsg, &value->handle, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->rnti, end))
|
|
return 0;
|
|
if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->rssi, end))
|
|
return 0;
|
|
|
|
// Bit 0 not used in PUSCH PDU
|
|
if ((value->pduBitmap >> 1) & 0x01) { // HARQ
|
|
if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
|
|
return 0;
|
|
const uint16_t harq_len = value->harq.harq_bit_len / 8 + 1;
|
|
value->harq.harq_payload = calloc(harq_len, sizeof(*value->harq.harq_payload));
|
|
|
|
if (value->harq.harq_payload == NULL) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
|
|
return 0;
|
|
}
|
|
|
|
if (!pullarray8(ppReadPackedMsg, value->harq.harq_payload, harq_len, harq_len, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
|
|
if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
|
|
return 0;
|
|
const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
|
|
value->csi_part1.csi_part1_payload = calloc(csi_len, sizeof(*value->csi_part1.csi_part1_payload));
|
|
|
|
if (value->csi_part1.csi_part1_payload == NULL) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n", __FUNCTION__);
|
|
return 0;
|
|
}
|
|
|
|
if (!pullarray8(ppReadPackedMsg, value->csi_part1.csi_part1_payload, csi_len, csi_len, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
|
|
if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
|
|
return 0;
|
|
const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
|
|
value->csi_part2.csi_part2_payload = calloc(csi_len, sizeof(*value->csi_part2.csi_part2_payload));
|
|
|
|
if (value->csi_part2.csi_part2_payload == NULL) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n", __FUNCTION__);
|
|
return 0;
|
|
}
|
|
|
|
if (!pullarray8(ppReadPackedMsg, value->csi_part2.csi_part2_payload, csi_len, csi_len, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *value,
|
|
uint8_t **ppReadPackedMsg,
|
|
uint8_t *end,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
if (!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && pull32(ppReadPackedMsg, &value->handle, end)
|
|
&& pull16(ppReadPackedMsg, &value->rnti, end) && pull8(ppReadPackedMsg, &value->pucch_format, end)
|
|
&& pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
|
|
&& pull16(ppReadPackedMsg, &value->rssi, end)))
|
|
return 0;
|
|
if (value->pduBitmap & 0x01) { // SR
|
|
if (!(pull8(ppReadPackedMsg, &value->sr.sr_indication, end) && pull8(ppReadPackedMsg, &value->sr.sr_confidence_level, end)))
|
|
return 0;
|
|
}
|
|
|
|
if (((value->pduBitmap >> 1) & 0x01)) { // HARQ
|
|
|
|
if (!(pull8(ppReadPackedMsg, &value->harq.num_harq, end) && pull8(ppReadPackedMsg, &value->harq.harq_confidence_level, end)))
|
|
return 0;
|
|
if (value->harq.num_harq > 0) {
|
|
for (int i = 0; i < value->harq.num_harq; i++) {
|
|
if (!pull8(ppReadPackedMsg, &value->harq.harq_list[i].harq_value, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t *value,
|
|
uint8_t **ppReadPackedMsg,
|
|
uint8_t *end,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
|
|
return 0;
|
|
if (!pull32(ppReadPackedMsg, &value->handle, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->rnti, end))
|
|
return 0;
|
|
if (!pull8(ppReadPackedMsg, &value->pucch_format, end))
|
|
return 0;
|
|
if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->rssi, end))
|
|
return 0;
|
|
|
|
if (value->pduBitmap & 0x01) { // SR
|
|
if (!pull16(ppReadPackedMsg, &value->sr.sr_bit_len, end))
|
|
return 0;
|
|
const uint16_t sr_len = value->sr.sr_bit_len / 8 + 1;
|
|
value->sr.sr_payload = calloc(sr_len, sizeof(*value->sr.sr_payload));
|
|
|
|
if (value->sr.sr_payload == NULL) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->sr.sr_payload\n", __FUNCTION__);
|
|
return 0;
|
|
}
|
|
|
|
if (!pullarray8(ppReadPackedMsg, value->sr.sr_payload, sr_len, sr_len, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 1) & 0x01) { // HARQ
|
|
if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
|
|
return 0;
|
|
const uint16_t harq_len = value->harq.harq_bit_len / 8 + 1;
|
|
value->harq.harq_payload = calloc(harq_len, sizeof(*value->harq.harq_payload));
|
|
|
|
if (value->harq.harq_payload == NULL) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
|
|
return 0;
|
|
}
|
|
|
|
if (!pullarray8(ppReadPackedMsg, value->harq.harq_payload, harq_len, harq_len, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
|
|
if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
|
|
return 0;
|
|
const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
|
|
value->csi_part1.csi_part1_payload = calloc(csi_len, sizeof(*value->csi_part1.csi_part1_payload));
|
|
|
|
if (value->csi_part1.csi_part1_payload == NULL) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n", __FUNCTION__);
|
|
return 0;
|
|
}
|
|
|
|
if (!pullarray8(ppReadPackedMsg, value->csi_part1.csi_part1_payload, csi_len, csi_len, end))
|
|
return 0;
|
|
}
|
|
|
|
if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
|
|
if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
|
|
return 0;
|
|
const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
|
|
value->csi_part2.csi_part2_payload = calloc(csi_len, sizeof(*value->csi_part2.csi_part2_payload));
|
|
|
|
if (value->csi_part2.csi_part2_payload == NULL) {
|
|
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n", __FUNCTION__);
|
|
return 0;
|
|
}
|
|
|
|
if (!pullarray8(ppReadPackedMsg, value->csi_part2.csi_part2_payload, csi_len, csi_len, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value,
|
|
uint8_t **ppReadPackedMsg,
|
|
uint8_t *end,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
if (!pull16(ppReadPackedMsg, &value->pdu_type, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &value->pdu_size, end))
|
|
return 0;
|
|
|
|
switch (value->pdu_type) {
|
|
case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
|
|
nfapi_nr_uci_pusch_pdu_t *uci_pdu = &value->pusch_pdu;
|
|
if (!unpack_nr_uci_pusch(uci_pdu, ppReadPackedMsg, end, config))
|
|
return 0;
|
|
break;
|
|
}
|
|
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
|
|
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1;
|
|
if (!unpack_nr_uci_pucch_0_1(uci_pdu, ppReadPackedMsg, end, config))
|
|
return 0;
|
|
break;
|
|
}
|
|
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
|
|
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4;
|
|
if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end, config))
|
|
return 0;
|
|
break;
|
|
}
|
|
default:
|
|
NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected UCI.indication PDU type %d\n", value->pdu_type);
|
|
break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t *)msg;
|
|
|
|
if (!pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &pNfapiMsg->slot, end))
|
|
return 0;
|
|
if (!pull16(ppReadPackedMsg, &pNfapiMsg->num_ucis, end))
|
|
return 0;
|
|
|
|
pNfapiMsg->uci_list = calloc(pNfapiMsg->num_ucis, sizeof(*pNfapiMsg->uci_list));
|
|
for (int i = 0; i < pNfapiMsg->num_ucis; i++) {
|
|
if (!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_nr_srs_report_tlv(const nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
|
|
|
|
if(!(push16(report_tlv->tag, ppWritePackedMsg, end) &&
|
|
push32(report_tlv->length, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
for (int i = 0; i < (report_tlv->length + 3) / 4; i++) {
|
|
if (!push32(report_tlv->value[i], ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_nr_srs_indication_body(const nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) {
|
|
|
|
if(!(push32(value->handle, ppWritePackedMsg, end) &&
|
|
push16(value->rnti, ppWritePackedMsg, end) &&
|
|
push16(value->timing_advance_offset, ppWritePackedMsg, end) &&
|
|
pushs16(value->timing_advance_offset_nsec, ppWritePackedMsg, end) &&
|
|
push8(value->srs_usage, ppWritePackedMsg, end) &&
|
|
push8(value->report_type, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
if (!pack_nr_srs_report_tlv(&value->report_tlv, ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t *)msg;
|
|
|
|
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
|
|
&& push16(pNfapiMsg->control_length, ppWritePackedMsg, end) && push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end))) {
|
|
return 0;
|
|
}
|
|
|
|
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
|
|
if (!pack_nr_srs_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
|
|
{
|
|
#ifndef ENABLE_AERIAL
|
|
for (int i = 0; i < (report_tlv->length + 3) / 4; i++) {
|
|
if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
#else
|
|
const int16_t last_idx = ((report_tlv->length + 3) / 4) - 1;
|
|
for (int i = 0; i < last_idx; i++) {
|
|
if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
// Pull last bytes according to how much padding it would need to be 32-bit aligned
|
|
const uint8_t padding = get_tlv_padding(report_tlv->length);
|
|
pullx32(4 - padding, ppReadPackedMsg, &report_tlv->value[last_idx], end);
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
|
|
|
|
if(!(pull16(ppReadPackedMsg, &report_tlv->tag, end) &&
|
|
pull32(ppReadPackedMsg, &report_tlv->length, end))) {
|
|
return 0;
|
|
}
|
|
#ifndef ENABLE_AERIAL
|
|
if (!unpack_nr_srs_report_tlv_value(report_tlv, ppReadPackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppReadPackedMsg, uint8_t *end) {
|
|
|
|
if(!(pull32(ppReadPackedMsg, &value->handle, end) &&
|
|
pull16(ppReadPackedMsg, &value->rnti, end) &&
|
|
pull16(ppReadPackedMsg, &value->timing_advance_offset, end) &&
|
|
pulls16(ppReadPackedMsg, &value->timing_advance_offset_nsec, end) &&
|
|
pull8(ppReadPackedMsg, &value->srs_usage, end) &&
|
|
pull8(ppReadPackedMsg, &value->report_type, end))) {
|
|
return 0;
|
|
}
|
|
|
|
if (!unpack_nr_srs_report_tlv(&value->report_tlv, ppReadPackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t *)msg;
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
|
|
&& pull16(ppReadPackedMsg, &pNfapiMsg->control_length, end) && pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
|
|
return 0;
|
|
}
|
|
pNfapiMsg->pdu_list = calloc(pNfapiMsg->number_of_pdus, sizeof(*pNfapiMsg->pdu_list));
|
|
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
|
|
if (!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t pack_nr_rach_indication_body(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
|
{
|
|
nfapi_nr_prach_indication_pdu_t *value = (nfapi_nr_prach_indication_pdu_t *)tlv;
|
|
|
|
if (!(push16(value->phy_cell_id, ppWritePackedMsg, end) && push8(value->symbol_index, ppWritePackedMsg, end)
|
|
&& push8(value->slot_index, ppWritePackedMsg, end) && push8(value->freq_index, ppWritePackedMsg, end)
|
|
&& push8(value->avg_rssi, ppWritePackedMsg, end) && push8(value->avg_snr, ppWritePackedMsg, end)
|
|
&& push8(value->num_preamble, ppWritePackedMsg, end)))
|
|
return 0;
|
|
for (int i = 0; i < value->num_preamble; i++) {
|
|
if (!(push8(value->preamble_list[i].preamble_index, ppWritePackedMsg, end)
|
|
&& push16(value->preamble_list[i].timing_advance, ppWritePackedMsg, end)
|
|
&& push32(value->preamble_list[i].preamble_pwr, ppWritePackedMsg, end)))
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
uint8_t pack_nr_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t *)msg;
|
|
|
|
if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
|
|
&& push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)))
|
|
return 0;
|
|
|
|
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
|
|
if (!pack_nr_rach_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t *value,
|
|
uint8_t **ppReadPackedMsg,
|
|
uint8_t *end,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
if (!(pull16(ppReadPackedMsg, &value->phy_cell_id, end) && pull8(ppReadPackedMsg, &value->symbol_index, end)
|
|
&& pull8(ppReadPackedMsg, &value->slot_index, end) && pull8(ppReadPackedMsg, &value->freq_index, end)
|
|
&& pull8(ppReadPackedMsg, &value->avg_rssi, end) && pull8(ppReadPackedMsg, &value->avg_snr, end)
|
|
&& pull8(ppReadPackedMsg, &value->num_preamble, end))) {
|
|
return 0;
|
|
}
|
|
|
|
for (int i = 0; i < value->num_preamble; i++) {
|
|
nfapi_nr_prach_indication_preamble_t *preamble = &(value->preamble_list[i]);
|
|
if (!(pull8(ppReadPackedMsg, &preamble->preamble_index, end) && pull16(ppReadPackedMsg, &preamble->timing_advance, end)
|
|
&& pull32(ppReadPackedMsg, &preamble->preamble_pwr, end))) {
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
|
|
{
|
|
nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t *)msg;
|
|
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
|
|
&& pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
|
|
return 0;
|
|
}
|
|
|
|
if (pNfapiMsg->number_of_pdus > 0) {
|
|
pNfapiMsg->pdu_list = calloc(pNfapiMsg->number_of_pdus, sizeof(*pNfapiMsg->pdu_list));
|
|
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
|
|
if (!unpack_nr_rach_indication_body(&(pNfapiMsg->pdu_list[i]), ppReadPackedMsg, end, config))
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|