⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at.c

📁 中文短信的编解码
💻 C
字号:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <semaphore.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <ioLib.h>
#include <selectLib.h>
/* #include <termio.h> */

#include "include/types.h"
#include "include/at.h"

AT_MODEM * at_modem_init(int fd_com)
{
	AT_MODEM * fd;
	
	fd = (AT_MODEM *) calloc(1,sizeof(AT_MODEM));
	if(NULL != fd)
	{
		fd->fd_com = fd_com;
		fd->rxhead = 0;
		fd->rxtail = 0;
	}
	else
	{
		sg_dbg("calloc AT_MODEM");
	}
	
	return fd;
}

int at_set(AT_MODEM * modem, AT_CMD * pack_at)
{
	if(ERROR == at_write(modem,pack_at))
	{
		sg_dbg("ERROR == at_write");
		return ERROR;
	}

	return (at_read(modem,pack_at));
}

typedef struct _AT_RETURN_DEF {
	int 	len;
	int		type;
	char *	atr;
} AT_RETURN_DEF;

int at_check_atr(AT_RX_BUF * p_rx)
{
	static AT_RETURN_DEF at_return_def[] = 
	{
		{2,ATR_OK		,"OK"		},
		{5,ATR_ERROR	,"ERROR"	},
		{4,ATR_RING		,"RING"		},
		{3,ATR_NO_		,"NO "		},
		{3,ATR_AT_		,"AT+"		},
		{4,ATR_BUSY		,"BUSY"		},
		{7,ATR_CONNECT	,"CONNECT"	},
		{4,ATR_ERROR_ 	,"+CME"		},
		{1,ATR_RET		,"+"		},
		{0,ATR_UNKNOWN	,""			},
		{0,ATR_NULL		,NULL		}
	};
	AT_RETURN_DEF * p_atr;

	p_atr = &(at_return_def[0]);
	p_rx->type = ATR_NULL;
	while(1)
	{
		if(p_atr->type == ATR_UNKNOWN)
		{
			p_rx->type = p_atr->type;
			break;
		}
		if(0 == bcmp(p_rx->buf,p_atr->atr,p_atr->len))
		{
			p_rx->type = p_atr->type;
			break;
		}
		p_atr++;
	}
#if 0
	switch(p_rx->type)
	{
	case ATR_RING:
		//...
		break;
	default:
		break;
	}
#endif

	return p_rx->type;
}

int at_write(AT_MODEM * modem, AT_CMD * pack_at)
{
	struct timeval  time_Val;
	int 	len;
	char *	buf;
	int		fd;
	
	if(NULL == pack_at)
	{
		return ERROR;
	}
	time_Val.tv_sec = 0;
	time_Val.tv_usec = pack_at->delay_usec;
	if(0 > select(0, NULL, NULL, NULL, &time_Val))
	{
		sg_dbg("0 > select delay!");
		return ERROR;
	}

#ifndef vx_simulator
	at_read(modem,NULL);
#endif
	fd = modem->fd_com;
	modem->rxhead = modem->rxtail;
	modem->status = ATR_NULL;

	buf = pack_at->at_str;
	len = strlen(pack_at->at_str);

	while(len > 0)
	{
		int len_wr;

		len_wr = write(fd,buf,len);
		if(len_wr < 0)
		{
			return ERROR;
		}
		buf += len_wr;
		len -= len_wr;
	}
	
	return OK;
}

