Tuesday, August 3, 2010

How To Read SMS Messages From Huawei E620 Modem

I always wanted to read SMS messages from my Huawei modem on Linux but unfortunately It seems that they only support Microsatan Winblows...

Anyway, while I was trying to read /dev/ttyUSB2, I was connecting a usb gadget with serial over usb, I got a of bunch of gibberish messages, I found out, beside the fact that the usb gadget didn't work :D, that the Huawei supports serial over usb ! it also seems that I have been in a cave, hence the bad reception, because people have been playing with this for decades :)

Cool I can finally read the messages without playing solitaire !

Huawei AT commands
While the modem is connected it keeps sending statistics which include the connection duration, upload/download rates and signal strength:
It also supports a subset of the AT commands, I googled for Huawei AT commands, It seems that every model (or perhaps Vendor) supports a different set of AT commands, but "they" don't publicly provide this information !
Anyway, most of them support dialling numbers, notifications, reading/sending SMS messages... Which means that you can easily turn your machine into an SMS gateway  ;) !
I'm only interested in a subset of the commands:
AT+CMGS="phone number" "message" <ctr+z>
The first command, enables the text mode for other commands, second one sets the encoding to UCS2, I set it to UCS2 to unifiy all the output from the Huawei so I can parse both English and Arabic messages, but there are other options try AT+CSCS=?.

The third one retrieves the list of messages and the last one sends out an SMS, but I haven't tried this one because I didn't have any credit left :)

Python Script
After a some attempts with minicom and ipython, I quickly put together a small python script to read the SMS messages, it's crappy but it works:
#!/usr/bin/env python
import serial

port = serial.Serial(baudrate=115200, port='/dev/ttyUSB2', timeout=5)
port.write('AT+CMGF=1\r\n')      #set text mode
port.write('AT+CSCS="UCS2"\r\n') #set encoding to UCS2
port.write('AT+CMGL="ALL"\r\n')  #get all messages

def __decode(str):
    ustr = u''
    str = str.strip().replace('"', '')
    for i in range(len(str)):
        if not i % 4:
            ustr += unichr(int(str[i:i+4], 16))
    return ustr

gotmsg = False

    line = port.readline()
    if line.startswith('+CMGL'):
        info = line.split(',')
        print 'message#%s from %s date %s time %s %s'     \
              %(info[0].split(':')[1], __decode(info[2]), \

info[4], info[5], __decode(port.readline()))
        gotmsg = True
    if gotmsg and line.startswith('OK'): break

Damn it ! more bills :(
message# 7 from 1011161051159710897116 date "10/07/23 time 16:59:55+12"
 عميلناالعزيز:نحيط سيادتكم علمابضرورة سدادفاتورتكم خلال48ساعة نظرا لانتهاء موعد 
message# 8 from 1011161051159710897116 date "10/07/23 time 16:59:55+12"
www.etisalat.com.eg استحقاقها وذلك لضمان استمرارالخدمة,كما يمكنكم السدادعن طريق موقع اتصالات
message# 9 from 1011161051159710897116 date "10/07/23 time 16:59:55+12"
 في حالةالسداديرجى تجاهل الرسالة


  1. This comment has been removed by the author.

  2. I got the ONDA AT Commands manual and I'm going to implement something similar for ZTE MF626 whenever I get some free time .... cool stuff :-)

  3. There is now a Python library to do that : http://pypi.python.org/pypi/sms