This commit is contained in:
parent
cb9f744a62
commit
83640f18c4
|
@ -0,0 +1,8 @@
|
||||||
|
#include "UTPort.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void UTCom::DoFunc(Buffer & packet, MemoryStream & ret)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef __UTPort_H__
|
||||||
|
#define __UTPort_H__
|
||||||
|
|
||||||
|
#include "Sys.h"
|
||||||
|
|
||||||
|
enum PacketEorrCode : byte
|
||||||
|
{
|
||||||
|
Good = 1,
|
||||||
|
CmdError = 2,
|
||||||
|
NoPort = 3,
|
||||||
|
Error = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PacketFlag : byte
|
||||||
|
{
|
||||||
|
Save = 1, // 保存
|
||||||
|
CycleDo = 1, // 定时执行
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
PacketEorrCode ErrorCode;
|
||||||
|
PacketFlag Flag;
|
||||||
|
}PacketUnion;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
byte PortID; // 端口号
|
||||||
|
byte Seq; // paket序列号 回复消息的时候原样返回不做校验 每个端口各自有一份
|
||||||
|
byte Type; // 数据类型
|
||||||
|
PacketUnion Error; // 错误编码返回时候使用(凑对齐) 数据包标识云端下发命令事使用 平时为0
|
||||||
|
ushort Length; // 数据长度
|
||||||
|
void * Next()const { return (void*)(&Length + Length + sizeof(Length)); };
|
||||||
|
}PacketHead;
|
||||||
|
|
||||||
|
|
||||||
|
// unvarnished transmission 透传端口基类
|
||||||
|
class UTPort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
byte Seq; // SEQ 值 用于辨认包的先后顺序,255 应该足够
|
||||||
|
String * Name; // 传输口名称
|
||||||
|
virtual void DoFunc(Buffer & packet, MemoryStream & ret) = 0; // packet 为输入命令,ret为返回值。
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
// 放到其他地方去 不要放在此处。
|
||||||
|
class UTCom : public UTPort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// SerialPort * Port;
|
||||||
|
virtual void DoFunc(Buffer & packet, MemoryStream & ret);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,10 +1,74 @@
|
||||||
#include "UTPacket.h"
|
#include "UTPacket.h"
|
||||||
|
|
||||||
|
|
||||||
void UTCom::DoFunc(Buffer & packet, MemoryStream & ret)
|
UTPacket* UTPacket::Current = nullptr;
|
||||||
|
|
||||||
|
UTPacket::UTPacket()
|
||||||
{
|
{
|
||||||
|
Ports.Clear();
|
||||||
|
Client = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UTPacket::UTPacket(TokenClient * client)
|
||||||
|
{
|
||||||
|
Ports.Clear();
|
||||||
|
if(client)Client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
UTPacket::~UTPacket()
|
||||||
|
{
|
||||||
|
Ports.Clear();
|
||||||
|
if (AycUptTaskId)Sys.RemoveTask(AycUptTaskId);
|
||||||
|
if (CacheA)delete CacheA;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UTPacket::Set(TokenClient * client)
|
||||||
|
{
|
||||||
|
// 设置迟了会直接启用
|
||||||
|
if (client)Client = client;
|
||||||
|
if (Ports.Count() && Client)Client->Register("UTPacket", &UTPacket::PressTMsg, this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 异步发送
|
||||||
|
void UTPacket::AsynUpdata()
|
||||||
|
{
|
||||||
|
if (!CacheA->Position())return;
|
||||||
|
Buffer data(CacheA->GetBuffer(), CacheA->Position());
|
||||||
|
Client->Invoke("UTPacket", data); // 发送
|
||||||
|
CacheA->SetPosition(0); // 清空缓冲区
|
||||||
|
Sys.SetTask(AycUptTaskId, false); // 不考虑双缓冲区,即不考虑发的时候有数据进缓冲区!!
|
||||||
|
// 关闭减少系统调度
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UTPacket::Send(Buffer &packet)
|
||||||
|
{
|
||||||
|
if (!Client|| !packet.Length())return false;
|
||||||
|
if ( packet.Length() > 256)Client->Invoke("UTPacket", packet); // 超过256 直接发送 减少拷贝的问题
|
||||||
|
if (!CacheA)CacheA = new MemoryStream();
|
||||||
|
if (!AycUptTaskId)AycUptTaskId = Sys.AddTask(&UTPacket::AsynUpdata,this,3000,3000,"UTPacket");
|
||||||
|
|
||||||
|
CacheA->Write(packet);
|
||||||
|
Sys.SetTask(AycUptTaskId, true, 3000); // 默认3秒后发送
|
||||||
|
if (CacheA->Position() > 1024)AsynUpdata(); // 超过1k直接调度 因为上面的256限制 所以这里最大1280 不超标
|
||||||
|
// Sys.SetTask(AycUptTaskId, true, 0); // 直接调用更直接 减少系统调度损耗时间
|
||||||
|
// 此处的优化会造成不能在中断内调用,如果有问题改用Sys.SetTask
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UTPacket::Register(byte id, UTPort* port)
|
||||||
|
{
|
||||||
|
Ports.Add((uint)id, port);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool UTPacket::PressTMsg(const BinaryPair& args, Stream& result)
|
bool UTPacket::PressTMsg(const BinaryPair& args, Stream& result)
|
||||||
{
|
{
|
||||||
Buffer buff = args.Get("Data"); // 引用源数据区,后面使用要小心,不能修改任何值。
|
Buffer buff = args.Get("Data"); // 引用源数据区,后面使用要小心,不能修改任何值。
|
||||||
|
@ -16,15 +80,15 @@ bool UTPacket::PressTMsg(const BinaryPair& args, Stream& result)
|
||||||
|
|
||||||
while (head<tail)
|
while (head<tail)
|
||||||
{
|
{
|
||||||
if ((uint)head->Next() >(uint)tail)break; // 要么越界,要么数据包错
|
if ((uint)head->Next() >(uint)tail)break; // 要么越界,要么数据包错
|
||||||
|
|
||||||
MemoryStream resms;
|
MemoryStream resms;
|
||||||
if (!Ports.TryGetValue((uint)head->PortID, port) || !port) // 获取端口
|
if (!Ports.TryGetValue((uint)head->PortID, port) || !port) // 获取端口
|
||||||
{
|
{
|
||||||
PacketHead err; // 获取失败 返回错误信息
|
PacketHead err; // 获取失败 返回错误信息
|
||||||
err.Seq = head->Seq;
|
err.Seq = head->Seq;
|
||||||
err.Length = 0;
|
err.Length = 0;
|
||||||
err.Error = NoPort; // 无端口的错误 需要定义类型
|
err.Error.ErrorCode = NoPort; // 无端口的错误 需要定义类型
|
||||||
err.PortID = head->PortID;
|
err.PortID = head->PortID;
|
||||||
err.Type = head->Type;
|
err.Type = head->Type;
|
||||||
Buffer errbuf(&err, sizeof(PacketHead));
|
Buffer errbuf(&err, sizeof(PacketHead));
|
||||||
|
@ -32,11 +96,11 @@ bool UTPacket::PressTMsg(const BinaryPair& args, Stream& result)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer packet(head, head->Length + sizeof(PacketHead));
|
Buffer packet(head, head->Length + sizeof(PacketHead)); // 封装Packet
|
||||||
port->DoFunc(packet, resms); // 执行 返回相应的信息
|
port->DoFunc(packet, resms); // 执行 返回相应的信息
|
||||||
result.Write(Buffer(resms.GetBuffer(), resms.Position())); // 写入响应
|
result.Write(Buffer(resms.GetBuffer(), resms.Position())); // 写入响应
|
||||||
|
|
||||||
head = (PacketHead*)head->Next();
|
head = (PacketHead*)head->Next(); // 下一个Packet
|
||||||
port = nullptr;
|
port = nullptr;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -4,55 +4,37 @@
|
||||||
#include "Sys.h"
|
#include "Sys.h"
|
||||||
#include "TokenNet\TokenMessage.h"
|
#include "TokenNet\TokenMessage.h"
|
||||||
#include "Message\BinaryPair.h"
|
#include "Message\BinaryPair.h"
|
||||||
|
#include "Device\UTPort.h"
|
||||||
|
#include "TokenNet\TokenClient.h"
|
||||||
|
|
||||||
|
|
||||||
enum EorrCode : byte
|
|
||||||
{
|
|
||||||
Good = 1,
|
|
||||||
CmdError = 2,
|
|
||||||
NoPort = 3,
|
|
||||||
Error = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
byte PortID; // 端口号
|
|
||||||
byte Seq; // paket序列号 回复消息的时候原样返回不做校验
|
|
||||||
byte Type; // 数据类型
|
|
||||||
EorrCode Error; // 错误编码返回时候使用 (凑对齐)
|
|
||||||
ushort Length; // 数据长度
|
|
||||||
void * Next()const { return (void*)(&Length + Length + sizeof(Length)); };
|
|
||||||
}PacketHead;
|
|
||||||
|
|
||||||
// unvarnished transmission 透传端口基类
|
|
||||||
class UTPort
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
String * Name; // 传输口名称
|
|
||||||
virtual void DoFunc(Buffer & packet, MemoryStream & ret) = 0; // packet 为输入命令,ret为返回值。
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
// 放到其他地方去 不要放在此处。
|
|
||||||
class UTCom : public UTPort
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// SerialPort * Port;
|
|
||||||
virtual void DoFunc(Buffer & packet, MemoryStream & ret);
|
|
||||||
};
|
|
||||||
|
|
||||||
// unvarnished transmission 透传报文
|
// unvarnished transmission 透传报文
|
||||||
// 由bsp注册端口到 Ports ID和对应的类
|
// 由bsp注册端口到 Ports ID和对应的类
|
||||||
// C++ 没有反射 找不到由UTPort派生的子类。
|
// C++ 没有反射 找不到由UTPort派生的子类。
|
||||||
// 为了节省内存,UTPort只包含Port指针 Name指针 和一个虚函数 在没有create之前只占用12字节(3个指针)
|
// 为了节省内存,UTPort只包含Port指针 Name指针 和一个虚函数 在没有create之前只占用12字节(3个指针)
|
||||||
class UTPacket : public Object
|
class UTPacket : public Object
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
Dictionary<uint, UTPort*> Ports; // 端口集合 Dic不支持byte 所以用uint替代
|
Dictionary<uint, UTPort*> Ports; // 端口集合 Dic不支持byte 所以用uint替代
|
||||||
|
TokenClient * Client; //
|
||||||
|
uint AycUptTaskId; // 异步上传数据ID
|
||||||
|
MemoryStream * CacheA; // 缓冲数据
|
||||||
|
// MemoryStream * CacheB; // 暂时不考虑双缓冲结构
|
||||||
|
|
||||||
|
public:
|
||||||
|
UTPacket();
|
||||||
|
UTPacket(TokenClient * client);
|
||||||
|
~UTPacket();
|
||||||
|
|
||||||
|
bool Set(TokenClient* client);
|
||||||
|
|
||||||
|
bool Send(Buffer & packet);
|
||||||
|
void AsynUpdata();
|
||||||
|
bool Register(byte id,UTPort* port);
|
||||||
bool PressTMsg(const BinaryPair& args, Stream& result);
|
bool PressTMsg(const BinaryPair& args, Stream& result);
|
||||||
// Client.Register("UTPacket",&UTPacket::PressTMsg,this);
|
// Client.Register("UTPacket",&UTPacket::PressTMsg,this);
|
||||||
|
|
||||||
|
static UTPacket * Current;
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
virtual String& ToStr(String& str) const;
|
virtual String& ToStr(String& str) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue