获取强度: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;
}