#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "ucos_ii.h"
#include "driver_usart.h"
#include "sys_time.h"
#include "msgRing.h"
#include "utility.h"
#include "esp8266.h"
#include "dz.h"
#include "debug_printf.h"
#include "sys_time.h"
#define WIFI_PORT USART_GPRS
#define COM_BUF_LEN 100 //串口发送命令缓冲区长度
#define COM_DATA_BUF_LEN 512 //串口发送报文数据缓冲区长度
#define DEFAULT_CMD_TIMEOUT 1500 //默认命令响应超时时间(单位ms)
#define DEFAULT_CMD_CIPSTART_TIMEOUT 8000 //默认命令响应超时时间(单位ms)
#define ECHO_TIMEOUT 2000
#define NETWORK_REGISTER_TIMEOUT 90000 //网络注册超时时间(单位ms)
#define STEP_TIME_OUT 300000 //每个阶段的默认超时时间
#define RECV_TIMEOUT 300000 //接收超时
#define RSSI_INTER 5000 //信号查询间隔
#define DEFAULT_RETRY_TIMES 3 //AT命令默认重试次数
#define WIFI_SOCK_NUM 4 //GPRS 建立SOCKET连接数量 最大4个
#define CMD_TABLE_END {NULL, 0} //初始化命令表结束标志
//描述符合法性判断宏
#define IS_VALID_FD(fd) ((fd) >= 0 && (fd) < WIFI_SOCK_NUM)
#define WIFI_INFO_SEG "\r\n" //正式使用
#define WIFI_TYPE_TCP "TCP"
#define WIFI_TYPE_UDP "UDP"
#define WIFI_TYPE_SSL "SSL"
#if 1
#define WIFI_DEBUG_SEG WIFI_INFO_SEG
#else
#define WIFI_DEBUG_SEG "\r" //调试使用
#endif
//GPRS指令返回结果
typedef enum
{
WIFI_AT_RET_OTHER = 0, //其他指令
WIFI_AT_RET_ERROR, //返回错误
WIFI_AT_RET_OK, //返回成功
WIFI_AT_RET_NUM,
}tWifiAtRet;
//GSM任务参数数据结构
typedef int tWifiTaskPara;
/*GPRS任务处理函数类型定义*/
typedef uint8_t (*tWifiTaskHandle)(char*, int);
//WIFI任务信息表项数据结构
typedef struct
{
char *name; //任务名称
tWifiTaskHandle handle; //任务处理函数
}tWifiTaskEntry;
typedef struct
{
uint8_t mipStat;
char mipIp[20];
uint8_t openId;
uint8_t openStat;
uint8_t sendFlag;
int sendFree;
uint8_t mipSets; //设置成功
uint8_t mipDwn; //连接关闭
}tWifiMipData;
//GPRS套接字地址数据结构
typedef struct
{
char str[WIFI_ADDR_LEN]; //服务器IP地址、域名或短信通信时的手机号码
uint16_t port; //服务器端口
}tWifiAddr;
//WIFI socket数据结构定义
typedef struct
{
tWifiState state; //socket状态
MSG_RING rxBuf; //数据接收缓存
MSG_RING txBuf; //数据发送缓存
tWifiAddr serv; //通讯对端地址信息
uint32_t stepTick[WIFI_SOCK_STAT_NUM]; //每一个阶段处理时间,防止死循环在单独状态
uint32_t rssiTick; //信号查询间隔
}tWifiSocketStruct;
typedef struct
{
uint8_t mode;
uint8_t stat;
char str[20];
uint8_t act;
}tWifiInterCops;
//GPRS模块驱动接口数据结构
typedef struct
{
uint8_t signal; //GSM网络信号强度,0-7(数值越大信号越好)
uint8_t wificnct; //WIFI连接状态
uint8_t wificnct_flag; //WIFI连接标志
uint8_t wifi_error_code; //
uint8_t wifi_cnct_AP_flag; //WIFI连接上AP工作状态
uint8_t wifimode; //wifi工作模式
uint8_t running; //GSM模块是否正常运行(初始化成功),TRUE-是,FALSE-否
uint8_t tcpsta_stat; //tcp网络连接信息
uint8_t tcpsta_work_flag; //tcp网络连接状态
uint8_t mode; //WIFI工作模式
uint8_t send_error_cnt; //发送错误计数
uint8_t send_tick; //发送错误计数
char ssid[17];
char pwd[17];
tWifiInterCops cops;
}tWifiInterface;
//命令数据结构
typedef struct
{
char *str; //命令字符串
uint32_t timeout; //响应超时时间(单位ms)
uint8_t retry; //重试次数
}tWiFIAtCmD;
//发送数据数据结构
typedef struct
{
uint8_t send_flag; //发送数据标志
uint16_t send_data_len; //发送数据的长度
uint8_t send_stage_now; //发送数据处理的阶段
uint8_t send_data_flag; //发送数据
uint8_t send_result; //发送数据的结果
uint32_t send_start_tick;
uint8_t send_buf[COM_DATA_BUF_LEN]; //发送数据缓存
}tWiFIAtSendDataSta;
//基本初始化表AT指令初始化
static const tWiFIAtCmD wifiInitCmdTable[] =
{
{"ATE0", DEFAULT_CMD_TIMEOUT, DEFAULT_RETRY_TIMES},//取消回显功能
// {"AT+UART_DEF", DEFAULT_CMD_TIMEOUT, DEFAULT_RETRY_TIMES},//取消回显功能
CMD_TABLE_END
};
//第二步初始化表基础WIFI初始化
static const tWiFIAtCmD wifiInitCmdTable2[] =
{
{"AT+CWMODE_DEF", DEFAULT_CMD_TIMEOUT, DEFAULT_RETRY_TIMES},//设置wifi工作模式
{"AT+CWJAP_DEF", DEFAULT_CMD_TIMEOUT, DEFAULT_RETRY_TIMES},//设置wifi连接的AP信息
{"AT+CWJAP?", DEFAULT_CMD_TIMEOUT, DEFAULT_RETRY_TIMES},//设置wifi连接的AP信息
CMD_TABLE_END
};
//GPRS连接命令表
static const tWiFIAtCmD wifiConnectCmdTable[] =
{
{"AT+CIPMUX=", DEFAULT_CMD_TIMEOUT, DEFAULT_RETRY_TIMES},//开启mux的多路连接
{"AT+CIPMODE=", DEFAULT_CMD_TIMEOUT, DEFAULT_RETRY_TIMES},//设置模块传输模式1为透传模式
{"AT+CIPSTART", DEFAULT_CMD_CIPSTART_TIMEOUT, DEFAULT_RETRY_TIMES},//与服务器建立邋錞CP连接
// {"AT+CIPSTATUS", DEFAULT_CMD_CIPSTART_TIMEOUT, DEFAULT_RETRY_TIMES},
CMD_TABLE_END
};
/*WIFI发送顺序枚举*/
typedef enum
{
WIFI_SEND_CIPSEND = 0, //写入缓存
WIFI_SEND_STEP_NUM,
}tWifiSendStep;
//WIFI数据发送命令表
static const tWiFIAtCmD wifiSendCmdTable[] =
{
{"AT+CIPSEND", DEFAULT_CMD_TIMEOUT, DEFAULT_RETRY_TIMES},//发送tcp信息
CMD_TABLE_END
};
static const tWiFIAtCmD wifiCloseCmdTable[] =
{
// {"AT+CIPCLOSE", DEFAULT_CMD_TIMEOUT, DEFAULT_RETRY_TIMES},//关闭TCP/UDP/SSL传输
{"AT+RST", DEFAULT_CMD_CIPSTART_TIMEOUT, DEFAULT_RETRY_TIMES},//重启模块
CMD_TABLE_END
};
static char comTxBuf[COM_BUF_LEN]; //模块控制串口发送缓冲区
static char comTxDataBuf[COM_DATA_BUF_LEN]; //模块控制串口发送报文数据缓冲区
static char comRxBuf[COM_DATA_BUF_LEN]; //模块控制串口接收缓冲区
static tWifiSocketStruct wifiSocket; //socket数组
static tWifiInterface wifiInterface; //驱动程序对外接口数据
static tWiFIAtSendDataSta wifiSendDataSta; //wifi发送数据处理状态
//套接字互斥锁操作宏
static uint8_t perr;
static OS_EVENT *g_wifiSem; //套接字互斥信号量,只创建一次
#define WIFI_SOCKET_LOCK OSSemPend(g_wifiSem, 0, &perr)
#define WIFI_SOCKET_UNLOCK OSSemPost(g_wifiSem)
/*切换wifi的工作状态机*/
static void wifi_step_jump(tWifiState step)
{
if (step > WIFI_SOCK_CLOSE)
return;
WIFI_SOCKET_LOCK;
wifiSocket.state = step;
wifiSocket.stepTick[step] = tick_get();
wifiSocket.rssiTick = tick_get();
WIFI_SOCKET_UNLOCK;
dbg_printf(1,"wifi step jump %u", step);
}
/*******************************************************************************
函 数 名: gprsComRecv
说 明: 从串口接收一个字符
输入参数: timeout: 接收超时时间,单位ms
输出参数: ch: 接收到的字符
返 回 值: uint8_t SUCCESS-成功,FAIL-失败
作 者: 魏强
创建日期: 2017.03.14
*******************************************************************************/
static int wifiComRecv(unsigned int timeout, char *rxBuf)
{
if (NULL == rxBuf)
{
return FAIL;
}
return usart_gprs_recv(WIFI_PORT, (uint8_t*)rxBuf, COM_DATA_BUF_LEN, timeout);
}
static const tWifiTaskEntry wifiTaskTable[];
static uint8_t wifiTaskTcpRecv(char *str, int len);
/*******************************************************************************
函 数 名: gprsAtProc
说 明: 根据返回字符串调用处理函数
输入参数:
输出参数: 无
返 回 值:
作 者: weiq
创建日期: 2017.03.15
*******************************************************************************/
static void wifiAtProc(char *str, int len, uint8_t *result)
{
uint8_t i;
const tWifiTaskEntry *pTaskProc;
if (0 == len)
{
return;
}
if (0 == strncmp("+IPD,", str, strlen("+IPD,")))
{
wifiTaskTcpRecv(str,len);
*result = WIFI_AT_RET_OK;
return;
}
if (0 == strncmp("ERROR", str, strlen("ERROR")) || 0 == strncmp("FAIL", str, strlen("FAIL")))
{
*result = WIFI_AT_RET_ERROR;
return;
}
else if (0 == strncmp("OK", str, strlen("OK")))
{
if(wifiSendDataSta.send_flag == 1 && wifiSendDataSta.send_stage_now == 0)
wifiSendDataSta.send_stage_now = 1;
*result = WIFI_AT_RET_OK;