Novatel Merlin X720 (Verizon V740) ExpressCard and BREW

Skywing <[email protected]>
Newsgroups gmane.comp.mobile.bitpim.devel
Message-ID <982D8D05B6407A49AD506E6C3AC8E7D60194F1D5D6@caralain.haven.nynaeve.net>
Hi,

I've been reversing the interface that is used to communicate with the Novatel Merlin X720 (EVDO Rev.A) ExpressCard (rebranded as the Verizon V740 ExpressCard when sold through Verizon) as a little side project of mine, and I've discovered something that might be a bit of interest to this list.  (Yes, I know that BitPim primarily deals with ordinary handsets and not data cards, but bear with me for a bit.)

The card presents a diagnostics virtual serial port that is owned by the driver, which seems to act as a pass-through to the firmware running on the card itself.  (The card uses a Qualcomm chipset.)

The Verizon connection manager software (seems to be a rebranded SmithMicro app) communicates with the card via a standard abstraction layer interface that is ostensibly uniform across all cards and handsets supported by the connection manager software; the way that works is that each model of card/handset has its own DLL that exports a standard set of functions, which are internally mapped to whatever model/vendor-specific mechanism is used to talk to that card/handset.  The abstraction layer provides support for doing things like querying attributes about the network / signal, sending/receiving SMS messages, and theoretically support for manipulating contacts on the device (based on the exports, however the connection manager abstraction layer module for the X720/V740 doesn't implement contact/phonebook management).

Now, the way I approached this project was to reverse parts of the interface at varying levels:

1. The (limited, but uniform) SmithMicro abstraction layer, as a starting point.  The handy thing here is that by manipulating data sent/received through the abstraction layer, changes become immediately visible in the Verizon connection manager UI, making it relatively easy to figure out what stuff does.
2. The internal functions in the V740 abstraction layer module for speaking to the firmware on the card.  It turns out that the card is static linked to a debug version of Novatel's SDK, which includes handy debug prints all over the place, giving lots of clues as to how functions are named and what they do to the card.
3. The binary protocol spoken over the virtual serial port by the Novatel SDK functions to communicate with the card firmware.

Based on analyzing these three interfaces, I've learned a bit about how to talk to the card and get things like signal/connection status attributes, suspend a call and place the device into dormant mode, and read/write various firmware values.

While looking around for something vaguely related to this, I found myself examining some BitPim source code, and noticed to my surprise that the parts that spoke the BREW protocol looked very similar to what I had seen in the Novatel SDK baked into the abstraction layer module for the V740.  I did a bit of digging, and it really looks more and more like the firmware serial port interface is some variation of BREW.

Specifically...:

- It uses the same crc16 and 0x7d/0x7e escaping (which you call "ppp encoding") and 0x7e lead byte as the BREW protocol component in BitPim.
- The commands to manipulate the filesystem, as used by BitPim, appear to map to what look like analogous functions in the Novatel SDK (though I have not tried poking the card's filesystem, from debug prints, it does appear that the commands are the same).  Specifically, as with BitPim's BREW client, for filesystem operations, it appears that the following are used:
  * Command code (byte) 0x4B (something I had named NVTL_CMD::SUBSYS_CMD)
  * A following byte that I termed the subsystem identifier, which for filesystem I/O appears to be 0x13, or what I had termed NVTL_SUBSYS::STORAGE.
  * A subsystem command code (two bytes; note that BitPim combines what I have termed "subsystem identifier" and the first byte of "subsystem command code" into one 16-bit field, with a trailing must-be-zero 8-bit field) that performs a subsystem-specific operation, which in the case of the storage subsystem (0x13) takes values such as:
    $ Diag_EFS2_Open (0x0002), taking two 32-bit arguments and a variable size argument (presumed to be a filename string), respectively.
    $ Diag_EFS2_Close (0x0003), taking a single 32-bit argument.
    $ Diag_EFS2_Read (0x0004), taking three 32-bit arguments.
    $ Diag_EFS2_Write (0x0005), taking two 32-bit arguments and a variable size argument (presumed to be file data), respectively.
    $ Diag_EFS2_Unlink (0x00008), taking a variable length argument (presumed to be a filename string) and an 8-bit argument which appears to always be zero (OR a null terminator for variable length buffer, which has a count of bytes in the API and is not assumed to be null terminated), respectively.
    $ Diag_EFS2_OpenDir (0x000B), taking a variable length argument (presumed to be a filename string) and an 8-bit argument which appears to always be zero (OR a null terminator for variable length buffer, which has a count of bytes in the API and is not assumed to be null terminated), respectively.
    $ Diag_EFS2_ReadDir (0x000C), taking two 32-bit arguments.
    $ Diag_EFS2_CloseDir (0x000D), taking a single 32-bit argument.
- The Diag_Get_Software_Version command (0x00) appears to match most of the firmwarerequest/firmwareresponse BitPim command with the same command code, although the response does not appear to be as long.  For example, here's a typical response to Diag_Get_Software_Version:
  * 0:001> db poi(@ebp-430) ldwo(@ebp-14)
  * 004b9f00  00 4e 6f 76 20 30 31 20-32 30 30 36 31 39 3a 34  .Nov 01 200619:4
  * 004b9f10  35 3a 30 30 4e 4f 56 20-30 32 20 32 30 30 36 31  5:00NOV 02 20061
  * 004b9f20  34 3a 30 30 3a 30 30 31-33 35 0a 00 00 00 00 2a  4:00:00135.....*
  * 004b9f30  06 ee 87 00 02 00 72                             ......r

Given all the above similarities (which all appear to map to what BitPim uses for BREW), I think it would be a good guess to say that the protocol I've been reversing is the BREW diagnostics/command protocol, as partially implemented in BitPim.

The protocol implemented by the device is capable of far more than just filesystem I/O, however, as I previously alluded to.  There are commands to do operations like get/set firmware nonvolatile values (e.g. ESN, NAM MIN, NAM SID/NID, earpiece volume, backlight (it would appear that the SDK supports more than data cards given the previous two firmware settings)), as well as perform operations like dial out, end call (the latter being of particular interest to me), manage SMS message transmission and reception, query detailed information about the active network, which protocols are in use, signal strength, and so forth.  Assuming that this protocol is indeed BREW, I would hazard a guess that at least some of this functionality will likely translate to other devices as well.

The latter point is what might make this particular insight of value to the BitPim developers, as the (debug) Novatel SDK linked into the V740 abstraction layer module has debug prints naming functions for performing a number of tasks, even functions that are not ever referenced by a call (it would appear that somebody had /OPT:REF turned off on their build in their linker settings).

Assuming that the protocol in question is again, really BREW, then by performing further analysis on C client code such as this abstraction layer module, it should be possible to develop a much more comprehensive and accurate understanding of the BREW protocol than blind trial and error, or simply analyzing protocol captures "on-the-wire".

I've also taken the liberty of examining the Sprint connection manager software for the Sprint-branded Merlin X720, and it too includes a (differing) abstraction layer module of sorts to adapt the Novatel SDK into a standard interface, albeit an exported MFC class and not a C API this time.  The Sprint DLL is also linked to a debug version of the Novatel SDK, and has correspondingly useful debug prints as well (and seems to include more functionality than the SmithMicro/Verizon connection manager abstraction DLL's version of the Novatel SDK, for instance commands to access the AGPS functionality on the device).

For those interested, I've put up a list of the Novatel SDK functions present in the Verizon connection manager abstraction DLL, as well as a list of firmware values (read/write via Diag_NV_Read (0x26), Diag_NV_Write (0x27) respectively), and several of the command codes up here: < http://www.nynaeve.net/Code/NvtlResearch-1.txt >  (Note that not all of the Diag_* APIs map to a unique command code, as many of them flow through NVTL_CMD::SUBSYS_CMD (0x4B).)  Most of the research here has been done via analyzing the Verizon connection manager app, although I have written a small test C program that uses various exported and non-exported functions in the V740 abstraction layer DLL to talk to the firmware for experimentation.  (Thus far, I've tried to avoid things that would appear to write to the card, in an attempt to avoid bricking it...)

- Ken Johnson (Skywing)
http://www.nynaeve.net

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.