使用 python 读取 GSM 调制解调器输出

Reading GSM modem output with python

我有一个 GSM 调制解调器 'D-Link DWM-157'。我想用这个调制解调器发送 SMS 和 USSD 代码。要发送短信,我使用 smstools3,一切正常。发送 USSD 代码的目的是检索余额以便为 SIM 卡充值。要发送 USSD 代码,我也想使用 smstools3。问题是当我从 /dev/ttyUSB0 端口发送一个 USSD 代码时,我必须从 /dev/ttyUSB1 端口接收它的应答!!我在 smstools 论坛上询问了这种行为,他们告诉我一些调制解调器使用两个端口来发送和接收 USSD 代码。我不认为 smstools3 中有这样的选项可以通过特定端口发送 USSD 代码并从不同端口接收它的答案(我在他们的论坛上问过这个问题,但他们还没有回复)。所以我想写一个简单的程序来持续监听一个端口(即/dev/ttyUSB1),接收并解析USSD代码的答案。 USSD 代码由 smstools3 发送,但答案由我的程序接收。为此,我编写了以下代码:

#!/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

我通过短信发送 USSD 代码:

当没有输出时我只得到空行: ./receive_ussd_gsm.py

/dev/ttyUSB1 is open ...

Thread statred... 

当我通过 smsd 发送 ussd 代码时:

# 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

我收到以下错误:

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?)

我可以从minicom 得到正确的输出。但我想把它放在我的程序中。顺便说一句,我一次使用一个程序连接到一个端口,所以我不知道为什么会这样:

device disconnected or multiple access on port?

我在使用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?)

我找不到合适的方法或更准确的示例纯 python 代码来解决这个问题,所以我用另一种方式解决了我的问题。 我使用下面的bash命令(代码)来接收发送USSD代码的结果:

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

我通过子进程模块在我的 python 程序中使用代码并解析结果。我认为它运行良好,没有任何问题。顺便说一句,我认为 smstools3 无法通过特定端口发送 USSD 代码,并在他们的论坛中回答我时从不同的端口接收它的答案。