dat parsing
unknown
plain_text
a year ago
17 kB
36
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/stat.h>
#include "share/l1_api.h"
#include "config.h"
// Function declarations
int deserializeL1ConfigRequest(const char* filePath, L1ConfigRequest_t* config);
int printL1ConfigToFile(const L1ConfigRequest_t* config, const char* outputPath);
/**
* @brief Deserializes L1ConfigRequest_t from binary data file
*
* This function properly parses the .dat file and creates the structure that
* ConfigReqParams expects. The key insight is that the .dat file already contains
* data in the exact format that ConfigReqParams produces, so we need to treat
* the payload as the input to ConfigReqParams in reverse.
*
* @param filePath Path to the .dat file
* @param config Pointer to L1ConfigRequest_t structure to fill
* @return 0 on success, -1 on error
*/
int deserializeL1ConfigRequest(const char* filePath, L1ConfigRequest_t* config) {
FILE* file;
struct stat st;
uint8_t* buffer;
size_t fileSize;
if (!filePath || !config) {
printf("ERROR: Invalid parameters\n");
return -1;
}
// Open binary file
file = fopen(filePath, "rb");
if (!file) {
printf("ERROR: Cannot open file %s\n", filePath);
return -1;
}
// Get file size
if (stat(filePath, &st) != 0) {
printf("ERROR: Cannot get file size\n");
fclose(file);
return -1;
}
fileSize = st.st_size;
// Allocate buffer for entire file
buffer = (uint8_t*)malloc(fileSize);
if (!buffer) {
printf("ERROR: Memory allocation failed\n");
fclose(file);
return -1;
}
// Read entire file
if (fread(buffer, 1, fileSize, file) != fileSize) {
printf("ERROR: Failed to read file\n");
free(buffer);
fclose(file);
return -1;
}
fclose(file);
printf("INFO: Deserializing %zu bytes from %s\n", fileSize, filePath);
// Parse header
if (fileSize < sizeof(L1GeneralMsgHdr_t)) {
printf("ERROR: File too small for header\n");
free(buffer);
return -1;
}
L1GeneralMsgHdr_t* header = (L1GeneralMsgHdr_t*)buffer;
uint8_t* payloadStart = buffer + sizeof(L1GeneralMsgHdr_t);
size_t payloadSize = fileSize - sizeof(L1GeneralMsgHdr_t);
printf("INFO: Message Header:\n");
printf(" msgId: 0x%08x (%s)\n", header->msgId,
header->msgId == 2 ? "CONFIG.request" : "Unknown");
printf(" msgSize: 0x%08x (%u bytes)\n", header->msgSize, header->msgSize);
printf(" Payload size: %zu bytes\n", payloadSize);
// Initialize config to zero
memset(config, 0, sizeof(L1ConfigRequest_t));
// Parse the basic fixed structures from payload
uint32_t offset = 0;
// Parse CarriConfig
if (offset + sizeof(L1CarriConfigInfo_t) > payloadSize) {
printf("ERROR: Insufficient data for CarriConfig\n");
free(buffer);
return -1;
}
memcpy(&config->CarriConfig, payloadStart + offset, sizeof(L1CarriConfigInfo_t));
offset += sizeof(L1CarriConfigInfo_t);
// Parse CellConfig
if (offset + sizeof(L1CellConfigInfo_t) > payloadSize) {
printf("ERROR: Insufficient data for CellConfig\n");
free(buffer);
return -1;
}
memcpy(&config->CellConfig, payloadStart + offset, sizeof(L1CellConfigInfo_t));
offset += sizeof(L1CellConfigInfo_t);
// Parse SSBConfig
if (offset + sizeof(L1SsbConfigInfo_t) > payloadSize) {
printf("ERROR: Insufficient data for SSBConfig\n");
free(buffer);
return -1;
}
memcpy(&config->SSBConfig, payloadStart + offset, sizeof(L1SsbConfigInfo_t));
offset += sizeof(L1SsbConfigInfo_t);
// Parse PRACHCfgInfo header
if (offset + sizeof(uint16_t) * 2 > payloadSize) {
printf("ERROR: Insufficient data for PRACH header\n");
free(buffer);
return -1;
}
config->PRACHCfgInfo.numPrachConfigurations = *(uint16_t*)(payloadStart + offset);
offset += 4; // Skip the variable array for now, just get the count
// Parse SSBtableInfo
if (offset + sizeof(L1SsbTableConfigInfo_t) > payloadSize) {
printf("ERROR: Insufficient data for SSBtableInfo\n");
free(buffer);
return -1;
}
memcpy(&config->SSBtableInfo, payloadStart + offset, sizeof(L1SsbTableConfigInfo_t));
offset += sizeof(L1SsbTableConfigInfo_t);
// Parse TDDtableInfo
if (offset + sizeof(L1TddTableConfigInfo_t) > payloadSize) {
printf("ERROR: Insufficient data for TDDtableInfo\n");
free(buffer);
return -1;
}
memcpy(&config->TDDtableInfo, payloadStart + offset, sizeof(L1TddTableConfigInfo_t));
offset += sizeof(L1TddTableConfigInfo_t);
// Parse MeasurementCfgInfo
if (offset + sizeof(L1MeasurementConfigInfo_t) > payloadSize) {
printf("ERROR: Insufficient data for MeasurementCfgInfo\n");
free(buffer);
return -1;
}
memcpy(&config->MeasurementCfgInfo, payloadStart + offset, sizeof(L1MeasurementConfigInfo_t));
offset += sizeof(L1MeasurementConfigInfo_t);
// Parse UciConfigurationInfo header
if (offset + 4 <= payloadSize) {
config->UciConfigurationInfo.numUci2Maps = *(uint16_t*)(payloadStart + offset);
offset += 4; // Skip variable array for now
}
// Parse PrbSym header
if (offset + 4 <= payloadSize) {
config->PrbSymol.numberOfPrbSymbRateMatchPatterns = *(uint8_t*)(payloadStart + offset);
config->PrbSymol.numCoresetRmPatterns = *(uint8_t*)(payloadStart + offset + 1);
offset += 4; // Skip variable arrays for now
}
// Parse PucchSSConfig header
if (offset + 4 <= payloadSize) {
config->PucchSSConfig.numUlBwpIds = *(uint8_t*)(payloadStart + offset);
offset += 4; // Skip variable array for now
}
// Parse PdschConfig
if (offset + sizeof(L1PdschConfig_t) > payloadSize) {
printf("WARNING: Insufficient data for PdschConfig\n");
} else {
memcpy(&config->PdschConfig, payloadStart + offset, sizeof(L1PdschConfig_t));
offset += sizeof(L1PdschConfig_t);
}
// Parse DBTInfo header
if (offset + 4 <= payloadSize) {
config->DBTInfo.numDigBeams = *(uint16_t*)(payloadStart + offset);
config->DBTInfo.numBasebandPorts = *(uint16_t*)(payloadStart + offset + 2);
offset += 4; // Skip variable arrays for now
}
// Parse PMInfo header
if (offset + 4 <= payloadSize) {
config->PMInfo.numPMTables = *(uint16_t*)(payloadStart + offset);
offset += 4; // Skip variable arrays for now
}
printf("INFO: Parsed all available structures (%u bytes)\n", offset);
printf("INFO: CarriConfig - dlFreq: 0x%08x, ulFreq: 0x%08x\n",
config->CarriConfig.dlFrequency, config->CarriConfig.ulFrequency);
printf("INFO: CellConfig - phyCellId: %u, FrameDuplexType: %u\n",
config->CellConfig.phyCellId, config->CellConfig.FrameDuplexType);
printf("INFO: PRACH numConfigurations: %u\n", config->PRACHCfgInfo.numPrachConfigurations);
printf("INFO: UCI numUci2Maps: %u\n", config->UciConfigurationInfo.numUci2Maps);
printf("INFO: PrbSym numPatterns: %u, numCoresets: %u\n",
config->PrbSymol.numberOfPrbSymbRateMatchPatterns, config->PrbSymol.numCoresetRmPatterns);
printf("INFO: DBT numDigBeams: %u, numBasebandPorts: %u\n",
config->DBTInfo.numDigBeams, config->DBTInfo.numBasebandPorts);
printf("INFO: PM numTables: %u\n", config->PMInfo.numPMTables);
free(buffer);
return 0;
}
/**
* @brief Print L1ConfigRequest_t data to a readable text file
*
* This function outputs all the parsed configuration data in a human-readable format.
*/
int printL1ConfigToFile(const L1ConfigRequest_t* config, const char* outputPath) {
FILE* file;
if (!config || !outputPath) {
printf("ERROR: Invalid parameters for file output\n");
return -1;
}
file = fopen(outputPath, "w");
if (!file) {
printf("ERROR: Cannot create output file %s\n", outputPath);
return -1;
}
fprintf(file, "===== L1 CONFIG REQUEST PARSED DATA =====\n\n");
// Print CarriConfig
fprintf(file, "1. CARRIER CONFIGURATION (L1CarriConfigInfo_t):\n");
fprintf(file, " dlFrequency: 0x%08x (%u Hz)\n", config->CarriConfig.dlFrequency, config->CarriConfig.dlFrequency);
fprintf(file, " ulFrequency: 0x%08x (%u Hz)\n", config->CarriConfig.ulFrequency, config->CarriConfig.ulFrequency);
fprintf(file, " dlBandwidth: %u\n", config->CarriConfig.dlBandwidth);
fprintf(file, " ulBandwidth: %u\n", config->CarriConfig.ulBandwidth);
fprintf(file, " dlCarrierOffset: [");
for (int i = 0; i < NUM_EROLOGIES; i++) {
fprintf(file, "%u%s", config->CarriConfig.dlCarrierOffset[i], i < NUM_EROLOGIES-1 ? ", " : "");
}
fprintf(file, "]\n");
fprintf(file, " ulCarrierOffset: [");
for (int i = 0; i < NUM_EROLOGIES; i++) {
fprintf(file, "%u%s", config->CarriConfig.ulCarrierOffset[i], i < NUM_EROLOGIES-1 ? ", " : "");
}
fprintf(file, "]\n");
fprintf(file, " dlGridSize: [");
for (int i = 0; i < NUM_EROLOGIES; i++) {
fprintf(file, "%u%s", config->CarriConfig.dlGridSize[i], i < NUM_EROLOGIES-1 ? ", " : "");
}
fprintf(file, "]\n");
fprintf(file, " ulGridSize: [");
for (int i = 0; i < NUM_EROLOGIES; i++) {
fprintf(file, "%u%s", config->CarriConfig.ulGridSize[i], i < NUM_EROLOGIES-1 ? ", " : "");
}
fprintf(file, "]\n");
fprintf(file, " numTxAnt: %u\n", config->CarriConfig.numTxAnt);
fprintf(file, " numRxAnt: %u\n", config->CarriConfig.numRxAnt);
fprintf(file, " FrequencyShift7p5KHz: %u\n", config->CarriConfig.FrequencyShift7p5KHz);
fprintf(file, " ulTimingAdvance: %u\n", config->CarriConfig.ulTimingAdvance);
fprintf(file, " frameOffset: %u\n", config->CarriConfig.frameOffset);
fprintf(file, "\n");
// Print CellConfig
fprintf(file, "2. CELL CONFIGURATION (L1CellConfigInfo_t):\n");
fprintf(file, " phyCellId: %u\n", config->CellConfig.phyCellId);
fprintf(file, " FrameDuplexType: %u (%s)\n", config->CellConfig.FrameDuplexType,
config->CellConfig.FrameDuplexType == 0 ? "FDD" : "TDD");
fprintf(file, " rev0: %u\n", config->CellConfig.rev0);
fprintf(file, "\n");
// Print SSBConfig
fprintf(file, "3. SSB CONFIGURATION (L1SsbConfigInfo_t):\n");
fprintf(file, " ssPbchBlockPowerScaling: %d\n", config->SSBConfig.ssPbchBlockPowerScaling);
fprintf(file, " bchPayloadFlag: %u\n", config->SSBConfig.bchPayloadFlag);
fprintf(file, " rev0: %u\n", config->SSBConfig.rev0);
fprintf(file, "\n");
// Print PRACH Config
fprintf(file, "4. PRACH CONFIGURATION (L1PrachConfigInfo_t):\n");
fprintf(file, " numPrachConfigurations: %u\n", config->PRACHCfgInfo.numPrachConfigurations);
fprintf(file, " [Variable-size arrays not fully parsed]\n");
fprintf(file, "\n");
// Print SSB Table Config
fprintf(file, "5. SSB TABLE CONFIGURATION (L1SsbTableConfigInfo_t):\n");
fprintf(file, " ssbConfigIndex: %u\n", config->SSBtableInfo.ssbConfigIndex);
fprintf(file, " ssbOffsetPointA: %u\n", config->SSBtableInfo.ssbOffsetPointA);
fprintf(file, " betaPssProfileSSS: %d\n", config->SSBtableInfo.betaPssProfileSSS);
fprintf(file, " ssbPeriod: %u\n", config->SSBtableInfo.ssbPeriod);
fprintf(file, " ssbSubcarrierOffset: %u\n", config->SSBtableInfo.ssbSubcarrierOffset);
fprintf(file, " Case: %u\n", config->SSBtableInfo.Case);
fprintf(file, " subcarrierSpacing: %u\n", config->SSBtableInfo.subcarrierSpacing);
fprintf(file, " subCarrierSpacingCommon: %u\n", config->SSBtableInfo.subCarrierSpacingCommon);
fprintf(file, " lMax: %u\n", config->SSBtableInfo.lMax);
fprintf(file, " rmsiPresence: %u\n", config->SSBtableInfo.rmsiPresence);
fprintf(file, " addSsbSubcarrierOffset: [%u, %u, %u]\n",
config->SSBtableInfo.addSsbSubcarrierOffset[0],
config->SSBtableInfo.addSsbSubcarrierOffset[1],
config->SSBtableInfo.addSsbSubcarrierOffset[2]);
fprintf(file, " addSsbOffsetPointA: [%u, %u, %u]\n",
config->SSBtableInfo.addSsbOffsetPointA[0],
config->SSBtableInfo.addSsbOffsetPointA[1],
config->SSBtableInfo.addSsbOffsetPointA[2]);
fprintf(file, " BeamId: [");
for (int i = 0; i < NUM_SSB_BEAM_ID && i < 16; i++) { // Show first 16 beam IDs
fprintf(file, "0x%02x%s", config->SSBtableInfo.BeamId[i], i < 15 ? ", " : "");
}
if (NUM_SSB_BEAM_ID > 16) fprintf(file, "...");
fprintf(file, "]\n");
fprintf(file, "\n");
// Print TDD Table Config
fprintf(file, "6. TDD TABLE CONFIGURATION (L1TddTableConfigInfo_t):\n");
fprintf(file, " TddPeriod: %u\n", config->TDDtableInfo.TddPeriod);
fprintf(file, " rev0: %u\n", config->TDDtableInfo.rev0);
fprintf(file, " rev1: %u\n", config->TDDtableInfo.rev1);
fprintf(file, " SlotConfig: [");
for (int i = 0; i < MAX_SLOT_CFG_NUM && i < 16; i++) { // Show first 16 slot configs
fprintf(file, "0x%02x%s", config->TDDtableInfo.SlotConfig[i], i < 15 ? ", " : "");
}
if (MAX_SLOT_CFG_NUM > 16) fprintf(file, "...");
fprintf(file, "]\n");
fprintf(file, "\n");
// Print Measurement Config
fprintf(file, "7. MEASUREMENT CONFIGURATION (L1MeasurementConfigInfo_t):\n");
fprintf(file, " RssiMeasurement: %u\n", config->MeasurementCfgInfo.RssiMeasurement);
fprintf(file, " RsrpMeasurement: %u\n", config->MeasurementCfgInfo.RsrpMeasurement);
fprintf(file, " rev: %u\n", config->MeasurementCfgInfo.rev);
fprintf(file, "\n");
// Print UCI Configuration
fprintf(file, "8. UCI CONFIGURATION (L1UciConfigurationInfo_t):\n");
fprintf(file, " numUci2Maps: %u\n", config->UciConfigurationInfo.numUci2Maps);
fprintf(file, " [Variable-size arrays not fully parsed]\n");
fprintf(file, "\n");
// Print PrbSym Configuration
fprintf(file, "9. PRB SYMBOL CONFIGURATION (L1PrbSym_t):\n");
fprintf(file, " numberOfPrbSymbRateMatchPatterns: %u\n", config->PrbSymol.numberOfPrbSymbRateMatchPatterns);
fprintf(file, " numCoresetRmPatterns: %u\n", config->PrbSymol.numCoresetRmPatterns);
fprintf(file, " [Variable-size arrays not fully parsed]\n");
fprintf(file, "\n");
// Print PUCCH SS Config
fprintf(file, "10. PUCCH SS CONFIGURATION (L1PucchSSConfig_t):\n");
fprintf(file, " numUlBwpIds: %u\n", config->PucchSSConfig.numUlBwpIds);
fprintf(file, " [Variable-size arrays not fully parsed]\n");
fprintf(file, "\n");
// Print PDSCH Config
fprintf(file, "11. PDSCH CONFIGURATION (L1PdschConfig_t):\n");
fprintf(file, " pdschCbgScheme: %u\n", config->PdschConfig.pdschCbgScheme);
fprintf(file, " rev0: %u\n", config->PdschConfig.rev0);
fprintf(file, " rev1: %u\n", config->PdschConfig.rev1);
fprintf(file, "\n");
// Print DBT Configuration
fprintf(file, "12. DBT CONFIGURATION (L1DBTConfigInfo_t):\n");
fprintf(file, " numDigBeams: %u\n", config->DBTInfo.numDigBeams);
fprintf(file, " numBasebandPorts: %u\n", config->DBTInfo.numBasebandPorts);
fprintf(file, " [Variable-size arrays not fully parsed]\n");
fprintf(file, "\n");
// Print PM Configuration
fprintf(file, "13. PM CONFIGURATION (L1PMCfgTableInfo_t):\n");
fprintf(file, " numPMTables: %u\n", config->PMInfo.numPMTables);
fprintf(file, " [Variable-size arrays not fully parsed]\n");
fprintf(file, "\n");
fprintf(file, "===== END OF PARSED DATA =====\n");
fclose(file);
printf("INFO: Configuration data written to %s\n", outputPath);
return 0;
}
int main(int argc, char* argv[]) {
L1ConfigRequest_t config;
const char* configFile;
if (argc != 2) {
printf("Usage: %s <config_file.dat>\n", argv[0]);
printf("Example: %s src/test_CPHY/test_CPHY.t100.1.1/config/fapi_config_cell0_request.dat\n", argv[0]);
return 1;
}
configFile = argv[1];
printf("=== L1 Config Deserializer ===\n");
printf("Input file: %s\n", configFile);
if (deserializeL1ConfigRequest(configFile, &config) == 0) {
printf("\n=== Deserialization SUCCESS ===\n");
// Print configuration data to a readable file
printf("\n=== Writing Parsed Data to Text File ===\n");
const char* outputFile = "config_parsed.txt";
if (printL1ConfigToFile(&config, outputFile) == 0) {
printf("✅ SUCCESS: Configuration data written to %s\n", outputFile);
printf("✅ All available fields have been parsed and displayed\n");
} else {
printf("❌ Failed to write configuration data to text file\n");
}
} else {
printf("\n=== Deserialization FAILED ===\n");
return 1;
}
return 0;
}
Editor is loading...
Leave a Comment