获取强度:AT+CSQ 以“\r","\n"结尾
遇到问题:
一方面是因为AT指令格式不对,最后只发了"\r",没有发"\n",另外 PPP与AT采用不同的tty,我的模块是BD_MF206(可以发AT+CGMR得到),对应的ttyUSB1为AT指令,ttyUSB2为PPP对应的,但有点不明白的是一开始用的是ttyUSB2,而且指令也没有加"\n",居然一样得到了信号强度。。。;而且使用ttyUSB1发送命令。。时常返回ERROR。。
是因为串初始化没做好。
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <errno.h> #include <sys/ioctl.h> #include <assert.h> #include <pthread.h> #include <sys/wait.h> #include <sys/klog.h> #include <syslog.h> #include <string.h> static int is_value_get(void); static int write_level(char *level); pthread_mutex_t read_mutex; pthread_cond_t read_cond; pthread_mutex_t wr_mutex; pthread_cond_t wr_cond; static wr_num_sig = 0; static re_num_sig = 0; static int m_fd; static int get_level = -1; static check_sec = 3 ; static err_num = 0; static int ok_flag = 0; static int snum = 5; //#define DEBUG #ifdef DEBUG #define debug(fmt,args...) do { syslog(LOG_INFO,"%s: -->"fmt, __FUNCTION__,##args); } while (0) #else #define debug(fmt,args...) while(0) #endif #define STORE_3G_LEVEL "/sys/devices/platform/netconstore/store_3g" //write level value to the sys interface int write_level(char *level) { char cmd[200]; sprintf(cmd,"echo %s > /sys/devices/platform/netconstore/store_3g",level); debug("LWP========= the cmd is %s\n",cmd); int ret = system(cmd); if (WEXITSTATUS (ret) == 0) { return 1; } debug("LWP=========HAS write %s into sys \n",level); return 1; } #if 1 //send the at cmd to the 3G MODEM int send_cmd(char *cmd) { debug("HAS INTO send_cmd!!!!!!!!!!!!!!!!!!!!!!!!!\n"); int n; int m = 0; rewrite: n = write(m_fd, cmd, strlen(cmd)); if(n < 0) { fprintf(stderr,"write 3g device failed by:%s",strerror(errno)); //open ttyusb1 close(m_fd); open_3g_dev_ttyusb1(); goto rewrite; //return -1; } debug("WRITE AT+CSQ ok!!\n"); #if 1 n = write(m_fd, "\r",1); if(n < 0) { fprintf(stderr,"write R device failed by:%s",strerror(errno)); return -1; } #endif #if 1 n = write(m_fd, "\n",1); if(n < 0) { fprintf(stderr,"write R device failed by:%s",strerror(errno)); return -1; } debug("WRITE \\r \\n ok!!\n"); #endif usleep(300); //send the signal to get_res pthread_mutex_lock(&read_mutex); if(re_num_sig > 0) { pthread_cond_signal(&read_cond); pthread_mutex_unlock(&read_mutex); } else { pthread_mutex_unlock(&read_mutex); } //then wait the get_res deal the result pthread_mutex_lock(&wr_mutex); wr_num_sig++; pthread_cond_wait(&wr_cond, &wr_mutex); pthread_mutex_unlock(&wr_mutex); return 1; } #endif //get the at cmd result void *get_res(void *para) { debug("lwp==========================HAS INTO GET RES\n!!!!!!!!!!!!!!!!!!!!!!!!!"); int n; char res[512]; char *g_tmp = NULL; char *g_token=NULL; for(;;) { //wait the write func to send the sigal to begin read pthread_mutex_lock(&read_mutex); re_num_sig++; pthread_cond_wait(&read_cond, &read_mutex); pthread_mutex_unlock(&read_mutex); memset(res,0,512); #if 1 while(read(m_fd, res, 512)) { debug("lwp==========================[[IN while]]HAS read %s \n",res); if(strstr(res,"+CSQ:")) { g_tmp = res; if((g_token = strsep (&g_tmp,":"))!=NULL) { debug("g_token is %s \n",g_token); if((g_token = strsep (&g_tmp,","))!=NULL) { debug("g_token is %s \n",g_token); write_level(g_token); get_level = atoi(g_token); debug("after atoi g_token is %d\n",get_level); //close(m_fd); //send signal to write func to get level again pthread_mutex_lock(&wr_mutex); if(wr_num_sig > 0) { pthread_cond_signal(&wr_cond); pthread_mutex_unlock(&wr_mutex); } else { pthread_mutex_unlock(&wr_mutex); } break; } } break; } else if(strstr(res,"ERROR")) { #if 0 close(m_fd); open_3g_dev(); err_num++; if(err_num == 16) { check_sec = 60; } #endif err_num++; pthread_mutex_lock(&wr_mutex); if(wr_num_sig > 0) { pthread_cond_signal(&wr_cond); pthread_mutex_unlock(&wr_mutex); } else { pthread_mutex_unlock(&wr_mutex); } break; } else if(strstr(res,"3GNET")) { #if 1 close(m_fd); open_3g_dev_ttyusb1(); #endif pthread_mutex_lock(&wr_mutex); if(wr_num_sig > 0) { pthread_cond_signal(&wr_cond); pthread_mutex_unlock(&wr_mutex); } else { pthread_mutex_unlock(&wr_mutex); } break; } //debug("lwp==========================HAS read %s \n",res); } #endif debug("lwp==========================after one read...\n"); } debug("lwp==========================++++++++++exit the read at result pthread++\n"); } //creat the get the at cmd results thread int init_get_res() { int err; pthread_t rtid; pthread_attr_t pthread_attr; if(pthread_attr_init(&pthread_attr)){ syslog(LOG_ERR, "Attribute creation failed in %s", __FUNCTION__); return -1; } if(pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACHED) ){ syslog(LOG_ERR,"Setting detach attribute failed in %s", __FUNCTION__); return -1; } if((err = pthread_create(&rtid, &pthread_attr, get_res, NULL))) { fprintf(stderr,"creat init_get_res failed:%s\n",strerror(errno)); return -1; } return 1; } int open_3g_dev() { debug("OPEN 3G DEVIECE ttyUSB2\n"); m_fd = open("/dev/ttyUSB2", O_RDWR | O_NOCTTY); if(m_fd < 0) { fprintf(stderr,"open 3g device failed by:%s",strerror(errno)); return -1; } return 1; } int open_3g_dev_ttyusb1() { //open ttyUSB2 failed we try to open ttyUSB1 debug("OPEN 3G DEVIECE ttyUSB1\n"); m_fd = open("/dev/ttyUSB1", O_RDWR | O_NOCTTY); if(m_fd < 0) { fprintf(stderr,"open 3g device failed by:%s\n",strerror(errno)); exit(-1); } return 1; } //judge if has get the 3g level at begin int is_value_get() { FILE *g_fp; int g_read = -1; char g_buffer[BUFSIZ]; g_fp = popen("cat /sys/devices/platform/netconstore/store_3g", "r"); if ( g_fp != NULL ) { g_read = fread(g_buffer, sizeof(char), BUFSIZ-1, g_fp); if (g_read <= 0) { pclose(g_fp); return -1; } else { pclose(g_fp); return 1; } } else { return -1; } } int is_3g_on() { debug("INTO the check modem!!!"); FILE *fp; char line[1024]; syslog(LOG_INFO, "%s:--> begin to check ppp0", __FUNCTION__); if( (fp=fopen("/proc/net/route", "r")) < 0) { syslog(LOG_ERR, "/proc/net/route open failed"); return 0; } while(fgets(line, 1023, fp)) { if(strstr(line, "ppp0")) { debug("3G IS ON!!!"); fclose(fp); return 1; } } syslog(LOG_INFO, "%s:--> 3g is off", __FUNCTION__); fclose(fp); return 0; } void init_log(void) { int option = LOG_NDELAY | LOG_PID | LOG_PERROR; openlog("CONNDAEMON", option, LOG_DAEMON); syslog(LOG_INFO, "connd started !"); } static int open_dev(const char *dev) { int fd = open( dev, O_RDWR | O_NOCTTY | O_NDELAY ); if (fd != -1 ){ fcntl(fd, F_SETFL,0); //set to block } return fd; } void close_serial_port(int fd) { close(fd); } int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop) { struct termios newtio,oldtio; //save old setting if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1"); return -1; } //extern void bzero(void *s, int n); set s zero bzero( &newtio, sizeof( newtio ) ); //set the size of char newtio.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= ~CSIZE; //set data mode switch( nBits ) { case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; } //set check switch( nEvent ) { case 'O': newtio.c_cflag |= PARENB; newtio.c_cflag |= PARODD; newtio.c_iflag |= (INPCK | ISTRIP); break; case 'E': newtio.c_iflag |= (INPCK | ISTRIP); newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; break; case 'N': newtio.c_cflag &= ~PARENB; break; } //set bound switch( nSpeed ) { case 2400: cfsetispeed(&newtio, B2400); cfsetospeed(&newtio, B2400); break; case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 9600: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; case 115200: cfsetispeed(&newtio, B115200); cfsetospeed(&newtio, B115200); break; default: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; } //set stop if( nStop == 1 ) newtio.c_cflag &= ~CSTOPB; else if ( nStop == 2 ) newtio.c_cflag |= CSTOPB; //set wait time and less recv char newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 0; //deal the char not recv tcflush(fd,TCIFLUSH); //new setting if((tcsetattr(fd,TCSANOW,&newtio))!=0) { perror("com set error");// return -1; } printf("set done!\n"); return 0; } int main(int argc, char *argv[]) { init_log(); #if 1 /* we should change daemon(0,1) to daemon(0,0) after finish all */ if(daemon(1,1)<0){ fprintf(stderr,"connd can't init daemon!"); exit(-1); } #endif if ((m_fd = open_dev("/dev/ttyUSB1")) < 0) { fprintf(stderr,"open 3g device failed \n"); return -1; } //set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop); if(set_opt(m_fd,115200,8,'N',1) < 0) { fprintf(stderr,"set serial failed \n"); return -1; } debug("set serial ok\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); //creat the get result thread if(init_get_res() < 0 ) { return -1; } #if 1 while(1) { if(send_cmd("AT+CSQ") < 0) { fprintf(stderr,"the send cmd to 3g wrong!!\n"); close(m_fd); return -1; } if((is_value_get()) == 1) { check_sec = 40; err_num = 0; } else { if(err_num > 10) { check_sec = 120; } else { check_sec = 2; } } sleep(check_sec); } #endif return 0; }