def run_diag(self): print('-------- start diag --------') oldbuf = b'' cur_pos = 0 try: while True: buf = self.handler.read(0x9000) #util.xxd(buf) if len(buf) == 0: continue cur_pos = 0 while cur_pos < len(buf): #print('---- subpacket ----') #assert buf[cur_pos] == 0x7f if buf[cur_pos] != 0x7f: print('Something wrong') util.xxd(buf) break len_1 = buf[cur_pos + 1] | (buf[cur_pos + 2] << 8) len_2 = buf[cur_pos + 3] | (buf[cur_pos + 4] << 8) #util.xxd(buf[cur_pos:cur_pos+len_1 + 2]) self.parse_diag(buf[cur_pos:cur_pos + len_1 + 2]) cur_pos += (len_1 + 2) #print('%s/%s' % (cur_pos, len(buf))) #print('---- end ----') except KeyboardInterrupt: return
def parse_diag_log_e333(self, pkt): process = { # 0x00 - only used during diag setup 0x01: lambda x: self.process_common_basic(x), 0x02: lambda x: self.process_lte_basic_e333(x), # 0x03 0x04: lambda x: self.process_hspa_basic(x), 0x07: lambda x: self.process_ip_data(x), #0x20: lambda x: process_control_message(x), 0x21: lambda x: self.process_common_data(x), 0x22: lambda x: self.process_lte_data(x), #0x23: lambda x: process_edge_data(x), #0x24: lambda x: process_hspa_data(x), #0x25: lambda x: process_trace_data(x), # 0x44 } if not (pkt[0] == 0x7f and pkt[-1] == 0x7e): print('Invalid packet structure') util.xxd(pkt) return b'' len_1 = pkt[1] | (pkt[2] << 8) len_2 = pkt[4] | (pkt[5] << 8) stamp = pkt[6] | (pkt[7] << 8) main_cmd = pkt[8] sub_cmd = pkt[9] #print('Length %s/%s, Main command %02x, Stamp %04x' % (len_1, len_2, main_cmd, stamp)) #util.xxd(pkt[0:10]) if main_cmd == 0xa0 or main_cmd == 0xa1: # IpcDmCmd if sub_cmd in process.keys(): return process[sub_cmd](pkt) else: #print('TODO: subcommand %02x' % sub_cmd) pass elif main_cmd == 0xa1: # IpcCtCmd if sub_cmd in process.keys(): return process[sub_cmd](pkt) else: #print('TODO: subcommand %02x' % sub_cmd) pass print('TODO: IpcCtCmd') util.xxd(pkt) elif main_cmd == 0xa2: # IpcHimCmd print('TODO: IpcHimCmd') else: print('Invalid main command ID %02x' % main_cmd) #print("%s %s %s %s %s %s %s %s" % (binascii.hexlify(pkt[0:1]).decode('ascii'), # binascii.hexlify(pkt[1:4]).decode('ascii'), # binascii.hexlify(pkt[4:6]).decode('ascii'), # binascii.hexlify(pkt[6:8]).decode('ascii'), # binascii.hexlify(pkt[8:9]).decode('ascii'), # binascii.hexlify(pkt[9:10]).decode('ascii'), # binascii.hexlify(pkt[10:-1]).decode('ascii'), # binascii.hexlify(pkt[-1:]).decode('ascii'))) return b''
def run_diag(self): self.logger.log(logging.INFO, 'Starting diag') oldbuf = b'' cur_pos = 0 try: while True: buf = self.io_device.read(0x9000) #util.xxd(buf, True) if len(buf) == 0: continue cur_pos = 0 while cur_pos < len(buf): #print('---- subpacket ----') #print(buf) #assert buf[cur_pos] == 0x7f if buf[cur_pos] != 0x7f: self.logger.warning(logging.WARNING, 'Something wrong') self.logger.log(logging.DEBUG, util.xxd(buf)) break len_1 = buf[cur_pos + 1] | (buf[cur_pos + 2] << 8) len_2 = buf[cur_pos + 3] | (buf[cur_pos + 4] << 8) #util.xxd(buf[cur_pos:cur_pos+len_1 + 2]) #util.xxd(buf[cur_pos: cur_pos + len_1 + 2], True) self.parse_diag(buf[cur_pos:cur_pos + len_1 + 2]) cur_pos += (len_1 + 2) #print('%s/%s' % (cur_pos, len(buf))) #print('---- end ----') except KeyboardInterrupt: return
def parse_diag_log_e303(self, pkt): #print('parse_diag_log_e303') #util.xxd(pkt) process = { # 0x00 - only used during diag setup 0x01: lambda x: self.process_common_data(x), 0x02: lambda x: self.process_lte_data(x), #0x03: lambda x: self.process_common_data(x), #0x04: lambda x: self.process_hspa_basic(x), 0x07: lambda x: self.process_ip_data(x), #0x20: lambda x: process_control_message(x), #0x21: lambda x: self.process_common_data(x), #0x22: lambda x: self.process_lte_data(x), #0x23: lambda x: process_edge_data(x), #0x24: lambda x: process_hspa_data(x), #0x25: lambda x: process_trace_data(x), # 0x44 } if not (pkt[0] == 0x7f and pkt[-1] == 0x7e): print('Invalid packet structure') util.xxd(pkt) return b'' len_1 = pkt[1] | (pkt[2] << 8) len_2 = pkt[4] | (pkt[5] << 8) stamp = pkt[6] | (pkt[7] << 8) main_cmd = pkt[8] sub_cmd = pkt[9] if main_cmd == 0xa0 or main_cmd == 0xa1: # IpcDmCmd if sub_cmd in process.keys(): return process[sub_cmd](pkt) else: #print('TODO: subcommand %02x' % sub_cmd) pass elif main_cmd == 0xa1: # IpcCtCmd print('TODO: IpcCtCmd') elif main_cmd == 0xa2: # IpcHimCmd print('TODO: IpcHimCmd') else: print('Invalid main command ID %02x' % main_cmd) return b''
def parse_wcdma_rlc_ul_am_control_pdu_log(self, pkt_ts, pkt, radio_id): print("0x4145") util.xxd(pkt, True) lcid, pdu_size = struct.unpack('<BH', pkt[0:3]) rlc_pdu = pkt[3:3 + pdu_size] # Directly pack RLC PDU on UDP packet, see epan/packet-umts_rlc-lte.h of Wireshark # Has header on PDU, CP (0x01), no ROHC # Direction: Downlink (0x01) ws_hdr = struct.pack('!BBBBB', util.wcdma_rlc_tags.RLC_MODE_TAG, util.wcdma_rlc_mode_types.RLC_AM, util.wcdma_rlc_tags.RLC_DIRECTION_TAG, util.wcdma_rlc_direction_types.DIRECTION_UPLINK, util.wcdma_rlc_tags.RLC_PAYLOAD_TAG) self.parent.writer.write_up(b'umts-rlc' + ws_hdr + rlc_pdu, radio_id, pkt_ts)
def parse_wcdma_search_cell_reselection(self, pkt_ts, pkt, radio_id): pkt_version = (pkt[0] >> 6) # upper 2b if pkt_version == 0: self.parse_wcdma_search_cell_reselection_v0(pkt_ts, pkt, radio_id) elif pkt_version == 1: self.parse_wcdma_search_cell_reselection_v1(pkt_ts, pkt, radio_id) elif pkt_version == 2: self.parse_wcdma_search_cell_reselection_v2(pkt_ts, pkt, radio_id) else: self.parent.logger.log( logging.WARNING, 'Unsupported WCDMA search cell reselection version {}'.format( pkt_version)) self.parent.logger.log(logging.DEBUG, util.xxd(pkt))
def parse_diag(self, pkt, hdlc_encoded=True, check_crc=True, radio_id=0): # Should contain DIAG command and CRC16 # pkt should not contain trailing 0x7E, and either HDLC encoded or not # When the pkt is not HDLC encoded, hdlc_encoded should be set to True # radio_id = 0 for default, larger than 1 for SIM 1 and such if len(pkt) < 3: return if hdlc_encoded: pkt = util.unwrap(pkt) # Check and strip CRC if existing if check_crc: crc = util.dm_crc16(pkt[:-2]) crc_pkt = (pkt[-1] << 8) | pkt[-2] if crc != crc_pkt: self.logger.log( logging.WARNING, "CRC mismatch: expected 0x{:04x}, got 0x{:04x}".format( crc, crc_pkt)) self.logger.log(logging.DEBUG, util.xxd(pkt)) pkt = pkt[:-2] if pkt[0] == diagcmd.DIAG_LOG_F: self.parse_diag_log(pkt, radio_id) elif pkt[0] == diagcmd.DIAG_EVENT_REPORT_F and self.parse_events: self.parse_diag_event(pkt, radio_id) elif pkt[0] == diagcmd.DIAG_EXT_MSG_F and self.parse_msgs: self.parse_diag_ext_msg(pkt, radio_id) elif pkt[0] == diagcmd.DIAG_QSR_EXT_MSG_TERSE_F and self.parse_msgs: #self.parse_diag_qsr_ext_msg(pkt, radio_id) pass elif pkt[0] == diagcmd.DIAG_QSR4_EXT_MSG_TERSE_F and self.parse_msgs: #self.parse_diag_qsr4_ext_msg(pkt, radio_id) pass elif pkt[0] == diagcmd.DIAG_MULTI_RADIO_CMD_F: self.parse_diag_multisim(pkt) else: #print("Not parsing non-Log packet %02x" % pkt[0]) #util.xxd(pkt) return
def process_lte_data(self, pkt): # 0x00: LTE PHY Status # 0x01: LTE PHY Cell Search Measurement # 0x04: LTE PHY System Info # 0x05: LTE PHY Channel Quality Info # 0x06: LTE PHY Parameter # 0x07: LTE PHY PHICH Info # 0x10: LTE L1 RF # 0x11: LTE L1 Sync # 0x12: LTE L1 Downlink # 0x13: LTE L1 Uplink # 0x18: LTE L1 Measurement Config # 0x30: LTE L2 UL Specific Param # 0x31: LTE L2 DL-SCH Config # 0x32: LTE L2 UL-SCH Config # 0x33: LTE L2 Time Alignment Timer (N_TA uint16 / FFFF == invalid?) # 0x34: LTE L2 PHR Config (periodicPHR-Timer uint16, prohibitPHR-Timer uint16, dl-PathlossChange uint16) RRCConnectionSetup # 0x35: LTE L2 Preamble Info (numberOfRA-Preambles uint16, sizeofRA-PreamblesGroupA uint16) SIB2 # 0x36: LTE L2 Power Ramping Step (powerRampingStep uint8, preambleInitialRXTargetPower int8) SIB2 # 0x37: LTE L2 RA Supervision Info (preambleTransMax uint8, ra-ResponseWindowSize uint8, mac-ContentionResolutionTimer uint8) SIB2 # 0x38: LTE L2 Max HARQ Msg 3 Tx (maxHARQ-Msg3Tx uint8) SIB2 # 0x39: LTE L2 RACH Info # 0x3A: LTE L2 RNTI Info # 0x3C: LTE L2 UL Sync Stat Info # 0x40: LTE L2 RB Info # 0x41: LTE L2 RLS Status Info # 0x42: LTE L2 PDCP UL Info # 0x43: LTE L2 PDCP DL Info # 0x50: LTE RRC Serving Cell # 0x51: LTE RRC Status Variable (00 - IDLE, 01 - CONNECTING, 02 - CONNECTED) # 0x52: LTE RRC OTA Packet # 0x53: LTE RRC Timer # 0x54: LTE RRC ASN Version # 0x58: LTE NAS SIM Data # 0x59: LTE NAS Status Variable # 0x5A: LTE NAS EMM Message # 0x5B: LTE NAS PLMN Selection # 0x5C: LTE NAS Security # 0x5D: LTE NAS PDP # 0x5E: LTE NAS IP # 0x5F: LTE NAS ESM Message # 0x60: LTE Data Throughput Info # 0x61: LTE Data Timing Info pkt = pkt[10:-1] arfcn = 0 if pkt[0] == 0x52: # 0x52: LTE RRC OTA Packet # pkt[1] - pkt[4]: TS channel = pkt[5] direction = pkt[6] # 0: DL, 1: UL rrc_len = pkt[7] | (pkt[8] << 8) rrc_msg = pkt[9:] rrc_subtype_dl = { 0: util.gsmtap_lte_rrc_types.DL_CCCH, 1: util.gsmtap_lte_rrc_types.PCCH, 2: util.gsmtap_lte_rrc_types.BCCH_BCH, 3: util.gsmtap_lte_rrc_types.BCCH_DL_SCH, 4: util.gsmtap_lte_rrc_types.DL_DCCH } rrc_subtype_ul = { 0: util.gsmtap_lte_rrc_types.UL_CCCH, 4: util.gsmtap_lte_rrc_types.UL_DCCH } subtype = 0 try: if direction == 0: subtype = rrc_subtype_dl[channel] else: subtype = rrc_subtype_ul[channel] except KeyError: print("Unknown LTE RRC channel type %d" % channel) util.xxd(pkt) if direction == 0: arfcn = self.lte_last_earfcn_dl else: arfcn = self.lte_last_earfcn_ul gsmtap_hdr = util.create_gsmtap_header( version=2, payload_type=util.gsmtap_type.LTE_RRC, arfcn=arfcn, sub_type=subtype) return gsmtap_hdr + rrc_msg elif pkt[0] == 0x55: # TODO: RACH Preamble/Response # pkt[1] - pkt[4]: TS direction = pkt[5] # 0 - UL, 1 - DL rach_vals = struct.unpack('<HIIH', pkt[6:18]) if direction == 0: # UL: RACH cause, Preamble ID, ?, ? pass elif direction == 1: # DL: ?, Preamble ID, TA, T-C-RNTI # MAC-LTE: RAR Header, TA, UL Grant, T-C-RNTI pass else: assert False, "Invalid RACH direction" return b'' elif pkt[0] == 0x5a or pkt[0] == 0x5f: # 0x5A: LTE NAS EMM Message # 0x5F: LTE NAS ESM Message # pkt[1] - pkt[4]: TS? direction = pkt[5] # 0 - DL, 1 - UL nas_len = pkt[6] | (pkt[7] << 8) # pkt[8] - duplicate? nas_msg = pkt[9:] if direction == 0: arfcn = self.lte_last_earfcn_dl else: arfcn = self.lte_last_earfcn_ul gsmtap_hdr = util.create_gsmtap_header( version=2, payload_type=util.gsmtap_type.LTE_NAS, arfcn=arfcn) return gsmtap_hdr + nas_msg else: #if len(pkt) < 0x60: # util.xxd(pkt) return b''
def parse_wcdma_rrc(self, pkt_ts, pkt, radio_id): channel_type, rbid, msg_len = struct.unpack('<BBH', pkt[0:4]) sib_class = -1 arfcn = 0 msg_content = b'' channel_type_map = { 0: util.gsmtap_umts_rrc_types.UL_CCCH, 1: util.gsmtap_umts_rrc_types.UL_DCCH, 2: util.gsmtap_umts_rrc_types.DL_CCCH, 3: util.gsmtap_umts_rrc_types.DL_DCCH, 4: util.gsmtap_umts_rrc_types.BCCH_BCH, # Encoded 5: util.gsmtap_umts_rrc_types.BCCH_FACH, # Encoded 6: util.gsmtap_umts_rrc_types.PCCH, 7: util.gsmtap_umts_rrc_types.MCCH, 8: util.gsmtap_umts_rrc_types.MSCH, 10: util.gsmtap_umts_rrc_types.System_Information_Container, } channel_type_map_extended_type = { 9: util.gsmtap_umts_rrc_types.BCCH_BCH, # Extension SIBs 0xFE: util.gsmtap_umts_rrc_types.BCCH_BCH, # Decoded 0xFF: util.gsmtap_umts_rrc_types.BCCH_FACH # Decoded } sib_type_map = { 0: util.gsmtap_umts_rrc_types.MasterInformationBlock, 1: util.gsmtap_umts_rrc_types.SysInfoType1, 2: util.gsmtap_umts_rrc_types.SysInfoType2, 3: util.gsmtap_umts_rrc_types.SysInfoType3, 4: util.gsmtap_umts_rrc_types.SysInfoType4, 5: util.gsmtap_umts_rrc_types.SysInfoType5, 6: util.gsmtap_umts_rrc_types.SysInfoType6, 7: util.gsmtap_umts_rrc_types.SysInfoType7, 8: util.gsmtap_umts_rrc_types.SysInfoType8, 9: util.gsmtap_umts_rrc_types.SysInfoType9, 10: util.gsmtap_umts_rrc_types.SysInfoType10, 11: util.gsmtap_umts_rrc_types.SysInfoType11, 12: util.gsmtap_umts_rrc_types.SysInfoType12, 13: util.gsmtap_umts_rrc_types.SysInfoType13, 14: util.gsmtap_umts_rrc_types.SysInfoType13_1, 15: util.gsmtap_umts_rrc_types.SysInfoType13_2, 16: util.gsmtap_umts_rrc_types.SysInfoType13_3, 17: util.gsmtap_umts_rrc_types.SysInfoType13_4, 18: util.gsmtap_umts_rrc_types.SysInfoType14, 19: util.gsmtap_umts_rrc_types.SysInfoType15, 20: util.gsmtap_umts_rrc_types.SysInfoType15_1, 21: util.gsmtap_umts_rrc_types.SysInfoType15_2, 22: util.gsmtap_umts_rrc_types.SysInfoType15_3, 23: util.gsmtap_umts_rrc_types.SysInfoType16, 24: util.gsmtap_umts_rrc_types.SysInfoType17, 25: util.gsmtap_umts_rrc_types.SysInfoType15_4, 26: util.gsmtap_umts_rrc_types.SysInfoType18, 27: util.gsmtap_umts_rrc_types.SysInfoTypeSB1, 28: util.gsmtap_umts_rrc_types.SysInfoTypeSB2, 29: util.gsmtap_umts_rrc_types.SysInfoType15_5, 30: util.gsmtap_umts_rrc_types.SysInfoType5bis, 31: util.gsmtap_umts_rrc_types.SysInfoType11bis, # Extension SIB 66: util.gsmtap_umts_rrc_types.SysInfoType11bis, 67: util.gsmtap_umts_rrc_types.SysInfoType19 } channel_type_map_new = { 0x80: util.gsmtap_umts_rrc_types.UL_CCCH, 0x81: util.gsmtap_umts_rrc_types.UL_DCCH, 0x82: util.gsmtap_umts_rrc_types.DL_CCCH, 0x83: util.gsmtap_umts_rrc_types.DL_DCCH, 0x84: util.gsmtap_umts_rrc_types.BCCH_BCH, # Encoded 0x85: util.gsmtap_umts_rrc_types.BCCH_FACH, # Encoded 0x86: util.gsmtap_umts_rrc_types.PCCH, 0x87: util.gsmtap_umts_rrc_types.MCCH, 0x88: util.gsmtap_umts_rrc_types.MSCH, } channel_type_map_new_extended_type = { 0x89: util.gsmtap_umts_rrc_types.BCCH_BCH, # Extension SIBs 0xF0: util.gsmtap_umts_rrc_types.BCCH_BCH, # Decoded } sib_type_map_new = { 0: util.gsmtap_umts_rrc_types.MasterInformationBlock, 1: util.gsmtap_umts_rrc_types.SysInfoType1, 2: util.gsmtap_umts_rrc_types.SysInfoType2, 3: util.gsmtap_umts_rrc_types.SysInfoType3, 4: util.gsmtap_umts_rrc_types.SysInfoType4, 5: util.gsmtap_umts_rrc_types.SysInfoType5, 6: util.gsmtap_umts_rrc_types.SysInfoType6, 7: util.gsmtap_umts_rrc_types.SysInfoType7, 8: util.gsmtap_umts_rrc_types.SysInfoType8, 9: util.gsmtap_umts_rrc_types.SysInfoType9, 10: util.gsmtap_umts_rrc_types.SysInfoType10, 11: util.gsmtap_umts_rrc_types.SysInfoType11, 12: util.gsmtap_umts_rrc_types.SysInfoType12, 13: util.gsmtap_umts_rrc_types.SysInfoType13, 14: util.gsmtap_umts_rrc_types.SysInfoType13_1, 15: util.gsmtap_umts_rrc_types.SysInfoType13_2, 16: util.gsmtap_umts_rrc_types.SysInfoType13_3, 17: util.gsmtap_umts_rrc_types.SysInfoType13_4, 18: util.gsmtap_umts_rrc_types.SysInfoType14, 19: util.gsmtap_umts_rrc_types.SysInfoType15, 20: util.gsmtap_umts_rrc_types.SysInfoType15_1, 21: util.gsmtap_umts_rrc_types.SysInfoType15_2, 22: util.gsmtap_umts_rrc_types.SysInfoType15_3, 23: util.gsmtap_umts_rrc_types.SysInfoType16, 24: util.gsmtap_umts_rrc_types.SysInfoType17, 25: util.gsmtap_umts_rrc_types.SysInfoType15_4, 26: util.gsmtap_umts_rrc_types.SysInfoType18, 27: util.gsmtap_umts_rrc_types.SysInfoTypeSB1, 28: util.gsmtap_umts_rrc_types.SysInfoTypeSB2, 29: util.gsmtap_umts_rrc_types.SysInfoType15_5, 30: util.gsmtap_umts_rrc_types.SysInfoType5bis, 31: util.gsmtap_umts_rrc_types.SysInfoType19, # Extension SIB 66: util.gsmtap_umts_rrc_types.SysInfoType11bis, 67: util.gsmtap_umts_rrc_types.SysInfoType19 } if channel_type in channel_type_map.keys(): arfcn = self.parent.umts_last_uarfcn_dl[ self.parent.sanitize_radio_id(radio_id)] if channel_type == 0 or channel_type == 1: arfcn = self.parent.umts_last_uarfcn_ul[ self.parent.sanitize_radio_id(radio_id)] subtype = channel_type_map[channel_type] msg_content = pkt[4:] elif channel_type in channel_type_map_extended_type.keys(): arfcn = self.parent.umts_last_uarfcn_dl[ self.parent.sanitize_radio_id(radio_id)] # uint8 subtype, uint8 msg[] if pkt[4] in sib_type_map.keys(): subtype = sib_type_map[pkt[4]] msg_content = pkt[5:] else: self.parent.logger.log( logging.WARNING, "Unknown WCDMA SIB Class {}".format(pkt[4])) return elif channel_type in channel_type_map_new.keys(): # uint16 uarfcn, uint16 psc, uint8 msg[] arfcn, psc = struct.unpack('<HH', pkt[4:8]) subtype = channel_type_map_new[channel_type] msg_content = pkt[8:] elif channel_type in channel_type_map_new_extended_type.keys(): # uint16 uarfcn, uint16 psc, uint8 subtype, uint8 msg[] arfcn, psc = struct.unpack('<HH', pkt[4:8]) if pkt[8] in sib_type_map_new.keys(): subtype = sib_type_map_new[pkt[8]] msg_content = pkt[9:] else: self.parent.logger.log( logging.WARNING, "Unknown WCDMA new SIB Class {}".format(pkt[8])) return else: self.parent.logger.log( logging.WARNING, "Unknown WCDMA RRC channel type {}".format(pkt[0])) self.parent.logger.log(logging.DEBUG, util.xxd(pkt)) return ts_sec = calendar.timegm(pkt_ts.timetuple()) ts_usec = pkt_ts.microsecond gsmtap_hdr = util.create_gsmtap_header( version=3, payload_type=util.gsmtap_type.UMTS_RRC, arfcn=arfcn, sub_type=subtype, device_sec=ts_sec, device_usec=ts_usec) self.parent.writer.write_cp(gsmtap_hdr + msg_content, radio_id, pkt_ts)
def parse_wcdma_rlc_ul_am_signaling_pdu(self, pkt_ts, pkt, radio_id): print("0x413C") util.xxd(pkt, True)