vl600: add some reverse engineering docs and an AT com utility

This commit is contained in:
Dan Williams
2012-05-16 12:13:48 -05:00
parent df1f21d17f
commit 9bee743a9d
2 changed files with 185 additions and 0 deletions

147
vl600/atcom.py Executable file
View File

@@ -0,0 +1,147 @@
#! /bin/env 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) 2012 Red Hat, Inc.
#
import os
import sys
import select
import struct
import string
from termios import *
debug = False
def lg_pack(data, seqno):
l = len(data)
fmt = "<"
fmt += "I" # magic
fmt += "I" # sequence number
fmt += "I" # data length
fmt += "H" # MUX channel
fmt += "%ds" % l # AT data
# Packets always padded to 4-byte boundaries
sz = struct.calcsize(fmt)
padding = 0
if sz % 4 > 0:
padding = 4 - (sz % 4)
fmt += "%ds" % padding
return struct.pack(fmt, 0xa512485a, seqno, l, 0xf011, data, "\0" * padding)
def lg_unpack(data):
fmt = "<"
fmt += "I" # magic
fmt += "I" # sequence number
fmt += "I" # data length
fmt += "H" # MUX channel
fmt += "%ds" % (len(data) - 14) # AT data
(magic, seq, l, chan, resp) = struct.unpack(fmt, data)
if magic != 0xa512485a:
raise Exception("Bad magic: 0x%08x" % magic)
if chan != 0xf011:
print "Unhandled channel 0x%04x" % chan
# It appears that we're supposed to ignore any data after \r\n, or if
# we don't get a \r\n we ignore all of it. The modem adds random
# data to the end of the response, for example:
#
# > 5a 48 12 a5 08 00 00 00 0a 00 00 00 11 f0 41 54 2b 43 45 52 45 47 3f 0a
# < 5a 48 12 a5 4e 00 00 00 15 00 00 00 11 f0 2b 43 45 52 45 47 3a 20 30 2c 31 0d 0a 00 00 4f 4b 0d 0a 00 47 74
#
# where there's a trailing "00 47 74". The trailing bytes appear
# totally random in value and length.
crlf = resp.rfind("\r\n")
if crlf == -1:
return ""
return resp[:crlf + 2]
def dump_raw(data, to_modem):
if debug:
line = ""
if to_modem:
line += "> "
else:
line += "< "
for c in data:
line += "%02x " % ord(c)
print line
def make_printable(data):
p = ""
for c in data:
if c in string.printable and ord(c) >= 32 or c == '\n' or c == '\r':
p += c
else:
p += "<%2x>" % ord(c)
return p
#########################################
if len(sys.argv) != 2 and len(sys.argv) != 3:
print "Usage: %s <port> [--debug]" % sys.argv[0]
sys.exit(1)
if len(sys.argv) > 2 and sys.argv[2] == "--debug":
debug = True
fd = os.open(sys.argv[1], os.O_RDWR)
# read existing port attributes and mask the ones we don't want
attrs = tcgetattr(fd)
attrs[0] = attrs[0] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON) # iflag
attrs[1] = attrs[1] & ~OPOST # oflag
attrs[2] = attrs[2] & ~(CSIZE | PARENB) # cflag
attrs[3] = attrs[3] & ~(ECHO | ICANON | IEXTEN | ISIG) # lflag
# Set up the attributes we do want
attrs[2] = attrs[2] | CS8 # cflag
attrs[4] = B115200 # ispeed
attrs[5] = B115200 # ospeed
attrs[6][VMIN] = 1 # cc
attrs[6][VTIME] = 0 # cc
tcsetattr(fd, TCSAFLUSH, attrs)
infd = sys.stdin.fileno()
seqno = 0
while 1:
try:
rfd, wfd, xfd = select.select([ fd, infd ], [], [])
except KeyboardInterrupt:
print ""
break
if fd in rfd:
data = os.read(fd, 4096)
dump_raw(data, False)
line = lg_unpack(data)
if line:
print make_printable(line)
if infd in rfd:
line = os.read(infd, 512)
if line:
data = lg_pack(line, seqno)
seqno += 1
dump_raw(data, True)
os.write(fd, data)
os.close(fd)

38
vl600/vl600.txt Normal file
View File

@@ -0,0 +1,38 @@
Device uses an LG L2000 LTE chip and a Qualcomm MDM6800A for CDMA/EVDO.
The firmware flasher tool speaks DIAG and includes a lot of LTE-related
NV items.
Device has two USB interfaces:
0 - Proprietary ethernet interface
1 - CDC-ACM serial port
The ACM port speaks a proprietary protocol that MUX-es traffic from the
following virtual interfaces (according to Windows):
0: LGE LTE DM Port
1: LGE USB Modem Port
2: LGE LTE RF Serial Port (com)
3: LGE CDMA USB Serial Port (com)
4: LGE CDMA USB GPS NMEA Port (com)
5: LGE CDMA LBS Serial Port (com)
MUX Header Format
-----------------
u32: magic, always [ 0x5a 0x48 0x12 0xa5 ]
u32: sequence number (unpaired; host and device use separate sequence numbers)
u32: length (not including this header, but including any padding)
u16: MUX channel (21 f0: CMD) (11 f0: AT)
<data>
Packets are 4-byte aligned with padding of zeros, and this padding is included
in the length given in the header.
AT commands may have trailing junk bytes. It appears that interpreters should
simply ignore any data in AT packets after the last CRLF.
CMD packets are terminated with a standard HDLC CRC-16 and 0x7E.