1 (28.01.2011 23:02:57 отредактировано Otten)

Приветствую форумчан. Снова погуглил на предмет возможности проверки баланса USB-модема под линуксом, и раньше и сейчас попалось несколько вариантов и для разных модемов/операторов, но то ли модем у меня такой, то ли руки, в общем ничего не выходило, и я решил составлять его сам. Немножко разобрался, рассматривая те скрипты. Остановился на таком моменте. Не знаю как передать команде содержимое текстового файла на обработку. Добился от миникома, чтобы он, опросив модем, длинный ответ вида "041C043E04310438043B044C043D044B04390020043F043B043004420......" положил в файл. Ответ в таком виде, потому что он закодирован, и это неудобно. Текст файла надо передать дальше на раскодировку, знаю что можно как-то, но какой командой вытащить его из файла? В скриптах я только начинаю разбираться, и нужна ваша помощь ))

Вот скрипт:

#!/bin/bash
#
#
SCR=/home/otten/balans/balans
LINE=/home/otten/balans/line
(
echo 'send "ATZ"'>$SCR
echo 'send ""' >>$SCR
echo "send \"AT+CUSD=1,*102#,15\"">>$SCR
echo 'expect {'>>$SCR
echo '"\"," ! killall -9 minicom'>>/$SCR
echo '   }'>>$SCR
echo '! killall -9 minicom'>>$SCR
minicom -w -S $SCR -C $LINE >/dev/null 2>&1
) >/dev/null 2>&1
reset

echo 'ТЕКСТ ФАЙЛА' | perl -ne '@a = m/([0-9A-F]{4})/g; map { eval "print \"\\x{$_}\""; } @a;' 2>/dev/null

unlink $SCR
unlink $LINE

Когда сработает скрипт, в терминале должно остаться примерно следующее:   Баланс 115.00р. Трафик 37800 Кб.
В этом и весь смысл, что хочется получить от модема USSD-ответ и раскодировать его одной командой-скриптом.

2

Покурил маны и понял, что все гораздо проще. Использовать надо совсем другую команду. Не  echo,  a  cat.
И тогда готовый скрипт выглядит таким образом:

#!/bin/bash
#
#
SCR=/home/otten/balans/balans
LINE=/home/otten/balans/line
(
echo 'send "ATZ"'>$SCR
echo 'send ""' >>$SCR
echo "send \"AT+CUSD=1,*102#,15\"">>$SCR
echo 'expect {'>>$SCR
echo '"\"," ! killall -9 minicom'>>/$SCR
echo '   }'>>$SCR
echo '! killall -9 minicom'>>$SCR
minicom -w -S $SCR -C $LINE >/dev/null 2>&1
) >/dev/null 2>&1
reset

cat /home/otten/balans/line | perl -ne '@a = m/([0-9A-F]{4})/g; map { eval "print \"\\x{$_}\""; } @a;' 2>/dev/null

unlink $SCR
unlink $LINE

Удалять пост не буду, может кому пригодится.
Скрипт делался для билайна и модема Связной, он же Alcatel x080s (определяется у меня как 1bbb:0000 T & A Mobile Phones).
Всем удачи!

3

А как этим пользоваться?

4

Otten пишет:

но какой командой вытащить его из файла?

sed

Otten пишет:

Удалять пост не буду, может кому пригодится.
Скрипт делался для билайна и модема Связной, он же Alcatel x080s (определяется у меня как 1bbb:0000 T & A Mobile Phones).
Всем удачи!

Otten пишет:

perl -ne '@a = m/([0-9A-F]{4})/g; map { eval "print \"\\x{$_}\""; } @a;' 2>/dev/null

ну можно и перловку.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

5

Dykus пишет:

А как этим пользоваться?

копируешь в файл через свой любимы текстовый редактор(gedit, kate, nano, vim)
делаешь исполняемым
вызываешь в консоли
/полный/путь/имя/файла

6

Это подошло для моего модема и оператора. Нет гарантий, что будет работать на других, и я отметил, что этот скрипт составной с разных примеров (часть примеров попадалась на форуме Ubuntu, часть в других форумах). Есть нюансы в виде того, что запрос *100# можно еще отправить как AA180C3602, у кого-то срабатывало именно так. Нужно перед составлением пробивать и проверять команды в миникоме, предварительно определив в настройках отзывающееся устройство (модем определяется как три устройства, а именно ttyUSB0, ttyUSB1, ttyUSB2). У меня USSD-запросы миникома в скрипте идут только на /dev/ttyUSB1, а wvdial звонит для инета на ttyUSB2, проверялось опытным путем. К тому же встречались случаи, когда ответ приходил не закодированным, а вполне нормальным. На форуме Ubuntu еще выложен пример вот такой, цитирую:

Можно так:

 Консоль:
sudo apt-get install gsm-ussd

 Консоль:
alexei@Aspire ~ $ gsm-ussd -m /dev/ttyUSB2 *100#
Баланс:5,3р

 Консоль:
alexei@Aspire ~ $ gsm-ussd -m /dev/ttyUSB2 *100*1#
Остаток: 183,9Мб.

7 (01.02.2011 12:37:20 отредактировано Otten)

Проверил у себя пакет gsm-ussd, работает отлично. Вывод такой же как у скрипта.
UPD: кстати поддерживает работу в режиме сессии. Например передвижение по меню внутри сессии. Дальше не тестил.

