Выполнение USSD запросов на модеме Huawei E1550

Категория: Linux

Выполнение USSD запросов на модеме Huawei E1550. Подключение к модему по tty. Кодирование USSD запроса и декодирование ответа.

Установка tty клиентов

Ставим терминальные tty утилиты:

sudo apt-get install picocom
sudo apt-get install minicom

Подключение к модему

Примечание

Для использования /dev/tty* устройств без супер-юзера (sudo) выполните:

sudo apt-get remove modemmanager
sudo usermod -a -G dialout $USER

picocom

Подключаемся к устройству /dev/ttyUSB0:

sudo picocom /dev/ttyUSB0

Подключаемся к устройству /dev/ttyUSB2:

sudo picocom --echo /dev/ttyUSB2
sudo picocom --echo -b 38400 /dev/ttyUSB2

Аргумент --echo включает вывод набираемых команд в терминал.

Документация: https://github.com/npat-efault/picocom

minicom

Настройка соединения:

sudo minicom -s

1. Переходим в "Настройка последовательного порта", далее "А - Последовательный порт" и указываем /dev/ttyUSB0 или /dev/ttyUSB2. Enter.

2. Выбираем "Сохранить настройки как dfl".

3. Выход. И мы подключимся к модему с выбранными настройками.

bash

Можно отправить запрос в tty без дополнительных утилит:

echo AT+CUSD=1,AA182C3602,15 | sudo tee /dev/ttyUSB2
cat /dev/ttyUSB2 & echo "AT+CUSD=1,AA582C3602,15" > /dev/ttyUSB2 ; sleep 10; kill %cat

Отладка соединения

Проверим, что терминал распознает команды и отвечает:

AT
ATI

Если вы не видите подобного вывода в терминал - значит что-то не так или устройство отвечает по другому каналу!

OK

Manufacturer: huawei
Model: E1550
Revision: 11.608.14.11.222
IMEI: 359124036507742
+GCAP: +CGSM,+DS,+ES

Управление соединением

Отключиться от терминала picocom (minicom): Ctrl+ACtrl+X.

Если вы не видите output выполняемых AT команд и USSD запросов - проверьте, не перенаправляется ли вывод на другое ttyUSB* устройство. 

Для получения вывода с /dev/ttyUSB2 выполните в соседней консоли:

sudo cat /dev/ttyUSB2

AT команды

Команда установки режима "только модем":

AT^U2DIAG=0

Проверить разлочен ли модем:

AT^CARDLOCK?
^CARDLOCK: 2,10,0
* 1 цифра:  2 - SIM Lock снят или его нет, 1 - означает что модем залочен
* 2 цифра:  оставшиеся попытки разблокировки (по умолчанию 10)

USSD запросы

Примечание

На модеме Huawei E1550 ответ на USSD запросы приходит только в /dev/ttyUSB2! Даже отправляя USSD запросы в /dev/ttyUSB0 все равно слушайте 2 порт.

Кодировка USSD запросов.

Для модема Huawei E1550 код USSD запроса необходимо кодировать в GSM 7bit (как я понял из-за того, что модем не поддерживает текстовый режим). Следующие запросы вернут ERROR:

AT+CUSD=1,"*111#","15"
AT+CUSD=1,"*121#",15

Пример python функции для кодирования USSD запроса в GSM 7bit:

def gsm7bitencode(src):
	"""
	Encode ASCII text to 7-bit encoding
	"""
	result, count, last = [], 0, 0
	for c in src:
		this = ord(c) << (8 - count)
		if count:
			result.append('%02X' % ((last >> 8) | (this & 0xFF)))
		count = (count + 1) % 8
		last = this
	result.append('%02x' % (last >> 8))
	return ''.join(result)

Онлайн сервис для работы с кодировками: http://smstools3.kekekasvi.com/topic.php?id=288

USSD запрос проверки баланса *101# (кодировка 7bit gsm):

AT+CUSD=1,"AA182C3602",15

Еще раз напомню - ответ приходит на устройство /dev/ttyUSB2!

+CUSD: 0,"C2303BEC9E83662E98ED2C77B340E2B7BB3E07C15C30D859EE7629542A9502442CD3C3ECB40EA48AC9622317E8299687E9697A196477A7DB6177BACC02B9DFEDB21C4466E7C320B8FC6D2FCBD7699038CC0EBBE761103B6D2E8FCB6C3648158BC5460A05",15

USSD запрос проверки баланса *101# (кодировка 7bit gsm):

AT+CUSD=1,"AA582C3602",15    # *111#
AT+CUSD=1,"AA182C3602",15    # *121#

Ответ:

+CUSD: 0,"C2303BEC9E83662E98ED2C77B340E2B7BB3E07C15C30D859EE762914",15

Для декодирования ответа из 7bit gsm в UTF-8 используйте python функцию:

def gsm7bitdecode(f):
   f = ''.join(["{0:08b}".format(int(f[i:i+2], 16)) for i in range(0, len(f), 2)][::-1])
   return ''.join([chr(int(f[::-1][i:i+7][::-1], 2)) for i in range(0, len(f), 7)])

Python скрипт

Python скрипт для отправки USSD запросов с модема Huawei E1550:

#!/usr/bin/python
#coding: utf8

import base64, io, tty, sys

ussd = sys.argv[1]

def write2p(a):
	#p.write(bytes(a + '\r\n', 'utf8'))
	p.write(a + '\r\n')

def gsm7bitencode(src):
	"""
	Encode ASCII text to 7-bit encoding
	"""
	result, count, last = [], 0, 0
	for c in src:
		this = ord(c) << (8 - count)
		if count:
			result.append('%02X' % ((last >> 8) | (this & 0xFF)))
		count = (count + 1) % 8
		last = this
	result.append('%02x' % (last >> 8))
	return ''.join(result)

def gsm7bitdecode(f):
   f = ''.join(["{0:08b}".format(int(f[i:i+2], 16)) for i in range(0, len(f), 2)][::-1])
   return ''.join([chr(int(f[::-1][i:i+7][::-1], 2)) for i in range(0, len(f), 7)])

p = io.open('/dev/ttyUSB2', 'w+b', 0)
tty.setraw(p)
write2p('AT+CUSD=1,' + gsm7bitencode(ussd) + ',15')

#print('Waiting answer...')
for l in p:
	#print(l)
	if l.startswith('+CUSD'):
		ussd_response = l[10:l.rfind('"')]
		#print(ussd_response)
		response_decoded = gsm7bitdecode(ussd_response)
		print(response_decoded)
		break

p.close()

Пример использования для проверки лимита пакетных СМС на лайфе (lifecell):

ussd_huawei_e1550.py *121#
122 SMS po Ukraine. 3G: 1024 MB Nomer do 01.05.18.

Успехов!

#picocom, #tty, #ussd, #at, #huawei e1550, #7bit gsm, #charset

категория: Linux