1) АТ команду нужно посылать в закодированном виде
2) Ответ модем также присылает в закодированном виде
АТ команда имеет общий вид AT+CUSD=1,*102#,15 . Вот в ней USSD-запрос *102# и надо кодировать в вид понятный модему.
Примерно так:
perl -e '@a=split(//,unpack("b*","*102#")); for ($i=7; $i < $#a; $i+=8) { $a[$i]="" } print uc(unpack("H*", pack("b*", join("", @a))))."\n"' AA184C3602
Ответ от модема приходит примерно такой:
AT+CUSD=1,AA184C3602,15 OK +CUSD: 0,"04110430043B0430043D04410020003500370039002E003600300440002E00200422044004300 4440438043A002000300020041A0431002E0414043504420430043B0438003A002000680074007400700073 003A002F002F00750073006C007500670069002E006200650065006C0069006E0065002E00720075",72
Декодировать его можно так:
echo "04110430043B0430043D04410020003500370039002E003600300440002E0 02004220440043004440438043A002000300020041A0431002E0414043504420430043B0438003A0020 00680074007400700073003A002F002F00750073006C007500670069002E006200650065006C0069006 E0065002E00720075" \ | perl -ne '@a = m/([0-9A-F]{4})/g; map { eval "print \"\\x{$_}\""; } @a;' 2>/dev/null Баланс 579.60р. Трафик 0 Кб.Детали: https://uslugi.beeline.ru
Поскольку с перлом у меня туго, а тут попался скрипт на питоне, я слегка адаптировал его под себя:
#!/usr/bin/env python # -*- coding: utf-8 -*- # # This script send 'get balance' request to the Beeline # from Huawei E219/E220 USB-GPRS modem. # # IDima (c) 2008 # import serial import string import os # # Decode string from Beeline to current charset # def str2byte(a): b='' for i in range(len(a)/4): b+=chr(eval('0x'+a[i*4+2:i*4+4]))+chr(eval('0x'+a[i*4:i*4+2])) return unicode(b, 'utf16') # # Definitions # USBPORT='/dev/ttyUSB2' USBSPEED=460800 MAXSTRINGLENGTH=300 #print "Wait a USSD request ... " s=serial.Serial(USBPORT,USBSPEED,timeout=5) s.write('ATZ \015') s.write('AT+CUSD=1,AA184C3602,15 \015') line='' while line[0:6] != '+CUSD:': line=s.readline(MAXSTRINGLENGTH) s.close() line2=line.split(',')[1] line3=string.replace(line2,'"','') line4=str2byte(line3) result=line4.encode('utf8') #result=line3 # вывод в консоль print result # вывод в нотификатор os.system('echo "message:' + result + '" | /usr/bin/zenity --notification --listen --timeout 5') #os.system('notify-send -i info -t 5000 "Запрос баланса" "' + result +'"')
У меня запрос и ответ пересылаются через /dev/ttyUSB2, в некоторых случаях порты ввода и вывода как я понял могут отличаться. Вызов скрипта повесил на горячую клавишу, поскольку стоит unity нотификатором служит zenity, в случае другого DE возможно нужно будет поменять последнюю строчку.
Update:
Для сравнения написал почти тоже самое на tcl:
#! /usr/bin/tclsh # порт set port /dev/ttyUSB2 # запрос баланса set req AT+CUSD=1,AA184C3602,15 # вывод в нотификатор #proc mess m { # puts $m #} proc mess m { exec notify-send -i info -t 5000 "Запрос баланса" $m } if {![file exists $port]} { mess "Модем не подключен?" exit 1 } if [catch {set f [open $port w+]}] { mess "Нет прав на открытие $port" exit 1 } fconfigure $f -mode 19200,n,8,1 -blocking 0 -buffering none # сброс модема puts $f ATZ after 100 puts $f $req set a "" set timeout 300 # читаем из порта до ответа while {![regexp {\+CUSD\:} $a]} { after 100 set a [read $f] incr timeout -1 if {!$timeout} { mess "Нет ответа от модема" exit 1 } } close $f # вырезаем ответ regexp {"([[:xdigit:]]*)"} $a => a set c 0 ; set str "" # декодируем ответ while {$c < [string length $a]} { set str $str[format "%c" "0x[string range $a $c [expr $c+3]]"] incr c 4 } mess $str
UPDATE:Для модема ZTE MF100 строчки конфигурации выглядят так:
# порт set port /dev/ttyUSB1 # запрос баланса set req AT+CUSD=1,#102#,15
Сюда же вставлю:
AT-команды ZTE: disable/enable flashdrive AT+ZCDRUN=8 enable AT+ZCDRUN=9 disable (включает AutoRUN для CD-ROM модема). AT+ZCDRUN=E удалить NODOWNLOAD.FLG AT+ZCDRUN=F восстановить NODOWNLOAD.FLG Set Operational Mode AT+ZSNT=0,0,0 (Auto) - Default AT+ZSNT=1,0,0 только GPRS AT+ZSNT=2,0,0 только 3G AT+ZSNT=0,0,1 предпочтение GPRS AT+ZSNT=0,0,2 предпочтение 3G stay online AT+ZOPRT=5 check net-/SIMlock AT+ZSEC? answer: <SEC_STATUE>,<SEC_ITEMS> < SEC_STATUE >: 0 Initializing the encryption (Insignificant SEC_ITEMS) 1 Network Lock error. (Insignificant SEC_ITEMS) 2 Network Locked 3 Unlocked or correct MCC/MNC <SEC_ITEMS>: 0 No action 1 Network lock 2 (U)SIM card lock 3 Network Lock and (U)SIM card Lock Unlock +ZNCK="unlock-code" +ZNCK? Unlock residual time 0-5 Set Band Status +ZBANDI at+zbandi=0 • Automatic (Auto) - Default at+zbandi=1 • UMTS 850 + GSM 900/1800 at+zbandi=2 • UMTS 2100 + GSM 900/1800 (Europe) at+zbandi=3 • UMTS 850/2100 + GSM 900/1800 at+zbandi=4 • UMTS 850/1900 + GSM 850/1900 Notice! the command is used only in platform 6290 and 6246. Подробнее: http://give-all.ru/faq/show/7/1/at-komandy-zte/