modem_script()

Запустить скрипт на устройстве

Прототип:

#include <sys/modem.h>
int modem_script( int fd,
struct modem_script *table,
speed_t *baud,
void (*io)( char *progress,
char *in,
char *out ),
int (*cancel)( void ) );

Аргументы:

fd
Файловый дескриптор устройства, которое необходимо cчитать; смотрите modem_open().
table
Массив структур struct modem_script который содержит сценарии команд, которые вы хотите запустить на устройстве.
baud
Указатель на переменную типа speed_t, куда функция может сохранить скорость передачи (если в сценарии указано, что необходимо это сделать).
io
Указатель на функцию-обработчик, которая вызывается процессом для каждой переданной и полученной строки.
cancel
NULL, или функция-обработчик, которая вызывается при истечении периода времени newquiet (указано в скрипте) во время ожидания ввода.

Библиотека:

libc

Описание:

Функция modem_script() запускает скрипт table на устройстве, связанном с файловым дескриптором fd. Сценарий реализует простой конечный автомат, который генерирует строки и ожидает ответы.

Каждая отправленная или полученная строка передаётся функции io() следующим образом:

Вызов Описание
(*io)( str, 0, 0 ) Отправленная строка прогресса
(*io)( 0, str, 0 ) Полученная строка
(*io)( 0, 0, str ) Отправленная строка ответа

Это позволяет программе настроить функцию, которая будет показывать работу скрипта в окне статуса.

Если была задана функция cancel, она вызывается каждые newquiet 1/10 секунд, пока ожидает ввод. Если функция возвращает ненулевое значение, чтение устройства вернёт немедленно значение -1 и установит для errno значение ETIMEDOUT. Можно использовать функцию cancel в качестве обработчика в графическом номеронабирателе, который должен поддерживать кнопку отмены для остановки сценария.

table - это массив структур struct modem_script.

Когда скрипт передаётся в modem_script(), для текущего состояния устанавливается значение 1, а в вывод записывается ATZ (первый элемент массива response).

При нахождении в любом состоянии, modem_script() ожидает ввод, при получении сопоставляет его с шаблоном текущего состояния или шаблоном состояния 0.

State 1

Ввод Действие
*ok* Переход в состояние 2 и отправка ATDT1-591-0934. Флаги, которые будут использоваться в новом состоянии, получают значение 0, значению времени ожидания в новом состоянии установлено значение 0.5 секунд, а таймаут в новом состоянии получает значение 30 секунд.
*no carrier* Переход к состоянию 0 (состояние прекращения), возврат содержимого retvalue (1).
*no answer* Переход к состоянию 0 (состояние прекращения), возврат содержимого retvalue (2).
*no dialtone* Переход к состоянию 0 (состояние прекращения), возврат содержимого retvalue (3).
*busy* Переход к состоянию 0 (состояние прекращения), возврат с содержимого retvalue (4).

State 2

Ввод Действие
*connect* Переход в состояние 3 без отправки на устройство. Флаги, используемые в данном состоянии, получают значение MODEM_LASTLINE, времени ожидания в новом состоянии установлено значение 0.5 секунд, а таймаут в новом состоянии получает значение 10 секунд. Поскольку текущие флаги равны MODEM_BAUD, скорость передачи извлекается из сообщения соединения.
*no carrier* То же самое, что в предыдущей таблице
*no answer* То же самое, что в предыдущей таблице
*no dialtone* То же самое, что в предыдущей таблице
*busy* То же самое, что в предыдущей таблице

State 3

Ввод Действие
*login* Перейти в состояние 4 и отправить имя гостя. Флаги, используемые в данном состоянии, получают значение 0, времени ожидания в новом состоянии установлено значение 0.5 секунд, а таймаут в новом состоянии получает значение 8 секунд.
*no carrier* То же самое, что в предыдущей таблице
*no answer* То же самое, что в предыдущей таблице
*no dialtone* То же самое, что в предыдущей таблице
*busy* То же самое, что в предыдущей таблице

State 4

Ввод Действие
*password* Перейти в состояние 5 и отправить пароль "xxxx". Флаги, используемые в данном состоянии, получают значение 0, времени ожидания в новом состоянии установлено значение 0.5 секунд, а таймаут в новом состоянии получает значение 15 секунд. Поскольку текущее значение флагов равно MODEM_NOECHO, пароль не отправляется в обработчик io().
*no carrier* То же самое, что в предыдущей таблице
*no answer* То же самое, что в предыдущей таблице
*no dialtone* То же самое, что в предыдущей таблице
*busy* То же самое, что в предыдущей таблице

State 5

Ввод Действие
*$ * Перейти в состояние 0 (прекращение), возврат со значением retvalue (0).
*no carrier* То же самое, что в предыдущей таблице
*no answer* То же самое, что в предыдущей таблице
*no dialtone* То же самое, что в предыдущей таблице
*busy* То же самое, что в предыдущей таблице

При установке флага MODEM_BAUD для состояния, любое число, находящееся в сообщении, извлекается, полученное значение записывается в baud.

Если не установить для состояния флаг MODEM_NOECHO, все отправленные строки будут передаваться в функцию io в качестве 3-го параметра (*io)( 0, 0, response ).

Возвращаемое значение:

≠-1
Поле retvalue завершает скрипт. Это значение всегда будет положительным.
-1
Возникла ошибка. Код ошибки записан в errno.

Коды ошибок:

EAGAIN
При установленном флаге O_NONBLOCK для файлового дескриптора процесс будет заблокирован при операции записи.
EBADF
Файловый дескриптор fd не является корректным файловым дескриптором для записи.
EINTR
Операция записи была прервана сигналом, и либо данные не были переданы, либо менеджер ресурсов, ответственный за этот файл, не сообщает о частичной передаче.
EIO
Произошла физическая ошибка ввода-вывода. Точная причина зависит от устройства.
EPIPE
Предпринята попытка записи в канал (или FIFO), который не открыт каким-либо процессом для чтения. Процессу отправляется сигнал SIGPIPE.

Классификация:

ЗОСРВ «Нейтрино»

Безопасность использования
Точка остановки потока
Да
Обработчик прерываний
Нет
Обработчик сигналов
Смотри ниже
В потоке
Смотри ниже

Предостережения:

В зависимости от того, что происходит в функции cancel, вызов функции modem_script() из обработчика сигнала или из потока может быть или не быть безопасным.

Тематические ссылки:

struct modem_script, modem_open(), modem_read(), modem_write()




Предыдущий раздел: Описание API системной библиотеки