解决获取3G信号强度


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

你可能感兴趣的:(function,cmd,null,token,FP,Signal)