![]() |
![]() |
![]() |
![]() |
![]() |
This version of this document is no longer maintained. For the latest documentation, see http://www.qnx.com/developers/docs. |
Run a script on a device
#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) );
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
![]() |
This function is in libc.a, but not in libc.so (in order to save space). |
The modem_script() function runs the script table on the device associated with the file descriptor fd. The script implements a simple state machine that emits strings and waits for responses.
Each string that's emitted or received is passed to the function io() as follows:
| Call | Description |
|---|---|
| (*io)(str, 0, 0) | Emitted progress string |
| (*io)(0, str, 0) | Received string |
| (*io)(0, 0, str) | Emitted response string |
This lets an application set up a callback that can display the script's interaction in a status window.
If you provide a cancel function, it's called once each newquiet 1/10 of a second while waiting for input. If this function returns a nonzero value, the read returns immediately with -1 and errno is set to ETIMEDOUT. You can use the cancel function as a callback in a graphical dialer that needs to support a cancel button to stop a script.
The table is an array of modem_script structures that contain the following members:
Here's an example that demonstrates the operation of the script:
/*
curstate curflags newstate newflags newtimeout
newquiet retvalue pattern response
*/
struct modem_script table[] ={
{1, 0, 1, 0, 2, 5, 0,
NULL, "ATZ\\r\\P0a"},
{1, 0, 2, 0, 30, 5, 0,
"*ok*", "ATDT5910934"},
{2, MODEM_BAUD, 3, MODEM_LASTLINE, 10, 5, 0,
"*connect*", NULL},
{3, 0, 4, 0, 8, 5, 0,
"*login:*", "guest"},
{4, MODEM_NOECHO, 5, 0, 15, 5, 0,
"*password:*", "xxxx"},
{5, 0, 0, 0, 0, 0, 0,
"*$ *", NULL},
{0, 0, 0, 0, 0, 0, 1,
"*no carrier*", NULL},
{0, 0, 0, 0, 0, 0, 2,
"*no answer*", NULL},
{0, 0, 0, 0, 0, 0, 3,
"*no dialtone*", NULL},
{0, 0, 0, 0, 0, 0, 4,
"*busy*", NULL},
{ NULL }
};
When this script is passed to modem_script(), the current state is set to 1, and the output is ATZ (the response in the first array element).
While in any state, modem_script() waits for input, matching it against the current state or the wildcard state of 0.
| Input | Action |
|---|---|
| *ok* | Go to state 2 and emit ATDT1-591-0934. The flags to be used in the new state are set to 0, the quiet time in the new state is set to 5/10 of a second, and the timeout time in the new state is set to 30 seconds. |
| *no carrier* | Go to state 0 (the termination newstate), return with the contents of retvalue (1). |
| *no answer* | Go to state 0 (the termination newstate), return with the contents of retvalue (2). |
| *no dialtone* | Go to state 0 (the termination newstate), return with the contents of retvalue (3). |
| *busy* | Go to state 0 (the termination newstate), return with the contents of retvalue (4). |
| Input | Action |
|---|---|
| *connect* | Go to state 3 and don't emit anything to the device. The flags to be used in the new state are set to MODEM_LASTLINE, the quiet time in the new state is set to 5/10 of a second, and the timeout time in the new state is set to 10 seconds. Since the current flags are MODEM_BAUD, the baud rate is extracted from the connect message. |
| *no carrier* | Same as previous table |
| *no answer* | Same as previous table |
| *no dialtone* | Same as previous table |
| *busy* | Same as previous table |
| Input | Action |
|---|---|
| *login* | Go to state 4 and emit guest. The flags to be used in the new state are set to 0, the quiet time in the new state is set to 5/10 of a second, and the timeout time in the new state is set to 8 seconds. |
| *no carrier* | Same as previous table |
| *no answer* | Same as previous table |
| *no dialtone* | Same as previous table |
| *busy* | Same as previous table |
| Input | Action |
|---|---|
| *password* | Go to state 5 and emit xxxx. The flags to be used in the new state are set to 0, the quiet time in the new state is set to 5/10 of a second, and the timeout time in the new state is set to 15 seconds. Since the current flags are MODEM_NOECHO, the password response xxxx isn't sent to the io() callback. |
| *no carrier* | Same as previous table |
| *no answer* | Same as previous table |
| *no dialtone* | Same as previous table |
| *busy* | Same as previous table |
| Input | Action |
|---|---|
| *$ * | Go to state 0 (the termination newstate), return with the contents of retvalue (0). |
| *no carrier* | Same as previous table |
| *no answer* | Same as previous table |
| *no dialtone* | Same as previous table |
| *busy* | Same as previous table |
If you set the flag MODEM_BAUD for a state, then any number embedded in a matching response is extracted and assigned as a number to the baud parameter.
If you don't set the flag MODEM_NOECHO for a state, then all emitted strings are also given to the passed io function as (*io)(0, 0, response).
The retvalue member of a script entry that terminates the script. This will always be a positive number. If modem_script fails, it returns -1 and sets errno.
| Safety: | |
|---|---|
| Cancellation point | Yes |
| Interrupt handler | No |
| Signal handler | Read the Caveats |
| Thread | Read the Caveats |
Depending on what you do in your cancel function, it might or might not be safe to call modem_script() from a signal handler or a multithreaded program.
modem_open(), modem_read(), modem_write()
![]() |
![]() |
![]() |
![]() |