Firmware uploader for HP un2400 with Qualcomm Gobi chipset (alpha quality)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[ Please CC me in replies, since I'm not subscribed to this list ]

Hello all,

I'm one of the owners of the HP un2400 WWAN card with the Qualcomm's Gobi
chipset and today, after many hours of desperate tries, I've managed to upload
firmware into this card and switch it into the modem mode. It works fine after
that. The shell script that I've used as well as an auxiliary program to
convert hex lists into strings are attached. I'm completely ignorant in what
USB and serial protocols are concerned (in fact, I've spent the most time
figuring out the correct settings for /dev/ttyUSB0), so I hope that someone
with a better knowledge can rewrite my crude hack into a useful program that
follows all the protocols and behaves nicely w.r.t. suspends etc. Below I'll
describe what I did and why.

My system is Debian Lenny with 2.6.28 kernel and qcserial.c driver from the
current tree.

1) Background.
  Qualcomm chipset apparently contains two USB devices with different product
  IDs (can be found in drivers/usb/serial/qcserial.c). After initialization,
  only the first one is visible (QDL port, in qcserial's slang). It is used 
  to upload firmware into the main modem device. After this is done, the QDL
  device is disconnected and the modem becomes visible to the system. This
  sequence is confirmed using a USB sniffer under Windows. Both devices use
  serial interface. The qcserial recognizes them correctly and logs the
  corresponding message if loaded with "debug" option.

2) Source of information:
  a) Log file of the Windows Qualcomm driver. I have found it in
        C:\Documents and Settings\All Users\Application Data\QUALCOMM\QDLService\QDLService.txt
     but your location can be different.
  b) List of the firmware corresponding to the correct wireless carrier found
     in the same directory (file Options.txt).
  c) UsbScoop sniffer

3) Protocol used.
  The firmware upload process consists of a couple of simple handshaking
  messages and verbatim shoving of the firmware into the corresponding serial
  interface. The firmware is sent in 1MB-long chunks with zero-length packets
  in between. One of the firmware file is cut short by 8 bytes for some
  reason. The correct length can be found in QDLService.txt
  This file contains all the messages completely, except that most of them are
  surrounded by 0xfe with the checksum added before sending (compare messages
  in QDLService.txt with those in my script).

  This is the only place where the sniffer is needed, since I wasn't able to
  guess the algorithm for this checksum. Perhaps someone can figure it out.
  Then all the information needed to upload the firmware will be contained in
  QDLService.txt completely.

4) Firmware
  Gobi uses different firmware for different wireless carriers. The current
  list can be found in C:\QUALCOMM\QDLService\ReadMe.rtf  Running "strings"
  also helps. My carrier is AT&T in the US, so my script works for the
  corresponding firmware ONLY.

  I place the firmware into Gobi-Firmware directory (evident from the script).

5) About the script
  Very crude, basic, and (hopefully) self-explanatory.
  `send?' --- are the messages that have to be sent.
  `receive?' --- are those that are supposed to be received in return. They
  are not used in the script and are only included for information purposes.
  Everything sent back by the card is logged in Gobi-WWAN-response. So one can
  use hexdump to compare this output with what is expected.

  `sleep 0.1' are added to guarantee that that the response is received before
  the next message is sent. I don't know whether it is needed.
  `echo -n ""' send empty packets that are present in the sniffer log.
  I don't know whether this is important either.

  0x00915188 in send2 and send3 and 0x0036711c in send4 and send5 are the
  lengths of the corresponding firmware files

I guess that's about it. 

I will be happy to answer any questions that you might have about this
procedure in general and my script in particular. I'm not subscribed to this
list, so please CC: me into your replies to this message.

I can also e-mail the USB sniffer's log file personally (it's large) if it can
be of any help.

Best,

   --- Alex.

