Protocol of a Wavecom 2C2 GSM module

By dose | December 6, 2018
Under: Uncategorized

As I recently wrote, I had a Wavecom FastTrak M1306B compatible GSM-Modem from China (branded as Ostent Q2303A modem) where I flashed a new firmware from Wavecom to it, as it didn’t receive any SMS, which finally broke it.
I found a good amount of documentation for the modem and mirrored it here for archival, in case the chinese sites serving the documentation go offline.

From what I have read in the documentation, there is a BOOT pin that you have to pull down to GND with a resistor in order to place the defunct modem in a Firmware upload Boot-mode.
After doing so, it really gets into download mode, but due to the fact that I have a board with an Prolific PL2303 USB->Serial converter on it and the RTS/CTS signals were not connected to the Wavecom 2C2 module, the downloader mode doesn’t work as expected.
Normally, the firmware upgrade should be done with the DwlWin application, which one can obtain from the Sierrawireless site, because they bought Wavecom.
I unfortunately was never able to flash the module with it, because the module always NACKed the initial Bootstrap command 0x28. Not sure if it has something to do with the unconnected RTS/CTS lines, because documentation states that these lines are necessary, but I finally gave up on it, it’s not worth the effort.
Nevertheless during my research, I found out a bit about the Downloader-protocol which I want to share with you.
As the DwlWin application is C++ with a lot of classes, it is a pain to reverse-engineer. Fortunately the company M-Star also mad a DwlWin-application for their chips, which seems to be loosely based on the WaveCom DwlWin, but with very verbose debug output and seemingly C-code, so I first had a look at this to find the general principle of the Recovery-procedure. Note that this is not related to the wavecom chip:

Procedure:
Download Bootstrap to chip:
1) Open port with 2400 baud.
2) GetChipID
3) Send SendAndRecvStartFrame
4) Send PacketLengthSettingFrame
5) Change to requested baudrate
6) Send DataFrame until Bootloader is transmitted
7) Send ExitFrame

Then run Bootstrapper:
1) Set Baudrate to 2400 baud
2) Send BootstrapStartFrame
3) Change to requested baudrate

Next is to send Downloader to Bootstrap, which is a seperate protocol spoken
by bootstrapper.

M-Star command frames
Here are the corresponding commands used by M-Star (I don’t explain them any further, i.e. how to calc CRC, because it’s not relevant for Wavecom chips anyway):

#define ACK 0x06
#define NACK 0x15

Frame data is organized as {Command, [Data...], CKSHi CKSLo}
So it has a 16bit frame checksum and specific commands:

PacketLengthSettingFrame = {0x01, LenHi, LenLo, 0x00, 0x00, CKSHi, CKSLo}
Max. 28 bytes
SendAndRecvStartFrame = {0x02, Baudrate, 0x00, 0x00, 0x00, CKSHi, CKSLo}
Baudrate:
1 - 2400
2 - 4800
3 - 9600
4 - 19200
5 - 38400
6 - 57600
7 - 115200
8 - 230400
9 - 460800
10 - 921600
-> ACK
DataFrame = {0x16, ....Framedata..., CKSHi, CKSLo}
-> ACK (0x06)
ExitFrame = {0x04, CRC4, CRC3, CRC2, CRC1, CKSHi, CKSLo}
-> ACK
GetChipID = {0x07, 0x04, 0x00, 0x00, 0x00, CKSHi, CKSLo}
-> ACK (0x06), 4 Bytes chip ID
BootstrapStartFrame = {0x28, 0x02, 0x53, Baudrate, CKSHi, CKSLo}
-> ACK

CKS..Frame Checksum
CRC..CRC over sent application

The Wismo 2C2 protocol

Now the WISMO 2C speak a different protocol. You can use the same baudrate table as above with the M-Star protocol.
CKS (Frame checksum) is always an XORed sum over the previous bytes of the frame, so very easy to calc.

Every data frame is organized as {Len, [Data…], CKS}
Therefore:

SendAndRecvStartFrame = {0x04, 0x53, Baudrate, 0x43, 0x01, CKS}
-> ACK
DataFrame = {Len, [Data...], CKS}
ExitFrame = {0x00, 0x00}
-> ACK
SetBaudrate = {0x02, 0x53, Baudrate, CKS}

0x53 = 'S' = Baudrate
0x50 = 'P' = Parity (0...None)
0x54 = 'T' = Stopbits (1..1 Stopbit)

Introduce downloader:
= {0x09, Ver_Maj, Ver_min, Ver_release, Ver_build, ?Baudrate?, Unixtime1, Unixtime2, Unixtime3, Unixtime4, CKS}
Ver_*.......Version octets of DWLWin Version
Unixtime*...Current time_t Unixtime timestamp as DWORD

I guess, nobody really has a use for this, but I just wanted to dump the information here in case there is interest in it and to save other ppl the effort of reversing it.

Leave a Comment

Name:

E-Mail :

Subscribe :
Website :

Comments :