Выполнение 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
    • 0
      Слабо через хайлайтер код прогнать?
      • +2
        подскажите хайлайтер который знает питон и при этом дружит с хабром — прогоню.
    • +1
      Жду что-то подобное для CDMA/Интертелеком (Украина)
      • 0
        так а разницы никакой нет, просто подставте ussd номера интертелекома в скрипт и он будет работать если модем поддерживает.
        • 0
          Только что гуглил по поводу AT-команд, для CDMA модемов… Многие не поддерживают.

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

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

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.