#! /bin/sh
#
# This is a crude hack to load firmware into broadband WWAN modules that
# incorporate Gobi chipset from Qualcomm. It appears to work with the HP
# un2400 card and AT&T firmware taken from
#     C:\QUALCOMM\QDLService\Packages\2\AMSS.mbn
#     C:\QUALCOMM\QDLService\Packages\2\Apps.mbn
#
# The firmware has to be split into pieces of length 2^20 bytes (that is, 1MB).
# Moreover, the last piece of AMSS.mbn has to be shorten by 8 bytes for some
# reason. Its correct length is 86408 bytes.
#
# DISCLAIMER:
#   This software is NOT authorized to be used by neither Qualcomm nor HP.
#   It is very likely to damage or destroy your hardware and/or void your
#   warranty on it. Use it at your own risk. The author of this software
#   can in no way be held liable for any damage caused by your use of it.
#

USBdev=/dev/ttyUSB0

# compile with "gcc hex2str.c -o hex2str"
hex2str=./hex2str

firmware1="Gobi-Firmware/2/amss"
firmware2="Gobi-Firmware/2/apps"
firmsuffix="mbn"

# This firmware is for AT&T _only_
md5sum -c --status <<- EOF
	2eeb70c3e71b712374a26b2d36e0dfdf  Gobi-Firmware/2/amss-01.mbn
	7d9254bc8d70bd83a09fcdde2865ccf8  Gobi-Firmware/2/amss-02.mbn
	d7a01eece2da5dc5e1c8f4c5ce197025  Gobi-Firmware/2/amss-03.mbn
	6fad55473e5a32a459152b8b817c2672  Gobi-Firmware/2/amss-04.mbn
	9c55ad1934f61c4da8a28c74624549a9  Gobi-Firmware/2/amss-05.mbn
	8604b77efc0442bfeb906b7379b98988  Gobi-Firmware/2/amss-06.mbn
	4cdfcf70e8b13ea3dfc8b8833c44a42b  Gobi-Firmware/2/amss-07.mbn
	4b533b028693faa2010211aedea07019  Gobi-Firmware/2/amss-08.mbn
	43241f8968a1e3c3f5a323691b6ac12d  Gobi-Firmware/2/amss-09.mbn
	5c9a794e424c676f4f75964bc0b80fad  Gobi-Firmware/2/amss-10.mbn
	999efd6c114f58847f4cf2c1957c949d  Gobi-Firmware/2/apps-01.mbn
	8ea05d62fa73826c4a50499e57bb4bac  Gobi-Firmware/2/apps-02.mbn
	d96ee221642e328d145fbf6cd6717e93  Gobi-Firmware/2/apps-03.mbn
	86bcadbcbafc376ad296e3c88e41750f  Gobi-Firmware/2/apps-04.mbn
EOF
if [ $? = 1 ]; then
	echo "ERROR: Firmware check sum mismatch, exiting."
	exit 1
fi

# Set the serial interface to be as raw as possible
stty -F $USBdev raw -hupcl -cread -clocal -echo -echoe -echok -echoctl -echoke -onlcr -iexten

responsefile=Gobi-WWAN-response

# Save everything that the modem sends back to us.
# This cat should quit by itself if everything works out fine when the QDL
# device disconnects. We will try to kill it at the end just in case.
cat $USBdev > $responsefile &
catID=$!

# ------------------------------------------------------------------------

send1="7e 01 51 43 4f 4d 20 68 69 67 68 20 73 70 65 65 64 20 70 72  \
	6f 74 6f 63 6f 6c 20 68 73 74 00 00 00 00 04 04 30 03 0b 7e"

# receive1="7e 02 51 43 4f 4d 20 68 69 67 68 20 73 70 65 65 64 20 70  \
#	72 6f 74 6f 63 6f 6c 20 74 67 74 04 00 f0 cb 04 04 00 00 00 \
#	00 00 00 00 00 00 00 00 00 00 30 64 7a 7e"

send2="7e 25 05 88 51 91 00 01 00 00 00 04 00 00 c4 e2 7e"

# receive2="7e 26 00 00 01 00 00 00 04 52 65 7e"

send3="27 00 00 00 00 00 00 88 51 91 00 b4 5c"

# receive3="7e 28 00 00 00 00 00 00 00 00 14 39 7e"

send4="7e 25 06 1c 71 36 00 01 00 00 00 04 00 00 98 ae 7e"

# receive4="7e 26 00 00 01 00 00 00 04 52 65 7e"

send5="27 00 00 00 00 00 00 1c 71 36 00 5b 21"

# receive5="7e 28 00 00 00 00 00 00 00 00 14 39 7e"

send6="7e 29 bb 4c 7e"

# ------------------------------------------------------------------------

echo -n "Doing the initial handshake . . ."

echo $send1 | $hex2str > $USBdev
sleep 0.1
echo $send2 | $hex2str > $USBdev
sleep 0.1
echo $send3 | $hex2str > $USBdev

echo " done."

echo -n "Sending the first firmware file"

for i in 01 02 03 04 05 06 07 08 09 10; do
	cat ${firmware1}-$i.$firmsuffix > $USBdev
	if [ "$i" != "10" ]; then echo -n "" > $USBdev; fi
	echo -n " ."
done

echo " done."

echo -n "Doing the intermediate handshake . . ."

echo $send4 | $hex2str > $USBdev
sleep 0.1
echo $send5 | $hex2str > $USBdev

echo " done."
echo -n "Sending the second firmware file"

for i in 01 02 03 04; do
	cat ${firmware2}-$i.$firmsuffix > $USBdev
	if [ "$i" != "04" ]; then echo -n "" > $USBdev; fi
	echo -n " ."
done

echo " done."

echo -n "Switching to the modem device . . ."

echo $send6 | $hex2str > $USBdev

echo " done???"

sleep 2

