Add pack/unpack for CONFIG.request Beamforming Table

Adds the packing and unpacking functions needed for the DBT Table in CONFIG.request
This table tag is specified in SCF222.5.0 (0x1043) and this tag is used to transport the table, previous versions did not include a tag for the table.
A struct nfapi_nr_dbt_tlv_ve_t is added to represent this TLV in order to be able to use the pack_nr_tlv function.
The necessary additions to the utility functions are done to account for this table.
The unitary test is changed to fill this table with randomized data to test transport and copy.
This commit is contained in:
Rúben Soares Silva
2025-06-17 10:09:29 +01:00
parent 5016fc75c6
commit 8519c748d1
5 changed files with 124 additions and 6 deletions
+59 -1
View File
@@ -724,6 +724,28 @@ uint8_t unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *
&pNfapiMsg->vendor_extension));
}
static uint8_t pack_dbt_table_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_dbt_tlv_ve_t *dbt_ve = (nfapi_nr_dbt_tlv_ve_t *)tlv;
nfapi_nr_dbt_pdu_t *dbt_config = &dbt_ve->value;
if (!( push16(dbt_config->num_dig_beams, ppWritePackedMsg, end) && push16(dbt_config->num_txrus, ppWritePackedMsg, end) )) {
return 0;
}
for (int i = 0; i< dbt_config->num_dig_beams; i++) {
const nfapi_nr_dig_beam_t *dig_beam = &dbt_config->dig_beam_list[i];
if (!(push16(dig_beam->beam_idx, ppWritePackedMsg, end))) {
return 0;
}
for (int k = 0; k< dbt_config->num_txrus; k++) {
const nfapi_nr_txru_t *tx_ru = &dig_beam->txru_list[k];
if (!(push16(tx_ru->dig_beam_weight_Re, ppWritePackedMsg, end) && push16(tx_ru->dig_beam_weight_Im, ppWritePackedMsg, end))) {
return 0;
}
}
}
return 1;
}
uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config)
{
uint8_t *pNumTLVFields = (uint8_t *)*ppWritePackedMsg;
@@ -1044,7 +1066,11 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
// END Measurement Config
// START Digital Beam Table (DBT) PDU
// Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_dbt_pdu_t, currently unused
if (pNfapiMsg->dbt_config.num_dig_beams != 0) {
nfapi_nr_dbt_tlv_ve_t dbt_tlv = {.tl.tag = NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG, .value = pNfapiMsg->dbt_config};
pack_nr_tlv(NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG, &dbt_tlv, ppWritePackedMsg, end, &pack_dbt_table_tlv_value);
numTLVs++;
}
// END Digital Beam Table (DBT) PDU
// START Precoding Matrix (PM) PDU
@@ -1156,6 +1182,33 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
return retval;
}
static uint8_t unpack_dbt_table_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
{
nfapi_nr_dbt_pdu_t *dbt_config = (nfapi_nr_dbt_pdu_t *)tlv;
if (!(pull16(ppReadPackedMsg, &dbt_config->num_dig_beams, end) && pull16(ppReadPackedMsg, &dbt_config->num_txrus, end))) {
return 0;
}
if (dbt_config->num_dig_beams > 0) {
dbt_config->dig_beam_list = calloc(dbt_config->num_dig_beams, sizeof(*dbt_config->dig_beam_list));
}
for (int i = 0; i < dbt_config->num_dig_beams; i++) {
nfapi_nr_dig_beam_t *dig_beam = &dbt_config->dig_beam_list[i];
if (!(pull16(ppReadPackedMsg, &dig_beam->beam_idx, end))) {
return 0;
}
if (dbt_config->num_txrus > 0) {
dig_beam->txru_list = calloc(dbt_config->num_txrus, sizeof(*dig_beam->txru_list));
}
for (int k = 0; k < dbt_config->num_txrus; k++) {
nfapi_nr_txru_t *tx_ru = &dig_beam->txru_list[k];
if (!(pull16(ppReadPackedMsg, &tx_ru->dig_beam_weight_Re, end) && pull16(ppReadPackedMsg, &tx_ru->dig_beam_weight_Im, end))) {
return 0;
}
}
}
return 1;
}
uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
{
// Helper vars for indexed TLVs
@@ -1221,6 +1274,7 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
{NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG, &(pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext), &unpack_uint8_tlv_value},
{NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG, NULL, &unpack_uint8_tlv_value},
{NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG, &(pNfapiMsg->measurement_config.rssi_measurement), &unpack_uint8_tlv_value},
{NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG, NULL, &unpack_dbt_table_tlv_value},
{NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), &unpack_ipv4_address_value},
{NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), &unpack_ipv6_address_value},
{NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), &unpack_uint16_tlv_value},
@@ -1268,6 +1322,10 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->analog_beamforming_ve.analog_beam_list[beam_ve_idx], ppReadPackedMsg, end);
beam_ve_idx ++;
break;
case NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG:
unpack_fns[idx].tlv = &generic_tl;
result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->dbt_config, ppReadPackedMsg, end);
break;
case NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG:
pNfapiMsg->prach_config.num_prach_fd_occasions.tl.tag = generic_tl.tag;
pNfapiMsg->prach_config.num_prach_fd_occasions.tl.length = generic_tl.length;
+39 -5
View File
@@ -259,6 +259,22 @@ bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const
EQ_TLV(unpacked_req->measurement_config.rssi_measurement, req->measurement_config.rssi_measurement);
EQ(unpacked_req->dbt_config.num_dig_beams, req->dbt_config.num_dig_beams);
EQ(unpacked_req->dbt_config.num_txrus, req->dbt_config.num_txrus);
for (int i = 0; i < req->dbt_config.num_dig_beams; i++) {
const nfapi_nr_dig_beam_t *unpacked_dig_beam = &unpacked_req->dbt_config.dig_beam_list[i];
const nfapi_nr_dig_beam_t *req_dig_beam = &req->dbt_config.dig_beam_list[i];
EQ(unpacked_dig_beam->beam_idx, req_dig_beam->beam_idx);
for (int k = 0; k < req->dbt_config.num_txrus; ++k) {
const nfapi_nr_txru_t *unpacked_tx_ru = &unpacked_dig_beam->txru_list[k];
const nfapi_nr_txru_t *req_tx_ru = &req_dig_beam->txru_list[k];
EQ(unpacked_tx_ru->dig_beam_weight_Re, req_tx_ru->dig_beam_weight_Re);
EQ(unpacked_tx_ru->dig_beam_weight_Im, req_tx_ru->dig_beam_weight_Im);
}
}
EQ(unpacked_req->nfapi_config.p7_vnf_address_ipv4.tl.tag, req->nfapi_config.p7_vnf_address_ipv4.tl.tag);
for (int i = 0; i < NFAPI_IPV4_ADDRESS_LENGTH; ++i) {
EQ(unpacked_req->nfapi_config.p7_vnf_address_ipv4.address[i], req->nfapi_config.p7_vnf_address_ipv4.address[i]);
@@ -406,9 +422,7 @@ void free_param_response(nfapi_nr_param_response_scf_t *msg)
void free_config_request(nfapi_nr_config_request_scf_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
if (msg->prach_config.num_prach_fd_occasions_list) {
for (int i = 0; i < msg->prach_config.num_prach_fd_occasions.value; i++) {
@@ -427,10 +441,14 @@ void free_config_request(nfapi_nr_config_request_scf_t *msg)
free(msg->tdd_table.max_tdd_periodicity_list);
}
if (msg->pmi_list.pmi_pdu) {
free(msg->pmi_list.pmi_pdu);
for (int i = 0; i < msg->dbt_config.num_dig_beams; i++) {
free(msg->dbt_config.dig_beam_list[i].txru_list);
}
free(msg->dbt_config.dig_beam_list);
free(msg->pmi_list.pmi_pdu);
if (msg->analog_beamforming_ve.analog_beam_list) {
free(msg->analog_beamforming_ve.analog_beam_list);
}
@@ -807,6 +825,22 @@ void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_conf
COPY_TLV(dst->measurement_config.rssi_measurement, src->measurement_config.rssi_measurement);
dst->dbt_config.num_dig_beams = src->dbt_config.num_dig_beams;
dst->dbt_config.num_txrus = src->dbt_config.num_txrus;
dst->dbt_config.dig_beam_list = calloc(dst->dbt_config.num_dig_beams, sizeof(*dst->dbt_config.dig_beam_list));
for (int i = 0; i < dst->dbt_config.num_dig_beams; i++) {
nfapi_nr_dig_beam_t *dst_dig_beam = &dst->dbt_config.dig_beam_list[i];
const nfapi_nr_dig_beam_t *src_dig_beam = &src->dbt_config.dig_beam_list[i];
dst_dig_beam->beam_idx = src_dig_beam->beam_idx;
dst_dig_beam->txru_list = calloc(dst->dbt_config.num_txrus , sizeof(*dst_dig_beam->txru_list ));
for (int k = 0; k < dst->dbt_config.num_txrus; ++k) {
nfapi_nr_txru_t *dst_tx_ru = &dst_dig_beam->txru_list[k];
const nfapi_nr_txru_t *src_tx_ru = &src_dig_beam->txru_list[k];
dst_tx_ru->dig_beam_weight_Re = src_tx_ru->dig_beam_weight_Re;
dst_tx_ru->dig_beam_weight_Im = src_tx_ru->dig_beam_weight_Im;
}
}
COPY_TL(dst->nfapi_config.p7_vnf_address_ipv4.tl, src->nfapi_config.p7_vnf_address_ipv4.tl);
memcpy(dst->nfapi_config.p7_vnf_address_ipv4.address,
src->nfapi_config.p7_vnf_address_ipv4.address,
@@ -34,6 +34,7 @@
#define NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG 0xA002
#define NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG 0xA003
typedef struct {
uint16_t phy_id;
uint16_t message_id;
@@ -328,6 +328,7 @@ typedef struct
#define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028
#define NFAPI_NR_CONFIG_TDD_TABLE 0x1035
#define NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG 0x1043 // This tag was added in version 5 of the SCF222 standard ( Table 3-50 of SCF222.10.05 )
//table 3-21
typedef struct
@@ -473,6 +474,11 @@ typedef struct {
nfapi_nr_dig_beam_t *dig_beam_list;
} nfapi_nr_dbt_pdu_t;
typedef struct {
nfapi_tl_t tl;
nfapi_nr_dbt_pdu_t value;
} nfapi_nr_dbt_tlv_ve_t;
// Table 3–62 Precoding matrix (PM) PDU (v.222.10.04)
typedef struct {
int16_t precoder_weight_Re;
@@ -206,6 +206,25 @@ static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfap
FILL_TLV(nfapi_resp->measurement_config.rssi_measurement, NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG, rand8());
nfapi_resp->num_tlv++;
uint16_t nb_beams = rand16_range(1, 15);
uint16_t nb_tx = rand16_range(1, 15);
nfapi_resp->dbt_config.num_dig_beams = nb_beams;
if (nfapi_resp->dbt_config.num_dig_beams > 0) {
nfapi_resp->dbt_config.num_txrus = nb_tx;
nfapi_resp->dbt_config.dig_beam_list = calloc(nb_beams , sizeof(*nfapi_resp->dbt_config.dig_beam_list));
for (int i = 0; i < nb_beams; i++) {
nfapi_nr_dig_beam_t *beam = &nfapi_resp->dbt_config.dig_beam_list[i];
beam->beam_idx = i;
beam->txru_list = calloc(nb_tx , sizeof(*beam->txru_list));
for (int j = 0; j < nb_tx; j++) {
nfapi_nr_txru_t *txru = &beam->txru_list[j];
txru->dig_beam_weight_Re = rand16_range(1, 0xffff);
txru->dig_beam_weight_Im = rand16_range(1, 0xffff);
}
}
nfapi_resp->num_tlv++;
}
nfapi_resp->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
for (int i = 0; i < NFAPI_IPV4_ADDRESS_LENGTH; ++i) {
nfapi_resp->nfapi_config.p7_vnf_address_ipv4.address[i] = rand8();