SmartOS/TinyNet/TokenMessage.cpp

178 lines
3.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "TokenMessage.h"
TokenMessage::TokenMessage(byte code) : Message(code)
{
Data = _Data;
/*Token = 0;
_Code = 0;
Error = 0;
_Length = 0;*/
memset(&Token, 0, HeaderSize);
Checksum= 0;
Crc = 0;
}
bool TokenMessage::Read(MemoryStream& ms)
{
if(ms.Remain() < MinSize) return false;
ms.Read((byte*)&Token, 0, HeaderSize);
// 占位符拷贝到实际数据
Code = _Code;
Length = _Length;
if(ms.Remain() < Length + 4) return false;
if(Length > 0) ms.Read(Data, 0, Length);
Checksum = ms.Read<uint>();
// 令牌消息是连续的可以直接计算CRC
Crc = Sys.Crc(&Token, HeaderSize + Length);
return true;
}
void TokenMessage::Write(MemoryStream& ms)
{
// 实际数据拷贝到占位符
_Code = Code;
_Length = Length;
ms.Write((byte*)&Token, 0, HeaderSize);
if(Length > 0) ms.Write(Data, 0, Length);
// 令牌消息是连续的可以直接计算CRC
Checksum = Crc = Sys.Crc(&Token, HeaderSize + Length);
ms.Write(Checksum);
}
void TokenMessage::ComputeCrc()
{
MemoryStream ms(Size());
Write(ms);
// 扣除不计算校验码的部分
Checksum = Crc = Sys.Crc(ms.GetBuffer(), HeaderSize + Length);
}
// 验证消息校验码是否有效
bool TokenMessage::Valid() const
{
if(Checksum == Crc) return true;
debug_printf("Message::Valid Crc Error %04X != Checksum: %04X \r\n", Crc, Checksum);
return false;
}
uint TokenMessage::Size() const
{
return HeaderSize + Length + 4;
}
void TokenMessage::SetError(byte error)
{
Error = 1;
Length = 1;
Data[0] = error;
}
TokenController::TokenController(ITransport* port) : Controller(port)
{
Init();
}
TokenController::TokenController(ITransport* ports[], int count) : Controller(ports, count)
{
Init();
}
void TokenController::Init()
{
Token = 0;
MinSize = TokenMessage::MinSize;
}
TokenController::~TokenController()
{
}
// 创建消息
Message* TokenController::Create() const
{
return new TokenMessage();
}
// 发送消息,传输口参数为空时向所有传输口发送消息
bool TokenController::Send(byte code, byte* buf, uint len)
{
TokenMessage msg;
msg.Code = code;
msg.SetData(buf, len);
return Send(msg);
}
// 发送消息
/*bool TokenController::Send(TokenMessage& msg, int expire)
{
MemoryStream ms(msg.Size());
msg.Write(ms);
while(true)
{
//_port->Write(ms.GetBuffer(), ms.Length);
if(expire <= 0) break;
// 等待响应
Sys.Sleep(1);
}
return true;
}*/
// 收到消息校验后调用该函数。返回值决定消息是否有效,无效消息不交给处理器处理
bool TokenController::OnReceive(Message& msg, ITransport* port)
{
TokenMessage& tmsg = (TokenMessage&)msg;
// 代码为0是非法的
if(!msg.Code) return false;
// 只处理本机消息或广播消息。快速处理,高效。
if(tmsg.Token != Token && tmsg.Token != 0) return false;
#if MSG_DEBUG
/*msg_printf("TokenController::Dispatch ");
// 输出整条信息
Sys.ShowHex(buf, ms.Length, '-');
msg_printf("\r\n");*/
#endif
return true;
}
// 发送消息,传输口参数为空时向所有传输口发送消息
int TokenController::Send(Message& msg, ITransport* port)
{
TokenMessage& tmsg = (TokenMessage&)msg;
// 附上自己的地址
tmsg.Token = Token;
#if MSG_DEBUG
// 计算校验
msg.ComputeCrc();
ShowMessage(tmsg, true);
#endif
return Controller::Send(msg, port);
}