Add a small FAPI Hex parser utility

Add utility functions to print the FAPI messages contents
Add dump functions for DL_TTI.request PDUs, remaining message structures to be finished
Add file examples.md with some examples on how to use nfapi_hex_parser
This commit is contained in:
Rúben Soares Silva
2025-01-23 13:34:24 +00:00
parent f9bff3d6a0
commit 1451f30b93
9 changed files with 1138 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
add_executable(nfapi_hex_parser nfapi_hex_parser.c)
target_link_libraries(nfapi_hex_parser PUBLIC nr_fapi_p5 nr_fapi_p7)
# This makes it so nfapi_hex_parser is always compiled whenever NFAPI_LIB is compiled
add_dependencies(NFAPI_LIB nfapi_hex_parser )
+258
View File
@@ -0,0 +1,258 @@
# Example runs of nfapi_hex_parser
## 1 - An invalid DL_TTI.request
```
./nfapi/open-nFAPI/utils/nfapi_hex_parser 0x00 0x00 0x00 0x80 0x00 0x00 0x01 0x7e 0x00 0x62 0x00 0x00 0x03 0x01 0x00 0x03 0x00 0x15 0x00 0x01 0x00 0x00 0x00 0x00 0x18 0x01 0x06 0x00 0x0d 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x34 0x01 0x11 0x00 0x00 0x00 0x00 0x00 0x02 0x00 0x00 0x00 0x00 0xe0 0x01 0x01 0x06 0x02 0x00 0x00 0x01 0x00 0x00 0x01 0xff 0xff 0x00 0x01 0x00 0x00 0x00 0x04 0x00 0x01 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x1c 0x00 0x00 0x00 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x71 0x00 0x00 0xff 0xff 0x00 0x00 0x01 0x11 0x00 0x00 0x00 0x00 0x01 0x01 0x34 0x02 0x04 0x00 0x00 0x00 0x00 0x00 0x7b 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x04 0x00 0x00 0x01 0x00 0x01 0x00 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x2d 0x00 0x0e 0x00 0x03 0x0b 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Parsed 382 bytes:
00 00 00 80 00 00 01 7e 00 62 00 00 03 01 00 03
00 15 00 01 00 00 00 00 18 01 06 00 0d 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 34 01 11 00 00 00 00 00 02 00
00 00 00 e0 01 01 06 02 00 00 01 00 00 01 ff ff
00 01 00 00 00 04 00 01 00 01 00 00 00 00 00 00
00 00 1c 00 00 00 80 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 01 00 71 00 00 ff ff
00 00 01 11 00 00 00 00 01 01 34 02 04 00 00 00
00 00 7b 00 00 00 00 00 00 00 00 00 00 00 01 01
00 00 00 04 00 00 01 00 01 00 01 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 2d 00 0e 00 03 0b 00 00 00 00 00 00 01 00 01
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00
Decoded message NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST message length 0x17e
Message ID = 0x80
Message Length = 0x17e
SFN = 98
Slot = 0
nPDUs = 3
nGroup = 1
PDU #0
PDUType = 0x03 (NFAPI_NR_DL_TTI_SSB_PDU_TYPE)
PDUSize = 0x15
physCellId = 1
BetaPss = 0
SSBBlockIndex = 0
SSBSubcarrierOffset = 0
SSBOffsetPointA = 24
bchPayloadFlag = 1
bchPayload = 6000d
numPRGs = 0
prgSize = 0
digBFInterfaces = 0
PDU #1
PDUType = 0x00 (NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE)
PDUSize = 0x00
BWPSize = 0
BWPStart = 0
Subcarrier Spacing = 0
Ciclic Prefix = 0
StartSymbolIndex = 0
DurationSymbols = 0
FrequencyDomainResource : 0 0 0 0 0 0
CCE Reg Mapping Type = 0
Reg Bundle Size = 0
Interleaver Size = 0
CoreSetType = 0
ShiftIndex = 0
precoderGranularity = 0
numDLDCI = 0
PDU #2
PDUType = 0x00 (NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE)
PDUSize = 0x00
BWPSize = 0
BWPStart = 0
Subcarrier Spacing = 0
Ciclic Prefix = 0
StartSymbolIndex = 0
DurationSymbols = 0
FrequencyDomainResource : 0 0 0 0 0 0
CCE Reg Mapping Type = 0
Reg Bundle Size = 0
Interleaver Size = 0
CoreSetType = 0
ShiftIndex = 0
precoderGranularity = 0
numDLDCI = 0
Group #0
nUe[0] = 0x00
```
## 2 - A valid ERROR.indication
```
./nfapi/open-nFAPI/utils/nfapi_hex_parser 0x00 0x00 0x00 0x07 0x00 0x00 0x00 0x06 0x00 0x0a 0x00 0x10 0x80 0x06
Parsed values:
00 00 00 07 00 00 00 06 00 0a 00 10 80 06
Processing message NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION
Message ID = 0x07
Message Length = 0x06
SFN = 0x0a
Slot = 0x10
Message ID = 0x80
Error Code = 0x06 (NFAPI_NR_PHY_API_MSG_INVALID_SFN)
```
## 3 - A valid SLOT.indication
```
./nfapi/open-nFAPI/utils/nfapi_hex_parser 0x00 0x01 0x00 0x82 0x00 0x00 0x00 0x04 0x00 0x05 0x00 0x06
Parsed values:
00 01 00 82 00 00 00 04 00 05 00 06
Processing message NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION
Message ID = 0x82
Message Length = 0x04
SFN = 5
Slot = 6
```
## 4 - A valid ERROR.indication, with diverging formats for the hexdump passed as a parameter
```
user@user-PC:~/nfapi_parser/cmake_targets/ran_build/build$ ./nfapi/open-nFAPI/utils/nfapi_hex_parser "00 0 0x00 7 0x00 0x00 0x00" 0x06 0x00 "a 0x00 0x10 0x80 7"
Parsed 14 bytes:
00 00 00 07 00 00 00 06 00 0a 00 10 80 07
Decoded message NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION message length 0x06
Message ID = 0x07
Message Length = 0x06
SFN = 0x0a (10)
Slot = 0x10 (16)
Message ID = 0x80
Error Code = 0x07 (NFAPI_NR_PHY_API_MSG_UL_DCI_ERR)
```
## 5 - An invalid message, passing less bytes than the minimum required to encode a FAPI message header
```
user@user-PC:~/nfapi_parser/cmake_targets/ran_build/build$ ./nfapi/open-nFAPI/utils/nfapi_hex_parser 1
Parsed 1 bytes:
01
Assertion (byte_count >= sizeof(fapi_message_header_t)) failed!
In main() /home/user/nfapi_parser/nfapi/open-nFAPI/utils/nfapi_hex_parser.c:293
Read byte amount not enough to encode the header. Should have a minimum of 8 bytes, aborting...
Exiting execution
/home/user/nfapi_parser/nfapi/open-nFAPI/utils/nfapi_hex_parser.c:293 main() Exiting OAI (n)FAPI Hex Parser: _Assert_Exit_
Aborted (core dumped)
```
## 7 - A valid DL_TTI.request
```
./nfapi/open-nFAPI/utils/nfapi_hex_parser 0x00 0x01 0x00 0x80 0x00 0x00 0x00 0xc3 0x00 0x02 0x00 0x00 0x03 0x00 0x00 0x03 0x00 0x19 0x00 0x00 0x00 0x00 0x0c 0x00 0xfc 0x01 0x06 0xc6 0x01 0x00 0x00 0x01 0x01 0x13 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x31 0x00 0x30 0x00 0x6e 0x01 0x00 0x00 0x01 0xff 0x00 0x00 0x00 0x00 0x00 0x01 0x06 0x02 0x00 0x00 0x00 0x00 0x00 0x01 0xff 0xff 0x00 0x00 0x00 0x00 0x00 0x04 0x00 0x00 0x00 0x00 0x01 0x00 0x01 0x00 0x27 0x00 0x00 0x14 0x01 0x2d 0x00 0x01 0x00 0x61 0x00 0x00 0xff 0xff 0x00 0x00 0x00 0x30 0x00 0x6e 0x01 0x00 0x01 0x0e 0xce 0x02 0x05 0x00 0x00 0x00 0x00 0x00 0x81 0x00 0x00 0x01 0x00 0x01 0x02 0x44 0x00 0x00 0x00 0x00 0x02 0x00 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x10 0x00 0x02 0x0a 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x02 0x00 0x00 0xe0 0x20 0x10 0x29 0x00 0x01 0x62 0x00 0x00 0x00
Parsed 193 bytes:
00 01 00 80 00 00 00 c3 00 02 00 00 03 00 00 03
00 19 00 00 00 00 0c 00 fc 01 06 c6 01 00 00 01
01 13 01 00 00 00 00 00 00 00 31 00 30 00 6e 01
00 00 01 ff 00 00 00 00 00 01 06 02 00 00 00 00
00 01 ff ff 00 00 00 00 00 04 00 00 00 00 01 00
01 00 27 00 00 14 01 2d 00 01 00 61 00 00 ff ff
00 00 00 30 00 6e 01 00 01 0e ce 02 05 00 00 00
00 00 81 00 00 01 00 01 02 44 00 00 00 00 02 00
01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 10 00 02 0a 00 00 00
00 01 00 00 02 00 00 e0 20 10 29 00 01 62 00 00
00
Decoded message NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST message length 0xc3
Message ID = 0x80
Message Length = 0xc3
SFN = 2
Slot = 0
nPDUs = 3
nGroup = 0
PDU #0
PDUType = 0x03 (NFAPI_NR_DL_TTI_SSB_PDU_TYPE)
PDUSize = 0x19
physCellId = 0
BetaPss = 0
SSBBlockIndex = 0
SSBSubcarrierOffset = 12
SSBOffsetPointA = 252
bchPayloadFlag = 1
bchPayload = 6c601
numPRGs = 1
prgSize = 275
digBFInterfaces = 1
PMIdx = 0
beamIDX = 0
PDU #1
PDUType = 0x00 (NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE)
PDUSize = 0x31
BWPSize = 48
BWPStart = 110
Subcarrier Spacing = 1
Ciclic Prefix = 0
StartSymbolIndex = 0
DurationSymbols = 1
FrequencyDomainResource : 255 0 0 0 0 0
CCE Reg Mapping Type = 1
Reg Bundle Size = 6
Interleaver Size = 2
CoreSetType = 0
ShiftIndex = 0
precoderGranularity = 0
numDLDCI = 1
RNTI = 0xffff
ScramblingId = 0
ScramblingRNTI = 0x0
CCEIndex = 0
AggregationLevel = 4
numPRGs = 0
prgSize = 0
digBFInterfaces = 1
beta_PDCCH_1_0 = 0
powerControlOffsetSS = 1
PayloadSizeBits = 39
Payload = 0x00 0x00 0x14 0x01 0x2d
PDU #2
PDUType = 0x01 (NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE)
PDUSize = 0x61
pduBitmap = 0
RNTI = ffff
pduIndex = 0
BWPSize = 48
BWPStart = 110
SubcarrierSpacing = 1
CyclicPrefix = 0
NrOfCodewords = 1
Codeword #0
targetCoderate = 3790
qamModOrder = 2
mcsIndex = 5
mcsTable = 0
rvIndex = 0
TBSize = 129
dataScramblingId = 0
nrOfLayers = 1
transmissionScheme = 0
refPoint = 1
dlDmrsSymbPos = 580
dmrsConfigType = 0
dlDmrsScramblingId = 0
SCID = 0
numDmrsCdmGrpsNoData = 2
dmrsPorts = 1
resourceAlloc = 1
rbBitmap = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
rbStart = 0
rbSize = 16
VRBtoPRBMapping = 0
StartSymbolIndex = 2
NrOfSymbols = 10
PTRSPortIndex = 0
PTRSTimeDensity = 0
PTRSFreqDensity = 0
PTRSReOffset = 0
nEpreRatioOfPDSCHToPTRS = 0
numPRGs = 0
prgSize = 0
digBFInterfaces = 1
powerControlOffset = 0
powerControlOffsetSS = 0
isLastCbPresent = 0
isInlineTbCrc = 0
dlTbCrc = 0
```
+294
View File
@@ -0,0 +1,294 @@
/*
* 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
*/
#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)
{
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
uint8_t **msg_ptr = &ptr; // Pointer to the pointer
fapi_message_header_t hdr = {.num_msg = 0, .opaque_handle = 0, .message_id = 0, .message_length = 0};
fapi_nr_message_header_unpack(msg_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;
}