Linux下短信功能实现

Linux下短信功能的实现

Linux版本Linux-3.2.0,无线模块是华为909SE,使用USB转串口模式,短信接口为/dev/ttyUSB4

驱动   

   USB转串口驱动自行下载合适的版本,安装后无线模块会自动转化为8个串口,ttyUSB0~ttyUSB7,其中ttyUSB0用于网络数据的传输,ttyUSB4用于短信发送与接收。转化后可作为串口直接使用。

初始化

  串口初始化:串口的初始化与一般一般串口相同,请自行参考串口初始化配置。

 下面是串口配置的主要代码:

  usbfd = open(Interface_USB4, O_RDWR);   // 选择串口句柄

  set_speed(usbfd , 115200);    //设置串口速度函数

  set_other_attribute(usbfd, 8, 1, 0, 0);  //设置串口其他参数的函数

static int speed_arr[] = {B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1800, B1200, B600, B300};

static int name_arr[]  = {230400,  115200,  57600,  38400,  19200,  9600,  4800,  2400,  1800,  1200,  600,  300};

int set_speed(int fd, int speed)

{

    int i, status; 

    struct termios Opt;

    

    tcgetattr(fd, &Opt); 

    for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) { 

        if (speed == name_arr[i]) {

            tcflush(fd, TCIOFLUSH);     

            cfsetispeed(&Opt, speed_arr[i]);  

            cfsetospeed(&Opt, speed_arr[i]);

            status = tcsetattr(fd, TCSANOW, &Opt);  

            if  (status != 0) {        

                printf("tcsetattr failed\n");  

                return -1;     

            }

    

            tcflush(fd,TCIOFLUSH);

return 0;

        }

    }

    return -1;

}

int set_other_attribute(int fd, int databits, int stopbits, int parity, int mode)

    struct termios options; 

    if (tcgetattr(fd, &options) != 0) { 

        printf("tcgetattr failed\n");     

        return -1;  

    }

    options.c_cflag &= ~CSIZE; 

    switch (databits) /*¨¦?¨º?Y?¨º*/

    {   

        case 7:

            options.c_cflag |= CS7; 

            break;

        case 8:     

            options.c_cflag |= CS8;

            break;   

        default:    

            fprintf(stderr,"Unsupported data size\n"); 

            return -1;  

    }

    switch (parity) 

    {   

        case 'n':

        case 'N':    

            options.c_cflag &= ~PARENB;   /* Clear parity enable */

            options.c_iflag &= ~INPCK;     /* Enable parity checking */ 

            break;  

        case 'o':   

        case 'O':    

case 1:

            options.c_cflag |= (PARODD | PARENB); /* ¨¦???§¹?*/  

            options.c_iflag |= INPCK;             /* Disnable parity checking */ 

            break;  

        case 'e':  

        case 'E':   

case 2:

            options.c_cflag |= PARENB;     /* Enable parity */    

            options.c_cflag &= ~PARODD;    /* ?????§¹?*/     

            options.c_iflag |= INPCK;      /* Disnable parity checking */

            break;

        case 'S': 

        case 's':  /*as no parity*/   

case 0:

            options.c_cflag &= ~PARENB;

            options.c_cflag &= ~CSTOPB;

            break;  

        default:   

            fprintf(stderr,"Unsupported parity\n");    

            return -1;  

    }  

    /* ¨¦???¦Ë*/  

    switch (stopbits)

    {   

        case 1:    

            options.c_cflag &= ~CSTOPB;  

            break;  

        case 2:    

            options.c_cflag |= CSTOPB;  

            break;

        default:    

            fprintf(stderr,"Unsupported stop bits\n");  

            return -1; 

    } 

    /* Set input parity option */ 

    if (parity != 'n')   

        options.c_iflag |= INPCK; 

    tcflush(fd,TCIFLUSH);

    options.c_iflag = 0;

    options.c_oflag = 0;

    options.c_lflag = 0;  

    options.c_cc[VTIME] = 50; /* ¨¦?3??15 seconds*/   

    options.c_cc[VMIN] = 1; /* Update the options and do it NOW */

// options.c_oflag 0;

switch(mode)

{

/*case 1://rs485

options.c_cflag |= RS485;

printf("Enable RS485 !\n");

break;

case 2://HWHD

options.c_cflag |= HWHD;

printf("Enable HWHD !\n");

break;

case 3://Modem

options.c_cflag |= Modem;

printf("Enable Modem !\n");

break;

case 4://ISO7816T0

options.c_cflag |= ISO7816T0;

printf("Enable ISO7816 T=0 \n");

break;

case 5://ISO7816T1

options.c_cflag |= ISO7816T1;

printf("Enable ISO7816 T=1 \n");

break;

case 6://IrDA

options.c_cflag |= IrDA;

printf("Enable IrDA \n");

break;*/

default:

break;

}

if (tcsetattr(fd,TCSANOW,&options) != 0)   

    { 

        perror("SetupSerial 3");   

        return -1;  

    }

#if 0

    tcgetattr(fd, &options);

    printf("c_iflag: %x\rc_oflag: %x\n", options.c_iflag, options.c_oflag);

    printf("c_cflag: %x\nc_lflag: %x\n", options.c_cflag, options.c_lflag);

    printf("c_line: %x\nc_cc[VTIME]: %d\nc_cc[VMIN]: %d\n", options.c_line, options.c_cc[VTIME], options.c_cc[VMIN]);

#endif

    return 0;  

}

  模块初始化:根据使用的模块,进行配置。包括短信模式、字符模式、新消息到来提醒、短信存储位置、清除已读短信等配置。

  MsgInit;//模块初始化函数

int MsgInit(void)

{

int rec;

rec = ATCMDSend("AT+IPR=0\r\n", strlen("AT+IPR=0\r\n") , "OK", 3);

if (rec != 0)

{

printf("波特率自适应设置失败\n");

return -1;

}

rec = ATCMDSend("AT+CMGF=1\r\n", strlen("AT+CMGF=1\r\n") , "OK", 3);

if (rec != 0)

{

printf(短信模式配置失败\n");

return -1;

}

rec = SetGSMMode();

if (rec != 0)

{

printf("字符格式设置失败\n");

return -1;

}

rec = ATCMDSend("AT+CNMI=2,1,0,0,0\r\n", strlen("AT+CNMI=2,1,0,0,0\r\n") , "OK", 3);

if(rec != 0)

{

printf("新消息提示设置失败\n");

return -1;

}

rec = SetFlashMode();

if (rec != 0)

{

printf("短信存储器选择失败\n");

return -1;

}

rec = ATCMDSend("AT+CMGD=1,4\r\n", strlen("AT+CMGD=1,4\r\n") , "OK", 5);

if (rec != 0)

{

printf("清空短消息失败\n");

return -1;

}

    printf("=====message initial done!\n");

return 0;

}

短信读取与发送:短信接收与发送分别使用不同的线程独立完成,在接收过程中提取接收的短信号码,留作发送时使用。

短信接收线程:

void SMS_RECV(int arg)

{  

    int    readlen ;

int    timeout=0;

int    ct=0;

char   ATrxbuf[COMPORT_BUFSIZE]={0};

    if(fcntl(usbfd, F_SETFL, FNDELAY) < 0)

    {

        printf("[%s:%d]>>>>error\n\n\n", __FILE__, __LINE__);

    }

    while(1)

    {

        readlen = read(usbfd, ATrxbuf+ct, COMPORT_BUFSIZE);   

        if(readlen > 0)

{  

//printf("Thread_SMS_RECV message<<<<<<<<\n %s \n>>>>>>>>>\n", ATrxbuf);

timeout=0;

if(readlen + ct < COMPORT_BUFSIZE)

            {

                ct += readlen;

            }

else

{

ct = 0;

                bzero(ATrxbuf, COMPORT_BUFSIZE);

}            

        }

else 

{

if((ct>0)&&(timeout > 5))//50ms once

{

//printf("ct= %d \n", ct);

//printf("readlen= %d \n", readlen);        

//printf("<<<<<<ATrxbuf[]>>>>>>\n",ATrxbuf);

printf("%s \n", ATrxbuf);

//printf("<<<<<<<<END>>>>>>>>>>\n",ATrxbuf);

Msg_CheckAndSend(ATrxbuf, ct);

//AckDataAnalyse(ATrxbuf, ct);    

timeout = 0;

                ct = 0;

                bzero(ATrxbuf, COMPORT_BUFSIZE);

}

}

 timeout++;

 usleep(10000);//10ms

    }

}

int Msg_CheckAndSend(char *Msgdata,int  len)

{

char *p1=NULL,*p2=NULL, *p3=NULL,*p4=NULL,*p5=NULL;

char Msgbuf[COMPORT_BUFSIZE]={0};

int  rec=0, i=3;

unsigned int lenOfsms;

bzero(Msgbuf, COMPORT_BUFSIZE);

memcpy(Msgbuf, Msgdata, len-2);/*except "\r\n"*/  

memcpy(Msgdata, Msgbuf, len-2);/*except "\r\n"*/  

if ((p4 = strstr(Msgdata, "CMTI")) != NULL)

{

printf("--------------------------------------\n");

p5 = strstr(p4, ",");

if (p5 != NULL)

{

Msgindex = atoi(p5+1);

printf("MsgindexOfNewSMS>>>>>>> %d <<<<<<\n", Msgindex);

Msgflag = 1;/*means get new message*/

}

printf("--------------------------------------\n");

}

    if ((p1 = strstr(Msgdata, "+CMGR:")) != NULL)

{

printf("++++++++++++++++++++++++++++++++++++++\n");

p2 = strstr(p1, "+86");

if (p2 != NULL)

{

memcpy(phonenumber, p2+3, 11);

//printf("\n p2:<<<<<<<<\n %s \n>>>>>>>>>\n", p2);//for debug

}

else

{

printf("骚扰短信或通信公司短信,不处理");

}

p3 = strstr(p1, "\n");

if (p3 != NULL)

{

bzero(Msgbuf, COMPORT_BUFSIZE);

lenOfsms = strlen(p3)-9;

memcpy(Msgbuf, p3+1, lenOfsms);//store SMS into Msgbuf

//printf("\n p3:<<<<<<<<\n %s \n>>>>>>>>>\n", p3);//for debug

#if 1 /*debug print*/

printf("PhoneNO:<<<<<<<< %s >>>>>>>>>\n", phonenumber);

printf("lenOfsms:<<<<<<<< %d >>>>>>>>>\n", lenOfsms);

printf("SMS_Detail: <<<<<<<<\n%s\n>>>>>>>>>\n", Msgbuf);

#endif 

printf("######################################\n");


Msg_FixParam(Msgbuf, lenOfsms);//短信解析线程



}

}

}

短信发送线程:

void Thread_SendATcmd(int arg)

{

int rec=1;

unsigned int i=2;/*×î´ó³¢ÊÔ·¢Ë͵ĴÎÊý*/

char tempbuf[5]={0}, ATSendbuf[30]={0};

 /*----------------------------------*/

 // test read message

 /*----------------------------------*/

while(1)

{

if (Msgflag == 1)//means recv new SMS

{

while(i--) //

{

rec = ATcmd_ReadMsg();

if (rec == 0)

break;

}

Msgflag = 0;

i = 3;

}

 usleep(10*1000);//10ms

}

}

发送读取短信命令的函数:

int ATcmd_ReadMsg(void)

{

int rec;

char tempbuf[100]={0};

    strcpy(tempbuf, "AT+CMGR=");

sprintf(&tempbuf[strlen(tempbuf)],"%d", Msgindex);

strcat(tempbuf, "\r\n");

//printf("send-AT-read-SMS-cmd: %s\n", tempbuf);

rec = ATCMDSend(tempbuf, strlen(tempbuf), "OK", 3);

if (rec == 0)

{

ATCMDSend("AT+CMGD=1,3\r\n", strlen("AT+CMGD=1,3\r\n") , NULL, 0);

//删除已读短信

}

return rec;

}




实现过程中参考的参考的主要代码:(功能较单一,代码简洁)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h> // open() close()
#include <unistd.h> // read() write()
#include <termios.h> // set baud rate
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#define FUNC_RUN 0
#define FUNC_NOT_RUN 1
#define SIMPLE_TEST 1
#define READ_SIM_CARD_ID 2
#define SHORT_MESSAGE 3
#define FUNC_QUIT 4
#define SEND_SHORT_MESSAGE 1
#define READ_SHORT_MESSAGE 2
#define CONFIG_SHORT_MESSAGE_ENV 3
#define QUIT_SHORT_MESSAGE 4
#define DEVICE_TTYS "/dev/ttyUSB4"        //(有些人的文件是”/dev/ttyS0,看看你是用那个串口”自己对号入座啦!)
#define MAX_LEN_OF_SHORT_MESSAGE 140
#define RECEIVE_BUF_WAIT_1S 1
#define RECEIVE_BUF_WAIT_2S 2
#define RECEIVE_BUF_WAIT_3S 3
#define RECEIVE_BUF_WAIT_4S 4
#define RECEIVE_BUF_WAIT_5S 5




//------------------------------------- read datas from GSM/GPRS ---------------------------
// succese return 1
// error return 0
int read_GSM_GPRS_datas(int fd, char *rcv_buf,int rcv_wait)
{
int retval;
fd_set rfds;
struct timeval tv;
int ret,pos;
tv.tv_sec = rcv_wait; // wait 2.5s
tv.tv_usec = 0;
pos = 0; // point to rceeive buf
while (1)
{
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
retval = select(fd+1 , &rfds, NULL, NULL, &tv);
if (retval == -1)
{
perror("select()");
break;
}
else if (retval)
{                  // pan duan shi fou hai you shu ju
ret = read(fd, rcv_buf+pos, 2048);
pos += ret;
if (rcv_buf[pos-2] == '\r' && rcv_buf[pos-1] == '\n')
{
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
retval = select(fd+1 , &rfds, NULL, NULL, &tv);
if (!retval) break;// no datas, break
}
}
else
{
printf("No data\n");
break;
}
}
return 1;
} // end read_GSM_GPRS_datas
//------------------------------------- send cmd ------------------------------------------// succese return 1
// error return 0
int send_GSM_GPRS_cmd(int fd, char *send_buf)
{
ssize_t ret;
ret = write(fd,send_buf,strlen(send_buf));
if (ret == -1)
{
printf ("write device %s error\n", DEVICE_TTYS);
return -1;
}
return 1;
} // end send_GSM_GPRS_cmd
//------------------------------------- send cmd and read back result ----------------------
void GSM_GPRS_send_cmd_read_result(int fd, char *send_buf, int rcv_wait)
{
char rcv_buf[2048];
if((send_buf==NULL) || (send_GSM_GPRS_cmd(fd,send_buf)))
{ // send success , then read
bzero(rcv_buf,sizeof(rcv_buf));
if (read_GSM_GPRS_datas(fd,rcv_buf,rcv_wait))
{
printf ("%s\n",rcv_buf);
}
else
{
printf ("read error\n");
}
}
else
{
printf("write error\n");
}
} // end GSM_GPRS_send_cmd_read_result
//------------------------------------- send cmd : "at" to GSM/GPRS MODEM ------------------
void GSM_simple_test(int fd)
{
char *send_buf="AT\r";
GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
} // end GSM_simple_test
//------------------------------------- send cmd : "at+ccid" to GSM/GPRS MODEM -------------
void GSM_read_sim_card_id(int fd)
{
char *send_buf="AT+CMGD=1,4\r";
GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
} // end GSM_read_sim_card_id


//------------------------------------- GSM/GPRS send short message ------------------------
void GSM_Send_Message(int fd)
{
char cmd_buf[23];
char *sendtxt_buf="AT+CMGF=1\r";
char short_message_buf[MAX_LEN_OF_SHORT_MESSAGE];
int i;
char rcv_buf;
bzero(cmd_buf,sizeof(cmd_buf));
bzero(short_message_buf,sizeof(short_message_buf));
printf ("send short message:\n");
GSM_GPRS_send_cmd_read_result(fd,sendtxt_buf,RECEIVE_BUF_WAIT_1S);
cmd_buf[0]='A';
cmd_buf[1]='T';
cmd_buf[2]='+';
cmd_buf[3]='C';
cmd_buf[4]='M';
cmd_buf[5]='G';
cmd_buf[6]='S';
cmd_buf[7]='=';
cmd_buf[8]='"';
printf ("please input telephone number:");
i = 9;
while (1)
{
cmd_buf[i]=getchar();
if (cmd_buf[i]=='\n') break;
i++;
}
cmd_buf[i]='"';
cmd_buf[i+1]='\r';
cmd_buf[i+2]='\0';
// send cmd : at+cmgs="(telephone number)"
GSM_GPRS_send_cmd_read_result(fd,cmd_buf,RECEIVE_BUF_WAIT_1S);
// input short message
printf("please input short message:");
i = 0;
while(i < MAX_LEN_OF_SHORT_MESSAGE-2)
{
short_message_buf[i] = getchar();
if (short_message_buf[i]=='\n') break;
i++;
}
short_message_buf[i] = 0x1A;
short_message_buf[i+1] = '\r';
short_message_buf[i+2] = '\0';
// send short message
GSM_GPRS_send_cmd_read_result(fd, short_message_buf,RECEIVE_BUF_WAIT_4S);
printf("\nend send short message\n");
} // end GSM_Send_Message


//------------------------------------- GSM/GPRS read all short message --------------------
void GSM_Read_Message(int fd)
{
char *send_buf="AT+CMGR=1\r";            //\"ALL\"\r";
char rcv_buf[2048];
GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_3S);
printf("end read first short message\n");
} // end GSM_Read_Message
//------------------------------------- GSM/GPRS Config short message env ------------------


void GSM_Conf_Message(int fd)
{
char *send_buf="AT+CMGF=1\r";
char *send_center_buf="AT+CSCA=\"+8613800210500\"\r";
GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
//char *sedd_buf="AT+CPMS=\"SM\"\r";
//GSM_GPRS_send_cmd_read_result(fd,send_buf,RECEIVE_BUF_WAIT_1S);
//printf("message storage in SM.");
// set short message center number
GSM_GPRS_send_cmd_read_result(fd,send_center_buf,RECEIVE_BUF_WAIT_1S);
printf("end config short message env\n");
} // end GSM_Conf_Message


//------------------------------------- GSM/GPRS short message -----------------------------
void GSM_short_mesg(int fd)
{
int flag_sm_run, flag_sm_select;
flag_sm_run = FUNC_RUN;
while (flag_sm_run == FUNC_RUN)
{
printf ("\n Select:\n");
printf ("1 : Send short message \n");
printf ("2 : Read first short message \n");
printf ("3 : Config short message env\n");
printf ("4 : quit\n");
printf (">");
scanf("%d",&flag_sm_select);
getchar();
// temp
// printf ("input select:%d\n",flag_sm_select);
// end temp
switch (flag_sm_select)
{
case SEND_SHORT_MESSAGE : { GSM_Send_Message(fd);}
case READ_SHORT_MESSAGE : { GSM_Read_Message(fd);}
case CONFIG_SHORT_MESSAGE_ENV : { GSM_Conf_Message(fd);}
case QUIT_SHORT_MESSAGE : { flag_sm_run = FUNC_NOT_RUN;}
default :
{
printf("please input your select use 1 to 3\n");
}
}
}
printf ("\n");
} // end GSM_send_mesg
//------------------------------------- print ----------------------------------------------
void print_prompt(void)
{
printf ("Select what you want to do:\n");
printf ("1 : Simple Test\n");
printf ("2 : Del all msg\n");
printf ("3 : Short message\n");
printf ("4 : Quit\n");
printf (">");
} // end print_prompt


