A Convenient Tool to Send AT Commands

PmgRiPhone of elite team has released a tool (sendmodem) to send command directly to iPhone modem. This is convenient. The tool uses /dev/tty.debug to communicate with modem, so you don’t have to turn off the communication center during the operations.

The command syntax is quite straight forward:

sendmodem “AT command”

Here are some examples:

Querying the baseband version:
sendmodem
“AT+XGENDATA”

Querying the lock state:
sendmodem “AT+XSIMSTATE=1”

Querying the battery capacity:
sendmodem “AT+CBC”

Querying the signal quality:
sendmodem “AT+CSQ”

If you wanna use double quote in an AT command, you have to escape it like in C language (“), eg.:

sendmodem “AT+CLCK=”PN”,2″

For available AT commands, refer to ETS 300 642 documentation.

UPDATE: to check the bootloader version of your iPhone, enter the following command (equivalent to ‘bbupdater -v’):

sendmodem “AT+XGENDATA”

Example output:

Sending command to modem: AT
-.+
AT
OK
Sending command to modem: AT+XGENDATA
-..+
AT+XGENDATA
+XGENDATA: ”
“,
“DEV_ICE_MODEM_04.01.13_G”,
“EEP_VERSION:207”,
“EEP_REVISION:8”,
“BOOTLOADER_VERSION:3.9_M3S2”,1,0

OK

The source code of sendmodem is here:

#include <stdio>
#include <stdlib>
#include <unistd>
#include <string>
#include <fcntl>
#include <termios>
#include <errno>
#include <time>

#define BUFSIZE (65536+100)
unsigned char readbuf[BUFSIZE];

static struct termios term;
static struct termios gOriginalTTYAttrs;
int InitConn(int speed);

void SendCmd(int fd, void *buf, size_t size)
{

    if(write(fd, buf, size) == -1) {
        fprintf(stderr, "SendCmd error. %sn", strerror(errno));
        exit(1);
    }
}

void SendStrCmd(int fd, char *buf)
{
    fprintf(stderr,"Sending command to modem: %sn",buf);
    SendCmd(fd, buf, strlen(buf));
}

int ReadResp(int fd)
{
    int len = 0;
    struct timeval timeout;
    int nfds = fd + 1;
    fd_set readfds;
    int select_ret;

    FD_ZERO(&readfds);
    FD_SET(fd, &readfds);

    // Wait a second
    timeout.tv_sec = 1;
    timeout.tv_usec = 500000;

    fprintf(stderr,"-");
    while (select_ret = select(nfds, &readfds, NULL, NULL, &timeout) > 0)
    {
        fprintf(stderr,".");
        len += read(fd, readbuf + len, BUFSIZE - len);
        FD_ZERO(&readfds);
        FD_SET(fd, &readfds);
        timeout.tv_sec = 0;
        timeout.tv_usec = 500000;
    }
    if (len > 0) {
        fprintf(stderr,"+n");
    }
    readbuf[len] = 0;
    fprintf(stderr,"%s",readbuf);
    return len;
}

int InitConn(int speed)
{
    int fd = open("/dev/tty.debug", O_RDWR | O_NOCTTY);

    if(fd == -1) {
        fprintf(stderr, "%i(%s)n", errno, strerror(errno));
        exit(1);
    }

    ioctl(fd, TIOCEXCL);
    fcntl(fd, F_SETFL, 0);

    tcgetattr(fd, &term);
    gOriginalTTYAttrs = term;

    cfmakeraw(&term);
    cfsetspeed(&term, speed);
    term.c_cflag = CS8 | CLOCAL | CREAD;
    term.c_iflag = 0;
    term.c_oflag = 0;
    term.c_lflag = 0;
    term.c_cc[VMIN] = 0;
    term.c_cc[VTIME] = 0;
    tcsetattr(fd, TCSANOW, &term);

    return fd;
}
void CloseConn(int fd)
{
    tcdrain(fd);
    tcsetattr(fd, TCSANOW, &gOriginalTTYAttrs);
    close(fd);
}

void SendAT(int fd)
{
    char cmd[5];

    //  SendStrCmd(fd, "ATr");
    sprintf(cmd,"ATr");
    SendCmd(fd, cmd, strlen(cmd));
}

