控制器提供发送的内层方法,静态消息,不需要修改。而普通的Send/Reply一般需要重新以实现专有功能
This commit is contained in:
parent
81090eee64
commit
a3e1cf9ccf
|
@ -1,7 +1,7 @@
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
|
|
||||||
//#define MSG_DEBUG DEBUG
|
#define MSG_DEBUG DEBUG
|
||||||
#define MSG_DEBUG 0
|
//#define MSG_DEBUG 0
|
||||||
#if MSG_DEBUG
|
#if MSG_DEBUG
|
||||||
#define msg_printf debug_printf
|
#define msg_printf debug_printf
|
||||||
#else
|
#else
|
||||||
|
@ -158,7 +158,19 @@ bool Controller::OnReceive(Message& msg)
|
||||||
|
|
||||||
bool Controller::Send(Message& msg)
|
bool Controller::Send(Message& msg)
|
||||||
{
|
{
|
||||||
TS("Controller::Send");
|
return SendInternal(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::Reply(Message& msg)
|
||||||
|
{
|
||||||
|
msg.Reply = 1;
|
||||||
|
|
||||||
|
return SendInternal(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::SendInternal(const Message& msg)
|
||||||
|
{
|
||||||
|
TS("Controller::SendInternal");
|
||||||
|
|
||||||
// 如果没有传输口处于打开状态,则发送失败
|
// 如果没有传输口处于打开状态,则发送失败
|
||||||
if(!Port->Open()) return false;
|
if(!Port->Open()) return false;
|
||||||
|
@ -170,10 +182,3 @@ bool Controller::Send(Message& msg)
|
||||||
Array bs(ms.GetBuffer(), ms.Position());
|
Array bs(ms.GetBuffer(), ms.Position());
|
||||||
return Port->Write(bs, msg.State);
|
return Port->Write(bs, msg.State);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Controller::Reply(Message& msg)
|
|
||||||
{
|
|
||||||
msg.Reply = 1;
|
|
||||||
|
|
||||||
return Send(msg);
|
|
||||||
}
|
|
||||||
|
|
|
@ -43,6 +43,9 @@ public:
|
||||||
// 收到消息时触发
|
// 收到消息时触发
|
||||||
MessageHandler Received;
|
MessageHandler Received;
|
||||||
void* Param;
|
void* Param;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool SendInternal(const Message& msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
|
|
||||||
void SendTask(void* param);
|
void SendTask(void* param);
|
||||||
void StatTask(void* param);
|
void StatTask(void* param);
|
||||||
static bool Encrypt(Message& msg,Array& pass);
|
|
||||||
|
|
||||||
|
/*================================ 微网消息 ================================*/
|
||||||
typedef struct{
|
typedef struct{
|
||||||
byte Retry:2; // 标识位。也可以用来做二级命令
|
byte Retry:2; // 重发次数。
|
||||||
byte TTL:2; // 路由TTL。最多3次转发
|
byte TTL:2; // 路由TTL。最多3次转发
|
||||||
byte NoAck:1; // 是否不需要确认包
|
byte NoAck:1; // 是否不需要确认包
|
||||||
byte Ack:1; // 确认包
|
byte Ack:1; // 确认包
|
||||||
|
@ -54,11 +54,11 @@ bool TinyMessage::Read(Stream& ms)
|
||||||
Error = _Error;
|
Error = _Error;
|
||||||
|
|
||||||
// 代码为0是非法的
|
// 代码为0是非法的
|
||||||
if(!Code) return false;
|
if(!Code) return false;
|
||||||
// 没有源地址是很不负责任的
|
// 没有源地址是很不负责任的
|
||||||
if(!Src) return false;
|
if(!Src) return false;
|
||||||
// 源地址和目的地址相同也是非法的
|
// 源地址和目的地址相同也是非法的
|
||||||
if(Dest == Src) return false;
|
if(Dest == Src) return false;
|
||||||
|
|
||||||
// 校验剩余长度
|
// 校验剩余长度
|
||||||
ushort len = Length;
|
ushort len = Length;
|
||||||
|
@ -132,7 +132,7 @@ bool TinyMessage::Valid() const
|
||||||
|
|
||||||
debug_printf("Message::Valid Crc Error %04X != Checksum: %04X \r\n", Crc, Checksum);
|
debug_printf("Message::Valid Crc Error %04X != Checksum: %04X \r\n", Crc, Checksum);
|
||||||
#if MSG_DEBUG
|
#if MSG_DEBUG
|
||||||
debug_printf("校验错误指令 ");
|
debug_printf("指令校验错误 ");
|
||||||
Show();
|
Show();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ void TinyMessage::Show() const
|
||||||
#if MSG_DEBUG
|
#if MSG_DEBUG
|
||||||
assert_ptr(this);
|
assert_ptr(this);
|
||||||
|
|
||||||
byte flag = *((byte*)&_Code+1);
|
byte flag = *((byte*)&_Code + 1);
|
||||||
msg_printf("0x%02X => 0x%02X Code=0x%02X Flag=0x%02X Seq=0x%02X Retry=%d", Src, Dest, Code, flag, Seq, Retry);
|
msg_printf("0x%02X => 0x%02X Code=0x%02X Flag=0x%02X Seq=0x%02X Retry=%d", Src, Dest, Code, flag, Seq, Retry);
|
||||||
|
|
||||||
if(flag)
|
if(flag)
|
||||||
|
@ -190,10 +190,10 @@ TinyMessage TinyMessage::CreateReply() const
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*================================ 微网控制器 ================================*/
|
||||||
// 构造控制器
|
// 构造控制器
|
||||||
TinyController::TinyController() : Controller()
|
TinyController::TinyController() : Controller()
|
||||||
{
|
{
|
||||||
_Sequence = 0;
|
|
||||||
_taskID = 0;
|
_taskID = 0;
|
||||||
Interval = 2;
|
Interval = 2;
|
||||||
Timeout = 200;
|
Timeout = 200;
|
||||||
|
@ -290,6 +290,19 @@ void ShowMessage(TinyMessage& msg, bool send, ITransport* port)
|
||||||
msg.Show();
|
msg.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//加密。组网不加密,退网不加密
|
||||||
|
static bool Encrypt(Message& msg, Array& pass)
|
||||||
|
{
|
||||||
|
// 加解密。组网不加密,退网不加密
|
||||||
|
if(msg.Length > 0 && pass.Length() > 0 && !(msg.Code == 0x01 || msg.Code == 0x02||msg.Code==0x03))
|
||||||
|
{
|
||||||
|
Array bs(msg.Data, msg.Length);
|
||||||
|
RC4::Encrypt(bs, pass);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool TinyController::Dispatch(Stream& ms, Message* pmsg, void* param)
|
bool TinyController::Dispatch(Stream& ms, Message* pmsg, void* param)
|
||||||
{
|
{
|
||||||
/*byte* buf = ms.Current();
|
/*byte* buf = ms.Current();
|
||||||
|
@ -385,7 +398,7 @@ bool TinyController::Valid(const Message& msg)
|
||||||
if(tmsg.Dest == Address)
|
if(tmsg.Dest == Address)
|
||||||
{
|
{
|
||||||
ByteArray key(0);
|
ByteArray key(0);
|
||||||
CallblackKey(tmsg.Src, key, Param);
|
CallblackKey(tmsg.Src, key, Param);
|
||||||
if(key.Length() > 0) Encrypt(tmsg, key);
|
if(key.Length() > 0) Encrypt(tmsg, key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -470,15 +483,7 @@ void TinyController::AckResponse(const TinyMessage& msg)
|
||||||
msg_printf(" 失败!\r\n");*/
|
msg_printf(" 失败!\r\n");*/
|
||||||
}
|
}
|
||||||
|
|
||||||
uint TinyController::Post(byte dest, byte code, const Array& arr)
|
static byte _Sequence = 0;
|
||||||
{
|
|
||||||
TinyMessage msg(code);
|
|
||||||
msg.Dest = dest;
|
|
||||||
msg.SetData(arr);
|
|
||||||
|
|
||||||
return Send(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发送消息,传输口参数为空时向所有传输口发送消息
|
// 发送消息,传输口参数为空时向所有传输口发送消息
|
||||||
bool TinyController::Send(Message& msg)
|
bool TinyController::Send(Message& msg)
|
||||||
{
|
{
|
||||||
|
@ -491,140 +496,25 @@ bool TinyController::Send(Message& msg)
|
||||||
if(!tmsg.Reply) tmsg.Seq = ++_Sequence;
|
if(!tmsg.Reply) tmsg.Seq = ++_Sequence;
|
||||||
|
|
||||||
ByteArray key;
|
ByteArray key;
|
||||||
CallblackKey(tmsg.Dest, key, Param);
|
CallblackKey(tmsg.Dest, key, Param);
|
||||||
Encrypt(tmsg,key);
|
if(key.Length() > 0) Encrypt(tmsg, key);
|
||||||
|
|
||||||
|
#if MSG_DEBUG
|
||||||
ShowMessage(tmsg, true, Port);
|
ShowMessage(tmsg, true, Port);
|
||||||
//#endif
|
#endif
|
||||||
|
|
||||||
//return Controller::Send(msg, port);
|
|
||||||
|
|
||||||
return Post(tmsg, -1);
|
return Post(tmsg, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//加密。组网不加密,退网不加密
|
bool TinyController::Reply(Message& msg)
|
||||||
static bool Encrypt(Message& msg, Array& pass)
|
|
||||||
{
|
{
|
||||||
// 加解密。组网不加密,退网不加密
|
auto& tmsg = (TinyMessage&)msg;
|
||||||
if(msg.Length > 0 && pass.Length() > 0 && !(msg.Code == 0x01 || msg.Code == 0x02||msg.Code==0x03))
|
|
||||||
{
|
|
||||||
Array bs(msg.Data, msg.Length);
|
|
||||||
RC4::Encrypt(bs, pass);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SendTask(void* param)
|
// 回复信息,源地址变成目的地址
|
||||||
{
|
if(tmsg.Dest == Address && tmsg.Src != Address) tmsg.Dest = tmsg.Src;
|
||||||
assert_ptr(param);
|
msg.Reply = 1;
|
||||||
TinyController* control = (TinyController*)param;
|
|
||||||
control->Loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TinyController::Loop()
|
return Send(msg);
|
||||||
{
|
|
||||||
TS("TinyController::Loop");
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
for(int i=0; i<ArrayLength(_Queue); i++)
|
|
||||||
{
|
|
||||||
auto& node = _Queue[i];
|
|
||||||
if(!node.Using) continue;
|
|
||||||
|
|
||||||
// 检查时间。至少发送一次
|
|
||||||
if(node.Next > 0)
|
|
||||||
{
|
|
||||||
ulong now2 = Sys.Ms();
|
|
||||||
// 下一次发送时间还没到,跳过
|
|
||||||
if(node.Next > now2) continue;
|
|
||||||
|
|
||||||
// 已过期则删除
|
|
||||||
if(node.Expired < now2)
|
|
||||||
{
|
|
||||||
debug_printf("消息过期 Dest=0x%02X Seq=0x%02X Period=%d Times=%d\r\n", node.Data[0], node.Seq, node.Period, node.Times);
|
|
||||||
node.Using = 0;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
count++;
|
|
||||||
node.Times++;
|
|
||||||
|
|
||||||
auto f = (TFlags*)&node.Data[3];
|
|
||||||
f->Retry++;
|
|
||||||
|
|
||||||
// 发送消息
|
|
||||||
Array bs(node.Data, node.Length);
|
|
||||||
Port->Write(bs);
|
|
||||||
|
|
||||||
// 增加发送次数统计
|
|
||||||
Total.Send++;
|
|
||||||
|
|
||||||
// 分组统计
|
|
||||||
if(Total.Send >= 100)
|
|
||||||
{
|
|
||||||
memcpy(&Last, &Total, sizeof(Total));
|
|
||||||
memset(&Total, 0, sizeof(Total));
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong now = Sys.Ms();
|
|
||||||
node.LastSend = now;
|
|
||||||
|
|
||||||
// 随机延迟。随机数1~5。每次延迟递增
|
|
||||||
byte rnd = (uint)now % 3;
|
|
||||||
node.Period = (rnd + 1) * Interval;
|
|
||||||
//node.Period = Interval;
|
|
||||||
node.Next = now + node.Period;
|
|
||||||
//debug_printf("下一次 %dus\r\n", node.Period);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(count == 0) Sys.SetTask(_taskID, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发送消息,usTimeout微秒超时时间内,如果对方没有响应,会重复发送,-1表示采用系统默认超时时间Timeout
|
|
||||||
bool TinyController::Post(TinyMessage& msg, int expire)
|
|
||||||
{
|
|
||||||
TS("TinyController::Post");
|
|
||||||
|
|
||||||
// 如果没有传输口处于打开状态,则发送失败
|
|
||||||
if(!Port->Open()) return false;
|
|
||||||
|
|
||||||
if(expire < 0) expire = Timeout;
|
|
||||||
// 需要响应
|
|
||||||
if(expire <= 0) msg.NoAck = true;
|
|
||||||
// 如果确定不需要响应,则改用Post
|
|
||||||
if(msg.NoAck || msg.Ack) return Controller::Send(msg);
|
|
||||||
|
|
||||||
// 针对Zigbee等不需要Ack确认的通道
|
|
||||||
if(Timeout < 0) return Controller::Send(msg);
|
|
||||||
|
|
||||||
// 准备消息队列
|
|
||||||
MessageNode* node = NULL;
|
|
||||||
for(int i=0; i<ArrayLength(_Queue); i++)
|
|
||||||
{
|
|
||||||
if(!_Queue[i].Using)
|
|
||||||
{
|
|
||||||
node = &_Queue[i];
|
|
||||||
node->Seq = 0;
|
|
||||||
node->Using = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 队列已满
|
|
||||||
if(!node) return false;
|
|
||||||
|
|
||||||
node->SetMessage(msg);
|
|
||||||
node->StartTime = Sys.Ms();
|
|
||||||
node->Next = 0;
|
|
||||||
node->Expired = Sys.Ms() + expire;
|
|
||||||
|
|
||||||
Total.Msg++;
|
|
||||||
|
|
||||||
Sys.SetTask(_taskID, true, 0);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 广播消息,不等待响应和确认
|
// 广播消息,不等待响应和确认
|
||||||
|
@ -643,18 +533,121 @@ bool TinyController::Broadcast(TinyMessage& msg)
|
||||||
ShowMessage(msg, true, Port);
|
ShowMessage(msg, true, Port);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return Post(msg, 0);
|
if(!Port->Open()) return false;
|
||||||
|
|
||||||
|
return Controller::SendInternal(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TinyController::Reply(Message& msg)
|
// 放入发送队列,超时之前,如果对方没有响应,会重复发送,-1表示采用系统默认超时时间Timeout
|
||||||
|
bool TinyController::Post(const TinyMessage& msg, int msTimeout)
|
||||||
{
|
{
|
||||||
auto& tmsg = (TinyMessage&)msg;
|
TS("TinyController::Post");
|
||||||
|
|
||||||
// 回复信息,源地址变成目的地址
|
// 如果没有传输口处于打开状态,则发送失败
|
||||||
if(tmsg.Dest == Address && tmsg.Src != Address) tmsg.Dest = tmsg.Src;
|
if(!Port->Open()) return false;
|
||||||
msg.Reply = 1;
|
|
||||||
|
|
||||||
return Send(msg);
|
if(msTimeout < 0) msTimeout = Timeout;
|
||||||
|
// 如果确定不需要响应,则改用Post
|
||||||
|
if(msTimeout <= 0 || msg.NoAck || msg.Ack) return Controller::SendInternal(msg);
|
||||||
|
|
||||||
|
// 针对Zigbee等不需要Ack确认的通道
|
||||||
|
if(Timeout < 0) return Controller::SendInternal(msg);
|
||||||
|
|
||||||
|
// 准备消息队列
|
||||||
|
MessageNode* node = NULL;
|
||||||
|
for(int i=0; i<ArrayLength(_Queue); i++)
|
||||||
|
{
|
||||||
|
if(!_Queue[i].Using)
|
||||||
|
{
|
||||||
|
node = &_Queue[i];
|
||||||
|
node->Using = 1;
|
||||||
|
node->Seq = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 队列已满
|
||||||
|
if(!node)
|
||||||
|
{
|
||||||
|
debug_printf("TinyController::Post 发送队列已满! \r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->Set(msg, msTimeout);
|
||||||
|
|
||||||
|
Total.Msg++;
|
||||||
|
|
||||||
|
Sys.SetTask(_taskID, true, 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendTask(void* param)
|
||||||
|
{
|
||||||
|
assert_ptr(param);
|
||||||
|
|
||||||
|
auto control = (TinyController*)param;
|
||||||
|
control->Loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TinyController::Loop()
|
||||||
|
{
|
||||||
|
TS("TinyController::Loop");
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for(int i=0; i<ArrayLength(_Queue); i++)
|
||||||
|
{
|
||||||
|
auto& node = _Queue[i];
|
||||||
|
if(!node.Using) continue;
|
||||||
|
|
||||||
|
// 检查时间。至少发送一次
|
||||||
|
if(node.Next > 0)
|
||||||
|
{
|
||||||
|
ulong now = Sys.Ms();
|
||||||
|
// 下一次发送时间还没到,跳过
|
||||||
|
if(node.Next > now) continue;
|
||||||
|
|
||||||
|
// 已过期则删除
|
||||||
|
if(node.Expired < now)
|
||||||
|
{
|
||||||
|
debug_printf("消息过期 Dest=0x%02X Seq=0x%02X Times=%d\r\n", node.Data[0], node.Seq, node.Times);
|
||||||
|
node.Using = 0;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
node.Times++;
|
||||||
|
|
||||||
|
// 递增重试次数
|
||||||
|
auto f = (TFlags*)&node.Data[3];
|
||||||
|
f->Retry++;
|
||||||
|
|
||||||
|
// 发送消息
|
||||||
|
Port->Write(Array(node.Data, node.Length));
|
||||||
|
|
||||||
|
// 增加发送次数统计
|
||||||
|
Total.Send++;
|
||||||
|
|
||||||
|
// 分组统计
|
||||||
|
if(Total.Send >= 100)
|
||||||
|
{
|
||||||
|
memcpy(&Last, &Total, sizeof(Total));
|
||||||
|
memset(&Total, 0, sizeof(Total));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算下一次重发时间
|
||||||
|
{
|
||||||
|
ulong now = Sys.Ms();
|
||||||
|
node.LastSend = now;
|
||||||
|
|
||||||
|
// 随机延迟。随机数1~5。每次延迟递增
|
||||||
|
byte rnd = (uint)now % 3;
|
||||||
|
node.Next = now + (rnd + 1) * Interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count == 0) Sys.SetTask(_taskID, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatTask(void* param)
|
void StatTask(void* param)
|
||||||
|
@ -693,19 +686,24 @@ void TinyController::ShowStat() const
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageNode::SetMessage(const TinyMessage& msg)
|
/*================================ 信息节点 ================================*/
|
||||||
|
void MessageNode::Set(const TinyMessage& msg, int msTimeout)
|
||||||
{
|
{
|
||||||
Seq = msg.Seq;
|
Seq = msg.Seq;
|
||||||
Period = 0;
|
|
||||||
Times = 0;
|
Times = 0;
|
||||||
LastSend = 0;
|
LastSend = 0;
|
||||||
|
|
||||||
|
StartTime = Sys.Ms();
|
||||||
|
Expired = StartTime + msTimeout;
|
||||||
|
Next = 0;
|
||||||
|
|
||||||
// 注意,此时指针位于0,而内容长度为缓冲区长度
|
// 注意,此时指针位于0,而内容长度为缓冲区长度
|
||||||
Stream ms(Data, ArrayLength(Data));
|
Stream ms(Data, ArrayLength(Data));
|
||||||
msg.Write(ms);
|
msg.Write(ms);
|
||||||
Length = ms.Position();
|
Length = ms.Position();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*================================ 环形队列 ================================*/
|
||||||
RingQueue::RingQueue()
|
RingQueue::RingQueue()
|
||||||
{
|
{
|
||||||
Index = 0;
|
Index = 0;
|
||||||
|
|
|
@ -10,10 +10,6 @@
|
||||||
|
|
||||||
// 消息
|
// 消息
|
||||||
// 头部按照内存布局,但是数据和校验部分不是
|
// 头部按照内存布局,但是数据和校验部分不是
|
||||||
// 请求 0038-0403-0000-BC4C,从0x38发往0(广播),功能4,标识3(保留字段用于业务),序号0长度0,校验0x4CBC(小字节序)
|
|
||||||
// 响应 3856-048x-0000-xxxx
|
|
||||||
// 错误 3856-044x-0000
|
|
||||||
// 负载 0038-1000-0003-030303-A936,从0x38广播,功能4,长度3,负载03-03-03
|
|
||||||
class TinyMessage : public Message
|
class TinyMessage : public Message
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -21,7 +17,7 @@ public:
|
||||||
byte Dest; // 目的地址
|
byte Dest; // 目的地址
|
||||||
byte Src; // 源地址
|
byte Src; // 源地址
|
||||||
byte _Code; // 功能代码
|
byte _Code; // 功能代码
|
||||||
byte Retry:2; // 标识位。也可以用来做二级命令
|
byte Retry:2; // 重发次数。
|
||||||
byte TTL:2; // 路由TTL。最多3次转发
|
byte TTL:2; // 路由TTL。最多3次转发
|
||||||
byte NoAck:1; // 是否不需要确认包
|
byte NoAck:1; // 是否不需要确认包
|
||||||
byte Ack:1; // 确认包
|
byte Ack:1; // 确认包
|
||||||
|
@ -55,27 +51,26 @@ public:
|
||||||
// 验证消息校验码是否有效
|
// 验证消息校验码是否有效
|
||||||
virtual bool Valid() const;
|
virtual bool Valid() const;
|
||||||
|
|
||||||
|
// 创建当前消息对应的响应消息。设置源地址目的地址、功能代码、序列号、标识位
|
||||||
TinyMessage CreateReply() const;
|
TinyMessage CreateReply() const;
|
||||||
|
|
||||||
// 显示消息内容
|
// 显示消息内容
|
||||||
virtual void Show() const;
|
virtual void Show() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RingQueue;
|
|
||||||
|
|
||||||
// 环形队列。记录收到消息的序列号,防止短时间内重复处理消息
|
// 环形队列。记录收到消息的序列号,防止短时间内重复处理消息
|
||||||
class RingQueue
|
class RingQueue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int Index;
|
int Index;
|
||||||
ushort Arr[32];
|
ushort Arr[32];
|
||||||
ulong Expired; // 过期时间,微秒
|
ulong Expired; // 过期时间,微秒
|
||||||
|
|
||||||
RingQueue();
|
RingQueue();
|
||||||
void Push(ushort item);
|
void Push(ushort item);
|
||||||
int Find(ushort item) const;
|
int Find(ushort item) const;
|
||||||
|
|
||||||
bool Check(ushort item);
|
bool Check(ushort item);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 统计信息
|
// 统计信息
|
||||||
|
@ -102,24 +97,22 @@ public:
|
||||||
byte Using; // 是否在使用
|
byte Using; // 是否在使用
|
||||||
byte Seq; // 序列号
|
byte Seq; // 序列号
|
||||||
byte Data[64];
|
byte Data[64];
|
||||||
uint Length;
|
ushort Length;
|
||||||
uint Period; // 延迟间隔ms。每次逐步递增
|
ushort Times; // 发送次数
|
||||||
ulong StartTime; // 开始时间ms
|
ulong StartTime; // 开始时间ms
|
||||||
ulong Next; // 下一次重发时间ms
|
ulong Next; // 下一次重发时间ms
|
||||||
ulong Expired; // 过期时间ms
|
ulong Expired; // 过期时间ms
|
||||||
uint Times; // 发送次数
|
|
||||||
ulong LastSend; // 最后一次发送时间ms
|
ulong LastSend; // 最后一次发送时间ms
|
||||||
|
|
||||||
void SetMessage(const TinyMessage& msg);
|
void Set(const TinyMessage& msg, int msTimeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 消息控制器。负责发送消息、接收消息、分发消息
|
// 消息控制器。负责发送消息、接收消息、分发消息
|
||||||
class TinyController : public Controller
|
class TinyController : public Controller
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
MessageNode _Queue[4]; // 消息队列。最多允许16个消息同时等待响应
|
MessageNode _Queue[4]; // 消息队列。最多允许4个消息同时等待响应
|
||||||
|
|
||||||
uint _Sequence; // 控制器的消息序号
|
|
||||||
RingQueue _Ring; // 环形队列
|
RingQueue _Ring; // 环形队列
|
||||||
uint _taskID; // 发送队列任务
|
uint _taskID; // 发送队列任务
|
||||||
|
|
||||||
|
@ -145,18 +138,16 @@ public:
|
||||||
|
|
||||||
virtual void Open();
|
virtual void Open();
|
||||||
|
|
||||||
// 发送消息,传输口参数为空时向所有传输口发送消息
|
// 发送消息
|
||||||
virtual bool Send(Message& msg);
|
virtual bool Send(Message& msg);
|
||||||
|
|
||||||
// 发送消息,传输口参数为空时向所有传输口发送消息
|
|
||||||
uint Post(byte dest, byte code, const Array& arr);
|
|
||||||
// 把消息放入发送队列,usTimeout微秒超时时间内,如果对方没有响应,会重复发送
|
|
||||||
bool Post(TinyMessage& msg, int usTimeout = -1);
|
|
||||||
// 回复对方的请求消息
|
// 回复对方的请求消息
|
||||||
virtual bool Reply(Message& msg);
|
virtual bool Reply(Message& msg);
|
||||||
// 广播消息,不等待响应和确认
|
// 广播消息,不等待响应和确认
|
||||||
bool Broadcast(TinyMessage& msg);
|
bool Broadcast(TinyMessage& msg);
|
||||||
|
|
||||||
|
// 放入发送队列,超时之前,如果对方没有响应,会重复发送
|
||||||
|
bool Post(const TinyMessage& msg, int msTimeout = -1);
|
||||||
|
|
||||||
// 循环处理待发送的消息队列
|
// 循环处理待发送的消息队列
|
||||||
void Loop();
|
void Loop();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue