Merge remote-tracking branch 'origin/nfapi_dump_functions' into integration_2025_w25 (!3445)

Finalize FAPI dump functions, add Digital Beamforming Table and Precoding Matrix
Table to CONFIG.request

This MR finalizes the addition of dump utility functions for the PARAM.response,
CONFIG.request, CONFIG.response, TX_DATA.request and UCI.indication messages.

These functions are intended to be used to aid in debugging FAPI messages between
the VNF and the PNF by printing out every parameter in a more readable form,
instead of a simple hexdump. These are also used by the nFAPI Hex Parser utility,
to be able to debug an Hex dump provided from elsewhere.

Furthermore, this MR also adds the necessary logic to send/receive the Digital
Beamforming Table and Precoding Matrix Table, this in the CONFIG.request message.
This is achieved by the addition of 2 Vendor Extension TLVs (0xA002 and 0xA003),
in order to be able to reuse existing logic to pack/unpack the data. Note: The
present implementation predicts the existence of multiple instances of the
Precoding Matrix Table via the parameter num_pm_idx, whic is not present in the
SCF specification. Note: The created TLVs are only used to ease the pack/unpack
procedure, by allowing to reuse already existing logic for other TlVs, the tag
and length are not sent.

The necessary additions to the utility functions are done to account for these
table. The CONFIG.request unitary test is changed to fill these tables with
randomized data to test transport and copy.
This commit is contained in:
Jaroslava Fiedlerova
2025-06-18 11:30:32 +02:00
7 changed files with 888 additions and 131 deletions
+3
View File
@@ -35,6 +35,9 @@
#include "debug.h"
#define INDENTED_PRINTF(format, ...) printf("%*s" format, depth * 2, "", ##__VA_ARGS__)
#define INDENTED_GENERIC_PRINT(string, format, ...) INDENTED_PRINTF(string " = " format "\n", ##__VA_ARGS__)
#define INDENTED_TLV_PRINT(tlv_name, tlv) INDENTED_GENERIC_PRINT("(0x%04x) " tlv_name, "0x%02x", tlv.tl.tag, tlv.value)
#define INDENTED_TLV_FORMAT_PRINT(tlv_name, format, tlv) INDENTED_GENERIC_PRINT("(0x%04x) " tlv_name, format, tlv.tl.tag, tlv.value)
#define EQ_TLV(_tlv_a, _tlv_b) \
do { \
+123 -2
View File
@@ -724,6 +724,53 @@ 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;
}
static uint8_t pack_pm_table_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_nr_pm_tlv_ve_t *pm_ve = (nfapi_nr_pm_tlv_ve_t *)tlv;
nfapi_nr_pm_list_t *pmi_list = &pm_ve->value;
if (!( push16(pmi_list->num_pm_idx, ppWritePackedMsg, end) )) {
return 0;
}
for (int i = 0; i< pmi_list->num_pm_idx; i++) {
const nfapi_nr_pm_pdu_t *pm_pdu = &pmi_list->pmi_pdu[i];
if (!(push16(pm_pdu->pm_idx, ppWritePackedMsg, end) && push16(pm_pdu->numLayers, ppWritePackedMsg, end)
&& push16(pm_pdu->num_ant_ports, ppWritePackedMsg, end))) {
return 0;
}
for (int k = 0; k < pm_pdu->numLayers; k++) {
for (int j = 0; j < pm_pdu->num_ant_ports; j++) {
const nfapi_nr_pm_weights_t *pm_weight = &pm_pdu->weights[k][j];
if (!(push16(pm_weight->precoder_weight_Re, ppWritePackedMsg, end) && push16(pm_weight->precoder_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,11 +1091,19 @@ 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
// Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_pm_pdu_t, currently unused, tag to use for AERIAL
if (pNfapiMsg->pmi_list.num_pm_idx != 0) {
nfapi_nr_pm_tlv_ve_t pm_tlv = {.tl.tag = NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG, .value = pNfapiMsg->pmi_list};
pack_nr_tlv(NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG, &pm_tlv, ppWritePackedMsg, end, &pack_pm_table_tlv_value);
numTLVs++;
}
// is 0xA011 END Precoding Matrix (PM) PDU
#ifndef ENABLE_AERIAL
// START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
@@ -1156,6 +1211,62 @@ 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;
}
static uint8_t unpack_pm_table_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
{
nfapi_nr_pm_list_t *pm_list = (nfapi_nr_pm_list_t *)tlv;
if (!(pull16(ppReadPackedMsg, &pm_list->num_pm_idx, end))) {
return 0;
}
if (pm_list->num_pm_idx > 0) {
pm_list->pmi_pdu = calloc(pm_list->num_pm_idx, sizeof(*pm_list->pmi_pdu));
}
for (int i = 0; i < pm_list->num_pm_idx; i++) {
nfapi_nr_pm_pdu_t *pm_pdu = &pm_list->pmi_pdu[i];
if (!(pull16(ppReadPackedMsg, &pm_pdu->pm_idx, end) && pull16(ppReadPackedMsg, &pm_pdu->numLayers, end)
&& pull16(ppReadPackedMsg, &pm_pdu->num_ant_ports, end))) {
return 0;
}
AssertFatal(pm_pdu->numLayers <= 4 && pm_pdu->num_ant_ports <= 4, "Precoding matrix size limited to 4X4 for the time being\n");
for (int k = 0; k < pm_pdu->numLayers; k++) {
for (int j = 0; j < pm_pdu->num_ant_ports; j++) {
nfapi_nr_pm_weights_t *pm_weight = &pm_pdu->weights[k][j];
if (!(pulls16(ppReadPackedMsg, &pm_weight->precoder_weight_Re, end)
&& pulls16(ppReadPackedMsg, &pm_weight->precoder_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 +1332,8 @@ 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_CONFIG_PRECODING_TABLE_V6_TAG, NULL, &unpack_pm_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 +1381,14 @@ 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_PRECODING_TABLE_V6_TAG:
unpack_fns[idx].tlv = &generic_tl;
result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->pmi_list, 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;
+472 -46
View File
@@ -259,6 +259,40 @@ 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->pmi_list.num_pm_idx, req->pmi_list.num_pm_idx);
for (int i = 0; i < req->pmi_list.num_pm_idx; i++) {
const nfapi_nr_pm_pdu_t *req_pmi_pdu = &req->pmi_list.pmi_pdu[i];
const nfapi_nr_pm_pdu_t *unpacked_pmi_pdu = &unpacked_req->pmi_list.pmi_pdu[i];
EQ(unpacked_pmi_pdu->pm_idx, req_pmi_pdu->pm_idx);
EQ(unpacked_pmi_pdu->numLayers, req_pmi_pdu->numLayers);
EQ(unpacked_pmi_pdu->num_ant_ports, req_pmi_pdu->num_ant_ports);
for (int j = 0; j < req_pmi_pdu->num_ant_ports; ++j) {
for (int k = 0; k < req_pmi_pdu->num_ant_ports; ++k) {
const nfapi_nr_pm_weights_t* req_pm_weight = &req_pmi_pdu->weights[j][k];
const nfapi_nr_pm_weights_t* unpacked_pm_weight = &unpacked_pmi_pdu->weights[j][k];
EQ(unpacked_pm_weight->precoder_weight_Re, req_pm_weight->precoder_weight_Re);
EQ(unpacked_pm_weight->precoder_weight_Im, req_pm_weight->precoder_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]);
@@ -391,27 +425,20 @@ bool eq_error_indication(const nfapi_nr_error_indication_scf_t *unpacked_req, co
void free_param_request(nfapi_nr_param_request_scf_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
}
void free_param_response(nfapi_nr_param_response_scf_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
free(msg->cell_param.config_tlvs_to_report_list);
if (msg->cell_param.config_tlvs_to_report_list) {
free(msg->cell_param.config_tlvs_to_report_list);
}
}
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++) {
@@ -430,10 +457,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);
}
@@ -441,60 +472,40 @@ void free_config_request(nfapi_nr_config_request_scf_t *msg)
void free_config_response(nfapi_nr_config_response_scf_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
if (msg->invalid_tlvs_list) {
free(msg->invalid_tlvs_list);
}
free(msg->invalid_tlvs_list);
if (msg->invalid_tlvs_configured_in_idle_list) {
free(msg->invalid_tlvs_configured_in_idle_list);
}
free(msg->invalid_tlvs_configured_in_idle_list);
if (msg->invalid_tlvs_configured_in_running_list) {
free(msg->invalid_tlvs_configured_in_running_list);
}
free(msg->invalid_tlvs_configured_in_running_list);
if (msg->missing_tlvs_list) {
free(msg->missing_tlvs_list);
}
free(msg->missing_tlvs_list);
}
void free_start_request(nfapi_nr_start_request_scf_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
}
void free_start_response(nfapi_nr_start_response_scf_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
}
void free_stop_request(nfapi_nr_stop_request_scf_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
}
void free_stop_indication(nfapi_nr_stop_indication_scf_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
}
void free_error_indication(nfapi_nr_error_indication_scf_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
}
void copy_param_request(const nfapi_nr_param_request_scf_t *src, nfapi_nr_param_request_scf_t *dst)
@@ -810,6 +821,42 @@ 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;
}
}
dst->pmi_list.num_pm_idx = src->pmi_list.num_pm_idx;
if (dst->pmi_list.num_pm_idx > 0) {
dst->pmi_list.pmi_pdu = calloc(dst->pmi_list.num_pm_idx , sizeof(*dst->pmi_list.pmi_pdu));
for (int i = 0; i < dst->pmi_list.num_pm_idx; i++) {
nfapi_nr_pm_pdu_t * dst_pmi_pdu = &dst->pmi_list.pmi_pdu[i];
const nfapi_nr_pm_pdu_t * src_pmi_pdu = &src->pmi_list.pmi_pdu[i];
dst_pmi_pdu->pm_idx = src_pmi_pdu->pm_idx;
dst_pmi_pdu->numLayers = src_pmi_pdu->numLayers;
dst_pmi_pdu->num_ant_ports = src_pmi_pdu->num_ant_ports;
for (int j = 0; j < dst_pmi_pdu->numLayers; ++j) {
for (int k = 0; k < dst_pmi_pdu->num_ant_ports; ++k) {
nfapi_nr_pm_weights_t* dst_pm_weight = &dst_pmi_pdu->weights[j][k];
const nfapi_nr_pm_weights_t* src_pm_weight = &src_pmi_pdu->weights[j][k];
dst_pm_weight->precoder_weight_Re = src_pm_weight->precoder_weight_Re;
dst_pm_weight->precoder_weight_Im = src_pm_weight->precoder_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,
@@ -986,22 +1033,382 @@ void dump_param_request(const nfapi_nr_param_request_scf_t *msg)
void dump_param_response(const nfapi_nr_param_response_scf_t *msg)
{
int depth = 0;
dump_p5_message_header(&msg->header,depth);
dump_p5_message_header(&msg->header, depth);
depth++;
INDENTED_PRINTF("Error Code = 0x%02x\n", msg->error_code);
INDENTED_PRINTF("Number of TLVs = 0x%02x\n", msg->num_tlv);
/* dump all TLVs from each table */
/* Cell Param */
const nfapi_nr_cell_param_t *cell_param = &msg->cell_param;
depth++;
INDENTED_TLV_PRINT("Release Capability", cell_param->release_capability);
INDENTED_TLV_PRINT("PHY State", cell_param->phy_state);
INDENTED_TLV_PRINT("Skip Blank Dl Config", cell_param->skip_blank_dl_config);
INDENTED_TLV_PRINT("Skip Blank UL Config", cell_param->skip_blank_ul_config);
INDENTED_TLV_PRINT("NumConfigTLVsToReport", cell_param->num_config_tlvs_to_report);
depth++;
for (int i = 0; i < cell_param->num_config_tlvs_to_report.value; i++) {
const nfapi_uint8_tlv_t *reportedTLV = &cell_param->config_tlvs_to_report_list[i];
INDENTED_PRINTF("(0x%04x) Reported CONFIG TLV #%d = 0x%02x\n", reportedTLV->tl.tag, i + 1, reportedTLV->value);
}
depth--;
/* Carrier Param */
const nfapi_nr_carrier_param_t *carrier_param = &msg->carrier_param;
INDENTED_TLV_PRINT("Cyclic Prefix", carrier_param->cyclic_prefix);
INDENTED_TLV_PRINT("Supported SCS DL", carrier_param->supported_subcarrier_spacings_dl);
INDENTED_TLV_PRINT("Supported BW DL", carrier_param->supported_bandwidth_dl);
INDENTED_TLV_PRINT("Supported SCS UL", carrier_param->supported_subcarrier_spacings_ul);
INDENTED_TLV_PRINT("Supported BW UL", carrier_param->supported_bandwidth_ul);
/* PDCCH Param */
const nfapi_nr_pdcch_param_t *pdcch_param = &msg->pdcch_param;
INDENTED_TLV_PRINT("CCE Mapping Type", pdcch_param->cce_mapping_type);
INDENTED_TLV_PRINT("CSet Outside First 3 OFDM Symbols of Slot", pdcch_param->coreset_outside_first_3_of_ofdm_syms_of_slot);
INDENTED_TLV_PRINT("Precoder Granularity Coreset", pdcch_param->coreset_precoder_granularity_coreset);
INDENTED_TLV_PRINT("PDCCH Mu MIMO", pdcch_param->pdcch_mu_mimo);
INDENTED_TLV_PRINT("PDCCH Precoder Cycling", pdcch_param->pdcch_precoder_cycling);
INDENTED_TLV_PRINT("Max PDCCH per Slot", pdcch_param->max_pdcch_per_slot);
/* PUCHH Params */
const nfapi_nr_pucch_param_t *pucch_param = &msg->pucch_param;
INDENTED_TLV_PRINT("PUCCH Formats", pucch_param->pucch_formats);
INDENTED_TLV_PRINT("Max PUCCH per Slot", pucch_param->max_pucchs_per_slot);
/* PDSCH Params */
const nfapi_nr_pdsch_param_t *pdsch_param = &msg->pdsch_param;
INDENTED_TLV_PRINT("PDSCH Mapping Type", pdsch_param->pdsch_mapping_type);
INDENTED_TLV_PRINT("PDSCH Allocation Types", pdsch_param->pdsch_allocation_types);
INDENTED_TLV_PRINT("PDSCH VRB to PRB Mapping", pdsch_param->pdsch_vrb_to_prb_mapping);
INDENTED_TLV_PRINT("PDSCH CBG", pdsch_param->pdsch_cbg);
INDENTED_TLV_PRINT("PDSCH DMRS Config Types", pdsch_param->pdsch_dmrs_config_types);
INDENTED_TLV_PRINT("PDSCH DMRS Max Length", pdsch_param->pdsch_dmrs_max_length);
INDENTED_TLV_PRINT("PDSCH DMRS Additional Position", pdsch_param->pdsch_dmrs_additional_pos);
INDENTED_TLV_PRINT("Max PDSCH TBs per Slot", pdsch_param->max_pdsch_tbs_per_slot);
INDENTED_TLV_PRINT("Max number MIMO Layers PDSCH", pdsch_param->max_number_mimo_layers_pdsch);
INDENTED_TLV_PRINT("Supported Max Modulation Order DL", pdsch_param->supported_max_modulation_order_dl);
INDENTED_TLV_PRINT("Max Mu MIMO Users DL", pdsch_param->max_mu_mimo_users_dl);
INDENTED_TLV_PRINT("PDSCH Data in DMRS Symbols", pdsch_param->pdsch_data_in_dmrs_symbols);
INDENTED_TLV_PRINT("Preemption Support", pdsch_param->premption_support);
INDENTED_TLV_PRINT("PDSCH Non Slot Support", pdsch_param->pdsch_non_slot_support);
/* PUSCH Params */
const nfapi_nr_pusch_param_t *pusch_param = &msg->pusch_param;
INDENTED_TLV_PRINT("UCI Mux ULSCH in PUSCH", pusch_param->uci_mux_ulsch_in_pusch);
INDENTED_TLV_PRINT("UCI Only PUSCH", pusch_param->uci_only_pusch);
INDENTED_TLV_PRINT("PUSCH Frequency Hopping", pusch_param->pusch_frequency_hopping);
INDENTED_TLV_PRINT("PUSCH DMRS Config Types", pusch_param->pusch_dmrs_config_types);
INDENTED_TLV_PRINT("PUSCH DMRS Max Len", pusch_param->pusch_dmrs_max_len);
INDENTED_TLV_PRINT("PUSCH DMRS Additional Pos", pusch_param->pusch_dmrs_additional_pos);
INDENTED_TLV_PRINT("PUSCH CBG", pusch_param->pusch_cbg);
INDENTED_TLV_PRINT("PUSCH Mapping Type", pusch_param->pusch_mapping_type);
INDENTED_TLV_PRINT("PUSCH Allocation Types", pusch_param->pusch_allocation_types);
INDENTED_TLV_PRINT("PUSCH VRB to PRB Mapping", pusch_param->pusch_vrb_to_prb_mapping);
INDENTED_TLV_PRINT("PUSCH Max PTRS Ports", pusch_param->pusch_max_ptrs_ports);
INDENTED_TLV_PRINT("Max PUSCH TBs per Slot", pusch_param->max_pduschs_tbs_per_slot);
INDENTED_TLV_PRINT("Max Number MIMO Layers non CB PUSCH", pusch_param->max_number_mimo_layers_non_cb_pusch);
INDENTED_TLV_PRINT("Supported Modulation Order UL", pusch_param->supported_modulation_order_ul);
INDENTED_TLV_PRINT("Max MU MIMO Users UL", pusch_param->max_mu_mimo_users_ul);
INDENTED_TLV_PRINT("DTFS OFDM Support", pusch_param->dfts_ofdm_support);
INDENTED_TLV_PRINT("PUSCH Aggregation Factor", pusch_param->pusch_aggregation_factor);
/* PRACH Params */
const nfapi_nr_prach_param_t *prach_param = &msg->prach_param;
INDENTED_TLV_PRINT("PRACH Long Formats", prach_param->prach_long_formats);
INDENTED_TLV_PRINT("PRACH Short Formats", prach_param->prach_short_formats);
INDENTED_TLV_PRINT("PRACH Restricted Sets", prach_param->prach_restricted_sets);
INDENTED_TLV_PRINT("Max PRACH Occasions in a Slot", prach_param->max_prach_fd_occasions_in_a_slot);
/* Measurement Params */
const nfapi_nr_measurement_param_t *measurement_param = &msg->measurement_param;
INDENTED_TLV_PRINT("RSSI Measurement Support", measurement_param->rssi_measurement_support);
/* nFAPI Config */
const nfapi_nr_nfapi_t *nfapi_config = &msg->nfapi_config;
if (nfapi_config->p7_vnf_address_ipv4.tl.tag) {
char ip_str[INET_ADDRSTRLEN];
INDENTED_GENERIC_PRINT("(0x%04x) P7 VNF Address IPv4",
"%s",
nfapi_config->p7_vnf_address_ipv4.tl.tag,
inet_ntop(AF_INET, nfapi_config->p7_vnf_address_ipv4.address, ip_str, sizeof(ip_str)));
}
if (nfapi_config->p7_vnf_address_ipv6.tl.tag) {
char addr6[INET6_ADDRSTRLEN];
INDENTED_GENERIC_PRINT("(0x%04x) P7 VNF Address IPv6",
"%s",
nfapi_config->p7_vnf_address_ipv6.tl.tag,
inet_ntop(AF_INET6, nfapi_config->p7_vnf_address_ipv6.address, addr6, sizeof(addr6)));
}
INDENTED_TLV_FORMAT_PRINT("P7 VNF Port", "%d", nfapi_config->p7_vnf_port);
if (nfapi_config->p7_pnf_address_ipv4.tl.tag) {
char ip_str[INET_ADDRSTRLEN];
INDENTED_GENERIC_PRINT("(0x%04x) P7 PNF Address IPv4",
"%s",
nfapi_config->p7_pnf_address_ipv4.tl.tag,
inet_ntop(AF_INET, nfapi_config->p7_pnf_address_ipv4.address, ip_str, sizeof(ip_str)));
}
if (nfapi_config->p7_pnf_address_ipv6.tl.tag) {
char addr6[INET6_ADDRSTRLEN];
INDENTED_GENERIC_PRINT("(0x%04x) P7 PNF Address IPv6",
"%s",
nfapi_config->p7_pnf_address_ipv6.tl.tag,
inet_ntop(AF_INET6, nfapi_config->p7_pnf_address_ipv6.address, addr6, sizeof(addr6)));
}
INDENTED_TLV_FORMAT_PRINT("P7 PNF Port", "%d", nfapi_config->p7_pnf_port);
INDENTED_TLV_FORMAT_PRINT("Timing Window", "%d", nfapi_config->timing_window);
INDENTED_TLV_FORMAT_PRINT("Timing Info Mode", "%d", nfapi_config->timing_info_mode);
INDENTED_TLV_FORMAT_PRINT("Timing Info Period", "%d", nfapi_config->timing_info_period);
INDENTED_TLV_FORMAT_PRINT("DL_TTI Timing Offset", "%d", nfapi_config->dl_tti_timing_offset);
INDENTED_TLV_FORMAT_PRINT("UL_TTI Timing Offset", "%d", nfapi_config->ul_tti_timing_offset);
INDENTED_TLV_FORMAT_PRINT("UL_DCI Timing Offset", "%d", nfapi_config->ul_dci_timing_offset);
INDENTED_TLV_FORMAT_PRINT("TX_DATA Timing Offset", "%d", nfapi_config->tx_data_timing_offset);
depth--;
}
void dump_config_request(const nfapi_nr_config_request_scf_t *msg)
{
int depth = 0;
dump_p5_message_header(&msg->header,depth);
dump_p5_message_header(&msg->header, depth);
depth++;
INDENTED_PRINTF("Number of TLVs = 0x%02x\n", msg->num_tlv);
/* dump all TLVs from each table */
/* Carrier Config */
const nfapi_nr_carrier_config_t *carrier_config = &msg->carrier_config;
INDENTED_TLV_PRINT("DL Bandwidth", carrier_config->dl_bandwidth);
INDENTED_TLV_PRINT("DL Frequency", carrier_config->dl_frequency);
INDENTED_PRINTF("(0x%04x) DL K0 = ", NFAPI_NR_CONFIG_DL_K0_TAG);
for (int i = 0; i < 5; i++) {
printf("%d ", carrier_config->dl_k0[i].value);
}
printf("\n");
INDENTED_PRINTF("(0x%04x) DL Grid Size = ", NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG);
for (int i = 0; i < 5; i++) {
printf("%d ", carrier_config->dl_grid_size[i].value);
}
printf("\n");
INDENTED_TLV_PRINT("Num TX Antennas", carrier_config->num_tx_ant);
INDENTED_TLV_PRINT("UL Bandwidth", carrier_config->uplink_bandwidth);
INDENTED_TLV_PRINT("UL Frequency", carrier_config->uplink_frequency);
INDENTED_PRINTF("(0x%04x) UL K0 = ", NFAPI_NR_CONFIG_UL_K0_TAG);
for (int i = 0; i < 5; i++) {
printf("%d ", carrier_config->ul_k0[i].value);
}
printf("\n");
INDENTED_PRINTF("(0x%04x) UL Grid Size = ", NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG);
for (int i = 0; i < 5; i++) {
printf("%d ", carrier_config->ul_grid_size[i].value);
}
printf("\n");
INDENTED_TLV_PRINT("Num RX Antennas", carrier_config->num_rx_ant);
INDENTED_TLV_PRINT("Frequency Shift 7p5KHz", carrier_config->frequency_shift_7p5khz);
/* Cell Config */
const nfapi_nr_cell_config_t *cell_config = &msg->cell_config;
INDENTED_TLV_PRINT("Physical Cell ID", cell_config->phy_cell_id);
INDENTED_TLV_PRINT("Frame Duplex Type", cell_config->frame_duplex_type);
/* SSB Config */
const nfapi_nr_ssb_config_t *ssb_config = &msg->ssb_config;
INDENTED_TLV_PRINT("SSB Block Power", ssb_config->ss_pbch_power);
INDENTED_TLV_PRINT("BCH Payload", ssb_config->bch_payload);
INDENTED_TLV_PRINT("SCS Common", ssb_config->scs_common);
/* PRACH Config */
const nfapi_nr_prach_config_t *prach_config = &msg->prach_config;
INDENTED_TLV_PRINT("PRACH Sequence Length", prach_config->prach_sequence_length);
INDENTED_TLV_PRINT("PRACH Subcarrier Spacing", prach_config->prach_sub_c_spacing);
INDENTED_TLV_PRINT("Restricted Set Config", prach_config->restricted_set_config);
INDENTED_TLV_PRINT("Num PRACH FD Occasions", prach_config->num_prach_fd_occasions);
INDENTED_TLV_PRINT("PRACH Config Index", prach_config->prach_ConfigurationIndex);
depth++;
for (int i = 0; i < prach_config->num_prach_fd_occasions.value; i++) {
const nfapi_nr_num_prach_fd_occasions_t *prach_fd_occasion = &(prach_config->num_prach_fd_occasions_list[i]);
INDENTED_TLV_PRINT("PRACH Root Sequence Index", prach_fd_occasion->prach_root_sequence_index);
INDENTED_TLV_PRINT("Num Root Sequences", prach_fd_occasion->num_root_sequences);
INDENTED_TLV_PRINT("K1", prach_fd_occasion->k1);
INDENTED_TLV_PRINT("PRACH Zero CorrelationZone Config", prach_fd_occasion->prach_zero_corr_conf);
INDENTED_TLV_PRINT("Num Unused Root Sequences", prach_fd_occasion->num_unused_root_sequences);
depth++;
for (int k = 0; k < prach_fd_occasion->num_unused_root_sequences.value; k++) {
INDENTED_TLV_PRINT("Unused Root Sequence", prach_fd_occasion->unused_root_sequences_list[k]);
}
depth--;
}
depth--;
INDENTED_TLV_PRINT("SSB Per RACH", prach_config->ssb_per_rach);
INDENTED_TLV_PRINT("PRACH Multiple Carriers in a Band", prach_config->prach_multiple_carriers_in_a_band);
/* SSB Table */
const nfapi_nr_ssb_table_t *ssb_table = &msg->ssb_table;
INDENTED_TLV_PRINT("SSB Offset PointA", ssb_table->ssb_offset_point_a);
INDENTED_TLV_PRINT("Beta PSS", ssb_table->beta_pss);
INDENTED_TLV_PRINT("SSB Period", ssb_table->ssb_period);
INDENTED_TLV_PRINT("SSB Subcarrier Offset", ssb_table->ssb_subcarrier_offset);
INDENTED_TLV_PRINT("MIB", ssb_table->MIB);
INDENTED_PRINTF("SSB Mask:\n");
depth++;
for (int i = 0; i < 2; i++) {
INDENTED_TLV_PRINT("SSB Mask", ssb_table->ssb_mask_list[i].ssb_mask);
}
depth--;
INDENTED_PRINTF("Beam ID:\n");
depth++;
for (int i = 0; i < 64; i++) {
INDENTED_TLV_PRINT("Beam ID", ssb_table->ssb_beam_id_list[i].beam_id);
}
depth--;
INDENTED_TLV_PRINT("ssPBCH Multiple Carriers in a Band", ssb_table->ss_pbch_multiple_carriers_in_a_band);
INDENTED_TLV_PRINT("Multiple Cells ssPBCH in a Carrier", ssb_table->multiple_cells_ss_pbch_in_a_carrier);
/* TDD Table */
const nfapi_nr_tdd_table_t *tdd_table = &msg->tdd_table;
if (cell_config->frame_duplex_type.value == 1 /* TDD */) {
INDENTED_TLV_PRINT("TDD Period", tdd_table->tdd_period);
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
uint8_t cyclicprefix = 1;
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
INDENTED_PRINTF("Slot Config:\n");
depth++;
for (int i = 0; i < slotsperframe[ssb_config->scs_common.value]; i++) {
for (int k = 0; k < number_of_symbols_per_slot; k++) {
const uint8_t slot_type = tdd_table->max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config.value;
const char *slot_dir = slot_type == 0 ? "DL" : slot_type == 1 ? "UL" : "S";
INDENTED_GENERIC_PRINT("(0x%04x) Slot Config",
"%d (%s)",
tdd_table->max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config.tl.tag,
slot_type,
slot_dir);
}
}
depth--;
}
/* Measurement Config */
const nfapi_nr_measurement_config_t *measurement_config = &msg->measurement_config;
INDENTED_TLV_PRINT("RSSI Measurement", measurement_config->rssi_measurement);
/* Beamforming Table */
const nfapi_nr_dbt_pdu_t *dbt_config = &msg->dbt_config;
INDENTED_PRINTF("Digital Beam Table\n");
depth++;
INDENTED_GENERIC_PRINT("Num Digital Beams", "%d", dbt_config->num_dig_beams);
INDENTED_GENERIC_PRINT("Num TX RUs", "%d", dbt_config->num_txrus);
depth++;
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];
INDENTED_GENERIC_PRINT("Beam IDX", "%d", dig_beam->beam_idx);
depth++;
for (int k = 0; k < dbt_config->num_txrus; k++) {
const nfapi_nr_txru_t *tx_ru = &dig_beam->txru_list[k];
INDENTED_GENERIC_PRINT("Dig Beam Weight Real", "0x%02x", tx_ru->dig_beam_weight_Re);
INDENTED_GENERIC_PRINT("Dig Beam Weight Imaginary", "0x%02x", tx_ru->dig_beam_weight_Im);
}
depth--;
}
depth--;
depth--;
/* Precoding Table */
const nfapi_nr_pm_list_t *pmi_list = &msg->pmi_list;
INDENTED_PRINTF("Precoding Matrix Table\n");
depth++;
INDENTED_GENERIC_PRINT("Num Precoding Tables", "%d", pmi_list->num_pm_idx);
depth++;
for (int i = 0; i < pmi_list->num_pm_idx; i++) {
const nfapi_nr_pm_pdu_t *pm_pdu = &pmi_list->pmi_pdu[i];
INDENTED_GENERIC_PRINT("Precoding Matrix IDX", "0x%02x", pm_pdu->pm_idx);
INDENTED_GENERIC_PRINT("Number of Layers", "%d", pm_pdu->numLayers);
INDENTED_GENERIC_PRINT("Number of Antenna Ports", "%d", pm_pdu->num_ant_ports);
depth++;
for (int k = 0; k < pm_pdu->numLayers; k++) {
for (int l = 0; l < pm_pdu->num_ant_ports; l++) {
const nfapi_nr_pm_weights_t *pm_weights = &pm_pdu->weights[k][l];
INDENTED_GENERIC_PRINT("Dig Beam Weight Real", "0x%02x", pm_weights->precoder_weight_Re);
INDENTED_GENERIC_PRINT("Dig Beam Weight Imaginary", "0x%02x", pm_weights->precoder_weight_Im);
}
}
depth--;
}
depth--;
depth--;
/* nFAPI Config */
const nfapi_nr_nfapi_t *nfapi_config = &msg->nfapi_config;
if (nfapi_config->p7_vnf_address_ipv4.tl.tag) {
char ip_str[INET_ADDRSTRLEN];
INDENTED_GENERIC_PRINT("(0x%04x) P7 VNF Address IPv4",
"%s",
nfapi_config->p7_vnf_address_ipv4.tl.tag,
inet_ntop(AF_INET, nfapi_config->p7_vnf_address_ipv4.address, ip_str, sizeof(ip_str)));
}
if (nfapi_config->p7_vnf_address_ipv6.tl.tag) {
char addr6[INET6_ADDRSTRLEN];
INDENTED_GENERIC_PRINT("(0x%04x) P7 VNF Address IPv6",
"%s",
nfapi_config->p7_vnf_address_ipv6.tl.tag,
inet_ntop(AF_INET6, nfapi_config->p7_vnf_address_ipv6.address, addr6, sizeof(addr6)));
}
INDENTED_TLV_FORMAT_PRINT("P7 VNF Port", "%d", nfapi_config->p7_vnf_port);
if (nfapi_config->p7_pnf_address_ipv4.tl.tag) {
char ip_str[INET_ADDRSTRLEN];
INDENTED_GENERIC_PRINT("(0x%04x) P7 PNF Address IPv4",
"%s",
nfapi_config->p7_pnf_address_ipv4.tl.tag,
inet_ntop(AF_INET, nfapi_config->p7_pnf_address_ipv4.address, ip_str, sizeof(ip_str)));
}
if (nfapi_config->p7_pnf_address_ipv6.tl.tag) {
char addr6[INET6_ADDRSTRLEN];
INDENTED_GENERIC_PRINT("(0x%04x) P7 PNF Address IPv6",
"%s",
nfapi_config->p7_pnf_address_ipv6.tl.tag,
inet_ntop(AF_INET6, nfapi_config->p7_pnf_address_ipv6.address, addr6, sizeof(addr6)));
}
INDENTED_TLV_FORMAT_PRINT("P7 PNF Port", "%d", nfapi_config->p7_pnf_port);
INDENTED_TLV_FORMAT_PRINT("Timing Window", "%d", nfapi_config->timing_window);
INDENTED_TLV_FORMAT_PRINT("Timing Info Mode", "%d", nfapi_config->timing_info_mode);
INDENTED_TLV_FORMAT_PRINT("Timing Info Period", "%d", nfapi_config->timing_info_period);
INDENTED_TLV_FORMAT_PRINT("DL_TTI Timing Offset", "%d", nfapi_config->dl_tti_timing_offset);
INDENTED_TLV_FORMAT_PRINT("UL_TTI Timing Offset", "%d", nfapi_config->ul_tti_timing_offset);
INDENTED_TLV_FORMAT_PRINT("UL_DCI Timing Offset", "%d", nfapi_config->ul_dci_timing_offset);
INDENTED_TLV_FORMAT_PRINT("TX_DATA Timing Offset", "%d", nfapi_config->tx_data_timing_offset);
/* Beamforming VE */
const nfapi_nr_analog_beamforming_ve_t *analog_beamforming_ve = &msg->analog_beamforming_ve;
INDENTED_TLV_FORMAT_PRINT("Num Beams per Period", "%d", analog_beamforming_ve->num_beams_period_vendor_ext);
INDENTED_TLV_PRINT("Analog Beamforming VE", analog_beamforming_ve->analog_bf_vendor_ext);
/* Vendor Extension */
if (msg->vendor_extension) {
const nfapi_tl_t *vendor_extension = (nfapi_tl_t *)&msg->vendor_extension;
switch (vendor_extension->tag) {
case VENDOR_EXT_TLV_1_TAG: {
vendor_ext_tlv_1 *ve = (vendor_ext_tlv_1 *)vendor_extension;
INDENTED_PRINTF("(0x%04x) Vendor extension = %d 0x%02x\n", ve->tl.tag, ve->tl.length, ve->dummy);
} break;
case VENDOR_EXT_TLV_2_TAG: {
vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)vendor_extension;
INDENTED_PRINTF("(0x%04x) Vendor extension = %d 0x%02x\n", ve->tl.tag, ve->tl.length, ve->dummy);
} break;
default:
break;
}
}
depth--;
}
static void dump_generic_tlv(const nfapi_nr_generic_tlv_scf_t* tlv, int depth)
{
INDENTED_PRINTF("TLV tag 0x%02x , Length 0x%02x , Value ", tlv->tl.tag, tlv->tl.length);
switch (tlv->tl.length) {
case UINT_8:
printf("0x%x\n", tlv->value.u8);
break;
case UINT_16:
printf("0x%02x\n", tlv->value.u16);
break;
case UINT_32:
printf("0x%04x\n", tlv->value.u32);
break;
case ARRAY_UINT_16:
for (int i = 0; i< 5 ; i++) {
printf("0x%04x ", tlv->value.array_u16[i]);
}
printf("\n");
break;
default:
printf("unknown length %d\n", tlv->tl.length);
DevAssert(1 == 0);
break;
}
}
void dump_config_response(const nfapi_nr_config_response_scf_t *msg)
@@ -1016,6 +1423,25 @@ void dump_config_response(const nfapi_nr_config_response_scf_t *msg)
msg->num_invalid_tlvs_configured_in_running);
INDENTED_PRINTF("Number of Missing TLVs = 0x%02x\n", msg->num_missing_tlvs);
/* dump all TLVs from each table */
INDENTED_PRINTF("Invalid or Unsupported TLVs (%d) :\n",msg->num_invalid_tlvs);
for (int i = 0; i < msg->num_invalid_tlvs; ++i) {
dump_generic_tlv(&msg->invalid_tlvs_list[i], depth+1);
}
INDENTED_PRINTF("TLVs that can only be configured in IDLE (%d):\n", msg->num_invalid_tlvs_configured_in_idle);
for (int i = 0; i < msg->num_invalid_tlvs; ++i) {
dump_generic_tlv(&msg->invalid_tlvs_list[i], depth+1);
}
INDENTED_PRINTF("TLVs that can only be configured in RUNNING (%d):\n",msg->num_invalid_tlvs_configured_in_running);
for (int i = 0; i < msg->num_invalid_tlvs; ++i) {
dump_generic_tlv(&msg->invalid_tlvs_list[i], depth+1);
}
INDENTED_PRINTF("Missing TLVs (%d):\n",msg->num_missing_tlvs);
for (int i = 0; i < msg->num_invalid_tlvs; ++i) {
dump_generic_tlv(&msg->invalid_tlvs_list[i], depth+1);
}
depth--;
}
+220 -82
View File
@@ -859,9 +859,7 @@ bool eq_rach_indication(const nfapi_nr_rach_indication_t *a, const nfapi_nr_rach
void free_dl_tti_request(nfapi_nr_dl_tti_request_t *msg)
{
if (msg->vendor_extension) {
free(msg->vendor_extension);
}
free(msg->vendor_extension);
}
void free_ul_tti_request(nfapi_nr_ul_tti_request_t *msg)
@@ -907,9 +905,7 @@ void free_rx_data_indication(nfapi_nr_rx_data_indication_t *msg)
if (msg->number_of_pdus > 0) {
for (int pdu_idx = 0; pdu_idx < msg->number_of_pdus; ++pdu_idx) {
nfapi_nr_rx_data_pdu_t *rx_pdu = &msg->pdu_list[pdu_idx];
if (rx_pdu->pdu) {
free(rx_pdu->pdu);
}
free(rx_pdu->pdu);
}
free(msg->pdu_list);
}
@@ -917,99 +913,75 @@ void free_rx_data_indication(nfapi_nr_rx_data_indication_t *msg)
void free_crc_indication(nfapi_nr_crc_indication_t *msg)
{
if (msg->crc_list) {
for (int crc_idx = 0; crc_idx < msg->number_crcs; ++crc_idx) {
nfapi_nr_crc_t *crc = &msg->crc_list[crc_idx];
if (crc->cb_crc_status) {
free(crc->cb_crc_status);
}
}
free(msg->crc_list);
for (int crc_idx = 0; crc_idx < msg->number_crcs; ++crc_idx) {
nfapi_nr_crc_t *crc = &msg->crc_list[crc_idx];
free(crc->cb_crc_status);
}
free(msg->crc_list);
}
void free_uci_indication(nfapi_nr_uci_indication_t *msg)
{
if (msg->uci_list) {
for (int pdu_idx = 0; pdu_idx < msg->num_ucis; ++pdu_idx) {
nfapi_nr_uci_t *uci_pdu = &msg->uci_list[pdu_idx];
switch (uci_pdu->pdu_type) {
case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
nfapi_nr_uci_pusch_pdu_t *pdu = &uci_pdu->pusch_pdu;
// Bit 0 not used in PUSCH PDU
// HARQ
if ((pdu->pduBitmap >> 1) & 0x01) {
if (pdu->harq.harq_payload) {
free(pdu->harq.harq_payload);
}
}
// CSI Part 1
if ((pdu->pduBitmap >> 2) & 0x01) {
if (pdu->csi_part1.csi_part1_payload) {
free(pdu->csi_part1.csi_part1_payload);
}
}
// CSI Part 2
if ((pdu->pduBitmap >> 3) & 0x01) {
if (pdu->csi_part2.csi_part2_payload) {
free(pdu->csi_part2.csi_part2_payload);
}
}
break;
for (int pdu_idx = 0; pdu_idx < msg->num_ucis; ++pdu_idx) {
nfapi_nr_uci_t *uci_pdu = &msg->uci_list[pdu_idx];
switch (uci_pdu->pdu_type) {
case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
nfapi_nr_uci_pusch_pdu_t *pdu = &uci_pdu->pusch_pdu;
// Bit 0 not used in PUSCH PDU
// HARQ
if ((pdu->pduBitmap >> 1) & 0x01) {
free(pdu->harq.harq_payload);
}
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
// Nothing to free
break;
// CSI Part 1
if ((pdu->pduBitmap >> 2) & 0x01) {
free(pdu->csi_part1.csi_part1_payload);
}
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu = &uci_pdu->pucch_pdu_format_2_3_4;
// SR
if (pdu->pduBitmap & 0x01) {
if (pdu->sr.sr_payload) {
free(pdu->sr.sr_payload);
}
}
// HARQ
if ((pdu->pduBitmap >> 1) & 0x01) {
if (pdu->harq.harq_payload) {
free(pdu->harq.harq_payload);
}
}
// CSI Part 1
if ((pdu->pduBitmap >> 2) & 0x01) {
if (pdu->csi_part1.csi_part1_payload) {
free(pdu->csi_part1.csi_part1_payload);
}
}
// CSI Part 2
if ((pdu->pduBitmap >> 3) & 0x01) {
if (pdu->csi_part2.csi_part2_payload) {
free(pdu->csi_part2.csi_part2_payload);
}
}
break;
// CSI Part 2
if ((pdu->pduBitmap >> 3) & 0x01) {
free(pdu->csi_part2.csi_part2_payload);
}
default:
AssertFatal(1 == 0, "Unknown UCI.indication PDU Type %d\n", uci_pdu->pdu_type);
break;
break;
}
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
// Nothing to free
break;
}
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu = &uci_pdu->pucch_pdu_format_2_3_4;
// SR
if (pdu->pduBitmap & 0x01) {
free(pdu->sr.sr_payload);
}
// HARQ
if ((pdu->pduBitmap >> 1) & 0x01) {
free(pdu->harq.harq_payload);
}
// CSI Part 1
if ((pdu->pduBitmap >> 2) & 0x01) {
free(pdu->csi_part1.csi_part1_payload);
}
// CSI Part 2
if ((pdu->pduBitmap >> 3) & 0x01) {
free(pdu->csi_part2.csi_part2_payload);
}
break;
}
default:
AssertFatal(1 == 0, "Unknown UCI.indication PDU Type %d\n", uci_pdu->pdu_type);
break;
}
free(msg->uci_list);
}
free(msg->uci_list);
}
void free_srs_indication(nfapi_nr_srs_indication_t *msg)
{
if (msg->pdu_list) {
free(msg->pdu_list);
}
free(msg->pdu_list);
}
void free_rach_indication(nfapi_nr_rach_indication_t *msg)
{
if (msg->pdu_list) {
free(msg->pdu_list);
}
free(msg->pdu_list);
}
static void copy_dl_tti_beamforming(const nfapi_nr_tx_precoding_and_beamforming_t *src,
@@ -2586,6 +2558,27 @@ void dump_ul_dci_request(const nfapi_nr_ul_dci_request_t *msg)
}
}
static void dump_tx_data_request_tlv(const nfapi_nr_tx_data_request_tlv_t *tlv, int depth)
{
INDENTED_PRINTF("Tag = %d\n", tlv->tag);
INDENTED_PRINTF("Length = %d\n", tlv->length);
INDENTED_PRINTF("Value = ");
switch (tlv->tag) {
case 0:
for (int i = 0; i < tlv->length; i++) {
printf("0x%02x ", ((uint8_t*)tlv->value.direct)[i]);
}
break;
case 1:
printf("%p", tlv->value.ptr);
break;
default:
printf( " Unknown tag value %d",tlv->tag);
break;
}
printf("\n");
}
void dump_tx_data_request(const nfapi_nr_tx_data_request_t *msg)
{
int depth = 0;
@@ -2594,15 +2587,18 @@ void dump_tx_data_request(const nfapi_nr_tx_data_request_t *msg)
INDENTED_PRINTF("SFN = %d\n", msg->SFN);
INDENTED_PRINTF("Slot = %d\n", msg->Slot);
INDENTED_PRINTF("Number of PDUs = %d\n", msg->Number_of_PDUs);
depth++;
for (int i = 0; i < msg->Number_of_PDUs; i++) {
depth++;
INDENTED_PRINTF("PDU #%d\n", i);
const nfapi_nr_pdu_t *pdu = &msg->pdu_list[i];
INDENTED_PRINTF("PDU Length = 0x%02x\n", pdu->PDU_length);
INDENTED_PRINTF("PDU Index = 0x%02x\n", pdu->PDU_index);
INDENTED_PRINTF("numTLV = 0x%02x\n", pdu->num_TLV);
for (int tlv_idx = 0; tlv_idx < pdu->num_TLV; tlv_idx++) {
const nfapi_nr_tx_data_request_tlv_t *tlv = &pdu->TLVs[tlv_idx];
/* call to dump_tx_data_request_tlv */
depth--;
dump_tx_data_request_tlv(tlv, depth + 1);
}
}
}
@@ -2664,6 +2660,134 @@ void dump_crc_indication(const nfapi_nr_crc_indication_t *msg)
}
}
static void dump_harq_2_3_4(const nfapi_nr_harq_pdu_2_3_4_t *harq, int depth)
{
INDENTED_PRINTF("HARQ CRC = %01x\n", harq->harq_crc);
INDENTED_PRINTF("HARQ Bit Length = %d\n", harq->harq_bit_len);
INDENTED_PRINTF("HARQ Payload = ");
for (int i = 0; i < harq->harq_bit_len / 8 + 1; i++) {
printf("%x ", harq->harq_payload[i]);
}
printf("\n");
}
static void dump_csi_part_1(const nfapi_nr_csi_part1_pdu_t *csi, int depth)
{
INDENTED_PRINTF("CSI Part 1 CRC = %01x\n", csi->csi_part1_crc);
INDENTED_PRINTF("CSI Part 1 Bit Length = %d\n", csi->csi_part1_bit_len);
INDENTED_PRINTF("CSI Part 1 Payload = ");
for (int i = 0; i < csi->csi_part1_bit_len / 8 + 1; i++) {
printf("%x ", csi->csi_part1_payload[i]);
}
printf("\n");
}
static void dump_csi_part_2(const nfapi_nr_csi_part2_pdu_t *csi, int depth)
{
INDENTED_PRINTF("CSI Part 1 CRC = %01x\n", csi->csi_part2_crc);
INDENTED_PRINTF("CSI Part 1 Bit Length = %d\n", csi->csi_part2_bit_len);
INDENTED_PRINTF("CSI Part 1 Payload = ");
for (int i = 0; i < csi->csi_part2_bit_len / 8 + 1; i++) {
printf("%x ", csi->csi_part2_payload[i]);
}
printf("\n");
}
static void dump_uci_PUSCH_PDU(const nfapi_nr_uci_pusch_pdu_t *pdu, int depth)
{
INDENTED_PRINTF("PDU Bitmap = 0x%01x\n", pdu->pduBitmap);
INDENTED_PRINTF("Handle = 0x%04x\n", pdu->handle);
INDENTED_PRINTF("RNTI = 0x%02x\n", pdu->rnti);
INDENTED_PRINTF("UL_CQI = 0x%02x\n", pdu->ul_cqi);
INDENTED_PRINTF("Timing Advance = 0x%02x\n", pdu->timing_advance);
INDENTED_PRINTF("RSSI = 0x%02x\n", pdu->rssi);
// HARQ payload, CSI Part 1 and 2 are conditionally allocated
if ((pdu->pduBitmap >> 1) & 0x01) {
INDENTED_PRINTF("HARQ Information\n");
dump_harq_2_3_4(&pdu->harq, depth + 1);
}
if ((pdu->pduBitmap >> 2) & 0x01) {
INDENTED_PRINTF("CSI Part 1\n");
dump_csi_part_1(&pdu->csi_part1, depth + 1);
}
if ((pdu->pduBitmap >> 3) & 0x01) {
INDENTED_PRINTF("CSI Part 1\n");
dump_csi_part_2(&pdu->csi_part2, depth + 1);
}
}
static void dump_sr_0_1(const nfapi_nr_sr_pdu_0_1_t *sr, int depth)
{
INDENTED_PRINTF("SR Indication = 0x%02x\n", sr->sr_indication);
INDENTED_PRINTF("SR Confidence Level = 0x%02x\n", sr->sr_confidence_level);
}
static void dump_harq_0_1(const nfapi_nr_harq_pdu_0_1_t *harq, int depth)
{
INDENTED_PRINTF("Num HARQ = 0x%02x\n", harq->num_harq);
INDENTED_PRINTF("HARQ Confidence Level = 0x%02x\n", harq->harq_confidence_level);
depth++;
for (int i = 0; i < harq->num_harq; i++) {
INDENTED_PRINTF("HARQ Value[%d] : 0x%02x \n", i, harq->harq_list[i].harq_value);
}
}
static void dump_uci_PUCCH_0_1(const nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu, int depth)
{
INDENTED_PRINTF("PDU Bitmap = 0x%01x\n", pdu->pduBitmap);
INDENTED_PRINTF("Handle = 0x%04x\n", pdu->handle);
INDENTED_PRINTF("RNTI = 0x%02x\n", pdu->rnti);
INDENTED_PRINTF("PUCCH Format = 0x%02x\n", pdu->pucch_format);
INDENTED_PRINTF("UL_CQI = 0x%02x\n", pdu->ul_cqi);
INDENTED_PRINTF("Timing Advance = 0x%02x\n", pdu->timing_advance);
INDENTED_PRINTF("RSSI = 0x%02x\n", pdu->rssi);
if ((pdu->pduBitmap) & 0x01) {
INDENTED_PRINTF("SR Information\n");
dump_sr_0_1(&pdu->sr, depth + 1);
}
if ((pdu->pduBitmap >> 1) & 0x01) {
INDENTED_PRINTF("HARQ Information\n");
dump_harq_0_1(&pdu->harq, depth + 1);
}
}
static void dump_sr_2_3_4(const nfapi_nr_sr_pdu_2_3_4_t *sr, int depth)
{
INDENTED_PRINTF("SR Bit Length = %d\n", sr->sr_bit_len);
INDENTED_PRINTF("SR Payload ");
for (int i = 0; i < sr->sr_bit_len / 8 + 1; i++) {
printf("%x ", sr->sr_payload[i]);
}
printf("\n");
}
static void dump_uci_PUCCH_2_3_4(const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu, int depth)
{
INDENTED_PRINTF("PDU Bitmap = 0x%01x\n", pdu->pduBitmap);
INDENTED_PRINTF("Handle = 0x%04x\n", pdu->handle);
INDENTED_PRINTF("RNTI = 0x%02x\n", pdu->rnti);
INDENTED_PRINTF("PUCCH Format = 0x%02x\n", pdu->pucch_format);
INDENTED_PRINTF("UL_CQI = 0x%02x\n", pdu->ul_cqi);
INDENTED_PRINTF("Timing Advance = 0x%02x\n", pdu->timing_advance);
INDENTED_PRINTF("RSSI = 0x%02x\n", pdu->rssi);
// SR
if (pdu->pduBitmap & 0x01) {
dump_sr_2_3_4(&pdu->sr, depth + 1);
}
// HARQ
if ((pdu->pduBitmap >> 1) & 0x01) {
dump_harq_2_3_4(&pdu->harq, depth + 1);
}
// CSI Part 1
if ((pdu->pduBitmap >> 2) & 0x01) {
dump_csi_part_1(&pdu->csi_part1, depth + 1);
}
// CSI Part 2
if ((pdu->pduBitmap >> 3) & 0x01) {
dump_csi_part_2(&pdu->csi_part2, depth + 1);
}
}
void dump_uci_indication(const nfapi_nr_uci_indication_t *msg)
{
int depth = 0;
@@ -2680,6 +2804,20 @@ void dump_uci_indication(const nfapi_nr_uci_indication_t *msg)
INDENTED_PRINTF("PDUType = 0x%02x\n", uci->pdu_type);
INDENTED_PRINTF("PDUSize = 0x%02x\n", uci->pdu_size);
/* call to dump_uci_indication_<PDU_Type>_pdu */
switch (uci->pdu_type) {
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
dump_uci_PUSCH_PDU(&uci->pusch_pdu, depth + 1);
break;
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
dump_uci_PUCCH_0_1(&uci->pucch_pdu_format_0_1, depth + 1);
break;
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
dump_uci_PUCCH_2_3_4(&uci->pucch_pdu_format_2_3_4, depth + 1);
break;
default:
INDENTED_PRINTF("Unknown PDU type 0x%02x\n", uci->pdu_type);
break;
}
depth--;
}
}
@@ -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,8 @@ 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 )
#define NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG 0x104B // This tag was added in version 6 of the SCF222 standard ( Table 3-52 of SCF222.10.06 )
//table 3-21
typedef struct
@@ -473,6 +475,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;
@@ -491,7 +498,12 @@ typedef struct {
typedef struct {
uint16_t num_pm_idx;
nfapi_nr_pm_pdu_t *pmi_pdu;
} nfapi_nr_pm_list_t;
} nfapi_nr_pm_list_t; // This corresponds to Table 3-69 of SCF222.10.06, which introduces the num_pm_idx parameter
typedef struct {
nfapi_tl_t tl;
nfapi_nr_pm_list_t value;
} nfapi_nr_pm_tlv_ve_t;
typedef struct {
nfapi_uint8_tlv_t num_beams_period_vendor_ext;
@@ -206,6 +206,47 @@ 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_nr_pm_list_t *pm_list = &nfapi_resp->pmi_list;
const uint16_t num_layers = rand16_range(1, 4);
const uint16_t num_ant_ports = rand16_range(1, 4);
pm_list->num_pm_idx = rand16_range(1, 4);
if (nfapi_resp->pmi_list.num_pm_idx > 0) {
pm_list->pmi_pdu = calloc(pm_list->num_pm_idx, sizeof(*pm_list->pmi_pdu));
for (int i = 0; i < pm_list->num_pm_idx; i++) {
nfapi_nr_pm_pdu_t *pmi_pdu = &pm_list->pmi_pdu[i];
pmi_pdu->pm_idx = i+1;
pmi_pdu->numLayers = num_layers;
pmi_pdu->num_ant_ports = num_ant_ports;
for (int j = 0; j < num_layers; j++) {
for (int k = 0; k < num_ant_ports; k++) {
nfapi_nr_pm_weights_t* pm_weight = &pmi_pdu->weights[j][k];
pm_weight->precoder_weight_Re = (int16_t)rand16_range(1, 0xffff);
pm_weight->precoder_weight_Im = (int16_t)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();
@@ -221,6 +262,21 @@ static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfap
FILL_TLV(nfapi_resp->nfapi_config.p7_vnf_port, NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, rand16());
nfapi_resp->num_tlv++;
nfapi_resp->nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG;
for (int i = 0; i < NFAPI_IPV4_ADDRESS_LENGTH; ++i) {
nfapi_resp->nfapi_config.p7_pnf_address_ipv4.address[i] = rand8();
}
nfapi_resp->num_tlv++;
nfapi_resp->nfapi_config.p7_pnf_address_ipv6.tl.tag = NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG;
for (int i = 0; i < NFAPI_IPV6_ADDRESS_LENGTH; ++i) {
nfapi_resp->nfapi_config.p7_pnf_address_ipv6.address[i] = rand8();
}
nfapi_resp->num_tlv++;
FILL_TLV(nfapi_resp->nfapi_config.p7_pnf_port, NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, rand16());
nfapi_resp->num_tlv++;
FILL_TLV(nfapi_resp->nfapi_config.timing_window, NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, rand8());
nfapi_resp->num_tlv++;