www.pudn.com > M35-ucos-II.zip > drv_gsm.c, change:2014-11-10,size:60715b


#include <typedef.h> 
#include "ucos_ii.h" 
#include <lib_api.h> 
#include "drv_gsm.h" 
 
 
//任务处理堆栈 
#define TASK_GSM_PROC_STK_SIZE			128 
#define TASK_GSM_ECHO_PROC_STK_SIZE		64 
static OS_STK task_gsmproc_stk[TASK_GSM_PROC_STK_SIZE]; 
static OS_STK task_echo_proc_stk[TASK_GSM_ECHO_PROC_STK_SIZE];	 
  
static OS_EVENT *WlReceiveDataOver; 
static OS_EVENT *WlSendDataOver; 
 
//应用请求 
static void *gsm_req_mq[MAX_GSM_REQ_MQ + 1]; 
static gsm_proc_req gsm_req_info[MAX_GSM_REQ_MQ], unsol_req; 
 
//对外接口 
device_gsm_desc wl_pDev; 
gsm_txrx_buf gsm_buffer; 
static OS_EVENT *gsm_req_event; 
static OS_EVENT *WlReceiveDataOver; 
gsm_unsol_info gsm_unsol_record; 
 
//public val 
extern struct _tmr_out usart3_tmr, usart2_tmr; 
 
 
#define clr_gsm_rx_buf()		{gsm_buffer.rx_buf_len = 0;} 
 
const uint8 *gsm_init_m35[] =  
{ 
//	"AT\r\n", 
	"ATE0\r\n", 
	"AT+CFUN=1,0\r\n", 
	"AT+CLIP=1\r", 
	"AT+COLP=1\r\n", 
//	"AT+QBAND=\"EGSM_MODE\"\r", 
	"AT+QSCLK=1\r\n", 
	"AT+CREG=0\r\n", 
	"AT+QENG=1,0\r\n", 
	"AT+QLJDC=1\r\n", 
//	"AT+QJDR=1\r\n", 
//	"AT+QAUDCH=2\r\n", 
//	"AT+QSIDET=15\x0d\x0a", 
//	"AT+QECHO=221,20,200,849,2\r\n", 
//	"AT+QMIC=2,10\r\n", 
//	"AT+CLVL=70\r\n", 
	"AT+CMGF=1\r\n",        				//Text格式 
	"AT+QSMSCODE=0\r\n", 
	"AT+CNMI=2,1,0,1,0\r\n",   				//新消息提示 
//	"AT+CNMI=1,2,2,1,1\r\n", 
	"AT+CSDH=0\r\n",         				//text模式下显示的内容 
//	"AT+CNUM\r\n", 
//	"AT+QSIMSTAT?\r\n", 
	"AT+QIMUX=0\r\n", 
	"AT+QIMODE=0\r\n", 
	NULL, 
}; 
 
 
const uint8 Dec2hex[16] = {"0123456789ABCDEF"}; 
 
#define GSM_FreeReq(req)	{(req)->gsm_status_machine = ENUM_WL_MAIN_STATUE_FREE;} 
#define GSM_LockRx()		{gsm_buffer.buf_lock |= 1;} 
#define GSM_UnlockRx()		{gsm_buffer.buf_lock &= ~(1 << 0);} 
#define GSM_IsRxLock()		(gsm_buffer.buf_lock & (1 << 0)) 
#define GSM_LockTx()		{gsm_buffer.buf_lock |= (1 << 1);} 
#define GSM_UnlockTx()		{gsm_buffer.buf_lock &= ~(1 << 1);} 
#define GSM_IsTxLock()		(gsm_buffer.buf_lock & (1 << 1)) 
 
uint32 gsm_isr_cnt = 0; 
void ISR_UartGsmRx (uint8 data) 
{ 
	if(gsm_buffer.rx_buf_len >= WL_MAX_RX_BUFFER) 
	{ 
		gsm_buffer.rx_buf_len = 0; 
//		return; 
	} 
	gsm_buffer.rx_buf[gsm_buffer.rx_buf_len++] = data; 
	gsm_isr_cnt++; 
	GSM_LockRx(); 
} 
 
 
uint8 GSM_SendData(uint8 *p, uint16 len) 
{ 
	uint8 err; 
#if GSM_COMMUNICATE_PRINT == 1 
	uint16 idx; 
#endif 
 
#if GSM_COMMUNICATE_PRINT == 1	 
	err = (len > 200) ? 200 : len; 
	for(idx = 0; idx < err; idx++) 
	{ 
		wl_err("%c", *(p + idx)); 
	} 
#endif 
 
	if(GSM_IsRxLock() == 0) 
	{ 
		gsm_buffer.rx_buf_len = 0; 
		gsm_buffer.pre_index = 0; 
	} 
	OSSemSet(WlReceiveDataOver, 0, &err); 
	EnGsmOut(); 
	USART_PutLen(WL_PORT, p, len); 
	DisGsmOut(); 
	return (1); 
} 
 
 
//gsm模块驱动的所有参数复位 
void GSM_ParaReset(void) 
{ 
	uint8 i; 
 
	for(i = 0; i < MAX_GSM_REQ_MQ; i++) 
	{ 
		gsm_req_info[i].gsm_status_machine = ENUM_WL_MAIN_STATUE_SHUT_DOWN; 
	} 
//	memset(wl_pDev.SimNum, 0x00, sizeof(wl_pDev.SimNum)); 
//	memset(wl_pDev.devIdTab, 0, MAX_PHONE_LEN); 
	wl_pDev.Initial = GSM_INIT_ST_PWROFF; 
	wl_pDev.SIMCard = 0; 
	wl_pDev.SimNum[0] = 0; 
	wl_pDev.err_cnt = 0; 
	wl_pDev.gprs_link_cnt = 0; 
	wl_pDev.csq_tmr = 0; 
	wl_pDev.net_tmr = 20; 
	wl_pDev.gprs_tx_err = 0; 
	wl_pDev.sms_tx_err = 0; 
	wl_pDev.call_st = 0; 
	wl_pDev.ring_cnt = 0; 
	wl_pDev.type = 0; 
	wl_pDev.sms_tx_err = 0; 
	wl_pDev.gsmNoNetCnt = 0; 
	wl_pDev.csq = 15; 
	wl_pDev.base_info.mcc = 460; 
 
	wl_pDev.gprs_st = GSM_GPRS_STAT_NO_LINK; 
	wl_pDev.gprs_relink_cnt = 0; 
	wl_pDev.gprs_resend_cnt = 0; 
 
	wl_pDev.base_info.lac = 0; 
	wl_pDev.base_info.ci = 0;	 
} 
 
gsm_proc_req *GSM_GetReq(void) 
{ 
	uint8 i; 
	static uint8 cnt = 0; 
 
	for(i = 0; i < MAX_GSM_REQ_MQ; i++) 
	{ 
		if(gsm_req_info[i].gsm_status_machine == ENUM_WL_MAIN_STATUE_FREE) 
		{ 
			cnt = 0; 
			gsm_req_info[i].gsm_status_machine = 2; 
			return &gsm_req_info[i]; 
		} 
	} 
 
	cnt++; 
	if(cnt > 10) 
	{ 
		cnt = 0; 
		for(i = 0; i < MAX_GSM_REQ_MQ; i++) 
		{ 
			gsm_req_info[i].gsm_status_machine = ENUM_WL_MAIN_STATUE_FREE; 
		} 
		return (&gsm_req_info[0]); 
	} 
	return NULL; 
} 
 
/************************************************************ 
** 
**				GSM_CheckRxStr 
** 
** used to: 等待并检查gsm回码是否包含str字符串,并返回该字符串在回码中所在的位置 
** parameters: 
				str[IN] - 需要检查是否包含的字符串, NULL表示只要等待回码 
				uTimes[IN] - 超时时间,秒 
** return: 返回str字符串在gsm回码中出现的位置, 0xffff表示不含str字符串 
			0xfffe表示返回"ERROR" 
** notes: 
**/ 
uint16 GSM_WaitCheckRxStr (const uint8 *str, uint16 uTimes) 
{ 
	uint8 err, time; 
	uint16 i, j; 
 
	for(time = 0; time < uTimes; time++) 
	{ 
		OSSemPend(WlReceiveDataOver, OS_TICKS_PER_SEC, &err); 
		if(err != OS_ERR_NONE) 
		{ 
			continue; 
		} 
		if(str == NULL) 
		{ 
			return 0; 
		} 
		i = strlen((const sint8 *)str); 
		for(j = 0; j < gsm_buffer.rx_buf_len - i; j++) 
		{ 
			if(0 == memcmp(str, gsm_buffer.rx_buf + j, i)) 
			{ 
				return j; 
			} 
			if(0 == memcmp("ERROR", gsm_buffer.rx_buf + j, i)) 
			{ 
				return 0xfffe; 
			} 
		} 
	} 
	return 0xFFFF; 
} 
 
 
uint8  GSM_DealGprsSend (uint8 link_num, uint8 *buf, uint16 buf_len, uint8 (*abort)(void)) 
{ 
	sint32 len; 
	uint16 k; 
 
	if(buf == NULL || buf_len == 0) 
		return 0; 
#if (GSM_COMMUNICATE_PRINT == 0) 
	kprintf("GPRS Send[%d]:", buf_len); 
	print_asc_buf(buf, buf_len > 128 ? 128 : buf_len); 
#endif 
	len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+QISEND=%d\r", buf_len); 
	gsm_buffer.tx_buf_len = len; 
	GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
	GSM_WaitCheckRxStr(">", 5); 
	GSM_SendData(buf, buf_len); 
	k = GSM_WaitCheckRxStr("SEND OK", 1); 
	if(k < 0xFFFE) 
		return 1; 
	 
	wl_err("GSM_DealGprsSend info: failed[%d]\r\n", wl_pDev.gprs_tx_err); 
	gsm_buffer.tx_buf[0] = GSM_TXESC; 
	gsm_buffer.tx_buf_len = 1; 
	GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
	 
	wl_pDev.gprs_tx_err++; 
	if(wl_pDev.gprs_tx_err > 10) 
	{ 
		GSM_Restart("GPRSTx"); 
	} 
	else if((wl_pDev.gprs_tx_err % 0x03) == 0x00) 
	{ 
		//查询gprs连接状态 
		unsol_req.gsm_status_machine = ENUM_WL_MAIN_STATUE_LINK_ST; 
		OSQPost(gsm_req_event, (void *)&unsol_req); 
	} 
	return 0; 
} 
 
 
/*************************************************************** 
** 
**			GSM_GprsSend 
** 
** used to: 发送gprs数据 
** parameters: 
				link_num[IN] - 连接号,通过该连接号发送数据,只在支持多连接的模块才有效,其他请置0 
				gprs_data[IN] - 待发送的数据 
				gprs_len[IN] - gprs_data的字节长度 
				abort_st[IN] - 当模块状态为本字段的子集时,终止发送 
** notes: abort_st可以为0,表示不终止发送 
** return: 0、1 
**/ 
uint8 GSM_GprsSend (uint8 link_num, uint8 *gprs_data, uint16 gprs_len, uint8 (*abort)(void)) 
{	 
	uint8 err; 
	gsm_proc_req *req; 
 
	if(gprs_data == NULL || gprs_len == 0) 
		return 0; 
	 
	if(wl_pDev.gprs_st != GSM_GPRS_STA_CONNECT_OK || wl_pDev.call_st != 0)	 
		return 0; 
	 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_SEND_TCPDATA; 
	req->req_data = gprs_data; 
	req->req_data_len = gprs_len; 
	req->abort = abort; 
	req->res = 0; 
	req->link_num = link_num; 
	wl_pDev.gprs_resend_cnt++; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, 70 * OS_TICKS_PER_SEC, &err); 
	if(err == OS_ERR_NONE) 
	{ 
		if(req->res == 1 && wl_pDev.gprs_link_type == 1) 
		{ 
			req->link_num = 0; 
			for(gprs_len = 0; gprs_len < 20; gprs_len++) 
			{ 
				OSTimeDly(2 * OS_TICKS_PER_SEC); 
				req->res = 0; 
				req->gsm_status_machine = ENUM_WL_MAIN_STATUE_QUERY_TCPSEND; 
//				req->req_data_len = 0; 
				OSSemSet(WlSendDataOver, 0, &err); 
				OSQPost(gsm_req_event, req); 
 
				OSSemPend(WlSendDataOver, OS_TICKS_PER_SEC, &err); 
				if(err == OS_ERR_NONE && req->res != 0) 
					break; 
			} 
			if(gprs_len >= 20) 
				wl_pDev.gprs_st = GSM_GPRS_STAT_ERR; 
		} 
		err = req->res; 
		GSM_FreeReq(req); 
		wl_pDev.gprs_resend_cnt = (err != 0) ? 0 : wl_pDev.gprs_resend_cnt; 
		return ((err != 0) ? 1 : 0); 
	} 
	GSM_FreeReq(req); 
	return 0; 
} 
 
//对短信内容以PDU格式编码 
uint16 TxPDUSMS_ENCODE(uint8 * dst_buf, uint8 *tb_Buf, uint16 *count,uint8 tb_EncodeLen,uint8 *telephone1) 
{ 
	uint8 j,r; 
	uint16 t,k,i; 
	uint8 tb_ObjBuf[16]; 
	uint8 *gb_TempBuf; 
 
	if(dst_buf == NULL || tb_Buf == NULL || telephone1 == NULL) 
		return 0; 
	 
	gb_TempBuf = dst_buf; 
	for (i=0;i<16;i++) 
	{ 
		if ((wl_pDev.csca_num[i]=='#')||(wl_pDev.csca_num[i]==0)) 
			break; 
		tb_ObjBuf[i]=wl_pDev.csca_num[i]; 
	} 
	 
	if (i&0x01) 
		tb_ObjBuf[i++]='F'; 
	 
	i>>=1; 
	t=0; 
	gb_TempBuf[t++]=Dec2hex[((i+1)>>4)&0x0f]; 
	gb_TempBuf[t++]=Dec2hex[(i+1)&0x0f]; 
	gb_TempBuf[t++]='9'; 
	gb_TempBuf[t++]='1'; 
	 
	for (j=0;j<i;j++) 
	{ 
		gb_TempBuf[t++]=tb_ObjBuf[j*2+1]; 
		gb_TempBuf[t++]=tb_ObjBuf[j*2]; 
	} 
	k=t; 
	 
	for (i=0,r=0;i<16;i++) 
	{ 
        if(i==0&&telephone1[i]=='+') 
			continue; 
		if(telephone1[i]==0) 
		{ 
			break; 
		} 
		tb_ObjBuf[r++]=telephone1[i]; 
	} 
	 
	gb_TempBuf[t++]='1'; 
	gb_TempBuf[t++]='1'; 
	gb_TempBuf[t++]='0'; 
	gb_TempBuf[t++]='0'; 
	gb_TempBuf[t++]=Dec2hex[(r>>4)&0x0f]; 
	gb_TempBuf[t++]=Dec2hex[r&0x0f]; 
 
	#if 1 
	gb_TempBuf[t++]='8'; 
	gb_TempBuf[t++]='1'; 
	#else 
   	gb_TempBuf[t++]='9'; 
	gb_TempBuf[t++]='1'; 
	#endif 
	 
	if (r&0x01) 
	{ 
		tb_ObjBuf[r++]='F'; 
	} 
	for (j=0;j<(r/2);j++) 
	{ 
		gb_TempBuf[t++]=tb_ObjBuf[j*2+1]; 
		gb_TempBuf[t++]=tb_ObjBuf[j*2]; 
	} 
	 
	gb_TempBuf[t++]='0'; 
	gb_TempBuf[t++]='0'; 
	gb_TempBuf[t++]='0'; 
	gb_TempBuf[t++]='8'; 
	gb_TempBuf[t++]='7'; 
	gb_TempBuf[t++]='8'; 
 
    gb_TempBuf[t++]=Dec2hex[((tb_EncodeLen)>>4)&0x0f]; 
	gb_TempBuf[t++]=Dec2hex[(tb_EncodeLen)&0x0f]; 
   
	for (i=0;i<tb_EncodeLen;i++) 
	{ 
	 
		gb_TempBuf[t++]=Dec2hex[((tb_Buf[i])>>4)&0x0f]; 
		gb_TempBuf[t++]=Dec2hex[tb_Buf[i]&0x0f]; 
	} 
	k=t-k; 
	k>>=1; 
	if(count != NULL) 
		*count = k; 
//	gb_TempBuf[t++]=0x1a; 
	return t; 
} 
 
 
/***************************************************** 
** 
**				GSM_DealSMSSend 
** 
** used to: 发送短信 
** parameters: 
				format[IN] - 短信编码格式,GSM_SMS_FORMAT_TEXT或GSM_SMS_FORMAT_PDU 
				phone[IN] - 短信发送的接收号码,字符串类型,以'\0'结尾 
				sms_data[IN] - 短信内容,如果发送编码为GSM_SMS_FORMAT_PDU,将对短信内容加密 
				sms_data_len[IN] - 短信内容的长度,字节 
				abort[IN] - 判断条件,当判断为1时,取消发送 
** return: 0/1 
** notes: 如果编码格式为GSM_SMS_FORMAT_PDU,编码会使用到gsm_buffer.tx_buf 
**/ 
uint8  GSM_DealSMSSend(uint8 format, uint8 *phone, uint8 *sms_data, uint16 sms_data_len, uint8 (*abort)(void)) 
{ 
	uint16 cnt, g_Sms_Encode_Len = 0; 
 
	if(phone == NULL || sms_data == NULL || sms_data_len == 0) 
		return 0; 
	if(format != GSM_SMS_FORMAT_PDU_UCS2 && format != GSM_SMS_FORMAT_TEXT) 
		return 0; 
 
#if (GSM_COMMUNICATE_PRINT == 0) 
	kprintf("SMS Send[%d] to %s:", sms_data_len, phone); 
	print_asc_buf(sms_data, sms_data_len); 
#endif 
	 
	if(format == GSM_SMS_FORMAT_TEXT) 
	{ 
		GSM_SendData("AT+CMGF=1\r\n", 12); 
		GSM_WaitCheckRxStr("OK", 2); 
		GSM_SendData("AT+CSCS=\"GSM\"\r\n", 15); 
		GSM_WaitCheckRxStr("OK", 2); 
		GSM_SendData("AT+CSMP=17,167,0,0\r\n", 20); 
		GSM_WaitCheckRxStr("OK", 4); 
		gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+CMGS=\"%s\"\r\n", phone); 
	} 
	else if(format == GSM_SMS_FORMAT_PDU_UCS2) 
	{ 
 
		memcpy(gsm_buffer.tx_buf, "AT+CMGS=\"", 9); 
		g_Sms_Encode_Len = 9; 
		cnt = 0; 
		if(*phone == '+') 
			cnt++; 
		for(; *(phone + cnt) != '\0'; cnt++) 
		{ 
			gsm_buffer.tx_buf[g_Sms_Encode_Len++] = '0'; 
			gsm_buffer.tx_buf[g_Sms_Encode_Len++] = '0'; 
			gsm_buffer.tx_buf[g_Sms_Encode_Len++] = '3'; 
			gsm_buffer.tx_buf[g_Sms_Encode_Len++] = *(phone + cnt); 
		} 
		gsm_buffer.tx_buf[g_Sms_Encode_Len++] = '"'; 
		gsm_buffer.tx_buf[g_Sms_Encode_Len++] = 0x0d; 
//		gsm_buffer.tx_buf[g_Sms_Encode_Len++] = '\n'; 
 
		gsm_buffer.tx_buf_len = g_Sms_Encode_Len; 
		 
//		g_Sms_Encode_Len = TxPDUSMS_ENCODE(gsm_buffer.tx_buf + 16, sms_data, &cnt, sms_data_len, phone); 
//		gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+CMGS=%02d\r\n", cnt); 
//		gsm_buffer.tx_buf[g_Sms_Encode_Len + 16] = 0x1A; 
//		gsm_buffer.tx_buf[g_Sms_Encode_Len + 17] = 0x0d; 
//		gsm_buffer.tx_buf[g_Sms_Encode_Len + 18] = 0x0a; 
	} 
	else if(format == GSM_SMS_FORMAT_PDU_7BIT) 
	{ 
		GSM_SendData("AT+CMGF=0\r", 10); 
		GSM_WaitCheckRxStr("OK", 2); 
		g_Sms_Encode_Len = TxPDUSMS_ENCODE(gsm_buffer.tx_buf + 16, sms_data, &cnt, sms_data_len, phone); 
		gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+CMGS=%02d\r\n", cnt); 
		gsm_buffer.tx_buf[g_Sms_Encode_Len + 16] = 0x1A; 
		gsm_buffer.tx_buf[g_Sms_Encode_Len + 17] = 0x0d; 
		gsm_buffer.tx_buf[g_Sms_Encode_Len + 18] = 0x0a; 
	} 
	GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
	cnt = GSM_WaitCheckRxStr(">", 4); 
 
	if(format == GSM_SMS_FORMAT_TEXT) 
	{ 
		memcpy(gsm_buffer.tx_buf, sms_data, sms_data_len); 
		gsm_buffer.tx_buf[sms_data_len] = 0x1A; 
		gsm_buffer.tx_buf[sms_data_len + 1] = '\r'; 
		gsm_buffer.tx_buf[sms_data_len + 2] = '\n'; 
		gsm_buffer.tx_buf_len = sms_data_len + 3; 
		GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
	} 
	else if(format == GSM_SMS_FORMAT_PDU_UCS2) 
	{ 
//		GSM_SendData(gsm_buffer.tx_buf + 16, g_Sms_Encode_Len + 3); 
		memcpy(gsm_buffer.tx_buf, sms_data, sms_data_len); 
		gsm_buffer.tx_buf[sms_data_len] = 0x1A; 
		gsm_buffer.tx_buf[sms_data_len + 1] = 0x0d; 
		gsm_buffer.tx_buf[sms_data_len + 2] = 0x0a; 
		GSM_SendData(sms_data, sms_data_len + 3); 
	} 
	else if(format == GSM_SMS_FORMAT_PDU_7BIT) 
	{ 
		GSM_SendData(gsm_buffer.tx_buf + 16, g_Sms_Encode_Len + 3); 
	} 
 
	cnt = GSM_WaitCheckRxStr("+CMGS", 90); 
	if(cnt < 0xFFFE) 
	{ 
		wl_pDev.sms_tx_err = 0; 
		return 1; 
	}	 
 
//SMS_SEND_ERR:	 
	wl_pDev.sms_tx_err++; 
	gsm_buffer.tx_buf[0] = GSM_TXESC; 
	gsm_buffer.tx_buf_len = 1; 
	GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
	if(wl_pDev.sms_tx_err > 20) 
		GSM_Restart("SMSTx"); 
	return 0; 
} 
 
/*********************************************************************************** 
** 
**				GSM_SMSSend 
** 
** used to: 发送短信 
** parameters:	 
				phone[IN] - 发送号码,字符串类型,以'\0'结尾 
				sms_data[IN] - 短信数据 
				sms_data_len[IN] - 短信数据长度 
				abort_st[IN] - 取消发送的判断函数 
** return: 1/0 
** notes: 
**/ 
uint8 GSM_SMSSend (uint8 format, uint8 *phone, uint8 *sms_data, uint16 sms_data_len, uint8 (*abort)(void)) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	if(phone == NULL || sms_data == NULL || sms_data_len == 0) 
		return 0; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
	 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_SEND_SMS; 
	req->req_data = sms_data; 
	req->req_data_len = sms_data_len; 
	req->phone = phone; 
	req->phone_len = strlen((const sint8 *)phone); 
	req->abort = abort; 
	req->sms_format = format; 
	req->res = 0; 
 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, 9500, &err); 
	if(err == OS_ERR_NONE) 
	{ 
		err = req->res; 
		GSM_FreeReq(req); 
		return (err == 1 ? 1 : 0); 
	} 
	GSM_FreeReq(req); 
	return 0; 
} 
 
/************************************************ 
** 
**			GSM_SMSDelete 
** 
** used to: 删除sim保存的短信 
** parameters: 
				index[IN] - 删除序号 
						DELALLSMS -- 删除全部 
						DELREADSMS -- 删除已读短信 
						else -- 删除对应序号的短信 
** return: 1/0 
** notes: 
**/ 
uint8 GSM_SMSDelete (uint8 index) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
	 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUS_DEL_SMS; 
	req->req_data = &index; 
	req->req_data_len = 1; 
	req->res = 0; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, 12 * OS_TICKS_PER_SEC, &err); 
	if(err == OS_ERR_NONE) 
	{ 
		err = req->res; 
		GSM_FreeReq(req); 
		return (err == 1 ? 1 : 0); 
	} 
	GSM_FreeReq(req); 
	return 0; 
} 
 
uint8 GSM_SMSRead(uint8 index, struct _gsm_sms_desc *sms) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
	 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_RECEIVE_SMS; 
	req->req_data = (uint8 *)sms; 
	req->req_data_len = sizeof(struct _gsm_sms_desc); 
	req->link_num = index; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, 6 * OS_TICKS_PER_SEC, &err); 
	if(err == OS_ERR_NONE) 
	{ 
		err = req->res; 
		GSM_FreeReq(req); 
		return (err); 
	} 
	GSM_FreeReq(req); 
	return 0; 
} 
 
uint8 GSM_SMSDealRead(uint8 index, struct _gsm_sms_desc *sms) 
{ 
	uint16 k; 
	uint8 *ptr; 
 
	gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+CMGR=%d\r\n", index); 
	GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
	k = GSM_WaitCheckRxStr("CMGR", 4); 
	if(k >= 0xFFFE) 
		return 0; 
 
	memset(sms, 0, sizeof(struct _gsm_sms_desc)); 
	ptr = strchar_len(gsm_buffer.rx_buf, '\"', 3, gsm_buffer.rx_buf_len, NULL); 
	if(ptr == NULL) 
	{ 
		return 0; 
	} 
	ptr++; 
	for(k = 0; ; k++) 
	{ 
		if(*ptr == '\"')break; 
		sms->tel[k] = *ptr; 
		ptr++; 
	} 
 
	//date-time 
	ptr = strchar_len(gsm_buffer.rx_buf, '\"', 7, gsm_buffer.rx_buf_len, NULL); 
	if(ptr == NULL) 
		return 0; 
	 
	ptr++; 
	sms->date_time[0] = (*(ptr + 2) - '0') * 10 + *(ptr + 3) - '0'; 
	sms->date_time[1] = (*(ptr + 5) - '0') * 10 + *(ptr + 6) - '0'; 
	sms->date_time[2] = (*(ptr + 8) - '0') * 10 + *(ptr + 9) - '0'; 
	sms->date_time[3] = (*(ptr + 11) - '0') * 10 + *(ptr + 12) - '0'; 
	sms->date_time[4] = (*(ptr + 14) - '0') * 10 + *(ptr + 15) - '0'; 
	sms->date_time[5] = (*(ptr + 17) - '0') * 10 + *(ptr + 18) - '0'; 
 
	//content 
	ptr = strchar_len(gsm_buffer.rx_buf, '\"', 8, gsm_buffer.rx_buf_len, NULL); 
	if(ptr == NULL) 
		return 0; 
	ptr++; 
	if(*ptr == 0x0d || *ptr == 0x0A)ptr += 2;	//Omit "\r\n" 
	k = ptr - gsm_buffer.rx_buf; 
	if((k + 8) >= gsm_buffer.rx_buf_len) 
		return 0; 
 
	k = gsm_buffer.rx_buf_len - k - 8; 
	if(k > sizeof(sms->txt)) 
	{ 
		k = sizeof(sms->txt); 
	} 
	memcpy(sms->txt, ptr, k); 
	sms->txt_len = k; 
	return 1; 
} 
 
/*********************************************** 
** 
**			GSM_CallOut 
** 
** used to:  拨打电话 
** parameters: 
				phone[IN] - 电话号码,字符串类型,以'\0'结尾 
				phone_len[IN] - 电话号码长度 
				channel[IN] - 通话通道,0--免提,1-耳麦 
				b_monitor[IN] - 监听状态,1-监听,不开speeker,0-正常通话,speeker和mic打开 
				abort[IN] - 终止拨号的判断函数 
** return: 1/0,2 -- 获取不到GSM资源   //anda 20130709 
** notes: 拨打过程会检查phone数据,将非数字截断 
**/ 
uint8 GSM_CallOut (uint8 *phone, uint8 phone_len, uint8 channel, uint8 mute, uint8 (*abort)(void)) 
{			 
	uint8 err; 
	gsm_proc_req *req; 
 
	if(phone == NULL || phone_len < 2 || wl_pDev.Initial < GSM_INIT_ST_NET) 
		return 0; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
	{ 
        return 2; 
	} 
#if (GSM_COMMUNICATE_PRINT == 0) 
	kprintf("Dial:"); 
	print_asc_buf(phone, phone_len); 
#endif 
 
	err = strlen((const sint8 *)phone); 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_DIAL_PHONE; 
	req->req_data = phone; 
	req->req_data_len = phone_len; 
	req->res = 0; 
	wl_pDev.call_st = 2; 
	wl_pDev.mute_opt = mute; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, 150, &err); 
	err = req->res; 
	if(err == 1) 
	{ 
		if(mute == MUTEON || mute == MUTEOFF_CONVER) 
		{ 
			phone_muteon(); 
		} 
		else 
		{ 
			phone_muteoff(); 
		} 
		phone_sel(); 
	} 
	GSM_FreeReq(req); 
    return  (err==0?2:1); 
} 
 
void  GSM_CallHangUp (void) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	if(wl_pDev.call_st == 0) 
		return; 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return; 
	 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_HANG_UP_PHONE; 
	req->req_data = NULL; 
	req->req_data_len = 0; 
	req->res = 0; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	phone_unsel(); 
	phone_muteon(); 
 
	OSSemPend(WlSendDataOver, 2 * OS_TICKS_PER_SEC, &err); 
	GSM_FreeReq(req); 
} 
 
uint8 GSM_Pickup_Phone(uint8 mute) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	if(wl_pDev.call_st != 1) 
		return 0; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_PICK_UP_PHONE; 
	req->req_data = NULL; 
	req->req_data_len = 0; 
	req->res = 0; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, OS_TICKS_PER_SEC, &err); 
	if(err == OS_ERR_NONE) 
	{ 
		phone_sel(); 
		if(mute == 0) 
		{ 
			phone_muteoff(); 
		} 
		GSM_FreeReq(req); 
		err = req->res; 
		return (err == 1 ? 1 : 0); 
	} 
	GSM_FreeReq(req); 
	return 0; 
} 
	 
 
/****************************************************** 
** 
**			GSM_SetAudioGain 
** 
** used to: 调整模块语音通道的增益 
** parameters: 
				ch[IN] - 语音通道 
				type[IN] - 通道选择 
					0 -- 免提喇叭增益 
					1 -- mic增益 
					2 -- 耳机音量增益 
					else -- 保留 
				lev[IN] - 待调整的值 
** return: 
** notes:  
**/ 
void  GSM_SetAudioGain (uint8 ch, uint8 type, uint8 lev) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return; 
 
	req->gsm_status_machine = (type == 1) ? ENUM_WL_MAIN_STATUE_ADJUST_MIC_VOLUM : ENUM_WL_MAIN_STATUE_ADJUST_SPK_VOLUM; 
	req->req_data = &lev; 
	req->req_data_len = 1; 
	req->res = 0; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, OS_TICKS_PER_SEC * 2, &err); 
	GSM_FreeReq(req); 
} 
 
 
uint8 GSM_SendDTMF (uint8 dtmf) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_SEND_DTMFDATA; 
	req->req_data = &dtmf; 
	req->req_data_len = 1; 
	req->res = 0; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, OS_TICKS_PER_SEC * 2, &err); 
	err = req->res; 
	GSM_FreeReq(req); 
	return (err == 1 ? 1 : 0); 
} 
 
 
void  GSM_GetOperatorInfo (void) 
{ 
	uint8  *prt; 
	uint16 k; 
 
	GSM_SendData("AT+QENG?\r\n", 10); 
	k = GSM_WaitCheckRxStr("QENG", 2); 
	if(k >= 0xfffe) 
		return; 
 
	prt = strchar_len((const uint8 *)gsm_buffer.rx_buf, ':', 2, gsm_buffer.rx_buf_len, NULL); 
	if(prt == NULL) 
		return; 
 
	if(*(prt + 2) != '0') 
		return; 
 
	prt = strchar_char((const SYS_UINT8 *)prt, ',', 1, 0x0A, NULL); 
	if(prt == NULL) 
		return; 
	prt++; 
	wl_pDev.base_info.mcc = simple_atoi((const char *)prt, gsm_buffer.rx_buf_len, ',', NULL); 
 
	prt = strchar_char((const uint8 *)prt, ',', 1, 0x0A, NULL); 
	if(prt == NULL) 
		return; 
	prt++; 
	wl_pDev.base_info.mnc = simple_atoi((const char *)prt, gsm_buffer.rx_buf_len, ',', NULL); 
} 
 
 
//查看网络注册状态 
uint8  GSM_GetNetworkRegs (void) 
{ 
	uint8  *prt; 
	uint16 k; 
 
	GSM_SendData("AT+CREG?\r\n", 10); 
	k = GSM_WaitCheckRxStr("CREG:", 2); 
	if(k >= 0xFFFE) 
		return 0; 
 
	prt = strchar_len((const uint8 *)gsm_buffer.rx_buf, ',', 1, gsm_buffer.rx_buf_len, NULL); 
	if(prt == NULL) 
		return 0; 
	if(*(prt + 1) == '0') 
		return 0; 
 
	prt = strchar_char((const uint8 *)prt, '"', 1, 0x0A, NULL); 
	if(prt == NULL) 
		return 0; 
	prt++; 
//	wl_pDev.base_info.lac = strtoul((const char *)prt, NULL, 16); 
	wl_pDev.base_info.lac = simple_strtoul((const sint8 *)prt, gsm_buffer.rx_buf_len, ',',NULL); 
 
	prt = strchar_char((const uint8 *)prt, '"', 2, 0x0A, NULL); 
	if(prt == NULL) 
		return 0; 
	prt++; 
//	wl_pDev.base_info.ci = strtoul((const char *)prt, NULL, 16); 
	wl_pDev.base_info.ci = simple_strtoul((const sint8 *)prt, gsm_buffer.rx_buf_len, 0, NULL); 
	return 1; 
} 
 
//检测网络状态,包括注册状态,基站信息,信号强度 
void GSMNetworkMonitor(void) 
{ 
	wl_pDev.net_tmr = 20; 
	if(1 == GSM_GetNetworkRegs()) 
	{  
		GSM_GetOperatorInfo(); 
		wl_pDev.gsmNoNetCnt = 0; 
	} 
	else  
	{ 
		GSM_SendData("AT+CREG=2\r\n", 11); 
		GSM_WaitCheckRxStr("OK", 1); 
		wl_pDev.gsmNoNetCnt++; 
		if(wl_pDev.gsmNoNetCnt >= 10) 
			GSM_Restart("NETMoni"); 
	} 
} 
 
//0 -- IP 
//1 -- name 
uint8 GSM_Chk_addr_type(uint8 *addr, uint8 max_len) 
{ 
	uint8 i; 
 
	if(addr == NULL || max_len < 4) 
		return 0xFF; 
	 
	for(i = 0; i < max_len && *addr != '\0'; i++) 
	{ 
		if((*addr > '9' || *addr < '0') && *addr != '.') 
			return 1; 
	} 
	return 0; 
} 
 
/************************************************************* 
** 
**				GSM_DealLink 
** 
** used to: 发送at指令连接gprs网络 
** parameters: 
				net_addr[IN] - 连接的网络地址 
				link_num[IN] - 连接号,用于多支持多连接模块,单连接模块置0 
** return: 1/0 
** notes: 本函数为实际的gprs连接 
**/ 
uint8 GSM_DealLink(net_desc *net_addr, uint8 link_num) 
{ 
	uint16 k; 
	 
	GSM_SendData("AT+QIHEAD=1\r\n", 13); 
	if(0xFFFE <= GSM_WaitCheckRxStr("OK", 2)) 
	{ 
		return 0; 
	} 
 
	GSM_SendData("AT+QIFGCNT=0\r\n", 14); 
	k = GSM_WaitCheckRxStr("OK", 2); 
	if(k >= 0xFFFE) 
	{ 
		return 0; 
	} 
 
	gsm_buffer.tx_buf_len = ksprintf((SYS_INT8 *)gsm_buffer.tx_buf, "AT+QICSGP=1,\"%s\",\"%s\",\"%s\"\r\n", net_addr->apn, net_addr->user_name, net_addr->password); 
	GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
	k = GSM_WaitCheckRxStr("OK", 4); 
	if(k >= 0xFFFE) 
	{ 
		return 0; 
	} 
 
	k = GSM_Chk_addr_type(net_addr->ip, sizeof(net_addr->ip)); 
	if(k == 0) 
		GSM_SendData("AT+QIDNSIP=0\r\n", 14); 
	else 
	{ 
		//Set DNS 
		k = strlen((const SYS_INT8 *)net_addr->dns); 
		if(k > 0) 
		{ 
			gsm_buffer.tx_buf_len = ksprintf((SYS_INT8 *)gsm_buffer.tx_buf, "AT+QIDNSCFG=\"%s\"\r\n", net_addr->dns); 
			GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
			k = GSM_WaitCheckRxStr("OK", 4); 
			if(k >= 0xFFFE) 
			{ 
				return 0; 
			} 
		} 
		GSM_SendData("AT+QIDNSIP=1\r\n", 14); 
	} 
		 
	k = GSM_WaitCheckRxStr("OK", 2); 
	if(k >= 0xFFFE) 
	{ 
		return 0; 
	} 
 
	//link 
	gsm_buffer.tx_buf_len = ksprintf((SYS_INT8 *)gsm_buffer.tx_buf, "AT+QIOPEN=\"%s\",\"%s\",\"%d\"\r\n", net_addr->type == 1 ? "TCP" : "UDP",  
																								net_addr->ip, net_addr->remoteport); 
 
	GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
	GSM_WaitCheckRxStr(NULL, 1); 
	wl_pDev.gprs_link_type = net_addr->type; 
#if (GSM_COMMUNICATE_PRINT == 0) 
	kprintf("Connect:%s:%d\r\n", net_addr->ip, net_addr->remoteport); 
#endif 
	return 1; 
} 
 
 
/******************************************************* 
** 
**			GSM_Open_NetConnect 
** 
** used to: 打开或关闭网络连接 
** parameters: 
				b_connect[IN] - 0,关闭网络连接,1-打开网络连接 
				link_num[IN] - 连接号,用于支持多连接的模块 
				net_addr[IN]-网络连接参数 
** return: 
**/ 
uint8 GSM_Open_NetConnect(uint8 b_connect, uint8 link_num, net_desc *net_addr) 
{ 
	uint8 err, tmr_out; 
	gsm_proc_req *req; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
	 
	if(b_connect == 0) 
	{ 
		//关闭网络连接 
		req->gsm_status_machine = ENUM_WL_MAIN_STATUE_IP_CLOSE; 
		req->req_data = NULL; 
		req->req_data_len = 0; 
		req->res = 0; 
		tmr_out = 60; 
	} 
	else if(net_addr != NULL) 
	{ 
		//连接网络服务器 
		if(wl_pDev.gprs_st == GSM_GPRS_STA_CONNECTING || wl_pDev.gprs_st == GSM_GPRS_STA_CONNECT_OK) 
		{ 
			GSM_FreeReq(req); 
			return 1; 
		} 
		req->gsm_status_machine = ENUM_WL_MAIN_STATUE_IP_LOGIN_IN; 
		req->net_addr = net_addr; 
		req->res = 0; 
		tmr_out = 4; 
	} 
	else 
	{ 
		GSM_FreeReq(req); 
		return 0; 
	} 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, tmr_out * OS_TICKS_PER_SEC, &err); 
	if(err == OS_ERR_NONE) 
	{ 
		err = req->res; 
		GSM_FreeReq(req); 
		return (err == 1 ? 1 : 0); 
	} 
	GSM_FreeReq(req); 
	return 0; 
} 
 
/************************************************************** 
** 
**				GSM_Set_Num 
** 
** used to: 设置本机号码 
** parameters: 
				type[IN] - 要设置的号码类型 
				simnum[IN] - sim卡号 
				len[IN] - 卡号长度 
** return: SYS_TRUE/SYS_FALSE 
**/ 
uint8 GSM_Set_Num(uint8 type, uint8 *num, uint8 len) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
 
	switch(type) 
	{ 
		case 1: 
			req->gsm_status_machine = ENUM_WL_MAIN_STATUE_SET_SIMNUM; 
			break; 
 
	       case 2: 
			req->gsm_status_machine = ENUM_WL_MAIN_STATUE_SET_CSCANUM; 
		 	break; 
 
		case 3: 
			req->gsm_status_machine = ENUM_WL_MAIN_STATUE_SET_CALL_RESTRICT; 
		 	break; 
 
		case 4: 
			req->gsm_status_machine = ENUM_WL_MAIN_STATUE_CHECK_CALL_RESTRICT; 
		 	break; 
 
		default: 
			GSM_FreeReq(req); 
			return 0; 
	} 
 
	req->req_data = num; 
	req->req_data_len = len; 
	req->res = 0; 
 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, OS_TICKS_PER_SEC * 5, &err); 
	if(err == OS_ERR_NONE) 
	{ 
		err = req->res; 
		GSM_FreeReq(req); 
		return (err == 1 ? 1 : 0); 
	} 
	GSM_FreeReq(req); 
	return 1; 
} 
 
//切换频段 
// 参数 
//		mode[IN] - 频段选择 
//			0=ALL_BAND 
//			1=PGSM_MODE(900) 
//			2=DCS_MODE(1800) 
//			3=PCS_MODE(1900) 
//			4=EGSM_DCS_MODE(900 extend) 
//			5=GSM850_PCS_MODE(850) 
uint8 GSM_SW_Mode(uint8 mode) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
	 
	req->link_num = mode; 
	req->res = 0; 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_BAND_SW; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, OS_TICKS_PER_SEC * 22, &err); 
	if(err == OS_ERR_NONE) 
	{ 
		err = req->res; 
		GSM_FreeReq(req); 
		return (err == 1 ? 1 : 0); 
	} 
	GSM_FreeReq(req); 
	return 1; 
} 
 
 
 
/***************************************************** 
** 
**				GSM_QueryLinkST 
** 
** used to: 查询网络连接状态 
** parameters: 
				link_num[IN] -  连接号,用于支持多连接的模块 
** return:GSM_GPRS_STAT_xxx 
**/ 
uint8 GSM_QueryLinkST(uint8 link_num) 
{ 
	return (((wl_pDev.gprs_st == GSM_GPRS_STA_CONNECT_OK) && (wl_pDev.call_st == 0)) ? 1 : 0); 
} 
 
/****************************************************** 
** 
**				GSM_UCR_Ctl 
** 
** used to: 使能/关闭gsm模块ucr上报 
**/ 
uint8 GSM_UCR_Ctl(uint8 ctl, uint16 ucr_type, uint32 option) 
{ 
	uint8 err; 
	gsm_proc_req *req; 
 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_UCR_CTL; 
	req->link_num = ctl; 
	req->req_data_len = ucr_type; 
	req->res = 0; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
 
	OSSemPend(WlSendDataOver, OS_TICKS_PER_SEC, &err); 
	err = req->res; 
	GSM_FreeReq(req); 
	return 1; 
} 
 
void GSM_Query_CallST(void) 
{ 
	uint16 k; 
 
	if(wl_pDev.call_st == 0) 
		return; 
	GSM_SendData("AT+CLCC\r\n", 9); 
	k = GSM_WaitCheckRxStr("CLCC", 1); 
	if(k >= 0xFFFE) 
	{ 
		GSM_SendData("ATH0\r\n", 6); 
		GSM_WaitCheckRxStr("OK", 1); 
		wl_pDev.call_st = 0; 
	} 
} 
 
//手动发送AT指令 
uint8 GSM_Manu_AT(uint8 *data, uint16 len) 
{ 
	gsm_proc_req *req; 
	uint8 err; 
 
	if(data == NULL) 
		return 0; 
	req = GSM_GetReq(); 
	if(req == NULL) 
		return 0; 
	 
	req->gsm_status_machine = ENUM_WL_MAIN_STATUE_MANU_AT; 
	req->req_data = data; 
	req->req_data_len = len; 
	OSSemSet(WlSendDataOver, 0, &err); 
	OSQPost(gsm_req_event, (void *)req); 
	 
	OSSemPend(WlSendDataOver, OS_TICKS_PER_SEC, &err); 
	GSM_FreeReq(req); 
	return 1; 
} 
 
//判断gsm的应答数据,判断是否gsm模块主动上发的数据,在systick中断中调用 
//gsm主动上发的数据包括 
//		1、"RING" -- 有电话呼入 
//		2、"NO CARRIER" -- 电话无人接听 
//		3、"+IPD," -- 收到gprs数据 
//		4、"+CMTI"--新的短信 
//		5、"+CREG"--gprs连接出错 
//		6、"COLP"--电话接通 
uint8 GSM_PreCheck(void) 
{ 
	uint16  k, idx; 
	uint8  *ptr; 
 
	ptr = gsm_buffer.rx_buf; 
	for(k = gsm_buffer.pre_index; k < gsm_buffer.rx_buf_len; k++, ptr++) 
    {     
ECHO_CHECK: 
		 
		if(0 == memcmp(ptr, "IPD", 3)) 
		{ 
			ptr += 3; 
			k += 3; 
			gsm_buffer.pre_index += 3; 
			idx = simple_atoi((const sint8 *)ptr, gsm_buffer.rx_buf_len - k, ' ', NULL); 
			for(; k < gsm_buffer.rx_buf_len; k++, ptr++) 
			{ 
				if(*ptr == ':') 
				{ 
					uint16 len; 
					 
					ptr++; 
					k++; 
					len = (WL_MAX_TCP_BUFFER - gsm_unsol_record.gprs_len) > idx ? idx : (WL_MAX_TCP_BUFFER - gsm_unsol_record.gprs_len); 
					memcpy(&gsm_unsol_record.gprs_data[gsm_unsol_record.gprs_len], ptr, len); 
					ptr += idx; 
					k += idx; 
					gsm_buffer.pre_index += idx; 
					gsm_unsol_record.gprs_len += len; 
					gsm_unsol_record.unsol_stat |= GPRS_DATA_IN; 
					goto ECHO_CHECK; 
				} 
			} 
		} 
 
		if(0 == memcmp(ptr, "BUSY", 4))	//电话忙音 
		{ 
			wl_pDev.call_st = 0; 
			wl_pDev.ring_cnt = 0; 
			ptr += 4; 
			k += 4; 
			gsm_unsol_record.unsol_stat |= CALL_ST_NO_ANSWER; 
			phone_muteon(); 
//			continue; 
		} 
 
		if(0 == memcmp(ptr, "CLOSED", 6))		//模块主动掉线,查询并重连 
		{ 
			wl_pDev.gprs_tmr = 0; 
			ptr += 6; 
			k += 6; 
			wl_pDev.gprs_st = GSM_GPRS_STAT_NO_LINK; 
//			continue; 
		} 
 
		if(0 == memcmp(ptr, "+CMTI", 5))//新的短信息 
		{ 
			uint8 *temp; 
 
			temp = strchar_len(ptr, '\"', 2, gsm_buffer.rx_buf_len - k, NULL); 
			if(temp != NULL) 
			{ 
				temp += 2; 
				idx = simple_atoi((const sint8 *)temp, gsm_buffer.rx_buf_len - k, ' ', NULL); 
				if(gsm_unsol_record.sms_index[0] == 0xFF) 
					gsm_unsol_record.sms_index[0] = idx; 
				else if(gsm_unsol_record.sms_index[1] == 0xFF) 
					gsm_unsol_record.sms_index[1] = idx; 
				else 
					gsm_unsol_record.sms_index[2] = idx; 
				gsm_unsol_record.unsol_stat |= SMS_DATA_IN; 
			} 
			ptr += 5; 
			k += 5; 
		} 
 
		if(0 == memcmp(ptr, "+COLP", 5))	//电话接通 
		{ 
			gsm_unsol_record.unsol_stat |= CALL_ST_CONN; 
			wl_pDev.call_st = 3; 
			wl_pDev.ring_cnt = 0; 
			ptr += 5; 
			k += 5; 
			if(wl_pDev.mute_opt == MUTEOFF_CONVER) 
				phone_muteoff(); 
		} 
		 
		if(0 == memcmp(ptr, "CARR", 4))//电话对方挂断 
		{ 
			gsm_unsol_record.unsol_stat |= (wl_pDev.call_st == 3) ? CALL_ST_NO_CARR : CALL_ST_NO_ANSWER; 
			gsm_unsol_record.unsol_stat &= ~(CALL_ST_IN | CALL_ST_CONN); 
			wl_pDev.call_st = 0; 
			wl_pDev.ring_cnt = 0; 
			ptr += 4; 
			k += 4; 
			phone_muteon(); 
		} 
		 
		if(0 == memcmp(ptr, "ANSWER", 6))//电话无人接听,要发送"ATH"指令 
		{ 
			unsol_req.gsm_status_machine = ENUM_WL_MAIN_STATUE_HANG_UP_PHONE; 
			OSQPost(gsm_req_event, (void *)&unsol_req); 
			gsm_unsol_record.unsol_stat |= CALL_ST_NO_ANSWER; 
			ptr += 6; 
			k += 6; 
			phone_muteon(); 
		} 
 
		if(0 == memcmp(ptr, "+CLIP", 5))//电话呼入 
		{ 
			k += 5; 
			ptr += 5; 
			for(; k < gsm_buffer.rx_buf_len; k++, ptr++) 
			{ 
				if(*ptr == '"') 
				{ 
		            ptr++;	 
					k++; 
					memset(gsm_unsol_record.phone_data, 0, MAX_PHONE_LEN); 
					for(idx = 0; *ptr != '"'; ptr++, k++) 
					{ 
						gsm_unsol_record.phone_data[idx] = *ptr; 
						idx++; 
					} 
					gsm_unsol_record.phone_len = idx; 
					if(wl_pDev.call_st != 1) 
						gsm_unsol_record.unsol_stat |= CALL_ST_IN; 
		             
					wl_pDev.call_st = 1; 
					wl_pDev.ring_cnt++; 
					phone_sel(); 
					break; 
				} 
			} 
		} 
 
		//AT+QLJDC: GSM干扰 
		//AT+QJDR: +QJDR: JAMMED 
		if(0 == memcmp(ptr, "+QLJDR", 6) || (0 == memcmp(ptr, "JAMMED", 6))) 
		{ 
			gsm_unsol_record.unsol_stat |= GSM_JAM; 
			ptr += 6; 
			k += 6; 
		} 
 
		//AT+QLDR: GSM干扰解除 
		if(0 == memcmp(ptr, "JAMMING", 7)) 
		{ 
			gsm_unsol_record.unsol_stat |= GSM_JAM_RM; 
			ptr += 7; 
			k += 7; 
		} 
	} 
	return 0; 
} 
 
/************************************************ 
** 
**			GSM_Restart 
** 
** used to: 重启无线模块 
** parameters: 
				level[IN] - 重启选项 
					level=0: 热启动,不发关机时序,不关断电源,只是用at指令集复位并重新初始化模块 
					level=1: 温启动,发关机时序,再发开机时序,并初始化模块 
					level=2: 冷启动,关闭模块电源,再打开电源,发开机时序,并初始化 
** notes: 函数只是启动模块的重启流程,函数退出时模块的初始化没有完成,代码要检测wl_pDev.Initial来判断重启的进度 
		  目前只支持冷启动,即level=2 
**/ 
void GSM_Restart(uint8 *src) 
{ 
	if(src != NULL) 
		wl_err("GSM restart %s...\r\n", src); 
	GSM_ParaReset(); 
	unsol_req.gsm_status_machine = ENUM_WL_MAIN_STATUE_POWER_DOWN; 
	OSQPost(gsm_req_event, (void *)&unsol_req); 
} 
 
 
/************************************************ 
** 
**			gsm_enter_sleep 
** 
** used to: 模块进入休眠省电模式 
** parameters: 
**		option[IN] - 选项 
				bit[0] - 关闭模块电源 
				else - 保留 
** notes: 
**/ 
void gsm_enter_sleep(uint8 option) 
{ 
	uint8 i; 
 
	if(wl_pDev.gprs_st == GSM_GPRS_STA_CONNECTING || wl_pDev.gprs_st == GSM_GPRS_STA_CONNECT_OK) 
	{ 
		GSM_Open_NetConnect(0, 0, NULL); 
	} 
 
	OSTaskSuspend(WL0_PRIO); 
//	OSTaskSuspend(WL1_PRIO); 
	dtr_high(); 
 
	if(option & 1) 
	{ 
		gsm_pwr_off(); 
		kprintf("gsm: enter sleep, pwr-off\r\n"); 
	} 
 
	for(i = 0; i < MAX_GSM_REQ_MQ; i++) 
		gsm_req_info[i].gsm_status_machine = ENUM_WL_MAIN_STATUE_FREE; 
	unsol_req.gsm_status_machine = ENUM_WL_MAIN_STATUE_FREE; 
} 
 
