parent
017035f573
commit
217618d848
|
@ -0,0 +1,397 @@
|
|||
#include "Kernel\Sys.h"
|
||||
#include "Kernel\Task.h"
|
||||
#include "Kernel\TTime.h"
|
||||
#include "Kernel\WaitHandle.h"
|
||||
|
||||
#include "Device\SerialPort.h"
|
||||
|
||||
#include "AT.h"
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include "App\FlushPort.h"
|
||||
|
||||
#define NET_DEBUG DEBUG
|
||||
//#define NET_DEBUG 0
|
||||
#if NET_DEBUG
|
||||
#define net_printf debug_printf
|
||||
#else
|
||||
#define net_printf(format, ...)
|
||||
#endif
|
||||
|
||||
struct CmdState
|
||||
{
|
||||
const String* Command = nullptr;
|
||||
String* Result = nullptr;
|
||||
cstring Key1 = nullptr;
|
||||
cstring Key2 = nullptr;
|
||||
cstring Key3 = nullptr;
|
||||
|
||||
bool Capture = true; // 是否捕获所有
|
||||
|
||||
uint Parse(const Buffer& bs, WaitHandle& handle);
|
||||
uint FindKey(const String& str);
|
||||
};
|
||||
|
||||
void LoadStationTask(void* param);
|
||||
|
||||
/*
|
||||
注意事项
|
||||
1、设置模式AT+CWMODE需要重启后生效AT+RST
|
||||
2、AP模式下查询本机IP无效,可能会造成死机
|
||||
3、开启server需要多连接作为基础AT+CIPMUX=1
|
||||
4、单连接模式,多连接模式 收发数据有参数个数区别
|
||||
*/
|
||||
|
||||
/******************************** AT ********************************/
|
||||
|
||||
AT::AT()
|
||||
{
|
||||
Port = nullptr;
|
||||
DataKey = nullptr;
|
||||
_Expect = nullptr;
|
||||
}
|
||||
|
||||
AT::~AT()
|
||||
{
|
||||
delete Port;
|
||||
}
|
||||
|
||||
void AT::Init(COM idx, int baudrate)
|
||||
{
|
||||
auto srp = new SerialPort(idx, baudrate);
|
||||
srp->Tx.SetCapacity(0x200);
|
||||
srp->Rx.SetCapacity(0x200);
|
||||
srp->MaxSize = 512;
|
||||
|
||||
Init(srp);
|
||||
}
|
||||
|
||||
void AT::Init(ITransport* port)
|
||||
{
|
||||
Port = port;
|
||||
if (Port) Port->Register(OnPortReceive, this);
|
||||
}
|
||||
|
||||
bool AT::Open()
|
||||
{
|
||||
if (!Port->Open()) return false;
|
||||
|
||||
/*if (!CheckReady())
|
||||
{
|
||||
net_printf("AT::Open 打开失败!");
|
||||
|
||||
return false;
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AT::Close()
|
||||
{
|
||||
Port->Close();
|
||||
}
|
||||
|
||||
// 发送指令,在超时时间内等待返回期望字符串,然后返回内容
|
||||
String AT::Send(const String& cmd, cstring expect, cstring expect2, uint msTimeout)
|
||||
{
|
||||
TS("AT::Send");
|
||||
|
||||
String rs;
|
||||
|
||||
auto& task = Task::Current();
|
||||
// 判断是否正在发送其它指令
|
||||
if (_Expect)
|
||||
{
|
||||
#if NET_DEBUG
|
||||
auto h = (WaitHandle*)_Expect;
|
||||
auto w = (CmdState*)h->State;
|
||||
net_printf("AT::Send %d 正在发送 ", h->TaskID);
|
||||
if (w->Command)
|
||||
w->Command->Trim().Show(false);
|
||||
else
|
||||
net_printf("数据");
|
||||
net_printf(" ,%d 无法发送 ", task.ID);
|
||||
cmd.Trim().Show(true);
|
||||
#endif
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
// 在接收事件中拦截
|
||||
CmdState we;
|
||||
// 数据不显示Command,没有打开NET_DEBUG时也不显示
|
||||
//we.Command = &cmd;
|
||||
we.Result = &rs;
|
||||
we.Key1 = expect;
|
||||
we.Key2 = expect2;
|
||||
we.Key3 = "busy ";
|
||||
|
||||
WaitHandle handle;
|
||||
handle.State = &we;
|
||||
|
||||
_Expect = &handle;
|
||||
|
||||
#if NET_DEBUG
|
||||
bool EnableLog = true;
|
||||
#endif
|
||||
|
||||
if (cmd)
|
||||
{
|
||||
Port->Write(cmd);
|
||||
|
||||
#if NET_DEBUG
|
||||
// 只有AT指令显示日志
|
||||
if (!cmd.StartsWith("AT") || (expect && expect[0] == '>')) EnableLog = false;
|
||||
if (EnableLog)
|
||||
{
|
||||
we.Command = &cmd;
|
||||
//net_printf("%d=> ", task.ID);
|
||||
cmd.Trim().Show(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
handle.WaitOne(msTimeout);
|
||||
if (_Expect == &handle) _Expect = nullptr;
|
||||
|
||||
//if(rs.Length() > 4) rs.Trim();
|
||||
|
||||
#if NET_DEBUG
|
||||
if (EnableLog && rs)
|
||||
{
|
||||
net_printf("%d<= ", task.ID);
|
||||
// 太长时不要去尾,避免产生重新分配
|
||||
if (rs.Length() < 0x40)
|
||||
rs.Trim().Show(true);
|
||||
else
|
||||
rs.Show(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
// 发送命令,自动检测并加上\r\n,等待响应OK
|
||||
bool AT::SendCmd(const String& cmd, uint msTimeout)
|
||||
{
|
||||
TS("AT::SendCmd");
|
||||
|
||||
static const cstring ok = "OK";
|
||||
static const cstring err = "ERROR";
|
||||
|
||||
String cmd2;
|
||||
|
||||
// 只有AT指令需要检查结尾,其它指令不检查,避免产生拷贝
|
||||
auto p = &cmd;
|
||||
if (cmd.StartsWith("AT") && !cmd.EndsWith("\r\n"))
|
||||
{
|
||||
cmd2 = cmd;
|
||||
cmd2 += "\r\n";
|
||||
p = &cmd2;
|
||||
}
|
||||
|
||||
// 二级拦截。遇到错误也马上结束
|
||||
auto rt = Send(*p, ok, err, msTimeout);
|
||||
|
||||
return rt.Contains(ok);
|
||||
}
|
||||
|
||||
bool AT::WaitForCmd(cstring expect, uint msTimeout)
|
||||
{
|
||||
String rs;
|
||||
|
||||
// 在接收事件中拦截
|
||||
CmdState we;
|
||||
we.Result = &rs;
|
||||
we.Key1 = expect;
|
||||
we.Capture = false;
|
||||
|
||||
WaitHandle handle;
|
||||
handle.State = &we;
|
||||
|
||||
_Expect = &handle;
|
||||
|
||||
// 等待收到数据
|
||||
bool rt = handle.WaitOne(msTimeout);
|
||||
|
||||
_Expect = nullptr;
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
void ParseFail(cstring name, const Buffer& bs)
|
||||
{
|
||||
#if NET_DEBUG
|
||||
if (bs.Length() == 0) return;
|
||||
|
||||
int p = 0;
|
||||
if (p < bs.Length() && bs[p] == ' ') p++;
|
||||
if (p < bs.Length() && bs[p] == '\r') p++;
|
||||
if (p < bs.Length() && bs[p] == '\n') p++;
|
||||
|
||||
// 无法识别的数据可能是空格前缀,需要特殊处理
|
||||
auto str = bs.Sub(p, -1).AsString();
|
||||
if (str)
|
||||
{
|
||||
net_printf("AT:%s 无法识别[%d]:", name, bs.Length());
|
||||
//if(bs.Length() == 2) net_printf("%02X %02X ", bs[0], bs[1]);
|
||||
str.Show(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint AT::OnPortReceive(ITransport* sender, Buffer& bs, void* param, void* param2)
|
||||
{
|
||||
auto esp = (AT*)param;
|
||||
return esp->OnReceive(bs, param2);
|
||||
}
|
||||
|
||||
// 引发数据到达事件
|
||||
uint AT::OnReceive(Buffer& bs, void* param)
|
||||
{
|
||||
if (bs.Length() == 0) return 0;
|
||||
|
||||
//!!! 分析数据和命令返回,特别要注意粘包
|
||||
int s = 0;
|
||||
int p = 0;
|
||||
auto str = bs.AsString();
|
||||
while (p >= 0 && p < bs.Length())
|
||||
{
|
||||
s = p;
|
||||
p = str.IndexOf(DataKey, s);
|
||||
|
||||
// +IPD之前之后的数据,留给命令分析
|
||||
int size = p >= 0 ? p - s : bs.Length() - s;
|
||||
if (size > 0)
|
||||
{
|
||||
if (_Expect)
|
||||
{
|
||||
ParseReply(bs.Sub(s, size));
|
||||
#if NET_DEBUG
|
||||
// 如果没有吃完,剩下部分报未识别
|
||||
//if(rs < size) ParseFail("ParseReply", bs.Sub(s + rs, size - rs));
|
||||
// 不要报未识别了,反正内部会全部吃掉
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if NET_DEBUG
|
||||
ParseFail("NoExpect", bs.Sub(s, size));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// +IPD开头的数据,作为收到数据
|
||||
if (p >= 0)
|
||||
{
|
||||
if (p + 5 >= bs.Length())
|
||||
{
|
||||
#if NET_DEBUG
|
||||
ParseFail("+IPD<=5", bs.Sub(p, -1));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto bs2 = bs.Sub(p, -1);
|
||||
Received(bs2);
|
||||
int rs = bs2.Length();
|
||||
if (rs <= 0)
|
||||
{
|
||||
#if NET_DEBUG
|
||||
ParseFail("ParseReceive", bs.Sub(p + rs, -1));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
// 游标移到下一组数据
|
||||
p += rs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 分析关键字。返回被用掉的字节数
|
||||
uint AT::ParseReply(const Buffer& bs)
|
||||
{
|
||||
if (!_Expect) return 0;
|
||||
|
||||
// 拦截给同步方法
|
||||
auto handle = (WaitHandle*)_Expect;
|
||||
auto we = (CmdState*)handle->State;
|
||||
bool rs = we->Parse(bs, *handle);
|
||||
|
||||
// 如果内部已经适配,则清空
|
||||
if (!we->Result) _Expect = nullptr;
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
uint CmdState::Parse(const Buffer& bs, WaitHandle& handle)
|
||||
{
|
||||
if (bs.Length() == 0 || !Result) return 0;
|
||||
|
||||
TS("WaitExpect::Parse");
|
||||
|
||||
// 适配任意关键字后,也就是收到了成功或失败,通知业务层已结束
|
||||
auto s_ = bs.AsString();
|
||||
auto& s = (const String&)s_;
|
||||
int p = FindKey(s);
|
||||
auto& rs = *Result;
|
||||
|
||||
// 捕获所有
|
||||
if (Capture)
|
||||
{
|
||||
if (p > 0)
|
||||
rs += bs.Sub(0, p).AsString();
|
||||
else
|
||||
rs += s;
|
||||
}
|
||||
else if (p > 0)
|
||||
rs = bs.Sub(0, p).AsString();
|
||||
|
||||
// 匹配关键字,任务完成
|
||||
if (p > 0)
|
||||
{
|
||||
Result = nullptr;
|
||||
|
||||
// 设置事件,通知等待任务退出循环
|
||||
handle.Set();
|
||||
}
|
||||
|
||||
// 如果后面是换行,则跳过
|
||||
if (p < s.Length() && s[p] == ' ') p++;
|
||||
if (p < s.Length() && s[p] == '\r') p++;
|
||||
if (p < s.Length() && s[p] == '\n') p++;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
uint CmdState::FindKey(const String& str)
|
||||
{
|
||||
// 适配第一关键字
|
||||
int p = Key1 ? str.IndexOf(Key1) : -1;
|
||||
if (p >= 0)
|
||||
{
|
||||
//net_printf("适配第一关键字 %s \r\n", Key1);
|
||||
return p + String(Key1).Length();
|
||||
}
|
||||
// 适配第二关键字
|
||||
p = Key2 ? str.IndexOf(Key2) : -1;
|
||||
if (p >= 0)
|
||||
{
|
||||
net_printf("适配第二关键字 %s \r\n", Key2);
|
||||
return p + String(Key2).Length();
|
||||
}
|
||||
// 适配busy
|
||||
p = str.IndexOf(Key3);
|
||||
if (p >= 0)
|
||||
{
|
||||
net_printf("适配第三关键字 %s \r\n", Key3);
|
||||
return p + String(Key3).Length();
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef __AT_H__
|
||||
#define __AT_H__
|
||||
|
||||
// GPRS的AT指令集 GSM 07.07
|
||||
class AT
|
||||
{
|
||||
public:
|
||||
ITransport* Port; // 传输口
|
||||
|
||||
cstring DataKey; // 数据关键字
|
||||
|
||||
Delegate<Buffer&> Received;
|
||||
|
||||
AT();
|
||||
~AT();
|
||||
|
||||
void Init(COM idx, int baudrate = 115200);
|
||||
void Init(ITransport* port);
|
||||
|
||||
// 打开与关闭
|
||||
bool Open();
|
||||
void Close();
|
||||
|
||||
/******************************** 发送指令 ********************************/
|
||||
// 发送指令,在超时时间内等待返回期望字符串,然后返回内容
|
||||
String Send(const String& cmd, cstring expect, cstring expect2 = nullptr, uint msTimeout = 1000);
|
||||
// 发送命令,自动检测并加上\r\n,等待响应OK
|
||||
bool SendCmd(const String& cmd, uint msTimeout = 1000);
|
||||
// 等待命令返回
|
||||
bool WaitForCmd(cstring expect, uint msTimeout);
|
||||
|
||||
private:
|
||||
void* _Expect; // 等待内容
|
||||
|
||||
// 分析关键字。返回被用掉的字节数
|
||||
uint ParseReply(const Buffer& bs);
|
||||
|
||||
// 引发数据到达事件
|
||||
uint OnReceive(Buffer& bs, void* param);
|
||||
static uint OnPortReceive(ITransport* sender, Buffer& bs, void* param, void* param2);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,9 +5,7 @@
|
|||
#include "Device\WatchDog.h"
|
||||
#include "Config.h"
|
||||
|
||||
#include "Drivers\NRF24L01.h"
|
||||
#include "Drivers\W5500.h"
|
||||
#include "Drivers\Esp8266\Esp8266.h"
|
||||
#include "Drivers\GSM07.h"
|
||||
|
||||
#include "TokenNet\TokenController.h"
|
||||
#include "TokenNet\TokenConfig.h"
|
||||
|
@ -124,52 +122,22 @@ void AP0803::InitButtons(const Delegate2<InputPort&, bool>& press)
|
|||
}
|
||||
}
|
||||
|
||||
NetworkInterface* AP0803::Create5500()
|
||||
NetworkInterface* AP0803::CreateGPRS()
|
||||
{
|
||||
debug_printf("\r\nW5500::Create \r\n");
|
||||
debug_printf("\r\nCreateGPRS::Create \r\n");
|
||||
|
||||
auto net = new W5500(Spi2, PE1, PD13);
|
||||
auto net = new GSM07();
|
||||
net->Init(COM4);
|
||||
net->Set(P0, P0);
|
||||
if(!net->Open())
|
||||
{
|
||||
delete net;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
net->EnableDNS();
|
||||
net->EnableDHCP();
|
||||
|
||||
return net;
|
||||
}
|
||||
|
||||
NetworkInterface* AP0803::Create8266(bool apOnly)
|
||||
{
|
||||
debug_printf("\r\nEsp8266::Create \r\n");
|
||||
|
||||
auto esp = new Esp8266(COM4, PE2, PD3);
|
||||
|
||||
// 初次需要指定模式 否则为 Wire
|
||||
bool join = esp->SSID && *esp->SSID;
|
||||
if (!join)
|
||||
{
|
||||
*esp->SSID = "WSWL";
|
||||
*esp->Pass = "12345678";
|
||||
|
||||
esp->Mode = NetworkType::STA_AP;
|
||||
esp->WorkMode = NetworkType::STA_AP;
|
||||
}
|
||||
|
||||
if(!esp->Open())
|
||||
{
|
||||
delete esp;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Client->Register("SetWiFi", &Esp8266::SetWiFi, esp);
|
||||
Client->Register("GetWiFi", &Esp8266::GetWiFi, esp);
|
||||
|
||||
return esp;
|
||||
}
|
||||
|
||||
/******************************** Token ********************************/
|
||||
|
||||
void AP0803::InitClient()
|
||||
|
@ -209,8 +177,7 @@ static void OnInitNet(void* param)
|
|||
{
|
||||
auto& bsp = *(AP0803*)param;
|
||||
|
||||
bsp.Create5500();
|
||||
bsp.Create8266(false);
|
||||
bsp.CreateGPRS();
|
||||
|
||||
Client->Open();
|
||||
}
|
||||
|
|
|
@ -40,12 +40,8 @@ public:
|
|||
void InitLeds();
|
||||
void InitButtons(const Delegate2<InputPort&, bool>& press);
|
||||
|
||||
// 打开以太网W5500
|
||||
NetworkInterface* Create5500();
|
||||
// 打开Esp8266,作为主控或者纯AP
|
||||
NetworkInterface* Create8266(bool apOnly);
|
||||
|
||||
// ITransport* Create2401();
|
||||
// 打开GPRS
|
||||
NetworkInterface* CreateGPRS();
|
||||
|
||||
void InitClient();
|
||||
void InitNet();
|
||||
|
|
|
@ -18,21 +18,6 @@ bool WaitExpect::Wait(int msTimeout)
|
|||
Sys.Sleep(40);
|
||||
if(!Result) return true;
|
||||
|
||||
/*// 等待收到数据
|
||||
TimeWheel tw(msTimeout - 40);
|
||||
// 默认检查间隔200ms,如果超时时间大于1000ms,则以四分之一为检查间隔
|
||||
// ESP8266串口任务平均时间为150ms左右,为了避免接收指令任务里面发送指令时等不到OK,需要加大检查间隔
|
||||
tw.Sleep = 200;
|
||||
if(msTimeout > 1000) tw.Sleep = msTimeout >> 2;
|
||||
if(tw.Sleep > 1000) tw.Sleep = 1000;
|
||||
|
||||
while(Result)
|
||||
{
|
||||
if(tw.Expired()) return false;
|
||||
}
|
||||
|
||||
return true;*/
|
||||
|
||||
return Handle.WaitOne(msTimeout);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,324 @@
|
|||
#include "Kernel\Sys.h"
|
||||
#include "Kernel\Task.h"
|
||||
#include "Kernel\TTime.h"
|
||||
#include "Kernel\WaitHandle.h"
|
||||
|
||||
#include "Device\SerialPort.h"
|
||||
|
||||
#include "GSM07.h"
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include "App\FlushPort.h"
|
||||
|
||||
#define NET_DEBUG DEBUG
|
||||
//#define NET_DEBUG 0
|
||||
#if NET_DEBUG
|
||||
#define net_printf debug_printf
|
||||
#else
|
||||
#define net_printf(format, ...)
|
||||
#endif
|
||||
|
||||
struct CmdState
|
||||
{
|
||||
String* Command = nullptr;
|
||||
String* Result = nullptr;
|
||||
cstring Key1 = nullptr;
|
||||
cstring Key2 = nullptr;
|
||||
|
||||
bool Capture = true; // 是否捕获所有
|
||||
};
|
||||
|
||||
/*
|
||||
注意事项
|
||||
1、设置模式AT+CWMODE需要重启后生效AT+RST
|
||||
2、AP模式下查询本机IP无效,可能会造成死机
|
||||
3、开启server需要多连接作为基础AT+CIPMUX=1
|
||||
4、单连接模式,多连接模式 收发数据有参数个数区别
|
||||
*/
|
||||
|
||||
/******************************** GSM07 ********************************/
|
||||
|
||||
GSM07::GSM07()
|
||||
{
|
||||
Name = "GSM07";
|
||||
Speed = 10;
|
||||
|
||||
APN = "CMNET";
|
||||
|
||||
Led = nullptr;
|
||||
|
||||
Buffer(_sockets, 5 * 4).Clear();
|
||||
|
||||
Mode = NetworkType::STA_AP;
|
||||
|
||||
InitConfig();
|
||||
LoadConfig();
|
||||
}
|
||||
|
||||
GSM07::~GSM07()
|
||||
{
|
||||
RemoveLed();
|
||||
}
|
||||
|
||||
void GSM07::Init(COM idx, int baudrate)
|
||||
{
|
||||
At.Init(idx, baudrate);
|
||||
}
|
||||
|
||||
void GSM07::Init(ITransport* port)
|
||||
{
|
||||
At.Init(port);
|
||||
}
|
||||
|
||||
void GSM07::Set(Pin power, Pin rst)
|
||||
{
|
||||
if (power != P0) _Power.Init(power, false);
|
||||
if (rst != P0) _Reset.Init(rst, true);
|
||||
|
||||
}
|
||||
|
||||
void GSM07::SetLed(Pin led)
|
||||
{
|
||||
if (led != P0)
|
||||
{
|
||||
auto port = new OutputPort(led);
|
||||
SetLed(*port);
|
||||
}
|
||||
}
|
||||
|
||||
void GSM07::SetLed(OutputPort& led)
|
||||
{
|
||||
auto fp = new FlushPort();
|
||||
fp->Port = &led;
|
||||
fp->Start();
|
||||
Led = fp;
|
||||
}
|
||||
|
||||
void GSM07::RemoveLed()
|
||||
{
|
||||
if (Led)delete (FlushPort*)Led;
|
||||
Led = nullptr;
|
||||
}
|
||||
|
||||
bool GSM07::OnOpen()
|
||||
{
|
||||
if (!At.Open()) return false;
|
||||
|
||||
if (!CheckReady())
|
||||
{
|
||||
net_printf("GSM07::Open 打开失败!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
At.Received.Bind(&GSM07::OnReceive, this);
|
||||
|
||||
// 开回显
|
||||
Echo(true);
|
||||
|
||||
#if NET_DEBUG
|
||||
// 获取版本
|
||||
GetVersion();
|
||||
//auto ver = GetVersion();
|
||||
//net_printf("版本:");
|
||||
//ver.Show(true);
|
||||
#endif
|
||||
|
||||
Config();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSM07::CheckReady()
|
||||
{
|
||||
// 先关一会电,然后再上电,让它来一个完整的冷启动
|
||||
if (!_Power.Empty())
|
||||
{
|
||||
_Power.Open(); // 使用前必须Open;
|
||||
_Power.Down(20);
|
||||
}
|
||||
if (!_Reset.Empty()) _Reset.Open(); // 使用前必须Open;
|
||||
|
||||
// 每两次启动会有一次打开失败,交替
|
||||
if (!_Reset.Empty())
|
||||
Reset(false); // 硬重启
|
||||
else
|
||||
Reset(true); // 软件重启命令
|
||||
|
||||
// 等待模块启动进入就绪状态
|
||||
if (!Test())
|
||||
{
|
||||
net_printf("GSM07::Open 打开失败!");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GSM07::OnClose()
|
||||
{
|
||||
// 先断开已有连接
|
||||
At.SendCmd("AT+CIPSHUT\r");
|
||||
|
||||
At.Close();
|
||||
|
||||
_Power.Close();
|
||||
_Reset.Close();
|
||||
}
|
||||
|
||||
bool GSM07::OnLink(uint retry)
|
||||
{
|
||||
//if(Linked) return true;
|
||||
|
||||
debug_printf("GSM07::OnLink\r\n");
|
||||
|
||||
/*bool join = SSID && *SSID;
|
||||
// 等待WiFi自动连接
|
||||
if (!WaitForCmd("WIFI CONNECTED", 3000))
|
||||
{
|
||||
auto mode = WorkMode;
|
||||
// 默认Both
|
||||
if (mode == NetworkType::Wire) mode = NetworkType::STA_AP;
|
||||
if (!join || mode == NetworkType::STA_AP) OpenAP();
|
||||
if (join)
|
||||
{
|
||||
if (!JoinAP(*SSID, *Pass)) return false;
|
||||
|
||||
ShowConfig();
|
||||
SaveConfig();
|
||||
}
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 配置网络参数
|
||||
void GSM07::Config()
|
||||
{
|
||||
// ATE0 关闭回显
|
||||
// ATE1 开启回显
|
||||
At.SendCmd("ATE0\r");
|
||||
At.SendCmd("AT+CIPSHUT\r");
|
||||
At.SendCmd("AT+CGCLASS=\"B\"\r");
|
||||
SetAPN(APN, false);
|
||||
At.SendCmd("AT+CGATT=1\r");
|
||||
// 先断开已有连接
|
||||
//At.SendCmd("AT+CIPSHUT\r");
|
||||
//设置APN
|
||||
SetAPN(APN, true);
|
||||
At.SendCmd("AT+CLPORT=\"UDP\",\"3399\"\r");
|
||||
// IP设置方式
|
||||
//At.SendCmd("AT+CIPSTART=\"UDP\",\"183.63.213.113\",\"3388\"\r");
|
||||
// 域名设置方式
|
||||
At.SendCmd("AT+CIPMUX=0\r");
|
||||
At.SendCmd("AT+CIPRXGET=1\r");
|
||||
At.SendCmd("AT+CIPQRCLOSE=1\r");
|
||||
At.SendCmd("AT+CIPMODE=0\r");
|
||||
}
|
||||
|
||||
Socket* GSM07::CreateSocket(NetType type)
|
||||
{
|
||||
/*auto es = (EspSocket**)_sockets;
|
||||
|
||||
int i = 0;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (es[i] == nullptr) break;
|
||||
}
|
||||
if (i >= 5)
|
||||
{
|
||||
net_printf("没有空余的Socket可用了 !\r\n");
|
||||
|
||||
return nullptr;
|
||||
}*/
|
||||
|
||||
switch (type)
|
||||
{
|
||||
/*case NetType::Tcp:
|
||||
return es[i] = new EspTcp(*this, i);
|
||||
|
||||
case NetType::Udp:
|
||||
return es[i] = new EspUdp(*this, i);*/
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// 数据到达
|
||||
void GSM07::OnReceive(Buffer& bs)
|
||||
{
|
||||
Received(bs);
|
||||
}
|
||||
|
||||
/******************************** 基础AT指令 ********************************/
|
||||
|
||||
// 基础AT指令
|
||||
bool GSM07::Test()
|
||||
{
|
||||
// 避免在循环内部频繁构造和析构
|
||||
String cmd = "AT";
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (At.SendCmd(cmd, 500)) return true;
|
||||
|
||||
Reset(false);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GSM07::Reset(bool soft)
|
||||
{
|
||||
if (soft) return At.SendCmd("AT+RST");
|
||||
|
||||
_Reset.Up(100);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
AT 版本信息
|
||||
基于的SDK版本信息
|
||||
编译生成时间
|
||||
*/
|
||||
String GSM07::GetVersion()
|
||||
{
|
||||
return At.Send("AT+GMR\r\n", "OK");
|
||||
}
|
||||
|
||||
bool GSM07::Sleep(uint ms)
|
||||
{
|
||||
String cmd = "AT+GSLP=";
|
||||
cmd += ms;
|
||||
return At.SendCmd(cmd);
|
||||
}
|
||||
|
||||
bool GSM07::Echo(bool open)
|
||||
{
|
||||
String cmd = "ATE";
|
||||
cmd = cmd + (open ? '1' : '0');
|
||||
return At.SendCmd(cmd);
|
||||
}
|
||||
|
||||
// 恢复出厂设置,将擦写所有保存到Flash的参数,恢复为默认参数。会导致模块重启
|
||||
bool GSM07::Restore()
|
||||
{
|
||||
return At.SendCmd("AT+RESTORE");
|
||||
}
|
||||
|
||||
// 00:CMNET 10:CMHK 01:CHKT 11:HKCSL
|
||||
void GSM07::SetAPN(cstring apn, bool issgp)
|
||||
{
|
||||
String str;
|
||||
if(issgp)
|
||||
str = "AT+CIPCSGP=1";
|
||||
else
|
||||
str = "AT+CGDCONT=1,\"IP\"";
|
||||
str = str + ",\"" + apn + "\"\r";
|
||||
|
||||
At.SendCmd(str);
|
||||
}
|
||||
|
||||
/******************************** TCP/IP ********************************/
|
|
@ -0,0 +1,84 @@
|
|||
#ifndef __GSM07_H__
|
||||
#define __GSM07_H__
|
||||
|
||||
#include "Device\Port.h"
|
||||
|
||||
#include "App\AT.h"
|
||||
|
||||
#include "Net\Socket.h"
|
||||
#include "Net\NetworkInterface.h"
|
||||
#include "Net\ITransport.h"
|
||||
|
||||
#include "Message\DataStore.h"
|
||||
#include "Message\Pair.h"
|
||||
|
||||
// GPRS的AT指令集 GSM 07.07
|
||||
class GSM07 : public NetworkInterface
|
||||
{
|
||||
public:
|
||||
AT At; // AT操作对象
|
||||
cstring APN;
|
||||
|
||||
IDataPort* Led; // 指示灯
|
||||
|
||||
OutputPort _Power;
|
||||
OutputPort _Reset;
|
||||
OutputPort _LowPower;
|
||||
|
||||
Delegate<Buffer&> Received;
|
||||
|
||||
GSM07();
|
||||
virtual ~GSM07();
|
||||
|
||||
void Init(ITransport* port);
|
||||
void Init(COM idx, int baudrate = 115200);
|
||||
void Set(Pin power = P0, Pin rst = P0);
|
||||
|
||||
virtual void Config();
|
||||
void SetLed(Pin led);
|
||||
void SetLed(OutputPort& led);
|
||||
void RemoveLed();
|
||||
|
||||
virtual Socket* CreateSocket(NetType type);
|
||||
|
||||
/******************************** 基础AT指令 ********************************/
|
||||
bool Test();
|
||||
bool Reset(bool soft);
|
||||
String GetVersion();
|
||||
bool Sleep(uint ms);
|
||||
bool Echo(bool open);
|
||||
// 恢复出厂设置,将擦写所有保存到Flash的参数,恢复为默认参数。会导致模块重启
|
||||
bool Restore();
|
||||
void SetAPN(cstring apn, bool issgp);
|
||||
|
||||
/******************************** 功能指令 ********************************/
|
||||
IPAddress GetIP(bool sta);
|
||||
|
||||
/******************************** TCP/IP ********************************/
|
||||
|
||||
/******************************** 发送指令 ********************************/
|
||||
|
||||
private:
|
||||
IPEndPoint _Remote; // 当前数据包远程地址
|
||||
|
||||
// 打开与关闭
|
||||
virtual bool OnOpen();
|
||||
virtual void OnClose();
|
||||
// 检测连接
|
||||
virtual bool OnLink(uint retry);
|
||||
|
||||
bool CheckReady();
|
||||
|
||||
// 多个硬件socket
|
||||
int* _sockets[5];
|
||||
|
||||
// 分析+IPD接收数据。返回被用掉的字节数
|
||||
uint ParseReceive(const Buffer& bs);
|
||||
// 分析关键字。返回被用掉的字节数
|
||||
uint ParseReply(const Buffer& bs);
|
||||
|
||||
// 数据到达
|
||||
void OnReceive(Buffer& bs);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -13,6 +13,7 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="..\App\ACZero.cpp" />
|
||||
<ClCompile Include="..\App\Alarm.cpp" />
|
||||
<ClCompile Include="..\App\AT.cpp" />
|
||||
<ClCompile Include="..\App\BlinkPort.cpp" />
|
||||
<ClCompile Include="..\App\Button.cpp" />
|
||||
<ClCompile Include="..\App\Button_GrayLevel.cpp" />
|
||||
|
@ -31,6 +32,7 @@
|
|||
<ClCompile Include="..\Board\AP0104.cpp" />
|
||||
<ClCompile Include="..\Board\AP0801.cpp" />
|
||||
<ClCompile Include="..\Board\AP0802.cpp" />
|
||||
<ClCompile Include="..\Board\AP0803.cpp" />
|
||||
<ClCompile Include="..\Board\BaseBoard.cpp" />
|
||||
<ClCompile Include="..\Board\IOK026X.cpp" />
|
||||
<ClCompile Include="..\Board\IOK027X.cpp" />
|
||||
|
@ -84,6 +86,7 @@
|
|||
<ClCompile Include="..\Drivers\Esp8266\EspTcp.cpp" />
|
||||
<ClCompile Include="..\Drivers\Esp8266\EspUdp.cpp" />
|
||||
<ClCompile Include="..\Drivers\Esp8266\WaitExpect.cpp" />
|
||||
<ClCompile Include="..\Drivers\GSM07.cpp" />
|
||||
<ClCompile Include="..\Drivers\HX711.cpp" />
|
||||
<ClCompile Include="..\Drivers\JTW8953.cpp" />
|
||||
<ClCompile Include="..\Drivers\NRF24L01.cpp" />
|
||||
|
|
|
@ -560,5 +560,14 @@
|
|||
<ClCompile Include="..\Drivers\Esp8266\WaitExpect.cpp">
|
||||
<Filter>Drivers\Esp8266</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Board\AP0803.cpp">
|
||||
<Filter>Board</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Drivers\GSM07.cpp">
|
||||
<Filter>Drivers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\App\AT.cpp">
|
||||
<Filter>App</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue