войти зарегистрироваться

Телекомы

индекс
164,53

Выполнение USSD запросов под Linux

Спасибо автору топика Проверка счета Киевстар модема в Linux который помог мне понять принцип работы модемов и способ работы с ними в линуксе. Мне как раз нужно было решить задачу отображения уровня сигнала, проверки баланса, пополнения счета с использованием 3ж модема. Но так как ставить на домашние машины пхп ради такой мелочи мне не хотелось, решил переписать скрипт под себя на Python, который есть в любом десктоп-линуксе из коробки.

Работать данный скрипт будет на любых модемах/телефонах которые поддерживают USSD без PDU кодирования. Для модемов требующих PDU-кодировку команд нужно написать функции-обертки аналогично php-скрипту из указаного выше топика. У меня к сожалению нету такого модема и проверить я бы не смог — потому писать не стал.

Проверена работа на 3G модеме ZTE MF100(должно работать с mf620, mf622, mf626, mf628) и тарифе Интернет 3G от Киевстара.

Сам скрипт ussd.py
#!/usr/bin/python
import binascii
import sys
f = open("/dev/ttyUSB2""r+")
data=''
error="Usage: python ussd.py action (code)\r\nActions: balans, popolnit, data-status, 3g-data-status, signal"
if len(sys.argv) < 2:
    print error
    sys.exit()
 
if sys.argv[1] == 'balans':
    print>>f, "AT+CUSD=1,*111#,15\r\n"
    while data[:5]!="+CUSD":
        data=f.readline()
    data = data[10:-6]
    print binascii.unhexlify(data)
elif sys.argv[1] == 'signal':
    print>>f, "AT+CSQ\r\n"
    while data[:5]!="+CSQ:":
        data=f.readline()
    data = data[6:-5]
    sig_str = -113+int(data)*2
    sig_per = int(data)*100 / 31
    print unicode(sig_str)+"dBm / "+unicode(sig_per)+"%"
elif sys.argv[1] == 'popolnit':
    print>>f, "AT+CUSD=1,*123*"+sys.argv[2]+"#,15\r\n"
    while data[:5]!="+CUSD":
        data=f.readline()
    data = data[10:-6]
    print binascii.unhexlify(data)
elif sys.argv[1] == 'data-status':
    print>>f, "AT+CUSD=1,*121#,15\r\n"
    while data[:5]!="+CUSD":
        data=f.readline()
    data = data[10:-6]
    print binascii.unhexlify(data)
elif sys.argv[1] == '3g-data-status':
    print>>f, "AT+CUSD=1,*122#,15\r\n"
    while data[:5]!="+CUSD":
        data=f.readline()
    data = data[10:-6]
    print binascii.unhexlify(data)
else:
    print error
f.close


Делаем скрипт исполняемым:
chmod +x ussd.py

Использование:
./ussd.py действие (код)
Доступные действия: balans, popolnit, data-status, 3g-data-status, signal
При выборе действия popolnit нужно вторым параметром передать скрипту код пополнения.
Пример:
./ussd.py popolnit 1234567890

Скрипт заточен под Киевстар, но думаю ни у кого не составит труда заменить короткие номера запросов на используемые вашим оператором.
Бывает скрипт «подвисает», насколько я понял это происходит когда он так и не дожидается нужного ответа от модема. Грешу на плохое покрытие в моем районе. Если у вас скрипт повиснет просто прервите его и запустите заново.Подвисания прекратились как только закрыл minicom.
Еще важный момент большинство 3ж-модемов под линуксом определяется как 3 устройства:/dev/ttyUSB0, /dev/ttyUSB1 ,/dev/ttyUSB2. Одно используется для передачи данных, другое похоже для какихто сервис команд модема, третье предоставляет стандартный COM интерфейс для управления. В скрипте нужно указать именно устройство COM интерфеса, в некоторых модемах это /dev/ttyUSB0, реже /dev/ttyUSB2.

В зависимости от возможностей модема и тарифа у оператора USSD запросами и AT командами, можно добится отправки смсок, переключения режимов(2G/3G), отключить виртуальный сд-ром итд. К сожалению для каждой модели прийдется подбирать команды вручную…

К сожалению я питон практически незнаю, потому скорее всего скрипт написан далеко не самым оптимальным образом, если ктото возьмется его оптимизировать(а еще лучше оформить это все в графическую оболочку) я буду благодарен и обновлю топик.

UPD Забыл рассказать еще одну вещь, на днях нашел какогото опсоса который предоставляет линукс софт к своим модемам. Модемы естественно стандартные китайские брендированые под опсоса. Вот тут например явно видно ZTE MF100/MF62X, но к сожалению я не смог заставить софтину работать с моим модемом. Может ктото поопытней сможет ее доколупать? Для ее работы нужен пакет libqt3-mt для архитектуры i386(иначе не запустится)

комментарии (19)

  • Слабо через хайлайтер код прогнать?
    • подскажите хайлайтер который знает питон и при этом дружит с хабром — прогоню.
  • Жду что-то подобное для CDMA/Интертелеком (Украина)
    • так а разницы никакой нет, просто подставте ussd номера интертелекома в скрипт и он будет работать если модем поддерживает.
      • Только что гуглил по поводу AT-команд, для CDMA модемов… Многие не поддерживают.

        Я понятия не имею какой USSD запрос надо отправлять в Интертелекоме. CDMA-трубки никогда не было.
        • попробуйте посмотреть на официальном сайте оператора в разделе помощь посмотреть USSD коды, у многих операторов они есть.
        • Саппорт оператора возможно имеет понятие. Иногда не стоит недооценивать их.
          • Искал только что у них на сайте, есть только с автоответчиком который говорит состояние счёта.
            Сегодня вечером буду писать парсер для assa.intertelecom.ua и выложу, возможно ещё кому-то надо :)
  • А вот чтобы SMS отправлять лучше не морочиться с AT-командами, а использовать что-то типа SMS Tools 3.
  • Обе статьи хороши, жаль, что опсосы не попросили у авторов разместить этот материал у себя :)
    • Ну уж извините, когда модемы запускали, то ориентировались на массовый рынок (95% — win, 4% mac, и толлько 1%-etc).
      Разместить эту информацию на офсайте это прямой путь к тому, чтобы очень большое количество абонентов звонили в колцентр и спрашивали «а о чем это написано?»
  • У меня не работает =(
    пишет
    File «ussd.py», line 2
    import binascii
    ^
    IndentationError: unexpected indent
    • Модуль binascii у вас скорее всего не стоит.
  • Поправьте 7-9 строки (надо отступы добавить, иначе на «print error» ругается):
    if len(sys.argv) < 2:
    	print error
    	sys.exit()

    • спасибо поправил. немного подвел хайлайтер кода)
  • Большое спасибо, как раз то что искал ;)
    Для модема MF626 можно добавить команды:
    AT+ZSNT=2,0,0\r\n — переключить модем в режим 3G
    AT+ZSNT=0,0,2\r\n — автоматический выбор доступной сети с приоритетом 3G
  • не очень правильно написано открытие порта:
    f = open("/dev/ttyUSB2", «r+»)
    и потом внезапный выход в случаи недостаточного кол-ва аргументов без закрытия дескриптора:
    if len(sys.argv) < 2:
    print error
    sys.exit()
    ИМХО лучше открытие порта переместить после проверки аргументов…
Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.