catID=`ps --pid $catID -o pid=`
if [ ! -z "$catID" ]; then kill $catID; fi
03/21/2009 06:01:41.500 Connect()
03/21/2009 06:01:41.625 Main()
03/21/2009 06:01:41.625 ReportStatus()
03/21/2009 06:01:41.625 Run( "Hewlett-Packard", 1 ) 
03/21/2009 06:01:41.625 ReportStatus()
03/21/2009 06:03:54.359 Control()
03/21/2009 06:03:54.359 DeviceChange( ARRIVAL ) - \\?\USB#Vid_03f0&Pid_201d#5&11e1997e&0&2#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
03/21/2009 06:03:54.781 PDA() - Attempting to start download thread, [COM6, vid_03f0&pid_201d#5&11e1997e&0&2]
03/21/2009 06:03:54.781 PDA() - Started download thread 248 (4648), [COM6, vid_03f0&pid_201d#5&11e1997e&0&2]
03/21/2009 06:03:55.000 QDL protocol server request sent
03/21/2009 06:03:55.000   0000 [9 03/21/2009 06:03:54.984]
03/21/2009 06:03:55.000     01 51 43 4F 4D 20 68 69 67 68 20 73 70 65 65 64 
03/21/2009 06:03:55.000     20 70 72 6F 74 6F 63 6F 6C 20 68 73 74 00 00 00 
03/21/2009 06:03:55.000     00 04 04 30 
03/21/2009 06:03:55.015 QDL protocol server response received
03/21/2009 06:03:55.015   0001 [8 03/21/2009 06:03:55.015]
03/21/2009 06:03:55.015     02 51 43 4F 4D 20 68 69 67 68 20 73 70 65 65 64 
03/21/2009 06:03:55.015     20 70 72 6F 74 6F 63 6F 6C 20 74 67 74 04 00 F0 
03/21/2009 06:03:55.015     CB 04 04 00 00 00 00 00 00 00 00 00 00 00 00 00 
03/21/2009 06:03:55.015     30 
03/21/2009 06:03:55.015 QDL sending image file: C:\QUALCOMM\QDLService\Packages\2\AMSS.mbn
03/21/2009 06:03:55.031 QDL protocol server request sent
03/21/2009 06:03:55.031   0002 [9 03/21/2009 06:03:55.031]
03/21/2009 06:03:55.031     25 05 88 51 91 00 01 00 00 00 04 00 00 
03/21/2009 06:03:55.031 QDL protocol server response received
03/21/2009 06:03:55.031   0003 [8 03/21/2009 06:03:55.031]
03/21/2009 06:03:55.031     26 00 00 01 00 00 00 04 
03/21/2009 06:03:55.265 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:55.390 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:55.546 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:55.828 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:56.062 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:56.296 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:56.437 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:56.578 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:56.671 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:56.687 QDL protocol server sent 86408 bytes of image
03/21/2009 06:03:56.687 QDL protocol server request sent
03/21/2009 06:03:56.687   0004 [9 03/21/2009 06:03:56.687]
03/21/2009 06:03:56.687     27 00 00 00 00 00 00 88 51 91 00 B4 5C 
03/21/2009 06:03:56.890 QDL protocol server response received
03/21/2009 06:03:56.890   0005 [8 03/21/2009 06:03:56.890]
03/21/2009 06:03:56.890     28 00 00 00 00 00 00 00 00 
03/21/2009 06:03:56.890 Sending image file: C:\QUALCOMM\QDLService\Packages\2\Apps.mbn
03/21/2009 06:03:56.890 QDL protocol server request sent
03/21/2009 06:03:56.890   0006 [9 03/21/2009 06:03:56.890]
03/21/2009 06:03:56.890     25 06 1C 71 36 00 01 00 00 00 04 00 00 
03/21/2009 06:03:56.937 QDL protocol server response received
03/21/2009 06:03:56.937   0007 [8 03/21/2009 06:03:56.937]
03/21/2009 06:03:56.937     26 00 00 01 00 00 00 04 
03/21/2009 06:03:57.187 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:57.312 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:57.437 QDL protocol server sent 1048576 bytes of image
03/21/2009 06:03:57.468 QDL protocol server sent 422172 bytes of image
03/21/2009 06:03:57.468 QDL protocol server request sent
03/21/2009 06:03:57.468   0008 [9 03/21/2009 06:03:57.468]
03/21/2009 06:03:57.468     27 00 00 00 00 00 00 1C 71 36 00 5B 21 
03/21/2009 06:03:57.593 QDL protocol server response received
03/21/2009 06:03:57.593   0009 [8 03/21/2009 06:03:57.593]
03/21/2009 06:03:57.593     28 00 00 00 00 00 00 00 00 
03/21/2009 06:03:57.593 QDL protocol server request sent
03/21/2009 06:03:57.593   0010 [9 03/21/2009 06:03:57.593]
03/21/2009 06:03:57.593     29 
03/21/2009 06:03:58.109 QDL protocol server response timeout
03/21/2009 06:03:58.109 QDL download complete
03/21/2009 06:03:58.796 CT() - Waiting for device removal (1 of 30)
03/21/2009 06:03:59.796 CT() - Waiting for device removal (2 of 30)
03/21/2009 06:04:00.796 CT() - Waiting for device removal (3 of 30)
03/21/2009 06:04:00.984 Control()
03/21/2009 06:04:00.984 DeviceChange( REMOVE ) - \\?\USB#Vid_03f0&Pid_201d#5&11e1997e&0&2#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
03/21/2009 06:04:00.984 CT() - Closed download thread 248, [COM6, vid_03f0&pid_201d#5&11e1997e&0&2, 0]
03/21/2009 06:04:03.921 Control()
03/21/2009 06:04:03.921 DeviceChange( ARRIVAL ) - \\?\USB#Vid_03f0&Pid_1f1d&MI_00#6&368ee46f&0&0000#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
03/21/2009 06:04:04.953 Control()
03/21/2009 06:04:04.953 DeviceChange( ARRIVAL ) - \\?\USB#Vid_03f0&Pid_1f1d&MI_01#6&368ee46f&0&0001#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
03/21/2009 06:06:59.046 Control()
03/21/2009 06:07:24.875 Control()
#include <stdio.h>
#include <ctype.h>
#include <stdio.h>

int main (void) {
	int inchar, outchar = 0, hexfound = 0;

	while ((inchar = getchar()) != EOF) {
		if (isspace(inchar)) {
			if (hexfound) printf("%c", outchar);
			hexfound = 0;
			outchar = 0;
			continue;
		}
		if (isxdigit(inchar)) {
			if (inchar >= 'a' && inchar <= 'f')
				inchar += 10 - 'a';
			else if (inchar >= 'A' && inchar <= 'F')
				inchar += 10 - 'A'; 
			else if (inchar >= '0' && inchar <= '9')
				inchar -= '0'; 
			else perror("Something is wrong with hex digits");

			outchar = (outchar << 4) + inchar;
			hexfound = 1;

			continue;
		}
		putchar (inchar);
	}

	return 0;
}

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux