decode: add some python tools to decode SniffUSB dumps
decode.py will read SniffUSB logs of communication with QMUX or WMC speaking devices. It will dump the packets in both hex and ASCII. If you know something about the device then you can tell it to decode the packets. For example, we know the Pantech UML290's WMC port speaks WMC using Bulk Transfers, so we can: decode.py --transfer=wmc <path to sniffusb logs> or we know the UML290's "rmnet" port speaks raw IP in the Bulk Transfers and QMUX in the Control Transfers, so: decode.py --control=qmux <path to sniffusb logs> qmiprotgen.py takes a path to an Entities.txt file and dumps out the protocol entities and services in Python code which is used by qmux.py. xml2ascii.py and analyze.py dump out UsbSnoopy XML logs but these are not as usable as the SniffUSB logs (they do not provide good direction information). http://www.wingmanteam.com/usbsnoopy/ http://www.pcausa.com/Utilities/UsbSnoop/
This commit is contained in:
179
decode/analyze.py
Executable file
179
decode/analyze.py
Executable file
@@ -0,0 +1,179 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details:
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# ---- Dumps UsbSnoopy XML captures of WMC traffic
|
||||||
|
|
||||||
|
from xml.sax import saxutils
|
||||||
|
from xml.sax import handler
|
||||||
|
import binascii
|
||||||
|
import string
|
||||||
|
|
||||||
|
packets = []
|
||||||
|
counts = {}
|
||||||
|
|
||||||
|
TO_UNKNOWN = 0
|
||||||
|
TO_MODEM = 1
|
||||||
|
TO_HOST = 2
|
||||||
|
|
||||||
|
class Packet:
|
||||||
|
def __init__(self, data, idx):
|
||||||
|
if len(data) % 2 != 0:
|
||||||
|
raise Exception("bad data length")
|
||||||
|
|
||||||
|
self.idx = idx
|
||||||
|
self.type = TO_UNKNOWN
|
||||||
|
if data[:14] == "41542a574d433d":
|
||||||
|
# host->device: remove the AT*WMC= bits and newline at the end
|
||||||
|
data = data[14:]
|
||||||
|
if data[len(data) - 2:] == "0d":
|
||||||
|
data = data[:len(data) - 2]
|
||||||
|
self.type = TO_MODEM
|
||||||
|
# elif data[len(data) - 6:] == "30307e":
|
||||||
|
# # device->host: remove HDLC terminator and fake CRC
|
||||||
|
# data = data[:len(data) - 6]
|
||||||
|
# self.type = TO_HOST
|
||||||
|
elif data[len(data) - 2:] == "7e":
|
||||||
|
# device->host: remove HDLC terminator and CRC
|
||||||
|
data = data[:len(data) - 6]
|
||||||
|
self.type = TO_HOST
|
||||||
|
|
||||||
|
self.data = binascii.unhexlify(data)
|
||||||
|
self.four = data[:4]
|
||||||
|
|
||||||
|
# PPP-unescape TO_MODEM data
|
||||||
|
escape = False
|
||||||
|
new_data = ""
|
||||||
|
for i in self.data:
|
||||||
|
if ord(i) == 0x7D:
|
||||||
|
escape = True
|
||||||
|
elif escape == True:
|
||||||
|
new_data += chr(ord(i) ^ 0x20)
|
||||||
|
escape = False
|
||||||
|
else:
|
||||||
|
new_data += i
|
||||||
|
self.data = new_data
|
||||||
|
|
||||||
|
def add_ascii(self, line, items):
|
||||||
|
if len(line) < 53:
|
||||||
|
line += " " * (53 - len(line))
|
||||||
|
for i in items:
|
||||||
|
if chr(i) in string.printable and i >= 32:
|
||||||
|
line += chr(i)
|
||||||
|
else:
|
||||||
|
line += "."
|
||||||
|
return line
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
line = "*"
|
||||||
|
if self.type == TO_MODEM:
|
||||||
|
line = ">"
|
||||||
|
elif self.type == TO_HOST:
|
||||||
|
line = "<"
|
||||||
|
|
||||||
|
offset = 0
|
||||||
|
items = []
|
||||||
|
printed = False
|
||||||
|
for i in self.data:
|
||||||
|
printed = False
|
||||||
|
line += " %02x" % ord(i)
|
||||||
|
items.append(ord(i))
|
||||||
|
if len(items) % 16 == 0:
|
||||||
|
print "%03d: %s" % (offset, self.add_ascii(line, items))
|
||||||
|
line = " "
|
||||||
|
items = []
|
||||||
|
printed = True
|
||||||
|
offset += 16
|
||||||
|
if not printed:
|
||||||
|
print "%03d: %s" % (offset, self.add_ascii(line, items))
|
||||||
|
print ""
|
||||||
|
|
||||||
|
class FindPackets(handler.ContentHandler):
|
||||||
|
def __init__(self):
|
||||||
|
self.inFunction = False
|
||||||
|
self.inPayload = False
|
||||||
|
self.ignore = False
|
||||||
|
self.inTimestamp = False
|
||||||
|
self.timestamp = None
|
||||||
|
self.packet = None
|
||||||
|
self.idx = 1
|
||||||
|
|
||||||
|
def startElement(self, name, attrs):
|
||||||
|
if name == "function":
|
||||||
|
self.inFunction = True
|
||||||
|
elif name == "payloadbytes":
|
||||||
|
self.inPayload = True
|
||||||
|
elif name == "timestamp":
|
||||||
|
self.inTimestamp = True
|
||||||
|
|
||||||
|
def characters(self, ch):
|
||||||
|
if self.ignore:
|
||||||
|
return
|
||||||
|
|
||||||
|
stripped = ch.strip()
|
||||||
|
if self.inFunction and ch != "BULK_OR_INTERRUPT_TRANSFER":
|
||||||
|
self.ignore = True
|
||||||
|
return
|
||||||
|
elif self.inTimestamp:
|
||||||
|
self.timestamp = stripped
|
||||||
|
elif self.inPayload and len(stripped) > 0:
|
||||||
|
if self.packet == None:
|
||||||
|
self.packet = stripped
|
||||||
|
else:
|
||||||
|
self.packet += stripped
|
||||||
|
|
||||||
|
def endElement(self, name):
|
||||||
|
if name == "function":
|
||||||
|
self.inFunction = False
|
||||||
|
elif name == "payloadbytes":
|
||||||
|
self.inPayload = False
|
||||||
|
elif name == "payload":
|
||||||
|
if self.packet:
|
||||||
|
p = Packet(self.packet, self.idx)
|
||||||
|
self.idx = self.idx + 1
|
||||||
|
packets.append(p)
|
||||||
|
self.packet = None
|
||||||
|
|
||||||
|
self.ignore = False
|
||||||
|
self.timestamp = None
|
||||||
|
elif name == "timestamp":
|
||||||
|
self.inTimestamp = False
|
||||||
|
|
||||||
|
|
||||||
|
from xml.sax import make_parser
|
||||||
|
from xml.sax import parse
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
dh = FindPackets()
|
||||||
|
parse(sys.argv[1], dh)
|
||||||
|
|
||||||
|
cmds = {}
|
||||||
|
for p in packets:
|
||||||
|
if cmds.has_key(p.four):
|
||||||
|
cmds[p.four].append(p)
|
||||||
|
else:
|
||||||
|
cmds[p.four] = [p]
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
if p.four == sys.argv[2]:
|
||||||
|
p.show()
|
||||||
|
else:
|
||||||
|
p.show()
|
||||||
|
|
||||||
|
print ""
|
||||||
|
print "cmd #tot"
|
||||||
|
for k in cmds.keys():
|
||||||
|
print "%s (%d)" % (k, len(cmds[k]))
|
||||||
|
print ""
|
||||||
|
|
71
decode/decode.py
Executable file
71
decode/decode.py
Executable file
@@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details:
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
|
||||||
|
import binascii
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
import defs
|
||||||
|
from packet import Packet
|
||||||
|
|
||||||
|
packets = []
|
||||||
|
control = None
|
||||||
|
transfer = None
|
||||||
|
|
||||||
|
def get_protocol(arg):
|
||||||
|
return arg[arg.index("=") + 1:]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
i = 1
|
||||||
|
if sys.argv[i].startswith("--control="):
|
||||||
|
control = get_protocol(sys.argv[i])
|
||||||
|
i = i + 1
|
||||||
|
if sys.argv[i].startswith("--transfer="):
|
||||||
|
transfer = get_protocol(sys.argv[i])
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
path = sys.argv[i]
|
||||||
|
f = open(path, 'r')
|
||||||
|
lines = f.readlines()
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
in_packet = False
|
||||||
|
finish_packet = False
|
||||||
|
pkt_lines = []
|
||||||
|
for l in lines:
|
||||||
|
if l[0] == '[':
|
||||||
|
# Start of a packet
|
||||||
|
if "] >>> URB" in l or "] <<< URB" in l:
|
||||||
|
if in_packet == True:
|
||||||
|
in_packet = False
|
||||||
|
finish_packet = True
|
||||||
|
else:
|
||||||
|
in_packet = True
|
||||||
|
elif "] UsbSnoop - " in l:
|
||||||
|
# Packet done?
|
||||||
|
if in_packet == True:
|
||||||
|
in_packet = False
|
||||||
|
finish_packet = True
|
||||||
|
|
||||||
|
if finish_packet == True:
|
||||||
|
packets.append(Packet(pkt_lines, control, transfer))
|
||||||
|
pkt_lines = []
|
||||||
|
finish_packet = False
|
||||||
|
|
||||||
|
if in_packet == True:
|
||||||
|
pkt_lines.append(l)
|
||||||
|
|
||||||
|
for p in packets:
|
||||||
|
p.show()
|
20
decode/defs.py
Normal file
20
decode/defs.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details:
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
|
||||||
|
TO_UNKNOWN = 0
|
||||||
|
TO_MODEM = 1
|
||||||
|
TO_HOST = 2
|
||||||
|
|
192
decode/packet.py
Normal file
192
decode/packet.py
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details:
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
|
||||||
|
import binascii
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import defs
|
||||||
|
|
||||||
|
import wmc
|
||||||
|
|
||||||
|
URBF_UNKNOWN = 0
|
||||||
|
URBF_GET_DESC = 1
|
||||||
|
URBF_SEL_CONF = 2
|
||||||
|
URBF_RESET_PIPE = 3
|
||||||
|
URBF_TRANSFER = 4
|
||||||
|
URBF_GET_STATUS = 5
|
||||||
|
URBF_CONTROL = 6
|
||||||
|
|
||||||
|
funcs = {
|
||||||
|
"-- URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:": (URBF_GET_DESC, False, None),
|
||||||
|
"-- URB_FUNCTION_SELECT_CONFIGURATION:": (URBF_SEL_CONF, False, None),
|
||||||
|
"-- URB_FUNCTION_RESET_PIPE:": (URBF_RESET_PIPE, False, None),
|
||||||
|
"-- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:": (URBF_TRANSFER, True, "T"),
|
||||||
|
"-- URB_FUNCTION_GET_STATUS_FROM_DEVICE:": (URBF_GET_STATUS, False, None),
|
||||||
|
"-- URB_FUNCTION_CONTROL_TRANSFER:": (URBF_CONTROL, True, "C")
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_urb_info(l):
|
||||||
|
num = 0
|
||||||
|
direction = defs.TO_UNKNOWN
|
||||||
|
|
||||||
|
idx = string.find(l, ">>> URB ")
|
||||||
|
if idx >= 0:
|
||||||
|
direction = defs.TO_MODEM
|
||||||
|
else:
|
||||||
|
idx = string.find(l, "<<< URB ")
|
||||||
|
if idx >= 0:
|
||||||
|
direction = defs.TO_HOST
|
||||||
|
else:
|
||||||
|
raise Exception("Invalid packet start line")
|
||||||
|
|
||||||
|
numstr = ""
|
||||||
|
for c in l[idx + 9:]:
|
||||||
|
if c.isdigit():
|
||||||
|
numstr = numstr + c
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
if not len(numstr):
|
||||||
|
raise Exception("Failed to get URB number ('%s')" % l)
|
||||||
|
|
||||||
|
return (direction, int(numstr))
|
||||||
|
|
||||||
|
class Packet:
|
||||||
|
def __init__(self, lines, control_prot, transfer_prot):
|
||||||
|
self.direction = defs.TO_UNKNOWN
|
||||||
|
self.func = URBF_UNKNOWN
|
||||||
|
self.extra = []
|
||||||
|
self.data = None
|
||||||
|
self.urbnum = 0
|
||||||
|
self.protocol = None
|
||||||
|
self.has_data = False
|
||||||
|
self.typecode = None
|
||||||
|
|
||||||
|
# Parse the packet
|
||||||
|
|
||||||
|
(self.direction, self.urbnum) = get_urb_info(lines[0])
|
||||||
|
|
||||||
|
try:
|
||||||
|
(self.func, self.has_data, self.typecode) = funcs[lines[1].strip()]
|
||||||
|
except KeyError:
|
||||||
|
raise KeyError("URB function %s not handled" % lines[1].strip())
|
||||||
|
|
||||||
|
if self.func == URBF_TRANSFER:
|
||||||
|
self.protocol = transfer_prot
|
||||||
|
elif self.func == URBF_CONTROL:
|
||||||
|
self.protocol = control_prot
|
||||||
|
|
||||||
|
# Parse transfer buffer data
|
||||||
|
in_data = False
|
||||||
|
data = ""
|
||||||
|
for i in range(2, len(lines)):
|
||||||
|
l = lines[i].strip()
|
||||||
|
if self.has_data:
|
||||||
|
if l.startswith("TransferBufferMDL"):
|
||||||
|
if in_data == True:
|
||||||
|
raise Exception("Already in data")
|
||||||
|
in_data = True
|
||||||
|
elif l.startswith("UrbLink"):
|
||||||
|
in_data = False
|
||||||
|
elif in_data and len(l) and not "no data supplied" in l:
|
||||||
|
d = l[l.index(": ") + 2:] # get data alone
|
||||||
|
data += d.replace(" ", "")
|
||||||
|
else:
|
||||||
|
self.extra.append(l)
|
||||||
|
|
||||||
|
if len(data) > 0:
|
||||||
|
self.parse_data(data)
|
||||||
|
|
||||||
|
def get_funcs(self):
|
||||||
|
if self.protocol:
|
||||||
|
exec "from %s import get_funcs" % self.protocol
|
||||||
|
return get_funcs()
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
def parse_data(self, data):
|
||||||
|
if not self.has_data:
|
||||||
|
raise Exception("Data only valid for URBF_TRANSFER or URBF_CONTROL")
|
||||||
|
|
||||||
|
(unpack, show) = self.get_funcs()
|
||||||
|
if unpack:
|
||||||
|
self.data = unpack(data, self.direction)
|
||||||
|
else:
|
||||||
|
self.data = binascii.unhexlify(data)
|
||||||
|
|
||||||
|
def add_ascii(self, line, items):
|
||||||
|
if len(line) < 53:
|
||||||
|
line += " " * (53 - len(line))
|
||||||
|
for i in items:
|
||||||
|
if chr(i) in string.printable and i >= 32:
|
||||||
|
line += chr(i)
|
||||||
|
else:
|
||||||
|
line += "."
|
||||||
|
return line
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
if not self.has_data or not self.data:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Ignore URBF_TRANSFER packets that appear to be returning SetupPacket data
|
||||||
|
if self.data == chr(0xa1) + chr(0x01) + chr(0x00) + chr(0x00) + chr(0x05) + chr(0x00) + chr(0x00) + chr(0x00):
|
||||||
|
return
|
||||||
|
|
||||||
|
offset = 0
|
||||||
|
items = []
|
||||||
|
printed = False
|
||||||
|
line = ""
|
||||||
|
|
||||||
|
prefix = "*"
|
||||||
|
if self.direction == defs.TO_MODEM:
|
||||||
|
prefix = ">"
|
||||||
|
elif self.direction == defs.TO_HOST:
|
||||||
|
prefix = "<"
|
||||||
|
|
||||||
|
if self.typecode:
|
||||||
|
prefix = prefix + " " + self.typecode + " "
|
||||||
|
else:
|
||||||
|
prefix = prefix + " "
|
||||||
|
|
||||||
|
prefix_printed = False
|
||||||
|
for i in self.data:
|
||||||
|
printed = False
|
||||||
|
line += " %02x" % ord(i)
|
||||||
|
items.append(ord(i))
|
||||||
|
if len(items) % 16 == 0:
|
||||||
|
output = "%04d: %s" % (offset, self.add_ascii(line, items))
|
||||||
|
if offset == 0:
|
||||||
|
print prefix + output
|
||||||
|
else:
|
||||||
|
print " " + output
|
||||||
|
line = ""
|
||||||
|
items = []
|
||||||
|
printed = True
|
||||||
|
offset += 16
|
||||||
|
prefix_printed = True
|
||||||
|
|
||||||
|
if not printed:
|
||||||
|
output = "%04d: %s" % (offset, self.add_ascii(line, items))
|
||||||
|
if prefix_printed:
|
||||||
|
print " " + output
|
||||||
|
else:
|
||||||
|
print prefix + output
|
||||||
|
print ""
|
||||||
|
|
||||||
|
(unpack, show) = self.get_funcs()
|
||||||
|
if show:
|
||||||
|
show(self.data, " " * 8, self.direction)
|
||||||
|
|
494
decode/qmiprotgen.py
Executable file
494
decode/qmiprotgen.py
Executable file
@@ -0,0 +1,494 @@
|
|||||||
|
#!/bin/env python
|
||||||
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
|
||||||
|
# Takes an Entity.txt and generates the Python dicts defining the commands
|
||||||
|
# and the TLVs associated with those commands
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
TP_REQUEST = 0
|
||||||
|
TP_RESPONSE = 1
|
||||||
|
TP_INDICATION = 2
|
||||||
|
|
||||||
|
cmdenum = """
|
||||||
|
eQMI_CTL_SET_INSTANCE_ID = 32, // 32 Set the unique link instance ID
|
||||||
|
eQMI_CTL_GET_VERSION_INFO, // 33 Get supported service version info
|
||||||
|
eQMI_CTL_GET_CLIENT_ID, // 34 Get a unique client ID
|
||||||
|
eQMI_CTL_RELEASE_CLIENT_ID, // 35 Release the unique client ID
|
||||||
|
eQMI_CTL_REVOKE_CLIENT_ID_IND, // 36 Indication of client ID revocation
|
||||||
|
eQMI_CTL_INVALID_CLIENT_ID, // 37 Indication of invalid client ID
|
||||||
|
eQMI_CTL_SET_DATA_FORMAT, // 38 Set host driver data format
|
||||||
|
eQMI_CTL_SYNC, // 39 Synchronize client/server
|
||||||
|
eQMI_CTL_SYNC_IND = 39, // 39 Synchronize indication
|
||||||
|
eQMI_CTL_SET_EVENT, // 40 Set event report conditions
|
||||||
|
eQMI_CTL_EVENT_IND = 40, // 40 Event report indication
|
||||||
|
eQMI_CTL_SET_POWER_SAVE_CFG, // 41 Set power save config
|
||||||
|
eQMI_CTL_SET_POWER_SAVE_MODE, // 42 Set power save mode
|
||||||
|
eQMI_CTL_GET_POWER_SAVE_MODE, // 43 Get power save mode
|
||||||
|
|
||||||
|
eQMI_WDS_RESET, // 00 Reset WDS service state variables
|
||||||
|
eQMI_WDS_SET_EVENT, // 01 Set connection state report conditions
|
||||||
|
eQMI_WDS_EVENT_IND = 1, // 01 Connection state report indication
|
||||||
|
eQMI_WDS_ABORT, // 02 Abort previously issued WDS command
|
||||||
|
eQMI_WDS_START_NET = 32, // 32 Start WDS network interface
|
||||||
|
eQMI_WDS_STOP_NET, // 33 Stop WDS network interface
|
||||||
|
eQMI_WDS_GET_PKT_STATUS, // 34 Get packet data connection status
|
||||||
|
eQMI_WDS_PKT_STATUS_IND = 34, // 34 Packet data connection status indication
|
||||||
|
eQMI_WDS_GET_RATES, // 35 Get current bit rates of the connection
|
||||||
|
eQMI_WDS_GET_STATISTICS, // 36 Get the packet data transfer statistics
|
||||||
|
eQMI_WDS_G0_DORMANT, // 37 Go dormant
|
||||||
|
eQMI_WDS_G0_ACTIVE, // 38 Go active
|
||||||
|
eQMI_WDS_CREATE_PROFILE, // 39 Create profile with specified settings
|
||||||
|
eQMI_WDS_MODIFY_PROFILE, // 40 Modify profile with specified settings
|
||||||
|
eQMI_WDS_DELETE_PROFILE, // 41 Delete the specified profile
|
||||||
|
eQMI_WDS_GET_PROFILE_LIST, // 42 Get all profiles
|
||||||
|
eQMI_WDS_GET_PROFILE, // 43 Get the specified profile
|
||||||
|
eQMI_WDS_GET_DEFAULTS, // 44 Get the default data session settings
|
||||||
|
eQMI_WDS_GET_SETTINGS, // 45 Get the runtime data session settings
|
||||||
|
eQMI_WDS_SET_MIP, // 46 Get the mobile IP setting
|
||||||
|
eQMI_WDS_GET_MIP, // 47 Set the mobile IP setting
|
||||||
|
eQMI_WDS_GET_DORMANCY, // 48 Get the dormancy status
|
||||||
|
eQMI_WDS_GET_AUTOCONNECT = 52, // 52 Get the NDIS autoconnect setting
|
||||||
|
eQMI_WDS_GET_DURATION, // 53 Get the duration of data session
|
||||||
|
eQMI_WDS_GET_MODEM_STATUS, // 54 Get the modem status
|
||||||
|
eQMI_WDS_MODEM_IND = 54, // 54 Modem status indication
|
||||||
|
eQMI_WDS_GET_DATA_BEARER, // 55 Get the data bearer type
|
||||||
|
eQMI_WDS_GET_MODEM_INFO, // 56 Get the modem info
|
||||||
|
eQMI_WDS_MODEM_INFO_IND = 56, // 56 Modem info indication
|
||||||
|
eQMI_WDS_GET_ACTIVE_MIP = 60, // 60 Get the active mobile IP profile
|
||||||
|
eQMI_WDS_SET_ACTIVE_MIP, // 61 Set the active mobile IP profile
|
||||||
|
eQMI_WDS_GET_MIP_PROFILE, // 62 Get mobile IP profile settings
|
||||||
|
eQMI_WDS_SET_MIP_PROFILE, // 63 Set mobile IP profile settings
|
||||||
|
eQMI_WDS_GET_MIP_PARAMS, // 64 Get mobile IP parameters
|
||||||
|
eQMI_WDS_SET_MIP_PARAMS, // 65 Set mobile IP parameters
|
||||||
|
eQMI_WDS_GET_LAST_MIP_STATUS, // 66 Get last mobile IP status
|
||||||
|
eQMI_WDS_GET_AAA_AUTH_STATUS, // 67 Get AN-AAA authentication status
|
||||||
|
eQMI_WDS_GET_CUR_DATA_BEARER, // 68 Get current data bearer
|
||||||
|
eQMI_WDS_GET_CALL_LIST, // 69 Get the call history list
|
||||||
|
eQMI_WDS_GET_CALL_ENTRY, // 70 Get an entry from the call history list
|
||||||
|
eQMI_WDS_CLEAR_CALL_LIST, // 71 Clear the call history list
|
||||||
|
eQMI_WDS_GET_CALL_LIST_MAX, // 72 Get maximum size of call history list
|
||||||
|
eQMI_WDS_SET_IP_FAMILY = 77, // 77 Set the client IP family preference
|
||||||
|
eQMI_WDS_SET_AUTOCONNECT = 81, // 81 Set the NDIS autoconnect setting
|
||||||
|
eQMI_WDS_GET_DNS, // 82 Get the DNS setting
|
||||||
|
eQMI_WDS_SET_DNS, // 83 Set the DNS setting
|
||||||
|
|
||||||
|
eQMI_DMS_RESET, // 00 Reset DMS service state variables
|
||||||
|
eQMI_DMS_SET_EVENT, // 01 Set connection state report conditions
|
||||||
|
eQMI_DMS_EVENT_IND = 1, // 01 Connection state report indication
|
||||||
|
eQMI_DMS_GET_CAPS = 32, // 32 Get the device capabilities
|
||||||
|
eQMI_DMS_GET_MANUFACTURER, // 33 Get the device manfacturer
|
||||||
|
eQMI_DMS_GET_MODEL_ID, // 34 Get the device model ID
|
||||||
|
eQMI_DMS_GET_REV_ID, // 35 Get the device revision ID
|
||||||
|
eQMI_DMS_GET_NUMBER, // 36 Get the assigned voice number
|
||||||
|
eQMI_DMS_GET_IDS, // 37 Get the ESN/IMEI/MEID
|
||||||
|
eQMI_DMS_GET_POWER_STATE, // 38 Get the get power state
|
||||||
|
eQMI_DMS_UIM_SET_PIN_PROT, // 39 UIM - Set PIN protection
|
||||||
|
eQMI_DMS_UIM_PIN_VERIFY, // 40 UIM - Verify PIN
|
||||||
|
eQMI_DMS_UIM_PIN_UNBLOCK, // 41 UIM - Unblock PIN
|
||||||
|
eQMI_DMS_UIM_PIN_CHANGE, // 42 UIM - Change PIN
|
||||||
|
eQMI_DMS_UIM_GET_PIN_STATUS, // 43 UIM - Get PIN status
|
||||||
|
eQMI_DMS_GET_MSM_ID = 44, // 44 Get MSM ID
|
||||||
|
eQMI_DMS_GET_OPERTAING_MODE, // 45 Get the operating mode
|
||||||
|
eQMI_DMS_SET_OPERATING_MODE, // 46 Set the operating mode
|
||||||
|
eQMI_DMS_GET_TIME, // 47 Get timestamp from the device
|
||||||
|
eQMI_DMS_GET_PRL_VERSION, // 48 Get the PRL version
|
||||||
|
eQMI_DMS_GET_ACTIVATED_STATE, // 49 Get the activation state
|
||||||
|
eQMI_DMS_ACTIVATE_AUTOMATIC, // 50 Perform an automatic activation
|
||||||
|
eQMI_DMS_ACTIVATE_MANUAL, // 51 Perform a manual activation
|
||||||
|
eQMI_DMS_GET_USER_LOCK_STATE, // 52 Get the lock state
|
||||||
|
eQMI_DMS_SET_USER_LOCK_STATE, // 53 Set the lock state
|
||||||
|
eQMI_DMS_SET_USER_LOCK_CODE, // 54 Set the lock PIN
|
||||||
|
eQMI_DMS_READ_USER_DATA, // 55 Read user data
|
||||||
|
eQMI_DMS_WRITE_USER_DATA, // 56 Write user data
|
||||||
|
eQMI_DMS_READ_ERI_FILE, // 57 Read the enhanced roaming indicator file
|
||||||
|
eQMI_DMS_FACTORY_DEFAULTS, // 58 Reset to factory defaults
|
||||||
|
eQMI_DMS_VALIDATE_SPC, // 59 Validate service programming code
|
||||||
|
eQMI_DMS_UIM_GET_ICCID, // 60 Get UIM ICCID
|
||||||
|
eQMI_DMS_GET_FIRWARE_ID, // 61 Get firmware ID
|
||||||
|
eQMI_DMS_SET_FIRMWARE_ID, // 62 Set firmware ID
|
||||||
|
eQMI_DMS_GET_HOST_LOCK_ID, // 63 Get host lock ID
|
||||||
|
eQMI_DMS_UIM_GET_CK_STATUS, // 64 UIM - Get control key status
|
||||||
|
eQMI_DMS_UIM_SET_CK_PROT, // 65 UIM - Set control key protection
|
||||||
|
eQMI_DMS_UIM_UNBLOCK_CK, // 66 UIM - Unblock facility control key
|
||||||
|
eQMI_DMS_GET_IMSI, // 67 Get the IMSI
|
||||||
|
eQMI_DMS_UIM_GET_STATE, // 68 UIM - Get the UIM state
|
||||||
|
eQMI_DMS_GET_BAND_CAPS, // 69 Get the device band capabilities
|
||||||
|
eQMI_DMS_GET_FACTORY_ID, // 70 Get the device factory ID
|
||||||
|
eQMI_DMS_GET_FIRMWARE_PREF, // 71 Get firmware preference
|
||||||
|
eQMI_DMS_SET_FIRMWARE_PREF, // 72 Set firmware preference
|
||||||
|
eQMI_DMS_LIST_FIRMWARE, // 73 List all stored firmware
|
||||||
|
eQMI_DMS_DELETE_FIRMWARE, // 74 Delete specified stored firmware
|
||||||
|
eQMI_DMS_SET_TIME, // 75 Set device time
|
||||||
|
eQMI_DMS_GET_FIRMWARE_INFO, // 76 Get stored firmware info
|
||||||
|
eQMI_DMS_GET_ALT_NET_CFG, // 77 Get alternate network config
|
||||||
|
eQMI_DMS_SET_ALT_NET_CFG, // 78 Set alternate network config
|
||||||
|
eQMI_DMS_GET_IMG_DLOAD_MODE, // 79 Get next image download mode
|
||||||
|
eQMI_DMS_SET_IMG_DLOAD_MODE, // 80 Set next image download mod
|
||||||
|
|
||||||
|
eQMI_NAS_RESET, // 00 Reset NAS service state variables
|
||||||
|
eQMI_NAS_ABORT, // 01 Abort previously issued NAS command
|
||||||
|
eQMI_NAS_SET_EVENT, // 02 Set NAS state report conditions
|
||||||
|
eQMI_NAS_EVENT_IND = 2, // 02 Connection state report indication
|
||||||
|
eQMI_NAS_SET_REG_EVENT, // 03 Set NAS registration report conditions
|
||||||
|
eQMI_NAS_GET_RSSI = 32, // 32 Get the signal strength
|
||||||
|
eQMI_NAS_SCAN_NETS, // 33 Scan for visible network
|
||||||
|
eQMI_NAS_REGISTER_NET, // 34 Initiate a network registration
|
||||||
|
eQMI_NAS_ATTACH_DETACH, // 35 Initiate an attach or detach action
|
||||||
|
eQMI_NAS_GET_SS_INFO, // 36 Get info about current serving system
|
||||||
|
eQMI_NAS_SS_INFO_IND = 36, // 36 Current serving system info indication
|
||||||
|
eQMI_NAS_GET_HOME_INFO, // 37 Get info about home network
|
||||||
|
eQMI_NAS_GET_NET_PREF_LIST, // 38 Get the list of preferred networks
|
||||||
|
eQMI_NAS_SET_NET_PREF_LIST, // 39 Set the list of preferred networks
|
||||||
|
eQMI_NAS_GET_NET_BAN_LIST, // 40 Get the list of forbidden networks
|
||||||
|
eQMI_NAS_SET_NET_BAN_LIST, // 41 Set the list of forbidden networks
|
||||||
|
eQMI_NAS_SET_TECH_PREF, // 42 Set the technology preference
|
||||||
|
eQMI_NAS_GET_TECH_PREF, // 43 Get the technology preference
|
||||||
|
eQMI_NAS_GET_ACCOLC, // 44 Get the Access Overload Class
|
||||||
|
eQMI_NAS_SET_ACCOLC, // 45 Set the Access Overload Class
|
||||||
|
eQMI_NAS_GET_SYSPREF, // 46 Get the CDMA system preference
|
||||||
|
eQMI_NAS_GET_NET_PARAMS, // 47 Get various network parameters
|
||||||
|
eQMI_NAS_SET_NET_PARAMS, // 48 Set various network parameters
|
||||||
|
eQMI_NAS_GET_RF_INFO, // 49 Get the SS radio/band channel info
|
||||||
|
eQMI_NAS_GET_AAA_AUTH_STATUS, // 50 Get AN-AAA authentication status
|
||||||
|
eQMI_NAS_SET_SYS_SELECT_PREF, // 51 Set system selection preference
|
||||||
|
eQMI_NAS_GET_SYS_SELECT_PREF, // 52 Get system selection preference
|
||||||
|
eQMI_NAS_SYS_SELECT_IND = 52, // 52 System selection pref indication
|
||||||
|
eQMI_NAS_SET_DDTM_PREF = 55, // 55 Set DDTM preference
|
||||||
|
eQMI_NAS_GET_DDTM_PREF, // 56 Get DDTM preference
|
||||||
|
eQMI_NAS_DDTM_IND = 56, // 56 DDTM preference indication
|
||||||
|
eQMI_NAS_GET_PLMN_MODE = 59, // 59 Get PLMN mode bit from CSP
|
||||||
|
eQMI_NAS_PLMN_MODE_IND, // 60 CSP PLMN mode bit indication
|
||||||
|
eQMI_NAS_GET_PLMN_NAME = 68, // 68 Get operator name for specified network
|
||||||
|
|
||||||
|
eQMI_WMS_RESET, // 00 Reset WMS service state variables
|
||||||
|
eQMI_WMS_SET_EVENT, // 01 Set new message report conditions
|
||||||
|
eQMI_WMS_EVENT_IND = 1, // 01 New message report indication
|
||||||
|
eQMI_WMS_RAW_SEND = 32, // 32 Send a raw message
|
||||||
|
eQMI_WMS_RAW_WRITE, // 33 Write a raw message to the device
|
||||||
|
eQMI_WMS_RAW_READ, // 34 Read a raw message from the device
|
||||||
|
eQMI_WMS_MODIFY_TAG, // 35 Modify message tag on the device
|
||||||
|
eQMI_WMS_DELETE, // 36 Delete message by index/tag/memory
|
||||||
|
eQMI_WMS_GET_MSG_PROTOCOL = 48, // 48 Get the current message protocol
|
||||||
|
eQMI_WMS_GET_MSG_LIST, // 49 Get list of messages from the device
|
||||||
|
eQMI_WMS_SET_ROUTES, // 50 Set routes for message memory storage
|
||||||
|
eQMI_WMS_GET_ROUTES, // 51 Get routes for message memory storage
|
||||||
|
eQMI_WMS_GET_SMSC_ADDR, // 52 Get SMSC address
|
||||||
|
eQMI_WMS_SET_SMSC_ADDR, // 53 Set SMSC address
|
||||||
|
eQMI_WMS_GET_MSG_LIST_MAX, // 54 Get maximum size of SMS storage
|
||||||
|
eQMI_WMS_SEND_ACK, // 55 Send ACK
|
||||||
|
eQMI_WMS_SET_RETRY_PERIOD, // 56 Set retry period
|
||||||
|
eQMI_WMS_SET_RETRY_INTERVAL, // 57 Set retry interval
|
||||||
|
eQMI_WMS_SET_DC_DISCO_TIMER, // 58 Set DC auto-disconnect timer
|
||||||
|
eQMI_WMS_SET_MEMORY_STATUS, // 59 Set memory storage status
|
||||||
|
eQMI_WMS_SET_BC_ACTIVATION, // 60 Set broadcast activation
|
||||||
|
eQMI_WMS_SET_BC_CONFIG, // 61 Set broadcast config
|
||||||
|
eQMI_WMS_GET_BC_CONFIG, // 62 Get broadcast config
|
||||||
|
eQMI_WMS_MEMORY_FULL_IND, // 63 Memory full indication
|
||||||
|
eQMI_WMS_GET_DOMAIN_PREF, // 64 Get domain preference
|
||||||
|
eQMI_WMS_SET_DOMAIN_PREF, // 65 Set domain preference
|
||||||
|
eQMI_WMS_MEMORY_SEND, // 66 Send message from memory store
|
||||||
|
eQMI_WMS_GET_MSG_WAITING, // 67 Get message waiting info
|
||||||
|
eQMI_WMS_MSG_WAITING_IND, // 68 Message waiting indication
|
||||||
|
eQMI_WMS_SET_PRIMARY_CLIENT, // 69 Set client as primary client
|
||||||
|
eQMI_WMS_SMSC_ADDR_IND, // 70 SMSC address indication
|
||||||
|
|
||||||
|
eQMI_PDS_RESET, // 00 Reset PDS service state variables
|
||||||
|
eQMI_PDS_SET_EVENT, // 01 Set PDS report conditions
|
||||||
|
eQMI_PDS_EVENT_IND = 1, // 01 PDS report indication
|
||||||
|
eQMI_PDS_GET_STATE = 32, // 32 Return PDS service state
|
||||||
|
eQMI_PDS_STATE_IND = 32, // 32 PDS service state indication
|
||||||
|
eQMI_PDS_SET_STATE, // 33 Set PDS service state
|
||||||
|
eQMI_PDS_START_SESSION, // 34 Start a PDS tracking session
|
||||||
|
eQMI_PDS_GET_SESSION_INFO, // 35 Get PDS tracking session info
|
||||||
|
eQMI_PDS_FIX_POSITION, // 36 Manual tracking session position
|
||||||
|
eQMI_PDS_END_SESSION, // 37 End a PDS tracking session
|
||||||
|
eQMI_PDS_GET_NMEA_CFG, // 38 Get NMEA sentence config
|
||||||
|
eQMI_PDS_SET_NMEA_CFG, // 39 Set NMEA sentence config
|
||||||
|
eQMI_PDS_INJECT_TIME, // 40 Inject a time reference
|
||||||
|
eQMI_PDS_GET_DEFAULTS, // 41 Get default tracking session config
|
||||||
|
eQMI_PDS_SET_DEFAULTS, // 42 Set default tracking session config
|
||||||
|
eQMI_PDS_GET_XTRA_PARAMS, // 43 Get the GPS XTRA parameters
|
||||||
|
eQMI_PDS_SET_XTRA_PARAMS, // 44 Set the GPS XTRA parameters
|
||||||
|
eQMI_PDS_FORCE_XTRA_DL, // 45 Force a GPS XTRA database download
|
||||||
|
eQMI_PDS_GET_AGPS_CONFIG, // 46 Get the AGPS mode configuration
|
||||||
|
eQMI_PDS_SET_AGPS_CONFIG, // 47 Set the AGPS mode configuration
|
||||||
|
eQMI_PDS_GET_SVC_AUTOTRACK, // 48 Get the service auto-tracking state
|
||||||
|
eQMI_PDS_SET_SVC_AUTOTRACK, // 49 Set the service auto-tracking state
|
||||||
|
eQMI_PDS_GET_COM_AUTOTRACK, // 50 Get COM port auto-tracking config
|
||||||
|
eQMI_PDS_SET_COM_AUTOTRACK, // 51 Set COM port auto-tracking config
|
||||||
|
eQMI_PDS_RESET_DATA, // 52 Reset PDS service data
|
||||||
|
eQMI_PDS_SINGLE_FIX, // 53 Request single position fix
|
||||||
|
eQMI_PDS_GET_VERSION, // 54 Get PDS service version
|
||||||
|
eQMI_PDS_INJECT_XTRA, // 55 Inject XTRA data
|
||||||
|
eQMI_PDS_INJECT_POSITION, // 56 Inject position data
|
||||||
|
eQMI_PDS_INJECT_WIFI, // 57 Inject Wi-Fi obtained data
|
||||||
|
eQMI_PDS_GET_SBAS_CONFIG, // 58 Get SBAS config
|
||||||
|
eQMI_PDS_SET_SBAS_CONFIG, // 59 Set SBAS config
|
||||||
|
eQMI_PDS_SEND_NI_RESPONSE, // 60 Send network initiated response
|
||||||
|
eQMI_PDS_INJECT_ABS_TIME, // 61 Inject absolute time
|
||||||
|
eQMI_PDS_INJECT_EFS, // 62 Inject EFS data
|
||||||
|
eQMI_PDS_GET_DPO_CONFIG, // 63 Get DPO config
|
||||||
|
eQMI_PDS_SET_DPO_CONFIG, // 64 Set DPO config
|
||||||
|
eQMI_PDS_GET_ODP_CONFIG, // 65 Get ODP config
|
||||||
|
eQMI_PDS_SET_ODP_CONFIG, // 66 Set ODP config
|
||||||
|
eQMI_PDS_CANCEL_SINGLE_FIX, // 67 Cancel single position fix
|
||||||
|
eQMI_PDS_GET_GPS_STATE, // 68 Get GPS state
|
||||||
|
eQMI_PDS_GET_METHODS = 80, // 80 Get GPS position methods state
|
||||||
|
eQMI_PDS_SET_METHODS, // 81 Set GPS position methods state
|
||||||
|
|
||||||
|
eQMI_AUTH_START_EAP = 32, // 32 Start the EAP session
|
||||||
|
eQMI_AUTH_SEND_EAP, // 33 Send and receive EAP packets
|
||||||
|
eQMI_AUTH_EAP_RESULT_IND, // 34 EAP session result indication
|
||||||
|
eQMI_AUTH_GET_EAP_KEYS, // 35 Get the EAP session keys
|
||||||
|
eQMI_AUTH_END_EAP, // 36 End the EAP session
|
||||||
|
|
||||||
|
eQMI_VOICE_INDICATION_REG = 3, // 03 Set indication registration state
|
||||||
|
eQMI_VOICE_CALL_ORIGINATE = 32, // 32 Originate a voice call
|
||||||
|
eQMI_VOICE_CALL_END, // 33 End a voice call
|
||||||
|
eQMI_VOICE_CALL_ANSWER, // 34 Answer incoming voice call
|
||||||
|
eQMI_VOICE_GET_CALL_INFO = 36, // 36 Get call information
|
||||||
|
eQMI_VOICE_OTASP_STATUS_IND, // 37 OTASP/OTAPA event indication
|
||||||
|
eQMI_VOICE_INFO_REC_IND, // 38 New info record indication
|
||||||
|
eQMI_VOICE_SEND_FLASH, // 39 Send a simple flash
|
||||||
|
eQMI_VOICE_BURST_DTMF, // 40 Send a burst DTMF
|
||||||
|
eQMI_VOICE_START_CONT_DTMF, // 41 Starts a continuous DTMF
|
||||||
|
eQMI_VOICE_STOP_CONT_DTMF, // 42 Stops a continuous DTMF
|
||||||
|
eQMI_VOICE_DTMF_IND, // 43 DTMF event indication
|
||||||
|
eQMI_VOICE_SET_PRIVACY_PREF, // 44 Set privacy preference
|
||||||
|
eQMI_VOICE_PRIVACY_IND, // 45 Privacy change indication
|
||||||
|
eQMI_VOICE_ALL_STATUS_IND, // 46 Voice all call status indication
|
||||||
|
eQMI_VOICE_GET_ALL_STATUS, // 47 Get voice all call status
|
||||||
|
eQMI_VOICE_MANAGE_CALLS = 49, // 49 Manage calls
|
||||||
|
eQMI_VOICE_SUPS_NOTIFICATION_IND, // 50 Supplementary service notifications
|
||||||
|
eQMI_VOICE_SET_SUPS_SERVICE, // 51 Manage supplementary service
|
||||||
|
eQMI_VOICE_GET_CALL_WAITING, // 52 Query sup service call waiting
|
||||||
|
eQMI_VOICE_GET_CALL_BARRING, // 53 Query sup service call barring
|
||||||
|
eQMI_VOICE_GET_CLIP, // 54 Query sup service CLIP
|
||||||
|
eQMI_VOICE_GET_CLIR, // 55 Query sup service CLIR
|
||||||
|
eQMI_VOICE_GET_CALL_FWDING, // 56 Query sup service call forwarding
|
||||||
|
eQMI_VOICE_SET_CALL_BARRING_PWD, // 57 Set call barring password
|
||||||
|
eQMI_VOICE_ORIG_USSD, // 58 Initiate USSD operation
|
||||||
|
eQMI_VOICE_ANSWER_USSD, // 59 Answer USSD request
|
||||||
|
eQMI_VOICE_CANCEL_USSD, // 60 Cancel USSD operation
|
||||||
|
eQMI_VOICE_USSD_RELEASE_IND, // 61 USSD release indication
|
||||||
|
eQMI_VOICE_USSD_IND, // 62 USSD request/notification indication
|
||||||
|
eQMI_VOICE_UUS_IND, // 63 UUS information indication
|
||||||
|
eQMI_VOICE_SET_CONFIG, // 64 Set config
|
||||||
|
eQMI_VOICE_GET_CONFIG, // 65 Get config
|
||||||
|
eQMI_VOICE_SUPS_IND, // 66 Sup service request indication
|
||||||
|
eQMI_VOICE_ASYNC_ORIG_USSD, // 67 Initiate USSD operation
|
||||||
|
eQMI_VOICE_ASYNC_USSD_IND = 67, // 67 USSD request/notification indication
|
||||||
|
|
||||||
|
eQMI_CAT_RESET, // 00 Reset CAT service state variables
|
||||||
|
eQMI_CAT_SET_EVENT, // 01 Set new message report conditions
|
||||||
|
eQMI_CAT_EVENT_IND = 1, // 01 New message report indication
|
||||||
|
eQMI_CAT_GET_STATE = 32, // 32 Get service state information
|
||||||
|
eQMI_CAT_SEND_TERMINAL, // 33 Send a terminal response
|
||||||
|
eQMI_CAT_SEND_ENVELOPE, // 34 Send an envelope command
|
||||||
|
|
||||||
|
eQMI_RMS_RESET, // 00 Reset RMS service state variables
|
||||||
|
eQMI_RMS_GET_SMS_WAKE = 32, // 32 Get SMS wake settings
|
||||||
|
eQMI_RMS_SET_SMS_WAKE, // 33 Set SMS wake settings
|
||||||
|
|
||||||
|
eQMI_OMA_RESET, // 00 Reset OMA service state variables
|
||||||
|
eQMI_OMA_SET_EVENT, // 01 Set OMA report conditions
|
||||||
|
eQMI_OMA_EVENT_IND = 1, // 01 OMA report indication
|
||||||
|
|
||||||
|
eQMI_OMA_START_SESSION = 32, // 32 Start client inititated session
|
||||||
|
eQMI_OMA_CANCEL_SESSION, // 33 Cancel session
|
||||||
|
eQMI_OMA_GET_SESSION_INFO, // 34 Get session information
|
||||||
|
eQMI_OMA_SEND_SELECTION, // 35 Send selection for net inititated msg
|
||||||
|
eQMI_OMA_GET_FEATURES, // 36 Get feature settings
|
||||||
|
eQMI_OMA_SET_FEATURES, // 37 Set feature settings
|
||||||
|
"""
|
||||||
|
|
||||||
|
entities = { 30: TP_REQUEST, # 30 QMI CTL request
|
||||||
|
31: TP_RESPONSE, # 31 QMI CTL response
|
||||||
|
32: TP_INDICATION, # 32 QMI CTL indication
|
||||||
|
33: TP_REQUEST, # 33 QMI WDS request
|
||||||
|
34: TP_RESPONSE, # 34 QMI WDS response
|
||||||
|
35: TP_INDICATION, # 35 QMI WDS indication
|
||||||
|
36: TP_REQUEST, # 36 QMI DMS request
|
||||||
|
37: TP_RESPONSE, # 37 QMI DMS response
|
||||||
|
38: TP_INDICATION, # 38 QMI DMS indication
|
||||||
|
39: TP_REQUEST, # 39 QMI NAS request
|
||||||
|
40: TP_RESPONSE, # 40 QMI NAS response
|
||||||
|
41: TP_INDICATION, # 41 QMI NAS indication
|
||||||
|
42: TP_REQUEST, # 42 QMI QOS request
|
||||||
|
43: TP_RESPONSE, # 43 QMI QOS response
|
||||||
|
44: TP_INDICATION, # 44 QMI QOS indication
|
||||||
|
45: TP_REQUEST, # 45 QMI WMS request
|
||||||
|
46: TP_RESPONSE, # 46 QMI WMS response
|
||||||
|
47: TP_INDICATION, # 47 QMI WMS indication
|
||||||
|
48: TP_REQUEST, # 48 QMI PDS request
|
||||||
|
49: TP_RESPONSE, # 49 QMI PDS response
|
||||||
|
50: TP_INDICATION, # 50 QMI PDS indication
|
||||||
|
51: TP_REQUEST, # 51 QMI AUTH request
|
||||||
|
52: TP_RESPONSE, # 52 QMI AUTH response
|
||||||
|
53: TP_INDICATION, # 53 QMI AUTH indication
|
||||||
|
54: TP_REQUEST, # 54 QMI CAT request
|
||||||
|
55: TP_RESPONSE, # 55 QMI CAT response
|
||||||
|
56: TP_INDICATION, # 56 QMI CAT indication
|
||||||
|
57: TP_REQUEST, # 57 QMI RMS request
|
||||||
|
58: TP_RESPONSE, # 58 QMI RMS response
|
||||||
|
59: TP_INDICATION, # 59 QMI RMS indication
|
||||||
|
60: TP_REQUEST, # 60 QMI OMA request
|
||||||
|
61: TP_RESPONSE, # 61 QMI OMA response
|
||||||
|
62: TP_INDICATION, # 62 QMI OMA indication
|
||||||
|
63: TP_REQUEST, # 63 QMI voice request
|
||||||
|
64: TP_RESPONSE, # 64 QMI voice response
|
||||||
|
65: TP_INDICATION # 65 QMI voice indication
|
||||||
|
}
|
||||||
|
|
||||||
|
class Tlv:
|
||||||
|
def __init__(self, entno, cmdno, tlvno, service, cmdname, tlvname, direction):
|
||||||
|
self.entno = entno
|
||||||
|
self.cmdno = cmdno
|
||||||
|
self.tlvno = tlvno
|
||||||
|
self.service = service
|
||||||
|
self.cmdname = cmdname
|
||||||
|
self.name = tlvname
|
||||||
|
self.direction = direction
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
print (" " * 10) + '%s: "%s/%s/%s",' % (self.tlvno, self.service, self.cmdname, self.name)
|
||||||
|
|
||||||
|
|
||||||
|
class Cmd:
|
||||||
|
def __init__(self, service, cmdno, name):
|
||||||
|
self.service = service
|
||||||
|
self.cmdno = cmdno
|
||||||
|
self.name = name
|
||||||
|
self.tlvs = { TP_REQUEST: {}, TP_RESPONSE: {}, TP_INDICATION: {} }
|
||||||
|
|
||||||
|
def add_tlv(self, direction, tlv):
|
||||||
|
if self.tlvs[direction].has_key(tlv.tlvno):
|
||||||
|
old = self.tlvs[direction][tlv.tlvno]
|
||||||
|
raise ValueError("Tried to add duplicate TLV [%s %d:%d (%s/%s/%s)] had [%s %d:%d (%s/%s/%s)]" % (self.service, \
|
||||||
|
self.cmdno, tlv.tlvno, self.service, self.name, tlv.name, self.service, self.cmdno, old.tlvno, self.service, \
|
||||||
|
self.name, old.name))
|
||||||
|
self.tlvs[direction][tlv.tlvno] = tlv
|
||||||
|
|
||||||
|
def show_direction(self, direction):
|
||||||
|
if len(self.tlvs[direction].keys()) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
print "%s = { # %d" % (self.get_array_name(direction), self.cmdno)
|
||||||
|
keys = self.tlvs[direction].keys()
|
||||||
|
keys.sort()
|
||||||
|
for k in keys:
|
||||||
|
tlv = self.tlvs[direction][k]
|
||||||
|
tlv.show()
|
||||||
|
print (" " * 8) + "}\n"
|
||||||
|
|
||||||
|
def show_tlvs(self):
|
||||||
|
self.show_direction(TP_REQUEST)
|
||||||
|
self.show_direction(TP_RESPONSE)
|
||||||
|
self.show_direction(TP_INDICATION)
|
||||||
|
|
||||||
|
def get_array_name(self, direction):
|
||||||
|
if len(self.tlvs[direction].keys()) == 0:
|
||||||
|
return "None"
|
||||||
|
tags = { TP_REQUEST: "req", TP_RESPONSE: "rsp", TP_INDICATION: "ind" }
|
||||||
|
return "%s_%s_%s_tlvs" % (self.service, self.name.lower(), tags[direction])
|
||||||
|
|
||||||
|
# parse list of services and their commands
|
||||||
|
services = {}
|
||||||
|
for l in cmdenum.split("\n"):
|
||||||
|
l = l.strip()
|
||||||
|
if not len(l):
|
||||||
|
continue
|
||||||
|
l = l.replace("eQMI_", "")
|
||||||
|
svcend = l.find("_")
|
||||||
|
if svcend < 0:
|
||||||
|
raise ValueError("Failed to get service")
|
||||||
|
svc = l[:svcend].lower()
|
||||||
|
l = l[svcend + 1:]
|
||||||
|
|
||||||
|
comma = l.find(",")
|
||||||
|
space = l.find(" =")
|
||||||
|
idx = -1
|
||||||
|
if comma >= 0 and (space < 0 or comma < space):
|
||||||
|
idx = comma
|
||||||
|
elif space >= 0 and (comma < 0 or space < comma):
|
||||||
|
idx = space
|
||||||
|
else:
|
||||||
|
raise ValueError("Couldn't determine command name")
|
||||||
|
cmdname = l[:idx]
|
||||||
|
l = l[idx:]
|
||||||
|
comment = l.index("// ")
|
||||||
|
l = l[comment + 3:]
|
||||||
|
end = l.index(" ")
|
||||||
|
cmdno = int(l[:end])
|
||||||
|
|
||||||
|
cmd = Cmd(svc, cmdno, cmdname)
|
||||||
|
|
||||||
|
if not services.has_key(svc):
|
||||||
|
services[svc] = {}
|
||||||
|
if services[svc].has_key(cmdno):
|
||||||
|
# ignore duplicat indication numbers
|
||||||
|
if cmdname.find("_IND") >= 0:
|
||||||
|
continue
|
||||||
|
raise KeyError("Already have %s/%s/%d" % (svc, cmdname, cmdno))
|
||||||
|
services[svc][cmdno] = cmd
|
||||||
|
|
||||||
|
# read in Entity.txt
|
||||||
|
f = open(sys.argv[1])
|
||||||
|
lines = f.readlines()
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
parts = line.split("^")
|
||||||
|
struct = int(parts[3])
|
||||||
|
|
||||||
|
entno = int(parts[0])
|
||||||
|
|
||||||
|
ids = parts[1].replace('"', "").split(",")
|
||||||
|
cmdno = int(ids[0])
|
||||||
|
tlvno = int(ids[1])
|
||||||
|
|
||||||
|
name = parts[2].replace('"', "").split("/")
|
||||||
|
service = name[0]
|
||||||
|
cmdname = name[1]
|
||||||
|
tlvname = name[2]
|
||||||
|
|
||||||
|
direction = entities[entno]
|
||||||
|
|
||||||
|
tlv = Tlv(entno, cmdno, tlvno, service, cmdname, tlvname, direction)
|
||||||
|
services[service.lower()][cmdno].add_tlv(direction, tlv)
|
||||||
|
|
||||||
|
svcsorted = services.keys()
|
||||||
|
svcsorted.sort()
|
||||||
|
for s in svcsorted:
|
||||||
|
# print each service's command's TLVs
|
||||||
|
cmdssorted = services[s].keys()
|
||||||
|
cmdssorted.sort()
|
||||||
|
for c in cmdssorted:
|
||||||
|
cmd = services[s][c]
|
||||||
|
cmd.show_tlvs()
|
||||||
|
|
||||||
|
# print each service's command dict
|
||||||
|
print "%s_cmds = {" % s
|
||||||
|
for c in cmdssorted:
|
||||||
|
cmd = services[s][c]
|
||||||
|
print ' %d: ("%s", %s, %s, %s),' % (cmd.cmdno, cmd.name, \
|
||||||
|
cmd.get_array_name(TP_REQUEST), cmd.get_array_name(TP_RESPONSE), cmd.get_array_name(TP_INDICATION))
|
||||||
|
print " }"
|
||||||
|
print ""
|
||||||
|
|
||||||
|
# print out services
|
||||||
|
slist = { 0: "ctl", 1: "wds", 2: "dms", 3: "nas", 4: "qos", 5: "wms",
|
||||||
|
6: "pds", 7: "auth", 9: "voice", 224: "cat", 225: "rms", 226: "oma" }
|
||||||
|
|
||||||
|
slistsorted = slist.keys()
|
||||||
|
slistsorted.sort()
|
||||||
|
print "services = {"
|
||||||
|
for s in slistsorted:
|
||||||
|
cmdlistname = "None"
|
||||||
|
if slist[s] != "qos":
|
||||||
|
# QoS doesn't appear to have any commands
|
||||||
|
cmdlistname = slist[s] + "_cmds"
|
||||||
|
print ' %d: ("%s", %s),' % (s, slist[s], cmdlistname)
|
||||||
|
print " }"
|
||||||
|
|
2352
decode/qmiprotocol.py
Normal file
2352
decode/qmiprotocol.py
Normal file
File diff suppressed because it is too large
Load Diff
187
decode/qmux.py
Normal file
187
decode/qmux.py
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details:
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
|
||||||
|
import binascii
|
||||||
|
import defs
|
||||||
|
import struct
|
||||||
|
|
||||||
|
from qmiprotocol import services
|
||||||
|
|
||||||
|
TP_REQUEST = 0x00
|
||||||
|
TP_RESPONSE = 0x02
|
||||||
|
TP_INDICATION = 0x04
|
||||||
|
|
||||||
|
def unpack(data, direction):
|
||||||
|
return binascii.unhexlify(data)
|
||||||
|
|
||||||
|
def service_to_string(s):
|
||||||
|
try:
|
||||||
|
return services[s][0]
|
||||||
|
except KeyError:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def qmi_cmd_to_string(cmdno, service):
|
||||||
|
(name, cmds) = services[service]
|
||||||
|
return cmds[cmdno][0]
|
||||||
|
|
||||||
|
class Tlv:
|
||||||
|
def __init__(self, tlvid, size, data, service, cmdno, direction):
|
||||||
|
self.id = tlvid
|
||||||
|
self.size = size
|
||||||
|
self.data = data
|
||||||
|
if size != len(data):
|
||||||
|
raise ValueError("Mismatched TLV size! (got %d expected %d)" % (len(data), size))
|
||||||
|
self.service = service
|
||||||
|
self.cmdno = cmdno
|
||||||
|
self.direction = direction
|
||||||
|
|
||||||
|
def show_data(self, prefix):
|
||||||
|
line = ""
|
||||||
|
for i in self.data:
|
||||||
|
line += " %02x" % ord(i)
|
||||||
|
print prefix + " Data: %s" % line
|
||||||
|
|
||||||
|
def show(self, prefix):
|
||||||
|
svc = services[self.service]
|
||||||
|
cmd = svc[1][self.cmdno]
|
||||||
|
tlvlist = None
|
||||||
|
if self.direction == TP_REQUEST:
|
||||||
|
tlvlist = cmd[1]
|
||||||
|
elif self.direction == TP_RESPONSE:
|
||||||
|
tlvlist = cmd[2]
|
||||||
|
elif self.direction == TP_INDICATION:
|
||||||
|
tlvlist = cmd[3]
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown TLV dir0ection %s" % self.direction)
|
||||||
|
|
||||||
|
tlvname = "!!! UNKNOWN !!!"
|
||||||
|
if self.service == 1 and self.cmdno == 77: # WDS/SET_IP_FAMILY
|
||||||
|
tlvname = "WDS/Set IP Family/IP Family !!! NOT DEFINED !!!"
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
tlvname = tlvlist[self.id]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
print prefix + " TLV: 0x%02x (%s)" % (self.id, tlvname)
|
||||||
|
print prefix + " Size: 0x%04x" % self.size
|
||||||
|
if self.id == 2:
|
||||||
|
# Status response
|
||||||
|
(status, error) = struct.unpack("<HH", self.data)
|
||||||
|
if status == 0:
|
||||||
|
sstatus = "SUCCESS"
|
||||||
|
else:
|
||||||
|
sstatus = "ERROR"
|
||||||
|
print prefix + " Status: %d (%s)" % (status, sstatus)
|
||||||
|
|
||||||
|
print prefix + " Error: %d" % error
|
||||||
|
else:
|
||||||
|
self.show_data(prefix)
|
||||||
|
print ""
|
||||||
|
|
||||||
|
def get_tlvs(data, service, cmdno, direction):
|
||||||
|
tlvs = []
|
||||||
|
while len(data) >= 3:
|
||||||
|
(tlvid, size) = struct.unpack("<BH", data[:3])
|
||||||
|
if size > len(data) - 3:
|
||||||
|
raise ValueError("Malformed TLV ID %d size %d (len left %d)" % (tlvid, size, len(data)))
|
||||||
|
tlvs.append(Tlv(tlvid, size, data[3:3 + size], service, cmdno, direction))
|
||||||
|
data = data[size + 3:]
|
||||||
|
if len(data) != 0:
|
||||||
|
raise ValueError("leftover data parsing tlvs")
|
||||||
|
return tlvs
|
||||||
|
|
||||||
|
def show(data, prefix, direction):
|
||||||
|
if len(data) < 7:
|
||||||
|
return
|
||||||
|
|
||||||
|
qmuxfmt = "<BHBBB"
|
||||||
|
sz = struct.calcsize(qmuxfmt)
|
||||||
|
(ifc, l, sender, service, cid) = struct.unpack(qmuxfmt, data[:sz])
|
||||||
|
|
||||||
|
if ifc != 0x01:
|
||||||
|
raise ValueError("Packet not QMUX")
|
||||||
|
|
||||||
|
print prefix + "QMUX Header:"
|
||||||
|
print prefix + " len: 0x%04x" % l
|
||||||
|
|
||||||
|
ssender = ""
|
||||||
|
if sender == 0x00:
|
||||||
|
ssender = "(client)"
|
||||||
|
elif sender == 0x80:
|
||||||
|
ssender = "(service)"
|
||||||
|
print prefix + " sender: 0x%02x %s" % (sender, ssender)
|
||||||
|
|
||||||
|
sservice = service_to_string(service)
|
||||||
|
print prefix + " svc: 0x%02x (%s)" % (service, sservice)
|
||||||
|
|
||||||
|
scid = ""
|
||||||
|
if cid == 0xff:
|
||||||
|
scid = "(broadcast)"
|
||||||
|
print prefix + " cid: 0x%02x %s" % (cid, scid)
|
||||||
|
|
||||||
|
print ""
|
||||||
|
|
||||||
|
# QMI header
|
||||||
|
data = data[sz:]
|
||||||
|
if service == 0:
|
||||||
|
qmifmt = "<BBHH"
|
||||||
|
else:
|
||||||
|
qmifmt = "<BHHH"
|
||||||
|
|
||||||
|
sz = struct.calcsize(qmifmt)
|
||||||
|
(flags, txnid, cmdno, size) = struct.unpack(qmifmt, data[:sz])
|
||||||
|
|
||||||
|
print prefix + "QMI Header:"
|
||||||
|
|
||||||
|
sflags = ""
|
||||||
|
if service == 0:
|
||||||
|
# Besides the CTL service header being shorter, the flags are different
|
||||||
|
if flags == 0x00:
|
||||||
|
flags = TP_REQUEST
|
||||||
|
elif flags == 0x01:
|
||||||
|
flags = TP_RESPONSE
|
||||||
|
elif flags == 0x02:
|
||||||
|
flags = TP_INDICATION
|
||||||
|
|
||||||
|
if flags == TP_REQUEST:
|
||||||
|
sflags = "(request)"
|
||||||
|
elif flags == TP_RESPONSE:
|
||||||
|
sflags = "(response)"
|
||||||
|
elif flags == TP_INDICATION:
|
||||||
|
sflags = "(indication)"
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown flags %d" % flags)
|
||||||
|
print prefix + " Flags: 0x%02x %s" % (flags, sflags)
|
||||||
|
|
||||||
|
print prefix + " TXN: 0x%04x" % txnid
|
||||||
|
|
||||||
|
scmd = qmi_cmd_to_string(cmdno, service)
|
||||||
|
print prefix + " Cmd: 0x%04x (%s)" % (cmdno, scmd)
|
||||||
|
|
||||||
|
print prefix + " Size: 0x%04x" % size
|
||||||
|
print ""
|
||||||
|
|
||||||
|
data = data[sz:]
|
||||||
|
tlvs = get_tlvs(data, service, cmdno, flags)
|
||||||
|
for tlv in tlvs:
|
||||||
|
tlv.show(prefix)
|
||||||
|
|
||||||
|
print ""
|
||||||
|
|
||||||
|
def get_funcs():
|
||||||
|
return (unpack, show)
|
||||||
|
|
211
decode/wmc.py
Normal file
211
decode/wmc.py
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details:
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
|
||||||
|
import binascii
|
||||||
|
import struct
|
||||||
|
import defs
|
||||||
|
|
||||||
|
def unpack(data, direction):
|
||||||
|
# unpack the data
|
||||||
|
if direction == defs.TO_MODEM:
|
||||||
|
if data[:14] == "41542a574d433d":
|
||||||
|
# remove the AT*WMC= bits, and the newline and CRC at the end
|
||||||
|
data = data[14:]
|
||||||
|
if data[len(data) - 2:] == "0d":
|
||||||
|
data = data[:len(data) - 6]
|
||||||
|
elif direction == defs.TO_HOST:
|
||||||
|
if data[len(data) - 2:] == "7e":
|
||||||
|
# remove HDLC terminator and CRC
|
||||||
|
data = data[:len(data) - 6]
|
||||||
|
else:
|
||||||
|
raise ValueError("No data direction")
|
||||||
|
|
||||||
|
data = binascii.unhexlify(data)
|
||||||
|
|
||||||
|
# PPP-unescape it
|
||||||
|
escape = False
|
||||||
|
new_data = ""
|
||||||
|
for i in data:
|
||||||
|
if ord(i) == 0x7D:
|
||||||
|
escape = True
|
||||||
|
elif escape == True:
|
||||||
|
new_data += chr(ord(i) ^ 0x20)
|
||||||
|
escape = False
|
||||||
|
else:
|
||||||
|
new_data += i
|
||||||
|
|
||||||
|
return new_data
|
||||||
|
|
||||||
|
def show_data(data, prefix):
|
||||||
|
line = ""
|
||||||
|
for i in data:
|
||||||
|
line += " %02x" % ord(i)
|
||||||
|
print prefix + " Data: %s" % line
|
||||||
|
|
||||||
|
def show_device_info(data, prefix, direction):
|
||||||
|
if direction != defs.TO_HOST:
|
||||||
|
return
|
||||||
|
|
||||||
|
fmt = "<"
|
||||||
|
fmt = fmt + "27s" # unknown1
|
||||||
|
fmt = fmt + "64s" # manf
|
||||||
|
fmt = fmt + "64s" # model
|
||||||
|
fmt = fmt + "64s" # fwrev
|
||||||
|
fmt = fmt + "64s" # hwrev
|
||||||
|
fmt = fmt + "64s" # unknown2
|
||||||
|
fmt = fmt + "64s" # unknown3
|
||||||
|
fmt = fmt + "10s" # min
|
||||||
|
fmt = fmt + "12s" # unknown4
|
||||||
|
fmt = fmt + "H" # home_sid
|
||||||
|
fmt = fmt + "6s" # unknown5
|
||||||
|
fmt = fmt + "H" # eri_ver?
|
||||||
|
fmt = fmt + "3s" # unknown6
|
||||||
|
fmt = fmt + "64s" # unknown7
|
||||||
|
fmt = fmt + "20s" # meid
|
||||||
|
fmt = fmt + "22s" # imei
|
||||||
|
fmt = fmt + "16s" # unknown9
|
||||||
|
fmt = fmt + "22s" # iccid
|
||||||
|
fmt = fmt + "4s" # unknown10
|
||||||
|
fmt = fmt + "16s" # MCC
|
||||||
|
fmt = fmt + "16s" # MNC
|
||||||
|
fmt = fmt + "4s" # unknown11
|
||||||
|
fmt = fmt + "4s" # unknown12
|
||||||
|
fmt = fmt + "4s" # unknown13
|
||||||
|
fmt = fmt + "1s"
|
||||||
|
|
||||||
|
expected = struct.calcsize(fmt)
|
||||||
|
if len(data) != expected:
|
||||||
|
raise ValueError("Unexpected Info command response len (got %d expected %d)" % (len(data), expected))
|
||||||
|
(u1, manf, model, fwrev, hwrev, u2, u3, cdmamin, u4, homesid, u5, eriver, \
|
||||||
|
u6, u7, meid, imei, u9, iccid, u10, mcc, mnc, u11, u12, u13, u14) = struct.unpack(fmt, data)
|
||||||
|
|
||||||
|
print prefix + " Manf: %s" % manf
|
||||||
|
print prefix + " Model: %s" % model
|
||||||
|
print prefix + " FW Rev: %s" % fwrev
|
||||||
|
print prefix + " HW Rev: %s" % hwrev
|
||||||
|
print prefix + " MIN: %s" % cdmamin
|
||||||
|
print prefix + " Home SID: %d" % homesid
|
||||||
|
print prefix + " ERI Ver: %d" % eriver
|
||||||
|
print prefix + " MEID: %s" % meid
|
||||||
|
print prefix + " IMEI: %s" % imei
|
||||||
|
print prefix + " Unk9: %s" % u9
|
||||||
|
print prefix + " ICCID: %s" % iccid
|
||||||
|
print prefix + " MCC: %s" % mcc
|
||||||
|
print prefix + " MNC: %s" % mnc
|
||||||
|
|
||||||
|
def show_ip_info(data, prefix, direction):
|
||||||
|
if direction != defs.TO_HOST:
|
||||||
|
return
|
||||||
|
|
||||||
|
fmt = "<"
|
||||||
|
fmt = fmt + "I" # rx_bytes
|
||||||
|
fmt = fmt + "I" # tx_bytes
|
||||||
|
fmt = fmt + "8s" # unknown3
|
||||||
|
fmt = fmt + "B" # unknown4
|
||||||
|
fmt = fmt + "7s" # unknown7
|
||||||
|
fmt = fmt + "16s" # ip4_address
|
||||||
|
fmt = fmt + "8s" # netmask?
|
||||||
|
fmt = fmt + "40s" # ip6_address
|
||||||
|
|
||||||
|
expected = struct.calcsize(fmt)
|
||||||
|
if len(data) != expected:
|
||||||
|
raise ValueError("Unexpected IP Info command response len (got %d expected %d)" % (len(data), expected))
|
||||||
|
(rxb, txb, u3, u4, u7, ip4addr, netmask, ip6addr) = struct.unpack(fmt, data)
|
||||||
|
|
||||||
|
print prefix + " RX Bytes: %d" % rxb
|
||||||
|
print prefix + " TX Bytes: %d" % txb
|
||||||
|
print prefix + " IP4 Addr: %s" % ip4addr
|
||||||
|
print prefix + " IP6 Addr: %s" % ip6addr
|
||||||
|
|
||||||
|
def get_signal(item):
|
||||||
|
if item == 0x7D:
|
||||||
|
return (item * -1, "(NO SIGNAL)")
|
||||||
|
else:
|
||||||
|
return (item * -1, "")
|
||||||
|
|
||||||
|
def show_status(data, prefix, direction):
|
||||||
|
if direction != defs.TO_HOST:
|
||||||
|
return
|
||||||
|
|
||||||
|
fmt = "<"
|
||||||
|
fmt = fmt + "B" # unknown1
|
||||||
|
fmt = fmt + "3s" # unknown2
|
||||||
|
fmt = fmt + "B" # unknown3
|
||||||
|
fmt = fmt + "B" # unknown4
|
||||||
|
fmt = fmt + "10s" # magic
|
||||||
|
fmt = fmt + "H" # counter1
|
||||||
|
fmt = fmt + "H" # counter2
|
||||||
|
fmt = fmt + "B" # unknown5
|
||||||
|
fmt = fmt + "3s" # unknown6
|
||||||
|
fmt = fmt + "B" # cdma1x_dbm
|
||||||
|
fmt = fmt + "3s" # unknown7
|
||||||
|
fmt = fmt + "16s" # cdma_opname
|
||||||
|
fmt = fmt + "18s" # unknown8
|
||||||
|
fmt = fmt + "B" # hdr_dbm
|
||||||
|
fmt = fmt + "3s" # unknown9
|
||||||
|
fmt = fmt + "B" # unknown10
|
||||||
|
fmt = fmt + "3s" # unknown11
|
||||||
|
fmt = fmt + "B" # unknown12
|
||||||
|
fmt = fmt + "8s" # lte_opname
|
||||||
|
fmt = fmt + "60s" # unknown13
|
||||||
|
fmt = fmt + "B" # lte_dbm
|
||||||
|
fmt = fmt + "3s" # unknown14
|
||||||
|
fmt = fmt + "4s" # unknown15
|
||||||
|
|
||||||
|
expected = struct.calcsize(fmt)
|
||||||
|
if len(data) != expected:
|
||||||
|
raise ValueError("Unexpected Status command response len (got %d expected %d)" % (len(data), expected))
|
||||||
|
(u1, u2, u3, u4, magic, counter1, counter2, u5, u6, cdma_dbm, u7, cdma_opname, \
|
||||||
|
u8, hdr_dbm, u9, u10, u11, u12, lte_opname, u13, lte_dbm, u14, u15) = struct.unpack(fmt, data)
|
||||||
|
|
||||||
|
print prefix + " Counter1: %s" % counter1
|
||||||
|
print prefix + " Counter2: %s" % counter2
|
||||||
|
print prefix + " CDMA dBm: %d dBm %s" % get_signal(cdma_dbm)
|
||||||
|
print prefix + " CDMA Op: %s" % cdma_opname
|
||||||
|
print prefix + " HDR dBm: %d dBm %s" % get_signal(hdr_dbm)
|
||||||
|
print prefix + " LTE Op: %s" % lte_opname
|
||||||
|
print prefix + " LTE dBm: %d dBm %s" % get_signal(lte_dbm)
|
||||||
|
|
||||||
|
def show_init(data, prefix, direction):
|
||||||
|
show_data(data, prefix)
|
||||||
|
|
||||||
|
def show_bearer_info(data, prefix, direction):
|
||||||
|
pass
|
||||||
|
|
||||||
|
cmds = { 0x06: ("DEVICE_INFO", show_device_info),
|
||||||
|
0x0A: ("IP_INFO", show_ip_info),
|
||||||
|
0x0B: ("STATUS", show_status),
|
||||||
|
0x0D: ("INIT", show_init),
|
||||||
|
0x4D: ("EPS_BEARER_INFO", show_bearer_info)
|
||||||
|
}
|
||||||
|
|
||||||
|
def show(data, prefix, direction):
|
||||||
|
data = data[1:] # skip 0xC8 header
|
||||||
|
cmdno = ord(data[:1])
|
||||||
|
try:
|
||||||
|
cmdinfo = cmds[cmdno]
|
||||||
|
except KeyError:
|
||||||
|
return
|
||||||
|
data = data[1:] # skip cmdno
|
||||||
|
|
||||||
|
print prefix + "WMC Packet:"
|
||||||
|
print prefix + " Cmd: 0x%02x (%s)" % (cmdno, cmdinfo[0])
|
||||||
|
cmdinfo[1](data, prefix, direction)
|
||||||
|
print ""
|
||||||
|
|
||||||
|
def get_funcs():
|
||||||
|
return (unpack, show)
|
||||||
|
|
82
decode/xml2ascii.py
Executable file
82
decode/xml2ascii.py
Executable file
@@ -0,0 +1,82 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details:
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# --- Dumps UsbSnoopy XML export files
|
||||||
|
|
||||||
|
from xml.sax import saxutils
|
||||||
|
from xml.sax import handler
|
||||||
|
|
||||||
|
packets = []
|
||||||
|
counts = {}
|
||||||
|
|
||||||
|
class FindPackets(handler.ContentHandler):
|
||||||
|
def __init__(self):
|
||||||
|
self.inFunction = False
|
||||||
|
self.inPayload = False
|
||||||
|
self.ignore = False
|
||||||
|
self.inTimestamp = False
|
||||||
|
self.timestamp = None
|
||||||
|
self.packet = None
|
||||||
|
|
||||||
|
def startElement(self, name, attrs):
|
||||||
|
if name == "function":
|
||||||
|
self.inFunction = True
|
||||||
|
elif name == "payloadbytes":
|
||||||
|
self.inPayload = True
|
||||||
|
elif name == "timestamp":
|
||||||
|
self.inTimestamp = True
|
||||||
|
|
||||||
|
def characters(self, ch):
|
||||||
|
if self.ignore:
|
||||||
|
return
|
||||||
|
|
||||||
|
stripped = ch.strip()
|
||||||
|
if self.inFunction and ch != "BULK_OR_INTERRUPT_TRANSFER":
|
||||||
|
self.ignore = True
|
||||||
|
return
|
||||||
|
elif self.inTimestamp:
|
||||||
|
self.timestamp = stripped
|
||||||
|
elif self.inPayload and len(stripped) > 0:
|
||||||
|
if self.packet == None:
|
||||||
|
self.packet = stripped
|
||||||
|
else:
|
||||||
|
self.packet += stripped
|
||||||
|
|
||||||
|
def endElement(self, name):
|
||||||
|
if name == "function":
|
||||||
|
self.inFunction = False
|
||||||
|
elif name == "payloadbytes":
|
||||||
|
self.inPayload = False
|
||||||
|
elif name == "payload":
|
||||||
|
if self.packet:
|
||||||
|
import binascii
|
||||||
|
bytes = binascii.a2b_hex(self.packet)
|
||||||
|
print bytes
|
||||||
|
self.packet = None
|
||||||
|
|
||||||
|
self.ignore = False
|
||||||
|
self.timestamp = None
|
||||||
|
elif name == "timestamp":
|
||||||
|
self.inTimestamp = False
|
||||||
|
|
||||||
|
|
||||||
|
from xml.sax import make_parser
|
||||||
|
from xml.sax import parse
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
dh = FindPackets()
|
||||||
|
parse(sys.argv[1], dh)
|
||||||
|
|
Reference in New Issue
Block a user