- How to send AT commands to a modem in Linux?
- Additional information
- 12.3. Configure modem with AT commands
- 12.3.1. Configure port speed
- 12.3.2. Configure answer mode
- 12.3.3. Configure CTS / RTS handshaking
- 12.3.4. Configure Data Carrier Detect
- 12.3.5. Configure Data Terminal Ready
- 12.3.6. Configure no CONNECT messages
- 12.3.7. Configure no echo of commands
- 12.3.8. Optionally, configure silent connection
- 12.3.9. Optionally, configure DTR delay
- 12.3.10. Configure no attention sequence
- 12.3.11. Configuration example
- 12.3.12. Resetting the modem
- Minicom - подключение к USB модему Huawei E1550 по /dev/ttyUSB*
- Установка minicom
- Подключение к модему
- minicom
- picocom
- Конфигурация
- Выполнение AT команд и USSD запросов
- Выполнение AT/USSD команд к /dev/ttyUSB* модему из консоли Linux
- Теория
- Выполнение AT/USSD команд
- bash
- minicom
- ussd.py
- Кодировка GSM 7bit в USSD запросах
- Кодирование в gsm7bit
- Декодирование из gsm7bit
How to send AT commands to a modem in Linux?
it seems to work. I type an AT and get an OK . I type some crap, I get an ERROR . It seems that modem1 for minicom is somehow configured to use the modem at /dev/ttyACM0 . How can I use socat to send AT commands? Do I need to configure something? Maybe I can use configurations for modem1 of minicom (I do not know how to find/see this configuration)?
Additional information
Is the given socat command correct? Should I play with some options? With the -v option I see the following:
AT > 2013/10/23 17:10:28.917413 length=3 from=0 to=2 AT < 2013/10/23 17:10:28.921598 length=3 from=0 to=2 AT AT ksjdhfjdgfhjkdfh >2013/10/23 17:10:30.244923 length=17 from=3 to=19 ksjdhfjdgfhjkdfh < 2013/10/23 17:10:30.251383 length=29 from=3 to=31 ksjdhfjdgfhjk\b \bd\b \bf\b \bh\b \b ksjdhfjdgfhj
[5983726.808063] usb 2-1: USB disconnect, device number 3 [5983730.800021] usb 2-1: new full-speed USB device number 4 using uhci_hcd [5983730.920014] usb 2-1: device descriptor read/64, error -71 [5983733.629524] usb 2-1: New USB device found, idVendor=0572, idProduct=1329 [5983733.629533] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [5983733.629539] usb 2-1: Product: USB Modem [5983733.629544] usb 2-1: Manufacturer: Conexant [5983733.629549] usb 2-1: SerialNumber: 24680246 [5983733.632673] cdc_acm 2-1:1.0: ttyACM0: USB ACM device
speed 57600 baud; line = 0; eof = ^A; min = 1; time = 0; -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -echo -echoe
12.3. Configure modem with AT commands
Most modems today are smart modems based upon the Hayes modems and their command sets. But as discussed above, the Linux serial console is designed to operate with a dumb modem.
Thus the smart modem is dumbed-down until it resembles a dumb modem. Some expensive modems will have a DIP switch or board jumper to put them into dumb mode.
It is essential to have a manual for the modem which describes that modem's AT commands. Although most modems agree on the more popular AT commands, they differ in the more technical commands.
12.3.1. Configure port speed
Hayes AT -style modems can maintain a static speed between the computer and the modem, no matter what speed the dialing modem uses.
For most modems this is set automatically based upon the speed of the first characters sent after power-on.
Power cycle the modem and connect to it with the command minicom -o console . Press Enter a few times. The modem should now be running at the same bit rate used by Minicom , which we set to the speed of the serial console in Section 12.1 .
You can check the port speed by asking the modem to generate some output.
Figure 12-2. Testing the modem's port speed
bash# minicom -o console Welcome to minicom Press CTRL-A Z for help on special keys Enter Enter Enter ATI Enter 56k V.90 Series 3 External V2.20 Ctrl - A Q Leave without reset? Yes
Some modems have an AT command to re-establish the port speed, look in your modem's manual for the AT&B1 command. Some modems have a command to explicitly set the port speed, look in you modem's manual for the ATB command.
12.3.2. Configure answer mode
The modem will answer an incoming call on the second ring using the command ATS0=2 .
Don't answer the phone on the first ring as this may invalidate the certification of the modem in some telephony jurisdictions.
12.3.3. Configure CTS / RTS handshaking
CTS / RTS handshaking prevents lost characters.
12.3.4. Configure Data Carrier Detect
Data Carrier Detect should follow the presence or absence of a calling modem.
12.3.5. Configure Data Terminal Ready
Data Terminal Ready should control the modem. If DTR is high the modem is ready to receive calls. If DTR is low the modem should not receive any more calls and should hang up any existing call.
12.3.6. Configure no CONNECT messages
A Hayes AT -style modem usually outputs a message when a call is received. For example:
The modem has a "quiet mode" that disables these messages.
The AT command is ATQ1 . There will be no OK printed in response to this command.
12.3.7. Configure no echo of commands
Echoing commands can confuse the console, so turn off command echoing.
12.3.8. Optionally, configure silent connection
Most modems have a speaker. By default this is connected whilst a modem is connecting and negotiating a common protocol and speed. This is very useful for a dialing modem, as it prevents a human being accidentally repeatedly called. The speaker can be annoying on answering modems.
If a quieter computer room is desirable, use the ATM0 command to turn off the speaker.
12.3.9. Optionally, configure DTR delay
Data Terminal Ready drops when the semiconductor that supports the RS-232 link is reset. This then hangs up the modem. This can be annoying. If the getty supports a parameter similar to mgetty 's toggle-dtr-waittime then it is possible to extend the time that the modem will ignore DTR . The time that getty holds DTR low to force a hang up is extended beyond the modem's setting. The result is that resetting the semiconductor does not hang up the modem, but getty can still hang up the modem at the end of a login session.
Check your modem's documentation. Our example modem uses S-register 25 to contain the threshold for noticing a change in DTR . The value is in one-hundreds of a second. By setting the modem with ATS25=150 (1.5 seconds) and setting mgetty with toggle-dtr-waittime 2000 (2 seconds) we ignore small blips in DTR .
12.3.10. Configure no attention sequence
Once the modem is correctly configured and works well, disable the +++ sequence that gives access to the modem's command mode.
The AT command is ATS2=255 .
If this command is accidentally given see Section 12.3.12 to reset the modem to its factory default parameters and start again.
12.3.11. Configuration example
Figure 12-3. Configure modem using AT commands
bash# minicom -o console Welcome to minicom Press CTRL-A Z for help on special keys AT &F Enter OK AT Z Enter OK AT &C1 &D2 &K3 S0=2 M0 Enter OK AT E0 Q1 S2=255 &W Enter Alt - A Q Leave without reset? Yes
12.3.12. Resetting the modem
If you need to issue more AT commands to the modem then power cycle the modem. This should place the modem into command mode.
Now issue the following commands to restore the modem's factory configuration.
Figure 12-4. Resetting a Hayes AT -style modem
bash# minicom -o console Welcome to minicom Press CTRL-A Z for help on special keys AT &F &Y0 &W &W1 Enter OK AT Z Enter OK Alt - A Q Leave without reset? Yes
If this fails then you will need to clear the modem's configuration memory. The procedure for this varies by manufacturer, and probably requires the disassembly of the modem.
Minicom - подключение к USB модему Huawei E1550 по /dev/ttyUSB*
Для коммуникации с USB 3G модемом есть несколько консольных и графических утилит:
- minicom - мне приглянулась больше остальных
- picocom
- cutecom (графическая программа для работы с терминалами).
Установка minicom
sudo apt install minicom -y
Примечание
Рекомендуют также устанавливать следующие пакеты:
sudo apt install libusb++-0.1-4v5 libusb++-dev
Подключение к модему
Примечание
Обычно USB модемы предоставляют 3 ttyUSB* интерфейса:
- /dev/ttyUSB0 - интернет/данные
- /dev/ttyUSB1
- /dev/ttyUSB2 - командный интерфейс/устройство
На модеме Huawei E1550 ответ на USSD запросы всегда приходит на интерфейс /dev/ttyUSB2! Даже отправляя USSD запросы в /dev/ttyUSB0 все равно слушайте 2 порт.
minicom
sudo minicom -D /dev/ttyUSB2 -b 9600
Подключение в режиме настройки:
sudo minicom -D /dev/ttyUSB2 -s
- Переходим в "Настройка последовательного порта", далее "А - Последовательный порт" и указываем /dev/ttyUSB0 или /dev/ttyUSB2.. Enter.
- Выбираем "Сохранить настройки как dfl".
- Выход.
И мы подключимся к модему с выбранными настройками.
Примечание
Для выхода из терминала minicom (отключения от устройства) используются комбинации клавиш Ctrl + A - X (без сохранения) или Ctrl + A - Q (с сохранением).
Выполнение набора команд и вывод в файл:
sudo minicom -D /dev/ttyUSB2 --capturefile=/path/minicom.log --script=/path/minicom-script.txt
Содержимое файла minicom-script.txt (не знаю как завершить процесс после выполнения AT команды):
picocom
Подключаемся к устройству /dev/ttyUSB2:
Подключаемся к устройству /dev/ttyUSB2 с отображением команд в терминал:
sudo picocom --echo -b 38400 /dev/ttyUSB2
Конфигурация
Использование /dev/tty* без sudo
Для использования /dev/tty* устройств без прав супер-юзера (sudo) необходимо добавить пользователя в группу dialout:
sudo apt remove modemmanager sudo usermod -a -G dialout $USER
Внимание!
Если не отображается результат выполняемых AT команд и USSD запросов - проверьте, не перенаправляется ли вывод на другое ttyUSB* устройство или в файл. Попробуйте сменить устройство с ttyUSB0 на ttyUSB2.
Выполнение AT команд и USSD запросов
Показать информацию о модеме:
Manufacturer: huawei Model: E1550 Revision: 11.608.13.02.00 IMEI: 353443043787139 +GCAP: +CGSM,+FCLASS,+DS
AT команды для получения оператора связи (carrier):
Выполнение USSD запроса для просмотра баланса:
#tty, #terminal, #minicom, #modem, #at, #ussd, #serial
Выполнение AT/USSD команд к /dev/ttyUSB* модему из консоли Linux
Утилиты и скрипты для коммуникации с /dev/ttyUSB* устройством из shell консоли (bash скриптов).
Теория
Отправить в /dev/ttyUSB* терминал AT команду не составляет проблем. Но результат вывода мы не увидим!
echo ATI > /dev/ttyUSB2 # или echo ATI | sudo tee /dev/ttyUSB2
Мы можем читать поток stdout c /dev/ttyUSB2 (результат выполнения команд):
- Нужно получить только результат выполнения конкретной AT команды, а не весь поток вывода.
- Нужно использовать gsm7bit кодировку для кодирования параметров и получения ответа при выполнении USSD запросов:
echo AT+CUSD=1,AA182C3602,15 | sudo tee /dev/ttyUSB2
Выполнение AT/USSD команд
bash
Скрипт at.sh для отправки AT команды и получения ответа в переменную:
at.sh "AT+COPS=3,0\nAT+COPS?" /dev/ttyUSB2
#!/bin/bash AT="$1" TTY="$2" SLEEP=0 RESULT=$(cat $TTY & echo -e "$AT" > $TTY; sleep $SLEEP; kill %cat) echo $RESULT
Но вы получите ответ вида:
AT+COPS? +COPS: 0,0,"lifecell",2 OK ^BOOT:36507742,0,0,0,87 ^RSSI:3 ^RSSI:3 ^RSSI:3
minicom
Можно отправить AT команду и перенаправить весь вывод в файл:
sudo minicom -D /dev/ttyUSB2 -S ./at/carrier-name.txt -C output.txt
После этого нужно закрыть терминал и разобрать/декодировать весь вывод из файла output.txt. Не круто..
ussd.py
В сети нашел python скрипт для отправки USSD запросов (немного поправил):
122 SMS po Ukraine. 3G: 1024 MB Nomer do 01.05.18.
#!/usr/bin/python #coding: utf8 import base64, io, tty, sys import time ussd = sys.argv[1] modem = '/dev/ttyUSB5' if len(sys.argv) > 2: modem = sys.argv[2] else: modem = '/dev/ttyUSB2' def write2p(a): #sp.write(bytes(a + '\r\n', 'utf8')) sp.write(a + '\r\n') def gsm7bitencode(src): """ Encode ASCII text to 7-bit encoding """ result, count, last = [], 0, 0 for c in src: this = ord(c) > 8) | (this & 0xFF))) count = (count + 1) % 8 last = this result.append('%02x' % (last >> 8)) return ''.join(result) def gsm7bitdecode(f): f = ''.join(["".format(int(f[i:i+2], 16)) for i in range(0, len(f), 2)][::-1]) return ''.join([chr(int(f[::-1][i:i+7][::-1], 2)) for i in range(0, len(f), 7)]) ### sp = io.open(modem, 'w+b', 0) tty.setraw(sp) write2p('AT+CUSD=1,' + gsm7bitencode(ussd) + ',15') ### start = time.time() while (time.time() - start < 10): l = sp.readline() #print(l) if l.startswith('+CUSD'): ussd_response = l[10:l.rfind('"')] response_decoded = gsm7bitdecode(ussd_response) print(response_decoded) break # @note Реализация без таймаута # @todo Нужен таймаут для прерывания ридера потока, если ничего #for l in sp: ##print(l) #if l.startswith('+CUSD'): #ussd_response = l[10:l.rfind('"')] ##print(ussd_response) #response_decoded = gsm7bitdecode(ussd_response) #print(response_decoded) #break sp.close()
Кодировка GSM 7bit в USSD запросах
Кодирование в gsm7bit
При отправке USSD запросов нужно кодировать USSD-код в кодировку GSM 7bit (как я понял из-за того, что модем не поддерживает текстовый режим).
Следующие запросы вернут ERROR:
AT+CUSD=1,"*111#","15" AT+CUSD=1,"*121#",15
Python функция gsm7bitencode для кодирования utf8 строки в gsm7bit:
def gsm7bitencode(src): """ Encode ASCII text to 7-bit encoding """ result, count, last = [], 0, 0 for c in src: this = ord(c) > 8) | (this & 0xFF))) count = (count + 1) % 8 last = this result.append('%02x' % (last >> 8)) return ''.join(result)
Примечание
Смотрите онлайн-сервис для работы с кодировками: http://smstools3.kekekasvi.com/topic.php?id=288
Пример USSD команд в кодировке 7bit gsm проверки баланса:
AT+CUSD=1,"AA582C3602",15 # *111# AT+CUSD=1,"AA182C3602",15 # *121#
Кодированные ответы (ответ всегда приходит на устройство /dev/ttyUSB2):
+CUSD: 0,"C2303BEC9E83662E98ED2C77B340E2B7BB3E07C15C30D859EE762914",15 +CUSD: 0,"C2303BEC9E83662E98ED2C77B340E2B7BB3E07C15C30D859EE7629542A9502442CD3C3ECB40EA48AC9622317E8299687E9697A196477A7DB6177BACC02B9DFEDB21C4466E7C320B8FC6D2FCBD7699038CC0EBBE761103B6D2E8FCB6C3648158BC5460A05",15
Декодирование из gsm7bit
Python функция gsm7bitdecode для декодирования gsm7bit в utf8:
def gsm7bitdecode(f): f = ''.join(["".format(int(f[i:i+2], 16)) for i in range(0, len(f), 2)][::-1]) return ''.join([chr(int(f[::-1][i:i+7][::-1], 2)) for i in range(0, len(f), 7)])