otten@debian:~$ gsm-ussd *111#
USSD session open, to cancel use "gsm-ussd -c".
1 Услуги при 0
2 Мой Билайн
3 Музыка
4 Игры
5 Знакомства
6 Обои+Видео
7 Погода+
otten@debian:~$ gsm-ussd 2
USSD session open, to cancel use "gsm-ussd -c".
1 Мои данные
2 Услуги
3 Скидки и акции
4 Тел. настройки
5 Роуминг
6 <<
otten@debian:~$ gsm-ussd 1
USSD session open, to cancel use "gsm-ussd -c".
1 Мой т/план
2 Мой номер
3 Мои услуги
4 Постоплата
5 Получить web-пароль
6 <<
otten@debian:~$ gsm-ussd -c
USSD cancel request successful
otten@debian:~$

8

А где для Debian найти пакет gsm-ussd?

9

Otten пишет:

У меня USSD-запросы миникома в скрипте идут только на /dev/ttyUSB1, а wvdial звонит для инета на ttyUSB2, проверялось опытным путем.

проверьте ещё раз, после перезагрузки. оно в первый раз определяет как USB1, а во второй как USB2. ИМХО это всё неплохо-бы выдрать из dmesg'а sed'ом, но беда в том, что для каждой комбинации модем+дистрибутив скрипт будет свой.  ac

unk пишет:

А где для Debian найти пакет gsm-ussd?

здесь

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

10

С моим модемом такой прикол, что он определяется сперва как накопитель (как сд-диск для винды, где все его дрова виндовые), и никакое устройство, ни USB1 ни USB2 не принимают команды. Для таких случаев, чтобы отрубить накопитель и задействовать модем, есть специальный пакет usb-modeswitch. Но обычно у пользователей все дозванивается и без него. У меня модем не такой популярный видимо, да и юзал я его только на дебиане.

11

спасибо большое

12

А можно еще проще.

#!/bin/bash

n=1;    #Тут задаем номер порта для запроса

F="/dev/ttyUSB$n"
echo -e "AT+CUSD=1,*102#,15\r">$F
head -n 4 $F | \
perl -ne '@a = m/([0-9A-F]{4})/g; map { eval "print \"\\x{$_}\""; } @a;' 2>/dev/null
echo ""

13

А дабы не лазить в консоль, не пускать команды... Кстати есть у gsm-ussd есть некий графический интерфейс, который у меня, правда не работает, вешает ttyUSB1, пока руками не уберешь его из /var/lock, и сам вешается, мол, идет подключение... Так вот, взял я да прописал в коньках строчку вот такую вот:

${execi 60 gsm-ussd *102# | sed -r 's/Трафик/\n&/;s/.*Баланс([^\n]*)\n.*/\1/'}

Исключив из вывода все лишнее, и оставив только то, что между словами Баланс и Трафик, строчка эта пишет мне сама, с обновлением раз в минуту например такое "115.00р."  Единственное, что в дебрях sed'а разбирался очень долго, и то мало, что понял.

14

Otten пишет:

Единственное, что в дебрях sed'а разбирался очень долго, и то мало, что понял.

мою книжку читали?

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

15

Взял на заметку, спасибо. Читать же ж лень как всегда, хочется чтоб сразу и само  ag

16 (04.02.2011 20:32:47 отредактировано drBatty)

Otten пишет:

Читать же ж лень как всегда, хочется чтоб сразу и само

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

Otten пишет:

Исключив из вывода все лишнее, и оставив только то, что между словами Баланс и Трафик,

ну всё правильно, но в данном случае можно было проще:
1) убираем всё, что перед "баланс" s/.*Баланс//
2) убираем всё, что после "Трафик" s/Трафик.*//
А ваш приём отлично работает если в ваших строчках много "Баланс" и "Трафик" (у вас наверное только по 1 разу).
ЗЫЖ или даже
s/.*Баланс(.*)Трафик.*/\1/

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

17

Действительно, так проще.

У меня еще получилось вот так, но видимо не совсем правильно и рационально, даже не смотря на работоспособность
's/.*Баланс//;s/Трафик//;s/Детали.*//'    Выдает "115.00р.  7200 Кб".
А вот как разделить и перенести 7200 Кб уже на новую строку, чтобы было так

115.00р.
7200 Кб

18

Otten пишет:

У меня еще получилось вот так, но видимо не совсем правильно и рационально, даже не смотря на работоспособность

ну я не знаю. какая исходная строчка?

Otten пишет:

Выдает "115.00р.  7200 Кб".
А вот как разделить и перенести 7200 Кб уже на новую строку, чтобы было так

115.00р.
7200 Кб

это просто: меняёте пробелы на перевод строки, вот так:

sed -r 's/ +/\n/'

(без ключа -r плюс не работает, точнее его нужно экранировать вот так \+)

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

19

Строка такая: Баланс 115.00р. Трафик 8700 Кб.Детали: https://uslugi.beeline.ru
Точно, не догадался пробел заменить, знаю же, что \n.

20

Otten пишет:

s/Трафик//

можно вместо этого сразу вписать замену. причём я-бы вписал так:
s/\s*Трафик\s*/\n/
тут \s означает "пробельные символы", аналог [[:space:]], туда входит пробел, табуляция, возврат каретки и перевод строки.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

21

Однако, насколько гибок sed. А уж каков perl наверное...

22

Спасибо! Давно искал!

Рецепты для Вас
http://receptforyou.ru

23

Otten пишет:

А уж каков perl наверное...

о, да. PCRE мощнейшая фишка, только ей надо пользоваться очень аккуратно.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

24

спасибо за разъяснение.

25 (15.03.2011 13:56:53 отредактировано Wanilinka)

спасибо.

26

Че вы пробовали? Одно вижу- пришли троллить на форуме и сайт свой показать. ah