Remove duplicated functions in fapi_vnf_p7.c, leaving only functions for messages that require usage of the secondaty data_buf for unpacking Move vnf_info struct declaration to nfapi_vnf.h to be available in fapi_nvIPC.c
220 lines
9.5 KiB
C
220 lines
9.5 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
|
|
*/
|
|
|
|
/*! \file fapi/oai-integration/fapi_vnf_p7.c
|
|
* \brief OAI FAPI VNF P7 message handler procedures
|
|
* \author Ruben S. Silva
|
|
* \date 2023
|
|
* \version 0.1
|
|
* \company OpenAirInterface Software Alliance
|
|
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
|
* \note
|
|
* \warning
|
|
*/
|
|
|
|
#include "fapi_vnf_p7.h"
|
|
#include "nr_nfapi_p7.h"
|
|
#include "nr_fapi_p7.h"
|
|
#include "nr_fapi_p7_utils.h"
|
|
|
|
static uint8_t aerial_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) &&
|
|
// For Aerial, RX_DATA.indication PDULength is changed to 32 bit field
|
|
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;
|
|
}
|
|
|
|
// Allocate space for the pdu to be unpacked later
|
|
value->pdu = nfapi_p7_allocate(sizeof(*value->pdu) * value->pdu_length, config);
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t aerial_unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg,
|
|
uint8_t *end,
|
|
uint8_t **pDataMsg,
|
|
uint8_t *data_end,
|
|
nfapi_nr_rx_data_indication_t *msg,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
// For Aerial unpacking, the PDU data is packed in pDataMsg, and we read it after unpacking the PDU headers
|
|
|
|
nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t *)msg;
|
|
// Unpack SFN, slot, nPDU
|
|
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
|
|
&& pull16(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
|
|
return 0;
|
|
}
|
|
// Allocate the PDU list for number of PDUs
|
|
if (pNfapiMsg->number_of_pdus > 0) {
|
|
pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config);
|
|
}
|
|
// For each PDU, unpack its header
|
|
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
|
|
if (!aerial_unpack_nr_rx_data_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config))
|
|
return 0;
|
|
}
|
|
// After unpacking the PDU headers, unpack the PDU data from the separate buffer
|
|
for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
|
|
if (!pullarray8(pDataMsg,
|
|
pNfapiMsg->pdu_list[i].pdu,
|
|
pNfapiMsg->pdu_list[i].pdu_length,
|
|
pNfapiMsg->pdu_list[i].pdu_length,
|
|
data_end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg,
|
|
uint8_t *end,
|
|
uint8_t **pDataMsg,
|
|
uint8_t *data_end,
|
|
void *msg,
|
|
nfapi_p7_codec_config_t *config)
|
|
{
|
|
uint8_t retval = unpack_nr_srs_indication(ppReadPackedMsg, end, msg, config);
|
|
nfapi_nr_srs_indication_t *srs_ind = (nfapi_nr_srs_indication_t *)msg;
|
|
for (uint8_t pdu_idx = 0; pdu_idx < srs_ind->number_of_pdus; pdu_idx++) {
|
|
nfapi_nr_srs_indication_pdu_t *pdu = &srs_ind->pdu_list[pdu_idx];
|
|
if (!unpack_nr_srs_report_tlv_value(&pdu->report_tlv, pDataMsg, data_end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
static int32_t aerial_pack_tx_data_request(void *pMessageBuf,
|
|
void *pPackedBuf,
|
|
void *pDataBuf,
|
|
uint32_t packedBufLen,
|
|
uint32_t dataBufLen,
|
|
nfapi_p7_codec_config_t *config,
|
|
nfapi_vnf_p7_config_t *p7_config,
|
|
uint32_t *data_len)
|
|
{
|
|
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 *data_end = pDataBuf + dataBufLen;
|
|
uint8_t *pDataPackedMessage = pDataBuf;
|
|
uint8_t *pPackedDataField = &pDataPackedMessage[0];
|
|
uint8_t *pPackedDataFieldStart = &pDataPackedMessage[0];
|
|
uint8_t **ppWriteData = &pPackedDataField;
|
|
const uint32_t dataBufLen32 = (dataBufLen + 3) / 4;
|
|
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)pMessageHeader;
|
|
// Actual payloads are packed in a separate buffer
|
|
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
|
|
nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)&pNfapiMsg->pdu_list[i];
|
|
// recalculate PDU_Length for Aerial (leave only the size occupied in the payload buffer afterward)
|
|
// assuming there is only 1 TLV present
|
|
value->PDU_length = value->TLVs[0].length;
|
|
for (uint32_t k = 0; k < value->num_TLV; ++k) {
|
|
// Ensure tag is 2
|
|
value->TLVs[k].tag = 2;
|
|
uint32_t num_values_to_push = ((value->TLVs[k].length + 3) / 4);
|
|
if (value->TLVs[k].length > 0) {
|
|
if (value->TLVs[k].length % 4 != 0) {
|
|
if (!pusharray32(value->TLVs[k].value.direct, dataBufLen32, num_values_to_push - 1, ppWriteData, data_end)) {
|
|
return 0;
|
|
}
|
|
int bytesToAdd = 4 - (4 - (value->TLVs[k].length % 4)) % 4;
|
|
if (bytesToAdd != 4) {
|
|
for (int j = 0; j < bytesToAdd; j++) {
|
|
uint8_t toPush = (uint8_t)(value->TLVs[k].value.direct[num_values_to_push - 1] >> (j * 8));
|
|
if (!push8(toPush, ppWriteData, data_end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// no padding needed
|
|
if (!pusharray32(value->TLVs[k].value.direct, dataBufLen32, num_values_to_push, ppWriteData, data_end)) {
|
|
return 0;
|
|
}
|
|
}
|
|
} else {
|
|
LOG_E(NR_MAC, "value->TLVs[i].length was 0! (%d.%d) \n", pNfapiMsg->SFN, pNfapiMsg->Slot);
|
|
}
|
|
}
|
|
}
|
|
|
|
// calculate data_len
|
|
uintptr_t dataHead = (uintptr_t)pPackedDataFieldStart;
|
|
uintptr_t dataEnd = (uintptr_t)pPackedDataField;
|
|
data_len[0] = dataEnd - dataHead;
|
|
|
|
if (!p7_config->pack_func(pMessageBuf, pPackedBuf, packedBufLen, config)) {
|
|
return -1;
|
|
}
|
|
|
|
return (int32_t)(pMessageHeader->message_length);
|
|
}
|
|
|
|
|
|
bool aerial_nr_send_p7_message(vnf_p7_t *vnf_p7, nfapi_nr_p7_message_header_t *header)
|
|
{
|
|
uint8_t FAPI_buffer[1024 * 64];
|
|
// Check if TX_DATA request, if true, need to pack to data_buf
|
|
if (header->message_id == NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST) {
|
|
nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)header;
|
|
uint64_t size = 0;
|
|
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; ++i) {
|
|
size += pNfapiMsg->pdu_list[i].PDU_length;
|
|
}
|
|
AssertFatal(size <= 1024 * 1024 * 2, "Message data larger than available buffer, tried to pack %" PRId64, size);
|
|
uint8_t FAPI_data_buffer[1024 * 1024 * 2]; // 2MB
|
|
uint32_t data_len = 0;
|
|
int32_t len_FAPI = aerial_pack_tx_data_request(header,
|
|
FAPI_buffer,
|
|
FAPI_data_buffer,
|
|
sizeof(FAPI_buffer),
|
|
sizeof(FAPI_data_buffer),
|
|
&vnf_p7->_public.codec_config,
|
|
((nfapi_vnf_p7_config_t *)vnf_p7),
|
|
&data_len);
|
|
if (len_FAPI <= 0) {
|
|
LOG_E(NFAPI_VNF, "Problem packing TX_DATA_request\n");
|
|
return false;
|
|
} else {
|
|
return aerial_send_P7_msg_with_data(FAPI_buffer, len_FAPI, FAPI_data_buffer, data_len, header) == 0;
|
|
}
|
|
} else {
|
|
// Create and send FAPI P7 message
|
|
int len_FAPI = ((nfapi_vnf_p7_config_t *)vnf_p7)->pack_func(header,
|
|
FAPI_buffer,
|
|
sizeof(FAPI_buffer),
|
|
&vnf_p7->_public.codec_config);
|
|
return aerial_send_P7_msg(FAPI_buffer, len_FAPI, header) == 0;
|
|
}
|
|
}
|