Adding QCDM messages to enable USB760 GPS

Dan Williams dcbw at redhat.com
Fri Nov 22 12:35:57 PST 2013


On Fri, 2013-11-22 at 00:53 -0600, Kevin Baker wrote:
> Hi all,
> 
> I have a Verizon USB760 / Novatel Wireless MC760 CDMA modem which is
> able to support GPS location data internally with an updated firmware
> version. Under Windows it needs a companion app to enable the GPS
> functionality; once this is enabled I can see NMEA data coming out on
> another serial port. See:
> http://support.verizonwireless.com/support/devices/knowledge_base.html/30102
> 
> So far I have logged the QCDM traffic under Windows and isolated
> the messages to strictly what is needed to enable the GPS interface and
> keep it alive, and written a C program to simulate the Windows app's
> traffic. This app works but is an extreme hack (also, doesn't work with new
> versions of MM which actually take the QCDM ports and do more useful things
> with them...) I would like to incorporate this functionality properly into
> MM.
> 
> Pseudocode for the app as written which works:
> 
> * send QCDM keepalive packet to wake up the QCDM interface
> 
> char id_msg[] = { 0x0,0x78,0xf0,0x7e };

That's a standard "version info" command.  You'll see it a lot, it does
get used as a keepalive sometimes.

> * sleep for 1 second, ignoring any reply but draining receive buffer
> like we actually read the data (after sending each command below as well)

The sleep/discard likely discard the "version info" response, of course.
You'll see that it's quite a lot bigger, and includes some strings like
model#, dates and times of release, etc.

> * send what I think is the GPS enable packet:
> char K0d_msg_x18[] = {
>     0x4b,0x0d,0x18,0x00,0x00,0x60,0xea,0x45,
>     0x00,0x00,0xe1,0x19,0x07,0x30,0x6e,0x42,
>     0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
>     0x0e,0xbd,0x7e
> };

0x4b = subsystem command
0x0d = GPS subsystem
0x0018 = GPS subsystem command number
<real command data>
0xbd0e = CRC
0x7e = HDLC marker

> * sleep for 1 second, again ignore replies

Obviously ignoring the response and any error that may be returned :)

> then loop forever, sending these:
> 
>     * first a QCDM keepalive packet (id_msg above)
> 
>     * sleep 500 mxxxxxxXXXXXHs
> 
>     * GPS keepalive packet?
>     char K0d_msg_x40[] = {
>         0x4b,0x0d,0x64,0x00,0x0a,0x00,0x01,0x01,
>         0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
>         0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xfa,
>         0xff,0xff,0xff,0xe9,0x03,0x00,0x00,0x00,
>         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
>         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
>         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
>         0x00,0x00,0x00,0x00,0x00,0x77,0x17,0x7e
>     };

0x4b = subsystem command
0x0d = GPS subsystem
0x0064 = GPS subsystem command number
<command data>
0x1777 = CRC
0x7e = HDLC marker

>     * sleep 500 ms
> 
> I don't have a clue about the data structure being passed to the modem.
> If you stop the loop repeating the messages, eventually after a period of
> time the GPS module will shutdown and NMEA traffic will stop. Unfortunately
> I have been throwing away the replies from the modem so I'm not exactly
> sure what the device is sending back; or how often the GPS keepalive
> packet should be sent, but I can try to hack these into ModemManager and
> get some better output.
> 
> I also have traces of the full connection log and network registration
> for a USB760 with --log-level=DEBUG: http://pastebin.com/XQvnRX1h
> 
> My thought is to add the existing opaque messages as-is into
> libqcdm commands then add a location setup section
> into plugins/novatel/mm-broadband-modem-novatel.c similar to how it is done
> in the option/..-hso.c driver... is that somewhat correct? I am very new
> to ModemManager's source.

That's the right way to go.  libqcdm is older code than MM, so it's a
bit less organized.  I would first add the structures to dm-commands.h
for the commands (just put something like "guint8 unknown[20]" for the
stuff we don't know and then memcpy it in later from a static array).
Then in commands.c and commands.h you create the public functions that
allocate & fill the command, and parse the results.  For the results
parser, you'd just check the header and error code, then return true or
false.

You could use the DMCmdSubsysWcdmaStateInfoRsp structure and associated
stuff in command.c/command.h as an example.

Dan

> Thanks in advance for any help, and thanks for all the work
> on ModemManager!!!
> 
> Kevin
> _______________________________________________
> ModemManager-devel mailing list
> ModemManager-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/modemmanager-devel




More information about the ModemManager-devel mailing list