/******************************************** 
** 
**			gsm_exit_sleep 
** 
** used to: 退出省电模式 
** parameters: 
		option[IN] - 选项 
			bit[0] - 打开模块电源 
** notes: 
**/ 
void gsm_exit_sleep(uint8 option) 
{ 
	if((option & 1) || (wl_pDev.Initial <= 2)) 
	{ 
	/* 
		for(option = 0; option < MAX_GSM_REQ_MQ; option++) 
			gsm_req_info[option].gsm_status_machine = ENUM_WL_MAIN_STATUE_FREE; 
		unsol_req.gsm_status_machine = ENUM_WL_MAIN_STATUE_FREE; 
		*/ 
		GSM_Restart("WKP"); 
		kprintf("gsm: exit sleep, pwr-on\r\n"); 
	} 
	dtr_low(); 
	OSTaskResume(WL0_PRIO); 
	OSTaskResume(WL1_PRIO); 
} 
 
void gsm_pwroff(void) 
{ 
	OSTaskSuspend(WL0_PRIO); 
	OSTaskSuspend(WL1_PRIO); 
	gsm_pwr_off(); 
} 
 
 
static void gsm_module_process(gsm_proc_req *req_info) 
{ 
	uint8 ret, value; 
	uint8 aa, bb; 
	uint16 k=0; 
	sint32 len; 
	uint8 *prt; 
 
	switch (wl_pDev.gsmStateMachine) 
	{ 
		case ENUM_WL_MAIN_STATUE_POWER_DOWN: 
			gsm_pwr_off(); 
			OSTimeDly(2 * OS_TICKS_PER_SEC); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_SHUT_DOWN; 
			break; 
			 
		case ENUM_WL_MAIN_STATUE_SHUT_DOWN:	// wl module is closed. 
			GSM_ParaReset(); 
			gsm_pwr_on(); 
			dtr_low(); 
			pwr_key_low(); 
			OSTimeDly(3 * OS_TICKS_PER_SEC); 
			pwr_key_high(); 
			wl_pDev.Initial = 1; 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_POWER_UP; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_POWER_UP: 
			GSM_SendData("AT\r\n", 4); 
			k = GSM_WaitCheckRxStr("OK", 2); 
			if(k < 0xfffE) 
			{ 
				//查询模块版本号 
				wl_pDev.err_cnt = 0; 
				GSM_SendData("AT+GMR\r\n", 8); 
				GSM_WaitCheckRxStr("Revision:", 2); 
				wl_pDev.Initial = GSM_INIT_ST_ATRDY; 
				wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_POWER_UP_INIT; 
				wl_pDev.err_cnt = 0; 
			} 
			else 
			{ 
				//接收超时或接收错误,重试 
				wl_pDev.err_cnt++; 
				if(wl_pDev.err_cnt > 10) 
					wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_POWER_DOWN; 
			} 
			break; 
 
		case ENUM_WL_MAIN_STATUE_POWER_UP_INIT: 
			aa = 0; 
			do 
			{ 
				prt = (uint8 *)gsm_init_m35[aa] ; 
				if(NULL != prt) 
				{	  	 
					GSM_SendData(prt, strlen((const sint8 *)prt)); 
					GSM_WaitCheckRxStr(NULL, 3); 
					aa++; 
				} 
			}while(NULL != prt); 
			wl_pDev.err_cnt = 0; 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_GET_IMEI; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_GET_IMEI: 
			ret = 0; 
			GSM_SendData("AT+GSN\x0d", 7); 
			k = GSM_WaitCheckRxStr("OK", 1); 
			if(k < 0xfffe) 
			{ 
				memset(wl_pDev.devIdTab, 0, MAX_PHONE_LEN); 
				prt = gsm_buffer.rx_buf; 
				for(aa = 0; aa < gsm_buffer.rx_buf_len; aa++, prt++) 
				{ 
					if(*prt >= '0' && *prt <= '9') 
					{ 
						bb = digit_len(prt, MAX_PHONE_LEN); 
						memcpy(wl_pDev.devIdTab, prt, bb); 
						wl_pDev.devIdLen = bb; 
						aa = gsm_buffer.rx_buf_len; 
						wl_pDev.Initial = GSM_INIT_ST_IMEI; 
						wl_pDev.err_cnt = 0; 
					} 
				}//for 
				wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_GET_CNUM; 
			}//if(k < 0xfffe) 
			break; 
/* 
		case ENUM_WL_MAIN_STATUE_POWER_SIMCARD_CHK: 
			GSM_SendData("AT+QSIMSTAT?\r", 13); 
			ret = 0; 
			k = GSM_WaitCheckRxStr("+QSIMSTAT", 2); 
			if(k < 0xFFFE) 
			{ 
				for(; k < gsm_buffer.rx_buf_len; k++) 
				{ 
					if(gsm_buffer.rx_buf[k] == ',') 
					{ 
						ret = gsm_buffer.rx_buf[k + 1] - '0'; 
						k = gsm_buffer.rx_buf_len; 
						if(ret == 1) 
						{ 
							wl_pDev.err_cnt = 0; 
							wl_pDev.SIMCard = 1; 
						} 
						wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_GET_CSCA; 
					} 
				} 
			} 
			if(ret == 0) 
			{ 
				wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_POWER_SIMCARD_CHK; 
				wl_pDev.err_cnt++; 
				if(wl_pDev.err_cnt > 10) 
				{ 
					wl_pDev.err_cnt = 0; 
					GSM_Restart(2); 
				} 
			} 
			break; 
 
		case ENUM_WL_MAIN_STATUE_GET_CSCA: 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_GET_CNUM; 
			GSM_SendData("AT+CSCA?\x0d", 9); 
			k = GSM_WaitCheckRxStr("+CSCA", 2); 
			ret = 0; 
			if(k < 0xFFFE) 
			{ 
				for(; k < gsm_buffer.rx_buf_len; k++) 
				{ 
					if(gsm_buffer.rx_buf[k] == '"') 
					{ 
						k++; 
						memset(wl_pDev.csca_num, 0, MAX_PHONE_LEN); 
						aa = 0; 
						for(; k < gsm_buffer.rx_buf_len; k++) 
						{ 
							if(gsm_buffer.rx_buf[k] == '"') 
							{ 
								wl_pDev.csca_num[aa] = '\0'; 
								k = gsm_buffer.rx_buf_len; 
								wl_pDev.err_cnt = 0; 
								ret = 1; 
								wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_GET_CNUM;//ENUM_WL_MAIN_STATUE_NORMAL 
								wl_pDev.Initial = GSM_INIT_ST_SMS; 
								kprintf("CSCA:%s\r\n", wl_pDev.csca_num); 
								return; 
							} 
							if(gsm_buffer.rx_buf[k] != '+') 
								wl_pDev.csca_num[aa] = gsm_buffer.rx_buf[k]; 
							else 
								aa++; 
						} 
					} 
				}//for 
			}//if(k != 0xFFFF) 
			if(ret == 0) 
			{ 
				wl_pDev.err_cnt++; 
				wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_GET_CSCA; 
				if(wl_pDev.err_cnt > 30) 
				{ 
					wl_pDev.err_cnt = 0; 
					GSM_Restart(2); 
				} 
			} 
			break; 
			*/ 
 
		case ENUM_WL_MAIN_STATUE_GET_CNUM: 
			//初始化完成,开放无线的应用请求 
			gsm_req_info[0].gsm_status_machine = ENUM_WL_MAIN_STATUE_NET_QUERY; 
			gsm_req_info[0].req_data_len = 0; 
			wl_pDev.net_query_cnt = 0; 
			OSQPost(gsm_req_event, &gsm_req_info[0]); 
			for(aa = 1; aa < MAX_GSM_REQ_MQ; aa++) 
			{ 
				gsm_req_info[aa].gsm_status_machine = ENUM_WL_MAIN_STATUE_FREE; 
			} 
			/* 
			GSM_SendData("AT+CNUM\r", 9); 
			k = GSM_WaitCheckRxStr("+CNUM:", 3); 
			wl_pDev.SIMCard = (k < 0xFFFE) ? 1 : 0; 
			if(k < 0xFFFE) 
			{ 
				wl_pDev.SIMCard = 1; 
				for(; k < gsm_buffer.rx_buf_len; k++) 
				{ 
					if(gsm_buffer.rx_buf[k] == ',') 
					{ 
						k += 2; 
						memset(wl_pDev.SimNum, 0, sizeof(wl_pDev.SimNum)); 
						for(aa = 0; aa < sizeof(wl_pDev.SimNum); aa++) 
						{ 
							if(gsm_buffer.rx_buf[k] == '\"') 
							{ 
								return; 
							} 
							wl_pDev.SimNum[aa] = gsm_buffer.rx_buf[k]; 
							k++; 
						} 
					} 
				} 
			} 
			*/ 
			wl_pDev.Initial = GSM_INIT_ST_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_NET_QUERY: 
			if(req_info != NULL) 
			{ 
				GSM_SendData("AT+CGATT?\r", 10); 
				k = GSM_WaitCheckRxStr("CGATT:", 6); 
				if(k >= 0xFFFE) 
				{ 
					wl_pDev.net_query_cnt += 5; 
					if(wl_pDev.net_query_cnt > 15) 
					{ 
						GSM_Restart("CGATT"); 
						wl_pDev.net_query_cnt = 0; 
					} 
					else 
						OSQPost(gsm_req_event, req_info); 
				} 
				else 
				{ 
					k += 7; 
					ret = gsm_buffer.rx_buf[k] - '0'; 
					if(ret == 1 || wl_pDev.net_query_cnt > 10) 
					{ 
						wl_pDev.Initial = GSM_INIT_ST_NET; 
						wl_pDev.net_query_cnt = 0; 
						wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
						GSM_FreeReq(req_info); 
					} 
					else 
					{ 
						wl_pDev.net_query_cnt++; 
						OSQPost(gsm_req_event, req_info); 
					} 
				} 
			} 
			OSTimeDly(OS_TICKS_PER_SEC * 2); 
			break; 
 
		case ENUM_WL_MAIN_STATUE_IP_LOGIN_IN: 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			if(req_info != NULL) 
			{ 
				wl_pDev.gprs_st = GSM_GPRS_STA_CONNECTING; 
				ret = GSM_DealLink(req_info->net_addr, req_info->link_num); 
				req_info->res = (ret == 1) ? 1 : 0; 
				wl_pDev.gprs_tmr = 6; 
				wl_pDev.gprs_tx_err = 0; 
				wl_pDev.gprs_relink_cnt++; 
			} 
			OSSemPost(WlSendDataOver); 
			break; 
 
		//模块初始化完成后在normal状态下维护,内容包括查询信号强度,检查gprs连接状态, 
		//检查网络注册状态,当网络出问题后,自动重启模块 
		case ENUM_WL_MAIN_STATUE_NORMAL: 
			if(wl_pDev.gprs_tx_err > 20 || wl_pDev.err_cnt> 10) 
			{ 
				GSM_Restart("Err"); 
				return; 
			} 
 
			wl_pDev.csq_tmr++; 
			if(wl_pDev.csq_tmr >= 20) 
			{ 
				wl_pDev.csq_tmr = 0; 
				GSM_SendData("AT+CSQ\x0d", 7);  
				k = GSM_WaitCheckRxStr("+CSQ: ", 3); 
				if(0xFFFE > k) 
				{ 
					prt = gsm_buffer.rx_buf + k + 6; 
					wl_pDev.csq = simple_atoi((const sint8 *)prt, gsm_buffer.rx_buf_len - k - 6, ' ', NULL); 
					wl_pDev.err_cnt = 0; 
				} 
				else 
				{ 
					wl_pDev.err_cnt++; 
				} 
				GSM_Query_CallST(); 
			} 
			 
			if(wl_pDev.Initial >= GSM_INIT_ST_NORMAL && wl_pDev.gprs_st > GSM_GPRS_STAT_NO_LINK) 
			{ 
				//检查gprs连接状态 
				if(wl_pDev.gprs_tmr != 0) 
				{ 
					wl_pDev.gprs_tmr--; 
				} 
				else//只在有网络连接的情况下才查询网络状态 
				{ 
					wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_LINK_ST; 
					return; 
				} 
			} 
			/* 
			if(wl_pDev.net_tmr != 0) 
				wl_pDev.net_tmr--; 
			else 
				GSMNetworkMonitor(); 
				*/ 
			break; 
 
		case ENUM_WL_MAIN_STATUE_LINK_ST:	//检测gprs连接状态 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			GSM_SendData("AT+QISTAT\x0d", 10); 
			wl_pDev.Initial = GSM_INIT_ST_NET; 
			k = GSM_WaitCheckRxStr("STATE:", 3); 
			if(0xFFFE > k) 
			{ 
				k += 7; 
				if(0 == memcmp(&gsm_buffer.rx_buf[k], "CONNECT OK", 10)) 
				{ 
					wl_pDev.gprs_link_cnt = 0; 
					wl_pDev.gprs_st = GSM_GPRS_STA_CONNECT_OK; 
					wl_pDev.gprs_tmr = 180; 
					wl_pDev.Initial = GSM_INIT_ST_NET; 
					wl_pDev.gprs_relink_cnt = 0; 
				} 
				else 
				{ 
					if(0 == memcmp(&gsm_buffer.rx_buf[k], "TCP CONNECTING", 14)) 
					{ 
						wl_pDev.gprs_st = GSM_GPRS_STA_CONNECTING; 
						wl_pDev.gprs_link_cnt++; 
					} 
					else if(0 == memcmp(&gsm_buffer.rx_buf[k], "UDP CONNECTING", 14)) 
					{ 
						wl_pDev.gprs_st = GSM_GPRS_STA_CONNECTING; 
						wl_pDev.gprs_link_cnt++; 
					} 
					else if(0 == memcmp(&gsm_buffer.rx_buf[k], "IP IND", 6)) 
					{ 
						wl_pDev.gprs_st = GSM_GPRS_STA_CONNECTING; 
						wl_pDev.gprs_link_cnt++; 
					} 
					else if(0 == memcmp(&gsm_buffer.rx_buf[k], "IP STATUS", 9)) 
					{ 
						wl_pDev.gprs_st = GSM_GPRS_STA_CONNECTING; 
						wl_pDev.gprs_link_cnt++; 
					} 
					else 
					{ 
						wl_pDev.gprs_link_cnt += 4; 
						wl_pDev.gprs_st = GSM_GPRS_STAT_ERR; 
					} 
					if(wl_pDev.gprs_relink_cnt > 5) 
					{ 
						GSM_Restart("LinkOut"); 
						wl_pDev.Initial = 0; 
						wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_POWER_DOWN; 
					} 
					 
					if(((wl_pDev.gprs_link_cnt % 6) == 0) && (wl_pDev.gprs_link_cnt != 0)) 
					{ 
						//更换服务器重连 
						wl_pDev.gprs_st = GSM_GPRS_STAT_NO_LINK; 
					} 
				} 
				wl_pDev.gprs_tmr = (wl_pDev.gprs_st == GSM_GPRS_STA_CONNECT_OK ? 180 : 10); 
			} 
			else 
			{ 
				wl_pDev.gprs_link_cnt += 4; 
				wl_pDev.gprs_tmr = 10; 
				if(wl_pDev.gprs_link_cnt > 12)GSM_Restart("QISTATErr"); 
			} 
			break; 
 
	 
		case ENUM_WL_MAIN_STATUS_DEL_SMS: 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			if(req_info != NULL) 
			{ 
				req_info->res = 0; 
				if(DELALLSMS == *req_info->req_data) 
				{ 
					GSM_SendData("AT+QMGDA=\"DEL ALL\"\r", 20); 
				} 
				else if(DELREADSMS == *req_info->req_data) 
				{ 
					GSM_SendData("AT+QMGDA=\"DEL READ\"\r", 21); 
				}   			 
				else	 
				{		 
					gsm_buffer.tx_buf_len = ksprintf((SYS_INT8 *)gsm_buffer.tx_buf, "AT+CMGD=%d\r\n", *req_info->req_data); 
					GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
				} 
				 
				//收到短信删除回复 
				k = GSM_WaitCheckRxStr("OK", 10); 
				req_info->res = (k >= 0xFFFE) ? 0 : 1; 
				OSSemPost(WlSendDataOver); 
			}//if(req_info != NULL) 
			break;		 
 
		case ENUM_WL_MAIN_STATUE_SEND_SMS: 
			if(req_info != NULL) 
			{ 
				ret = GSM_DealSMSSend(req_info->sms_format, req_info->phone, req_info->req_data, req_info->req_data_len, req_info->abort); 
				req_info->res = ret; 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_RECEIVE_SMS: 
			if(req_info != NULL) 
			{ 
				if(req_info->req_data != NULL && req_info->req_data_len == sizeof(struct _gsm_sms_desc)) 
				{ 
					req_info->res = GSM_SMSDealRead(req_info->link_num, (struct _gsm_sms_desc *)req_info->req_data); 
				} 
			}//if(req_info != NULL) 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_DIAL_PHONE: 
			if(req_info != NULL) 
			{ 
				prt = gsm_buffer.tx_buf; 
				strcpy((sint8 *)prt, "ATD"); 
				prt += 3; 
				memcpy(prt, req_info->req_data, req_info->req_data_len); 
				prt += req_info->req_data_len; 
				*prt++ = ';'; 
				*prt++ = '\r'; 
//				*prt++ = '\n'; 
				gsm_buffer.tx_buf_len = prt - gsm_buffer.tx_buf; 
	    
				GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
				wl_pDev.call_st = 2; 
				req_info->res = 1; 
				k = GSM_WaitCheckRxStr("CME", 1); 
				if(k < 0xfffe) 
				{ 
					wl_pDev.call_st = 0; 
					req_info->res = 0; 
				} 
				OSSemPost(WlSendDataOver); 
			} 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case  ENUM_WL_MAIN_STATUE_PICK_UP_PHONE: 
			if(req_info != NULL) 
			{ 
				GSM_SendData("ATA\x0d", 4); 
				req_info->res = 0; 
		        if(0xfffe > GSM_WaitCheckRxStr("OK", 2)) 
				{ 
					req_info->res = 1; 
				} 
				wl_pDev.call_st = 3; 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_HANG_UP_PHONE: 
			if(req_info != NULL) 
			{ 
				req_info->res = 0; 
				GSM_SendData("ATH0\r", 5); 
				if(0xFFFE > GSM_WaitCheckRxStr("OK", 4)) 
				{ 
					req_info->res = 1; 
				} 
				wl_pDev.call_st = 0; 
				wl_pDev.ring_cnt = 0; 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_UCR_CTL: 
			if(req_info != NULL) 
			{ 
				if(req_info->link_num == 0) 
					GSM_SendData("AT+CREG=0\r\n", 11); 
				else 
					GSM_SendData("AT+CREG=2\r\n", 11); 
				GSM_WaitCheckRxStr("OK", 1); 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_MANU_AT: 
			if(req_info != NULL) 
			{ 
				memcpy(gsm_buffer.tx_buf, req_info->req_data, req_info->req_data_len); 
				gsm_buffer.tx_buf_len = req_info->req_data_len; 
				if(gsm_buffer.tx_buf[req_info->req_data_len - 1] != 0x0D && gsm_buffer.tx_buf[req_info->req_data_len - 1] != 0x0A) 
				{ 
					gsm_buffer.tx_buf[req_info->req_data_len] = 0x0D; 
					gsm_buffer.tx_buf[req_info->req_data_len + 1] = 0x0A; 
					gsm_buffer.tx_buf_len += 2; 
				} 
				GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_BAND_SW: 
			if(req_info != NULL) 
			{ 
				switch(req_info->link_num) 
				{ 
					case 1: 
						gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+QBAND=\"EGSM_MODE\"\r\n"); 
						break; 
 
					case 2: 
						gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+QBAND=\"DCS_MODE\"\r\n"); 
						break; 
 
					case 3: 
						gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+QBAND=\"PCS_MODE\"\r\n"); 
						break; 
 
					case 4: 
						gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+QBAND=\"EGSM_DCS_MODE\"\r\n"); 
						break; 
 
					case 5: 
						gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+QBAND=\"GSM850_PCS_MODE\"\r\n"); 
						break; 
 
					default: 
						gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+QBAND=\"GSM850_EGSM_DCS_PCS_MODE\"\r\n"); 
						break; 
				} 
				GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
				k = GSM_WaitCheckRxStr("OK", 20); 
				req_info->res = (k >= 0xFFFE) ? 0 : 1; 
				wl_pDev.gprs_st = GSM_GPRS_STAT_NO_LINK; 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
			 
		case ENUM_WL_MAIN_STATUE_SEND_TCPDATA: 
			if(req_info != NULL) 
			{ 
				if(req_info->req_data == NULL || req_info->req_data_len == 0) 
				{ 
					gsm_err("gsm_module_proc err: No data to sent\r\n"); 
				} 
				else 
				{ 
					req_info->res = GSM_DealGprsSend(req_info->link_num, req_info->req_data, req_info->req_data_len, req_info->abort); 
					/* 
					if(req_info->res == 1 && wl_pDev.gprs_link_type == 1) 
					{ 
						req_info->gsm_status_machine = ENUM_WL_MAIN_STATUE_QUERY_TCPSEND; 
						req_info->req_data_len = 0; 
						OSQPost(gsm_req_event, req_info); 
						return; 
					} 
					*/ 
				} 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
			 
		case ENUM_WL_MAIN_STATUE_QUERY_TCPSEND: 
			if(req_info != NULL) 
			{ 
				if((wl_pDev.gprs_st != GSM_GPRS_STA_CONNECT_OK) || (wl_pDev.call_st != 0)) 
				{ 
					req_info->res = 0xFF; 
					OSSemPost(WlSendDataOver); 
					return; 
				} 
				GSM_SendData("AT+QISACK\r", 11); 
				k = GSM_WaitCheckRxStr("ACK:", 1); 
				if(k >= 0xfffe) 
				{ 
					req_info->link_num++; 
					if(req_info->link_num >= 3) 
					{ 
						GSM_Restart("QSACKErr"); 
						req_info->res = 0xFF; 
						OSSemPost(WlSendDataOver); 
						return; 
					} 
				} 
				wl_pDev.gprs_tx_err = 0; 
				req_info->link_num = 0; 
				for(; k < gsm_buffer.rx_buf_len; k++) 
				{ 
					if(gsm_buffer.rx_buf[k] == ',') 
					{ 
						k += 2; 
						len = simple_atoi((const sint8 *)(gsm_buffer.rx_buf + k), gsm_buffer.rx_buf_len - k, ' ', NULL); 
						if(len == 0) 
						{ 
							k = gsm_buffer.rx_buf_len; 
						} 
						for(; k < gsm_buffer.rx_buf_len; k++) 
						{ 
							if(gsm_buffer.rx_buf[k] == ',') 
							{ 
								k += 2; 
								len = simple_atoi((const sint8 *)(gsm_buffer.rx_buf + k), gsm_buffer.rx_buf_len - k, ' ', NULL); 
								if(len == 0) 
								{ 
									req_info->res = 1; 
									OSSemPost(WlSendDataOver); 
									return; 
								} 
								k = gsm_buffer.rx_buf_len; 
							} 
						} 
					} 
				} 
				OSSemPost(WlSendDataOver); 
			} 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
			 
 
		case ENUM_WL_MAIN_STATUE_IP_CLOSE: 
			if(req_info != NULL) 
			{ 
				GSM_SendData("AT+QICLOSE\x0d", 12); 
				GSM_WaitCheckRxStr("OK", 6); 
 
				GSM_SendData("AT+QIDEACT\x0d", 12); 
				k = GSM_WaitCheckRxStr("OK", 90); 
				if(k >= 0xFFFE) 
				{ 
					GSM_Restart("DeactErr"); 
				} 
				req_info->res = 1; 
				wl_pDev.gprs_st = GSM_GPRS_STAT_NO_LINK; 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_SEND_DTMFDATA: 
			if(req_info != NULL) 
			{ 
				gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+VTS=%c\r\n", *req_info->req_data); 
				GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
				if(0xFFFE > GSM_WaitCheckRxStr("OK", 2)) 
				{ 
					req_info->res = 1; 
					wl_pDev.err_cnt = 0; 
				} 
				else 
				{ 
					wl_pDev.err_cnt++; 
				} 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
			 
		case ENUM_WL_MAIN_STATUE_ADJUST_SPK_VOLUM: 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			if(req_info != NULL) 
			{ 
				value = *req_info->req_data; 
				value = (value > 90) ? 90 : value; 
				gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+CLVL=%d\r\n", value); 
				GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
				if(0xFFFE > GSM_WaitCheckRxStr("OK", 2)) 
				{ 
					req_info->res = 1; 
					wl_pDev.err_cnt = 0; 
				} 
				else 
				{ 
					wl_pDev.err_cnt++; 
				} 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_SET_SIMNUM: 
			if(req_info != NULL) 
			{ 
				GSM_SendData("AT+CPBS=\"ON\"\r\n", 14); 
				k = GSM_WaitCheckRxStr("OK", 4); 
				if(k < 0xFFFE) 
				{ 
					aa = (req_info->req_data_len > sizeof(wl_pDev.SimNum)) ? sizeof(wl_pDev.SimNum) : req_info->req_data_len; 
					memset(wl_pDev.SimNum, 0, sizeof(wl_pDev.SimNum)); 
					memcpy(wl_pDev.SimNum, req_info->req_data, aa); 
					len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+CPBW=1,\""); 
					for(k = 0; k < aa; k++) 
					{ 
						if(*req_info->req_data > '9' || *req_info->req_data < '0') 
							k = 0xFF; 
						else 
							gsm_buffer.tx_buf[len++] = *req_info->req_data++; 
					} 
					len += ksprintf((sint8 *)&gsm_buffer.tx_buf[len], "\",129,\"MLG\"\r\n"); 
					gsm_buffer.tx_buf_len = len; 
					GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
					k = GSM_WaitCheckRxStr("OK", 6); 
					if(k < 0xFFFE) 
					{ 
						req_info->res = 1; 
					} 
				} 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
			 
		case ENUM_WL_MAIN_STATUE_SET_CSCANUM: 
			if(req_info != NULL) 
			{ 
				gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+CSCA=\""); 
				memcpy(gsm_buffer.tx_buf + gsm_buffer.tx_buf_len, req_info->req_data, req_info->req_data_len); 
				gsm_buffer.tx_buf_len += req_info->req_data_len; 
				gsm_buffer.tx_buf_len += ksprintf((sint8 *)(gsm_buffer.tx_buf + gsm_buffer.tx_buf_len), "\",145\r\n"); 
				GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len);	  		 
				k = GSM_WaitCheckRxStr("OK", 3); 
				req_info->res = (k < 0xFFFE) ? 1 : 0; 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
 
		case ENUM_WL_MAIN_STATUE_ADJUST_MIC_VOLUM: 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			if(req_info != NULL) 
			{ 
				value = *req_info->req_data; 
				value = (value > 15) ? 15 : value; 
				gsm_buffer.tx_buf_len = ksprintf((sint8 *)gsm_buffer.tx_buf, "AT+QMIC=2,%d\r\n", value); 
				GSM_SendData(gsm_buffer.tx_buf, gsm_buffer.tx_buf_len); 
				if(0xFFFE > GSM_WaitCheckRxStr("OK", 2)) 
				{ 
					req_info->res = 1; 
					wl_pDev.err_cnt = 0; 
				} 
				else 
				{ 
					wl_pDev.err_cnt++; 
				} 
			} 
			OSSemPost(WlSendDataOver); 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
						 
		default: 
			wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_NORMAL; 
			break; 
	} 
} 
 
 
//GSM处理,内容包括接收应用请求,与无线模块交互 
void task_gsm_proc(void *pdata) 
{ 
	uint8 SemError; 
	gsm_proc_req *req_info; 
 
	WlSendDataOver = OSSemCreate(0); 
	if(WlSendDataOver == NULL) 
	{ 
		OSTaskDel(OS_PRIO_SELF); 
	} 
 
	wl_pDev.gsmStateMachine = ENUM_WL_MAIN_STATUE_POWER_DOWN; 
	wl_pDev.Initial = 1; 
	 
	for(;;) 
	{ 
		req_info = NULL; 
		req_info = (gsm_proc_req *)OSQPend(gsm_req_event, OS_TICKS_PER_SEC, &SemError); 
 
		if(SemError == OS_ERR_NONE) 
		{ 
			if(req_info == NULL) 
			{ 
				continue; 
			} 
			wl_pDev.gsmStateMachine = req_info->gsm_status_machine; 
		} 
		gsm_module_process(req_info); 
	} 
} 
 
static void  wl_task_rx_data(void *pdata) 
{ 
    uint16 i; 
	uint8 err; 
    
	pdata = pdata; 
    for (;;) 
    { 
    	OSSemPend(usart3_tmr.notify, 0, &err); 
		if(err == OS_ERR_NONE) 
		{ 
#if (GSM_COMMUNICATE_ECHO == 1) 
			for(i = 0; i < (gsm_buffer.rx_buf_len > 80 ? 80 : gsm_buffer.rx_buf_len); i++) 
			{ 
				wl_err("%c", gsm_buffer.rx_buf[i]); 
			} 
#endif 
			GSM_PreCheck(); 
			OSSemPost(WlReceiveDataOver); 
			GSM_UnlockRx(); 
			gsm_buffer.rx_buf_len = 0; 
		} 
    }  
} 
 
 
uint8 GSM_init(void) 
{ 
	uint8 ret; 
 
	phone_sel_init(); 
	phone_mute_init(); 
	phone_muteon(); 
	GSM_ParaReset(); 
	gsm_buffer.buf_lock = 0; 
	gsm_buffer.pre_index = 0; 
	gsm_buffer.rx_buf_len = 0; 
	gsm_buffer.tx_buf_len = 0; 
	gsm_unsol_record.unsol_stat = 0; 
	gsm_unsol_record.sms_index[0] = 0xFF; 
	gsm_unsol_record.sms_index[1] = 0xFF; 
	gsm_unsol_record.sms_index[2] = 0xFF; 
 
	WlReceiveDataOver = OSSemCreate(0); 
	if(WlReceiveDataOver == NULL) 
	{ 
		gsm_err("wl_drv_init err: Cannot create echo event, abort\r\n"); 
		return 0; 
	} 
 
	gsm_req_event = OSQCreate(gsm_req_mq, MAX_GSM_REQ_MQ + 1); 
	if(gsm_req_event == NULL) 
	{ 
		gsm_err("wl_drv_init err: NULL MQ, task abort\r\n"); 
		OSSemDel(WlSendDataOver, OS_DEL_ALWAYS, &ret); 
		return 0; 
	} 
 
	memset(task_gsmproc_stk, 0, sizeof(task_gsmproc_stk)); 
	ret = OSTaskCreate(task_gsm_proc, NULL, &task_gsmproc_stk[TASK_GSM_PROC_STK_SIZE - 1], WL0_PRIO); 
    if (ret != OS_ERR_NONE) 
    { 
        wl_err("wl drive task create failed: %d\r\n", ret); 
    } 
 
	memset(task_echo_proc_stk, 0, sizeof(task_echo_proc_stk)); 
    ret = OSTaskCreate(wl_task_rx_data, NULL, &task_echo_proc_stk[TASK_GSM_ECHO_PROC_STK_SIZE - 1], WL1_PRIO); 
    if (ret != OS_ERR_NONE) 
    { 
        wl_err("wl_task_rx_data create failed: %d\r\n", ret); 
    } 
    return 1; 
}