Sinai Sinai - 1 year ago 258
Linux Question

Reading GSM modem output with python

I have a GSM modem 'D-Link DWM-157'. I want to use this modem to send SMS and USSD codes. To send sms I use smstools3 and everything is OK. The goal of sending USSD code is to retrieve the balance in order to recharge the SIM card. To send USSD codes I want to use smstools3 as well. The problem is that when I send a USSD code from port /dev/ttyUSB0, I have to receive it's answer from /dev/ttyUSB1 port!! I asked on smstools forum about this behavior and they told me some modems used two ports for sending and receiving USSD codes. I don't think there is such an option in smstools3 to send a USSD code via a specific port and receive it's answer from a different port (I asked about this on their forum, but they have not replied yet). So I want to write a simple program to continuously listen to a port (i.e. /dev/ttyUSB1), receive and parse the answers of USSD codes. The USSD codes are sent by smstools3 but the answers are received by my program. To do this, I wrote the following code:

#!/usr/bin/python
import serial, time
from time import sleep
import threading
def serial_def():
ser = serial.Serial()
ser.port = "/dev/ttyUSB1"
ser.baudrate = 9600
ser.timeout= 5
ser.xonxoff = False
ser.rtscts = False
ser.dsrdtr = False
ser.open()

if ser.isOpen():
print (ser.name+ " is open ...\n")
print "Thread started... \n"

while True:
out=ser.readline()
print out


I send the USSD code via smsd:

When there is no output I only get blank lines:
./receive_ussd_gsm.py

/dev/ttyUSB1 is open ...

Thread statred...


and when I send the ussd code via smsd:

# smsd -C GSM1
Communicating with GSM1. ( Press Ctrl-C to abort. )
( If you need to send Ctrl-Z, use Alt-Z )
Default device is /dev/ttyUSB0
Press Enter to start or type an another device name.

Opening device /dev/ttyUSB0
Ready.
ATE1
OK
ATZ
OK
at+cusd=1,"*140*11#",15
OK


I get the following error:

Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "./receive_ussd_gsm.py", line 31, in serial_def
out=ser.readline()
File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 501, in read
'device reports readiness to read but returned no data '
SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)


I can get the output correctly from minicom. But I want to have it in my program. By the way, I use one program connected to a port at a time so I do not know why I get this:

device disconnected or multiple access on port?


I also give the above error when using miniterm.py!!

# miniterm.py

--- Available ports:
--- 1: /dev/ttyUSB0 'D-Link DWM-157'
--- 2: /dev/ttyUSB1 'D-Link DWM-157'
--- 3: /dev/ttyUSB2 'D-Link DWM-157'
--- 4: /dev/ttyUSB3 'D-Link DWM-157'
--- Enter port index or full name: 2
--- Miniterm on /dev/ttyUSB1 9600,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---

--- exit ---
Exception in thread rx:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/local/bin/miniterm.py", line 445, in reader
data = self.serial.read(self.serial.in_waiting or 1)
File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 501, in read
'device reports readiness to read but returned no data '
SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

Answer Source

I could not find a suitable way or more precisely a sample pure python code to resolve this issue, so I fixed my problem in another way. I use the following bash command (code) to receive the results of sending USSD codes:

( stty raw; cat >> /tmp/gsm1_ussd ) < /dev/ttyUSB1

I use the code within my python program by using subprocess module and parse the results. I think it is working great without any problems. By the way as I thought there is no way in smstools3 to send a USSD code via a specific port and receive it's answer from a different port as they answered me in their forum.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download