Skip to content

Commit

Permalink
qualcomm: port to GSMTAPv3 draft
Browse files Browse the repository at this point in the history
  • Loading branch information
peremen committed May 30, 2024
1 parent a1e287e commit d29f5e2
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 41 deletions.
112 changes: 72 additions & 40 deletions src/scat/parsers/qualcomm/diagnrlogparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,16 @@ def parse_nr_rrc(self, pkt_header, pkt_body, args):

if pkt_ver in (0x09, 0x0c):
rrc_type_map = {
1: "BCCH_BCH",
2: "BCCH_DL_SCH",
3: "DL_CCCH",
4: "DL_DCCH",
5: "PCCH",
6: "UL_CCCH",
7: "UL_CCCH1",
8: "UL_DCCH",
1: util.gsmtapv3_nr_rrc_types.BCCH_BCH,
2: util.gsmtapv3_nr_rrc_types.BCCH_DL_SCH,
3: util.gsmtapv3_nr_rrc_types.DL_CCCH,
4: util.gsmtapv3_nr_rrc_types.DL_DCCH,
5: util.gsmtapv3_nr_rrc_types.PCCH,
6: util.gsmtapv3_nr_rrc_types.UL_CCCH,
7: util.gsmtapv3_nr_rrc_types.UL_CCCH1,
8: util.gsmtapv3_nr_rrc_types.UL_DCCH,
}
rrc_type_map_stdout = {
9: "RRC_RECONFIGURATION",
10: "RRC_RECONFIGURATION_COMPLETE",
25: "nr-RadioBearerConfig",
Expand All @@ -163,14 +165,16 @@ def parse_nr_rrc(self, pkt_header, pkt_body, args):
}
elif pkt_ver in (0x0e, ):
rrc_type_map = {
1: "BCCH_BCH",
2: "BCCH_DL_SCH",
3: "DL_CCCH",
4: "DL_DCCH",
5: "PCCH",
6: "UL_CCCH",
7: "UL_CCCH1",
8: "UL_DCCH",
1: util.gsmtapv3_nr_rrc_types.BCCH_BCH,
2: util.gsmtapv3_nr_rrc_types.BCCH_DL_SCH,
3: util.gsmtapv3_nr_rrc_types.DL_CCCH,
4: util.gsmtapv3_nr_rrc_types.DL_DCCH,
5: util.gsmtapv3_nr_rrc_types.PCCH,
6: util.gsmtapv3_nr_rrc_types.UL_CCCH,
7: util.gsmtapv3_nr_rrc_types.UL_CCCH1,
8: util.gsmtapv3_nr_rrc_types.UL_DCCH,
}
rrc_type_map_stdout = {
9: "RRC_RECONFIGURATION",
10: "RRC_RECONFIGURATION_COMPLETE",
31: "UE_MRDC_CAPABILITY",
Expand All @@ -179,29 +183,33 @@ def parse_nr_rrc(self, pkt_header, pkt_body, args):
}
elif pkt_ver in (0x11, 0x13, ):
rrc_type_map = {
1: "BCCH_BCH",
2: "BCCH_DL_SCH",
3: "DL_CCCH",
4: "DL_DCCH",
5: "PCCH",
6: "UL_CCCH",
7: "UL_CCCH1",
8: "UL_DCCH",
1: util.gsmtapv3_nr_rrc_types.BCCH_BCH,
2: util.gsmtapv3_nr_rrc_types.BCCH_DL_SCH,
3: util.gsmtapv3_nr_rrc_types.DL_CCCH,
4: util.gsmtapv3_nr_rrc_types.DL_DCCH,
5: util.gsmtapv3_nr_rrc_types.PCCH,
6: util.gsmtapv3_nr_rrc_types.UL_CCCH,
7: util.gsmtapv3_nr_rrc_types.UL_CCCH1,
8: util.gsmtapv3_nr_rrc_types.UL_DCCH,
}
rrc_type_map_stdout = {
9: "RRC_RECONFIGURATION",
10: "RRC_RECONFIGURATION_COMPLETE",
29: "nr-RadioBearerConfig",
}
elif pkt_ver in (0x17, ):
rrc_type_map = {
1: "BCCH_BCH",
2: "BCCH_DL_SCH",
3: "DL_CCCH",
4: "DL_DCCH",
5: "MCCH",
6: "PCCH",
7: "UL_CCCH",
8: "UL_CCCH1",
9: "UL_DCCH",
1: util.gsmtapv3_nr_rrc_types.BCCH_BCH,
2: util.gsmtapv3_nr_rrc_types.BCCH_DL_SCH,
3: util.gsmtapv3_nr_rrc_types.DL_CCCH,
4: util.gsmtapv3_nr_rrc_types.DL_DCCH,
5: util.gsmtapv3_nr_rrc_types.MCCH,
6: util.gsmtapv3_nr_rrc_types.PCCH,
7: util.gsmtapv3_nr_rrc_types.UL_CCCH,
8: util.gsmtapv3_nr_rrc_types.UL_CCCH1,
9: util.gsmtapv3_nr_rrc_types.UL_DCCH,
}
rrc_type_map_stdout = {
10: "RRC_RECONFIGURATION",
11: "RRC_RECONFIGURATION_COMPLETE",
36: "nr-RadioBearerConfig",
Expand All @@ -213,13 +221,28 @@ def parse_nr_rrc(self, pkt_header, pkt_body, args):

if item.pdu_id in rrc_type_map.keys():
type_str = rrc_type_map[item.pdu_id]
stdout += "NR RRC OTA Packet: NR-ARFCN {}, PCI {}".format(item.nrarfcn, item.pci)
nr_pdu_id_gsmtap = rrc_type_map[item.pdu_id]

gsmtap_hdr = util.create_gsmtap_header(
version = 3,
payload_type = util.gsmtapv3_types.NR_RRC,
arfcn = 0,
sub_type = nr_pdu_id_gsmtap,
device_sec = ts_sec,
device_usec = ts_usec)

return {'layer': 'rrc', 'cp': [gsmtap_hdr + msg_content], 'ts': pkt_ts, 'stdout': stdout}
else:
type_str = '{}'.format(item.pdu_id)
if item.pdu_id in rrc_type_map_stdout.keys():
type_str = rrc_type_map_stdout[item.pdu_id]
else:
type_str = '{}'.format(item.pdu_id)

stdout += "NR RRC OTA Packet: NR-ARFCN {}, PCI {}, Type: {}\n".format(item.nrarfcn, item.pci, type_str)
stdout += "NR RRC OTA Packet: Body: {}".format(binascii.hexlify(msg_content).decode())
stdout += "NR RRC OTA Packet: NR-ARFCN {}, PCI {}, Type: {}\n".format(item.nrarfcn, item.pci, type_str)
stdout += "NR RRC OTA Packet: Body: {}".format(binascii.hexlify(msg_content).decode())

return {'layer': 'rrc', 'stdout': stdout, 'ts': pkt_ts}
return {'layer': 'rrc', 'stdout': stdout, 'ts': pkt_ts}

def parse_nr_mib_info(self, pkt_header, pkt_body, args):
pkt_ts = util.parse_qxdm_ts(pkt_header.timestamp)
Expand Down Expand Up @@ -306,24 +329,33 @@ def parse_nr_nas(self, pkt_header, pkt_body, args, cmd_id):
ts_sec = calendar.timegm(pkt_ts.timetuple())
ts_usec = pkt_ts.microsecond
stdout = ''
plain = (cmd_id in (0xB800, 0xB801, 0xB80A, 0xB80B, 0xB814))

# Version 4b, std version maj.min.rev 1b each
pkt_ver = struct.unpack('<L', pkt_body[0:4])[0]
item_struct = namedtuple('QcDiagNrNasMsg', 'vermaj vermid vermin')
msg_content = pkt_body[7:]
if pkt_ver == 0x1:
item = item_struct._make(struct.unpack('<BBB', pkt_body[4:7]))
stdout = "NAS-5GS message ({:04X}) version {:x}.{:x}.{:x}: ".format(cmd_id, item.vermaj, item.vermid, item.vermin)
stdout = "NAS-5GS message ({:04X}) version {:x}.{:x}.{:x}".format(cmd_id, item.vermaj, item.vermid, item.vermin)
msg_content = pkt_body[7:]
stdout += "{}".format(binascii.hexlify(msg_content).decode())

gsmtap_hdr = util.create_gsmtap_header(
version = 3,
payload_type = util.gsmtapv3_types.NAS_5GS,
arfcn = 0,
sub_type = 0 if plain else 1,
device_sec = ts_sec,
device_usec = ts_usec)

return {'layer': 'nas', 'cp': [gsmtap_hdr + msg_content], 'ts': pkt_ts, 'stdout': stdout}
else:
if self.parent:
self.parent.logger.log(logging.WARNING, 'Unknown NR NAS Message packet version {:#x}'.format(pkt_ver))
self.parent.logger.log(logging.DEBUG, "Body: {}".format(util.xxd_oneline(pkt_body)))
return None

return {'layer': 'nas', 'stdout': stdout, 'ts': pkt_ts}

def parse_nr_mm_state(self, pkt_header, pkt_body, args):
pkt_ts = util.parse_qxdm_ts(pkt_header.timestamp)
pkt_ver = struct.unpack('<I', pkt_body[0:4])[0]
Expand Down
61 changes: 60 additions & 1 deletion src/scat/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,65 @@ class gsmtap_lte_rrc_types(IntEnum):
PCCH_NB = 21
SC_MCCH_NB = 22

@unique
class gsmtapv3_types(IntEnum):
OSMOCORE_LOG = 0x0000
SIM = 0x0001
BASEBAND_DIAG = 0x0002
SIGNAL_STATUS_REPORT = 0x0003
TETRA_I1 = 0x0004
TETRA_I1_BURST = 0x0005
GMR1_UM = 0x0006
E1T1 = 0x0007
WMX_BURST = 0x0008

UM = 0x0200
UM_BURST = 0x0201
GB_RLCMAC = 0x0202
GB_LLC = 0x0203
GB_SNDCP = 0x0204
ABIS = 0x0205
RLP = 0x0206

UMTS_MAC = 0x0300
UMTS_RLC = 0x0301
UMTS_PDCP = 0x0302
UMTS_RRC = 0x0303

LTE_MAC = 0x0400
LTE_RLC = 0x0401
LTE_PDCP = 0x0402
LTE_RRC = 0x0403
NAS_EPS = 0x0404

NR_MAC = 0x0500
NR_RLC = 0x0501
NR_PDCP = 0x0502
NR_RRC = 0x0503
NAS_5GS = 0x0504

@unique
class gsmtapv3_nr_rrc_types(IntEnum):
BCCH_BCH = 0x0001
BCCH_DL_SCH = 0x0002
DL_CCCH = 0x0003
DL_DCCH = 0x0004
MCCH = 0x0005
PCCH = 0x0006
UL_CCCH = 0x0007
UL_CCCH1 = 0x0008
UL_DCCH = 0x0009

SBCCH_SL_BCH = 0x0101
SCCH = 0x0102

def create_gsmtap_header(version = 2, payload_type = 0, timeslot = 0,
arfcn = 0, signal_dbm = 0, snr_db = 0, frame_number = 0,
sub_type = 0, antenna_nr = 0, sub_slot = 0,
device_sec = 0, device_usec = 0):

gsmtap_v2_hdr_def = '!BBBBHBBLBBBB'
gsmtap_v3_hdr_def = '!BBHHH'
gsmtap_hdr = b''

# Sanity check - Wireshark GSMTAP dissector accepts only 14 bits of ARFCN
Expand All @@ -295,7 +348,13 @@ def create_gsmtap_header(version = 2, payload_type = 0, timeslot = 0,
0 # Reserved
)
elif version == 3:
assert False, "New GSMTAPv3 is WIP"
gsmtap_hdr = struct.pack(gsmtap_v3_hdr_def,
3, # Version
0, # Reserved
2, # Header Length
payload_type, # Type
sub_type, # Subtype
)
else:
assert (version == 2) or (version == 3), "GSMTAP version should be either 2 or 3"

Expand Down

0 comments on commit d29f5e2

Please sign in to comment.