Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <time.h>
#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. %s\n", strerror(errno));
exit(1);
}
}
void SendStrCmd(int fd, char *buf)
{
fprintf(stderr,"Sending command to modem: %s\n",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/modem", 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, "AT\r");
sprintf(cmd,"AT\r");
SendCmd(fd, cmd, strlen(cmd));
}
void AT(int fd)
{
fprintf(stderr, "Sending command to modem: AT\n");
SendAT(fd);
for (;;) {
if(ReadResp(fd) != 0) {
if(strstr((const char *)readbuf,"OK") != NULL)
{
break;
}
}
SendAT(fd);
}
}
int SetPDUMode(int fd)
{
AT(fd);
SendStrCmd(fd, "ATE0\r");
ReadResp(fd);
SendStrCmd(fd, "AT+CMGF=0\r");
ReadResp(fd);
if(strstr(readbuf,"OK"))
return 0;
return -1;
}
typedef unsigned char UCHAR;
typedef unsigned char *LPSTR;
typedef unsigned char *LPBYTE;
extern LPSTR BinToHex(LPBYTE p, int len);
int SendSMS(int fd, char *to, char *text)
{
UCHAR buf[200];
UCHAR at_cmd[1024];
LPSTR strHex;
int len;
int pdu_len;
int retry = 10;
fd = InitConn(115200);
SetPDUMode(fd);
len = ComposeSubmitSms(buf, sizeof(buf), to, NULL, text);
strHex = BinToHex(buf, len);
pdu_len = strlen(strHex)/2-1;
//printf("%d: %s\n",strlen(strHex)/2-1, strHex);
sprintf(at_cmd,"AT+CMGS=%d\r",pdu_len);
fprintf(stderr,"S");
SendStrCmd(fd, at_cmd);
do{
len = ReadResp(fd);
}while(!strstr(readbuf,">") && retry-- > 0);
if(retry > 0)
{
fprintf(stderr,">");
sprintf(at_cmd,"%s\032",strHex); //CTRL-Z
SendStrCmd(fd, at_cmd);
do{
fprintf(stderr,".");
len = ReadResp(fd);
}while(!strstr(readbuf,"+CMGS:") && retry-- > 0);
}
if(retry > 0)
{
fprintf(stderr,"OK\n");
CloseConn(fd);
return 0;//success
}
else{
fprintf(stderr,"%s: %s\n",at_cmd,readbuf);
free(strHex);
}
CloseConn(fd);
return -1;//failed
}
int main(int argc, char **argv)
{
int fd;
char cmd[1024];
if(argc < 2)
{
fprintf(stderr,"usage: %s <at command>\n",argv[0]);
fprintf(stderr,"examples:\t%s \"AT+XSIMSTATE=1\"\n",argv[0]);
exit(1);
}
fd = InitConn(115200);
AT(fd);
sprintf(cmd,"%s\r",argv[1]);
SendStrCmd(fd,cmd);
ReadResp(fd);
CloseConn(fd);
return 0;
}