void AT(int fd)
{
    fprintf(stderr, "Sending command to modem: ATn");
    SendAT(fd);
    for (;;) {
        if(ReadResp(fd) != 0) {
            if(strstr((const char *)readbuf,"OK") != NULL)
            {
                break;
            }
        }
        SendAT(fd);
    }
}

int main(int argc, char **argv)
{
    int fd;
    char cmd[1024];
    if(argc < 2)
    {
        fprintf(stderr,"usage: %s <at>n",argv[0]);
        fprintf(stderr,"examples:t%s "AT+XSIMSTATE=1"n",argv[0]);
        fprintf(stderr,"tt%s "AT+XGENDATA"n",argv[0]);
        fprintf(stderr,"tt%s "AT+CLCK=\"SC\",2"n",argv[0]);
        exit(1);
    }
    fd = InitConn(115200);

    AT(fd);
    sprintf(cmd,"%sr",argv[1]);
    SendStrCmd(fd,cmd);
    ReadResp(fd);
    CloseConn(fd);
    return 0;
}

UPDATE: Another proggie (igsm from Marcio’s iPhone Apps) has the similar functions (thanks Ais’ comment) or maybe more powerful, however, the igsm uses /dev/tty.baseband which means you have to turn off the communication center before using it, fortunately, igsm has options to do these jobs so you don’t have to enter the long ‘launchctl …’ lines manually.

The syntax:

usage: igsm [-p pin] [-c command … -c command] [-l] [-L] [-u] [-d] [-v] [-r]

-p pin SIM pin (if needed)
-d dump IMEI IMSI …
-c cmd command to be executed (more than 1 is supported)
-l load commcenter
-L list all jobs loaded into launchd
-u unload commcenter
-r reset baseband
-m string modem init string
-M num max lines on any command
-v verbose mode
-vv verbose mode and hex dump
-h this help
-hh extended help

An example:

# igsm -c AT+CPBS?
Opened: /dev/tty.baseband
> ATE0 – set echo OFF
< OK

> AT
< OK

> AT+CPIN? – SIM requires PIN ?
< +CPIN: READY
< OK

> AT+CPBS?
< +CPBS: “SM”,34,150
< OK
Done

Marcio’s site also has a native utility iToggle, which can be useful if you frequently switch on/off some of your services. The following is a screenshot of the application’s startup screen:

iToggle


8 Comments

  1. Naren
    Posted January 6, 2009 at 9:21 pm | Permalink

    Hi there,
    in what case openconn(“dev/tty.debug “) will return -1,
    because my application is returning -1 and getting exit with status 1.
    how to avoid this situation. plase help me.
    Thanks a lot

  2. Naren
    Posted January 6, 2009 at 9:26 pm | Permalink

    Hi there,
    in what case openconn(“dev/tty.debug “) will return -1,
    because my application is returning -1 and getting exit with status 1.
    how to avoid this situation. plase help me.
    Thanks a lot

  3. Naren
    Posted January 6, 2009 at 9:37 pm | Permalink

    Hi
    i am getting -1 from openConn(“dev/tty.debug”), can you tell me what is the problem and how can i avoid that. please reply.
    thanks a lot.
    Naren

  4. Posted January 6, 2009 at 9:42 pm | Permalink

    Hi ,
    In what case i will get -1 from openConn(“dev/tty.debug”), i am getting it and my application is terminated with the status 1. I am writing an application to send an sms and getting this problem . I am stucked here. please help.
    thanks a lot

  5. naren
    Posted January 7, 2009 at 1:23 pm | Permalink

    Hi all,
    I am very sorry for posting same message 4 times, when i was posting
    it was not redirecting to other page so i was retrying and today i found that there are 4 posts. anyhow please reply for the same.

  6. Amine Salmane REKIK
    Posted January 10, 2010 at 12:34 am | Permalink

    Dear Sir,
    I’d like to know if I can implement your code in the iPhone application.
    Because I need to develop an iphone application that send programmatically AT command to the gsm network. This command look like at+cusd=1,”#123#”,15

    Please reply to me

    thank you

  7. Posted January 10, 2010 at 5:06 pm | Permalink

    In that case, you may like to contact the author of sendmodem, the project is at http://code.google.com/p/iphone-elite/wiki/sendmodem .

  8. Amine Salmane REKIK
    Posted January 11, 2010 at 1:11 am | Permalink

    thank you

One Trackback

  1. […] to this site for the source code of […]

WordPress Appliance - Powered by TurnKey Linux