Приобрёл на днях 3g модем Huawei E352 от Мегафон. Разумеется, сразу же сильно захотелось как-то узнавать состояние счёта и, возможно, не только его. Гугление привело меня к нескольким скриптам на Perl (
http://betment-6.livejournal.com/6002.html), PHP (посеял ссылку, в недрах ЖЖ где-то), Python (
Форум - General - вменяемый скрипт или программа для USSD Выполнение USSD запросов под Linux / Телекомы / Хабрахабр)
PHP-скрипт не заработал, не заработали и Python'овые скрипты, кроме того, мне не очень понравился стиль, в котором они были написаны и я решил сделать свой вариант:
code python
#!/usr/bin/env python3
import io, tty, base64, sys
def main():
fd=None
try:
fn=str(sys.argv[1])
ussd=str(sys.argv[2])
fd=io.open(fn, 'w+b', buffering=0)
if fd.isatty():
print("Opened tty device")
tty.setraw(fd)
requssd(fd, 'AT+CUSD=1,' + to7bit(ussd) + ',15')
ans=getanswer(fd)
if ans is not None:
print(base64.b16decode(ans.encode()).decode("utf-16-be"))
else:
print("It is non-tty device")
except IOError as err:
print(err)
except IndexError:
print("Usage: ussd.py /path/to/tty/modem *ussd*request#")
finally:
if fd is not None:
fd.close()
# gets answer st as a String from file descriptor fd
def getanswer(fd):
print("Waiting answer... You can break it with ^C")
while True:
try:
st=fd.readline().decode("latin1")
if st.startswith('+CUSD'):
return st[st.index('"')+1:st.rfind('"')]
except KeyboardInterrupt:
break
# sends request req in file descriptor fd
def requssd(fd, req):
try:
print("Send request")
# Uncomment when you starts this script
# in Python3 enviroment
fd.write(bytes(req + '\r\n', 'utf-8'))
# in Python2 enviroment
#fd.write(req + '\r\n')
except IOError as err:
print(err)
except TypeError:
fd.close()
exit("Python version problems: look at requssd function.")
# encoding function
def to7bit(src):
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)
main()
По сути, моя программа является переработанной и причёсанной версией той, что на LOR, но она, вдобавок, ещё и работает.
Может принимать любые верные для данного оператора USSD-запросы и отправлять их на указанный порт.