int at_read(AT_MODEM * modem, AT_CMD * pack_at)
{
	struct timeval  time_Val;
	fd_set 			fd_RSet;
	int				i_Sel;
	int				fd;
	AT_RX_BUF *	p_rx;

	if(NULL == pack_at)
	{
		time_Val.tv_sec = 0;
		time_Val.tv_usec = 100000;
	}
	else
	{
		time_Val.tv_sec = pack_at->wait_sec;
		time_Val.tv_usec = 0;
	}
#ifdef vx_simulator
	fd = 2;
#else
	fd = modem->fd_com;
#endif
	p_rx = &(modem->rxbuf[modem->rxtail]);
	
	FD_ZERO(&fd_RSet);
	FD_SET(fd, &fd_RSet);

	while(1)
	{
	#ifdef vx_simulator
		i_Sel = select(fd + 1, &fd_RSet, NULL, NULL, NULL);
		if(0 > i_Sel)
		{
		/*	FD_CLR(fd, &fd_RSet); */
			return ERROR;
		}
		else if(i_Sel)
		{
			char * p;
			int i_Bytes;
			char ch;

			ioctl(fd, FIONREAD, (int)&i_Bytes);
			if((p_rx->len + i_Bytes) >= WIDE_RX)
			{
				if(p_rx->len > i_Bytes)
				{
					p_rx->len = 0;
				}
				else
				{
					i_Bytes = WIDE_RX / 2;
				}
			}
			while(i_Bytes--)
			{
				if(1 != read(fd, &ch, 1))
				{
					sg_dbg("xxx");
					return ERROR;
				}
				p_rx->buf[p_rx->len] = ch;
				p_rx->len += 1;
				if(0x0A == ch)
				{
					p_rx->buf[p_rx->len] = 0;
					printf("\n%s",p_rx->buf);
					modem->rxtail++;
					if(modem->rxtail >= NUM_RX)
					{
						modem->rxtail = 0;
					}
					if(p_rx->len > 2)
					{
						at_check_atr(p_rx);
						modem->status |= p_rx->type;
					}
					if(NULL != pack_at)
					{
						if(((modem->status)&(pack_at->ret_type)) == (pack_at->ret_type))
						{
						/*	sg_dbg("at_read exit--normal!\n"); */
						/*	FD_ZERO(&fd_RSet); */
							return OK;
						}
					}
					if(ATR_OK == p_rx->type)
					{
						sg_dbg("at_read exit--OK!\n");
						return OK;
					}
					if(ATR_ERROR == p_rx->type)
					{
						sg_dbg("at_read exit--ERROR!\n");
						return ERROR;
					}
					p_rx = &(modem->rxbuf[modem->rxtail]);
					p_rx->len = 0;
					p_rx->type = ATR_NULL;
					break;
				}
			}
		}
	#else
		i_Sel = select(fd + 1, &fd_RSet, NULL, NULL, &time_Val);
		if(0 > i_Sel)
		{
		/*	FD_CLR(fd, &fd_RSet); */
			return ERROR;
		}
		else if(i_Sel)
		{
			char * p;
			int i_Bytes;
				
			ioctl(fd, FIONREAD, (int)&i_Bytes);
			if((p_rx->len + i_Bytes) >= WIDE_RX)
			{
				if(p_rx->len > i_Bytes)
				{
					p_rx->len = 0;
				}
				else
				{
					i_Bytes = WIDE_RX / 2;
				}
			}
			if(i_Bytes != read(fd, &(p_rx->buf[p_rx->len]), i_Bytes))
			{
				return ERROR;
			}
			p_rx->len += i_Bytes;
			p_rx->buf[p_rx->len] = 0;
			
			while(1)
			{
				if(NULL != (p = strstr(p_rx->buf,"\r")))
				{
					AT_RX_BUF *	pt_rx;
					
					*p = 0;
					printf("\n%s",p_rx->buf);
					modem->rxtail++;
					if(modem->rxtail >= NUM_RX)
					{
						modem->rxtail = 0;
					}
					pt_rx = &(modem->rxbuf[modem->rxtail]);
					strcpy(pt_rx->buf,(p+2));
					pt_rx->len = strlen(pt_rx->buf);
					pt_rx->type = ATR_NULL;
					
					if((p_rx->len = strlen(p_rx->buf)) > 1)
					{
						at_check_atr(p_rx);
						modem->status |= p_rx->type;
					}
					if(ATR_OK == p_rx->type)
					{
						sg_dbg("at_read exit--OK!\n");
						return OK;
					}
					if(NULL != pack_at)
					{
						if(((modem->status)&(pack_at->ret_type)) == (pack_at->ret_type))
						{
							sg_dbg("at_read exit--normal!\n");
						/*	FD_ZERO(&fd_RSet); */
							return OK;
						}
					}
					p_rx = pt_rx;
				}
				else
				{
					break;
				}
			}
		}
		else
		{
			sg_dbg("at_read exit--timeout!\n");
			if(p_rx->len != 0)
			{
				modem->status |= ATR_UNKNOWN;
				p_rx->buf[p_rx->len] = 0;
				sg_dbg("at_read>%d:%s\n",p_rx->len,p_rx->buf);
			}
			modem->status |= ATR_TIMEOUT;
		/*	FD_ZERO(&fd_RSet); */
			return ERROR;
		}
	#endif
	}
	
	return ERROR;
}

AT_RX_BUF * at_get_rxbuf(AT_MODEM * modem,unsigned int type)
{
	AT_RX_BUF * p_rx;
	int head,tail;
	
	if(NULL == modem)
	{
		return NULL;
	}
	head = modem->rxhead;
	tail = head;
	p_rx = &(modem->rxbuf[head]);
	
	while(1)
	{
		if(0 != (p_rx->type&type))
		{
			sg_dbg("at_get_rxbuf>%d:%s",p_rx->len,p_rx->buf);
			p_rx->type = ATR_NULL;
			return p_rx;
		}
		head++;
		if(head >= NUM_RX)
		{
			head = 0;
		}
		p_rx = &(modem->rxbuf[head]);
		if(tail == head)
		{
			sg_dbg("at_get_rxbuf:NULL");
			return NULL;
		}
	}
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -