Files
openairinterface5g/nfapi/open-nFAPI/utils/nfapi_hex_parser.c

278 lines
8.9 KiB
C

/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "nr_fapi.h"
#include "nr_fapi_p5.h"
#include "nr_fapi_p5_utils.h"
#include "nr_fapi_p7.h"
#include "nr_fapi_p7_utils.h"
#define MAX_BUFFER_SIZE (1024 * 1024 * 2)
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
UNUSED(assert);
if (s != NULL) {
printf("%s:%d %s() Exiting OAI (n)FAPI Hex Parser: %s\n", file, line, function, s);
}
abort();
}
char *message_id_to_str(uint32_t message_id)
{
switch (message_id) {
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
return "NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST";
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
return "NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE";
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
return "NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST";
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
return "NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE";
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
return "NFAPI_NR_PHY_MSG_TYPE_START_REQUEST";
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
return "NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE";
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
return "NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST";
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION:
return "NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION";
case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION:
return "NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION";
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
return "NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST";
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
return "NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST";
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
return "NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION";
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
return "NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST";
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
return "NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST";
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
return "NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION";
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
return "NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION";
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
return "NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION";
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
return "NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION";
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
return "NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION";
default:
return "UNKNOWN PHY MSG TYPE";
}
}
void unpack_and_dump_message(void *buf, fapi_message_header_t hdr)
{
void *unpacked_req = calloc(1,MAX_BUFFER_SIZE);
AssertFatal(unpacked_req != NULL, "malloc failed");
if (hdr.message_id >= NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST && hdr.message_id <= NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION) {
const int ret = fapi_nr_p5_message_unpack(buf, hdr.message_length + NFAPI_HEADER_LENGTH, unpacked_req, MAX_BUFFER_SIZE, 0);
DevAssert(ret >= 0);
} else if (hdr.message_id >= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST && hdr.message_id <= NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION) {
const int ret = fapi_nr_p7_message_unpack(buf, hdr.message_length + NFAPI_HEADER_LENGTH, unpacked_req, MAX_BUFFER_SIZE, 0);
DevAssert(ret >= 0);
}
switch (hdr.message_id) {
/* P5 messages */
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST: {
dump_param_request(unpacked_req);
free_param_request(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE: {
dump_param_response(unpacked_req);
free_param_response(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST: {
dump_config_request(unpacked_req);
free_config_request(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: {
dump_config_response(unpacked_req);
free_config_response(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST: {
dump_start_request(unpacked_req);
free_start_request(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE: {
dump_start_response(unpacked_req);
free_start_response(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST: {
dump_stop_request(unpacked_req);
free_stop_request(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION: {
dump_stop_indication(unpacked_req);
free_stop_indication(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION: {
dump_error_indication(unpacked_req);
free_error_indication(unpacked_req);
return;
}
/* P7 messages */
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: {
dump_dl_tti_request(unpacked_req);
free_dl_tti_request(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: {
dump_ul_tti_request(unpacked_req);
free_ul_tti_request(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: {
dump_slot_indication(unpacked_req);
free_slot_indication(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: {
dump_ul_dci_request(unpacked_req);
free_ul_dci_request(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: {
dump_tx_data_request(unpacked_req);
free_tx_data_request(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: {
dump_rx_data_indication(unpacked_req);
free_rx_data_indication(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: {
dump_crc_indication(unpacked_req);
free_crc_indication(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: {
dump_uci_indication(unpacked_req);
free_crc_indication(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: {
dump_srs_indication(unpacked_req);
free_srs_indication(unpacked_req);
return;
}
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: {
dump_rach_indication(unpacked_req);
free_rach_indication(unpacked_req);
return;
}
default:
printf("Unknown Msg ID 0x%02x\n", hdr.message_id);
}
free(unpacked_req);
}
static uint8_t to_hex(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
printf("found invalid char %c\n", c);
return 0xff;
}
/* @brief decodes one byte in text representation (0xab or just ab) of s and places it in b
* @return the number of bytes read, or -1 on error */
static int parse_byte(const char *s, uint8_t *b)
{
if (!s)
return -1;
int c = 0;
// skip any whitespaces
while (s[0] && isspace(*s)) {
c++;
s++;
}
// end of string -> nothing to be read
if (s[0] == 0)
return -1;
// jump over leading "0x"
if (s[0] == '0' && s[1] == 'x') {
c += 2;
s += 2;
}
// only one digit, if s[1] has other garbage, it will be caught after
if (s[1] == 0 || s[1] == ' ') {
// only one digit
*b = to_hex(s[0]);
// check if valid
return *b != 0xff ? c + 1 : -1;
}
// read both bytes, check if valid
uint8_t hb = to_hex(s[0]);
uint8_t lb = to_hex(s[1]);
if (hb == 0xff || lb == 0xff)
return -1;
*b = ((hb & 0xf) << 4) | (lb & 0xf);
return c + 2;
}
int main(int argc, char *argv[])
{
// Check if there are enough arguments
if (argc < 2) {
printf("Usage: %s [0xNN 0xNN ... | NN NN ... ]\n", argv[0]);
return 1;
}
uint8_t hex_values[MAX_BUFFER_SIZE]; // Array to hold the parsed values, assuming max 1024 values
int byte_count = 0;
for (int i = 1; i < argc; ++i) {
const char *l = argv[i];
int ret;
do {
ret = parse_byte(l, &hex_values[byte_count]);
if (ret > 0)
byte_count++;
l += ret;
} while (ret > 0 && byte_count < MAX_BUFFER_SIZE);
}
// Print the converted values
printf("Parsed %d bytes:\n", byte_count);
for (int i = 0; i < byte_count; i++) {
if (i % 16 == 0 && i != 0) {
printf("\n"); // Start a new line every 16 bytes
} else if (i % 8 == 0 && i % 16 != 0) {
printf(" "); // Add extra space between 8-byte sections
}
printf("%02x ", hex_values[i]);
}
printf("\n");
AssertFatal(byte_count >= sizeof(fapi_message_header_t), "Read byte amount not enough to encode the header. Should have a minimum of %lu bytes, aborting...", sizeof(fapi_message_header_t));
uint8_t *ptr = hex_values; // Points to the first element of the array
fapi_message_header_t hdr = {.num_msg = 0, .opaque_handle = 0, .message_id = 0, .message_length = 0};
fapi_nr_message_header_unpack(ptr, NFAPI_HEADER_LENGTH, &hdr, sizeof(fapi_message_header_t), 0);
printf("Decoded message %s message length 0x%02x\n", message_id_to_str(hdr.message_id), hdr.message_length);
// Unpack the message
unpack_and_dump_message((uint8_t *)hex_values, hdr);
return 0;
}