//------------------------------------- Control GSM/GPRS MODULE ----------------------------
void func_GSM(int fd)
{
int flag_func_run;
int flag_select_func;
ssize_t ret;
flag_func_run = FUNC_RUN;
while (flag_func_run == FUNC_RUN)
{
print_prompt(); // print select functions
scanf("%d",&flag_select_func); // user input select
getchar();
switch(flag_select_func)
{
case SIMPLE_TEST : {GSM_simple_test(fd); break;}
case READ_SIM_CARD_ID : {GSM_read_sim_card_id(fd); break;}
//case MAKE_A_CALL : {GSM_call(fd); break;}
//case WAIT_A_CALL : {GSM_wait_call(fd); break;}
case SHORT_MESSAGE : {GSM_short_mesg(fd); break;}
case FUNC_QUIT :
{
flag_func_run = FUNC_NOT_RUN;
printf("Quit GSM/GPRS function. byeb");
break;
}
default :
{
printf("please input your select use 1 to 7\n");
}
}
}
}// end func_GPRS


//------------------------------------- init seriel port ----------------------------------
void init_ttyS(int fd)
{
struct termios options;
bzero(&options, sizeof(options)); // clear options
cfsetispeed(&options,B9600); // setup baud rate
cfsetospeed(&options,B9600);
options.c_cflag |= (CRTSCTS | CS8 | CLOCAL | CREAD);
options.c_iflag = IGNPAR;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &options);
}//end init_ttyS
//------------------------------------- main -----------------------------------------------
int main(void)
{
int fd;
printf("\nGSM/GPRS TESTS\n\n");
// open seriel port
fd = open(DEVICE_TTYS, O_RDWR);
if (fd == -1)
{
printf("open device %s error\n",DEVICE_TTYS);
}
else
{
init_ttyS(fd); // init device
func_GSM(fd); // GSM/GPRS functions
// close ttyS0
if (close(fd)!=0) printf("close device %s error",DEVICE_TTYS);
}
return 0;
}// end main


猜你喜欢

转载自blog.csdn.net/yiyongzhifu/article/details/50715760