SmartOS/TinyNet/TokenClient.cpp

278 lines
5.8 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 "TokenClient.h"
#include "SerialPort.h"
#include "TokenMessage.h"
bool OnTokenClientReceived(Message& msg, void* param);
void HelloTask(void* param);
void PingTask(void* param);
static uint _taskHello = 0;
//static uint _taskPing = 0;
TokenClient::TokenClient(TokenController* control)
{
assert_ptr(control);
_control = control;
Token = 0;
memset(ID, 0, ArrayLength(ID));
memset(Key, 0, ArrayLength(Key));
LoginTime = 0;
LastActive = 0;
_control->Received = OnTokenClientReceived;
_control->Param = this;
Received = NULL;
Param = NULL;
OnHello = NULL;
//OnPing = NULL;
Switchs = NULL;
Regs = NULL;
#if DEBUG
_control->AddTransport(SerialPort::GetMessagePort());
#endif
// 注册消息。每个消息代码对应一个功能函数
_control->Register(1, Hello, this);
//_control->Register(2, Ping, this);
//_control->Register(3, SysID, this);
//_control->Register(4, SysTime, this);
//_control->Register(5, SysMode, this);
// 发现服务端的任务
debug_printf("开始寻找服务端 ");
_taskHello = Sys.AddTask(HelloTask, this, 0, 2000000);
}
void TokenClient::Send(Message& msg)
{
_control->Send(msg);
}
void TokenClient::Reply(Message& msg)
{
_control->Reply(msg);
}
bool OnTokenClientReceived(Message& msg, void* param)
{
TokenClient* client = (TokenClient*)param;
assert_ptr(client);
// 消息转发
if(client->Received) return client->Received(msg, client->Param);
return true;
}
// 常用系统级消息
void HelloTask(void* param)
{
assert_ptr(param);
TokenClient* client = (TokenClient*)param;
client->Hello();
}
// 发送发现消息,告诉大家我在这
// 请求2版本 + S类型 + S名称 + 8本地时间 + 本地IP端口 + S支持加密算法列表
// 响应2版本 + S类型 + S名称 + 8对方时间 + 对方IP端口 + S加密算法 + N密钥
void TokenClient::Hello()
{
TokenMessage msg(1);
// 发送的广播消息设备类型和系统ID
Stream ms(msg._Data, ArrayLength(msg._Data));
ms.Length = 0;
ms.Write(Sys.Version);
// 注意Code小字节序
ushort code = Sys.Code << 8;
code |= Sys.Code >> 8;
byte type[4];
Sys.ToHex(type, (byte*)&code, 2);
ms.Write((byte)4);
ms.Write(type, 0, 4);
ms.Write(Sys.Name);
ms.Write(Time.Now().TotalMicroseconds() * 10);
ms.Write((int)0);
ms.Write((ushort)3377);
char ds[] = "RC4";
ms.Write((byte)1);
ms.Write((byte)(ArrayLength(ds) - 1));
ms.Write((byte*)ds, 0, ArrayLength(ds) - 1);
msg.Length = ms.Length;
_control->SendAndReceive(msg, 3, 500);
msg.Show();
}
// Discover响应
// 格式1字节地址 + 8字节密码
bool TokenClient::Hello(Message& msg, void* param)
{
TokenMessage& tmsg = (TokenMessage&)msg;
// 客户端只处理Discover响应
if(!tmsg.Reply) return true;
assert_ptr(param);
TokenClient* client = (TokenClient*)param;
//TokenController* ctrl = (TokenController*)client->_control;
// 解析数据
Stream ms(msg.Data, msg.Length);
// 取消Discover任务
debug_printf("停止寻找服务端 ");
Sys.RemoveTask(_taskHello);
_taskHello = 0;
if(client->OnHello) return client->OnHello(msg, param);
return true;
}
/*void PingTask(void* param)
{
assert_ptr(param);
TokenClient* client = (TokenClient*)param;
client->Ping();
}
// Ping指令用于保持与对方的活动状态
void TokenClient::Ping()
{
if(LastActive > 0 && LastActive + 30000000 < Time.Current())
{
// 30秒无法联系服务端可能已经掉线重启Discover任务关闭Ping任务
debug_printf("30秒无法联系服务端可能已经掉线重启Discover任务关闭Ping任务\r\n");
debug_printf("停止Ping服务端 ");
Sys.RemoveTask(_taskPing);
debug_printf("开始寻找服务端 ");
_taskHello = Sys.AddTask(DiscoverTask, this, 0, 2000000);
Server = 0;
Password = 0;
return;
}
Message* msg = _control->Create();
msg->Code = 2;
_control->Send(*msg);
delete msg;
if(LastActive == 0) LastActive = Time.Current();
}
bool TokenClient::Ping(Message& msg, void* param)
{
assert_ptr(param);
TokenClient* client = (TokenClient*)param;
TokenMessage& tmsg = (TokenMessage&)msg;
// 忽略响应消息
if(tmsg.Reply)
{
if(tmsg.Src == client->Server) client->LastActive = Time.Current();
return true;
}
debug_printf("Message_Ping Length=%d\r\n", msg.Length);
if(client->OnPing) return client->OnPing(msg, param);
return true;
}
// 系统时间获取与设置
bool TokenClient::SysTime(Message& msg, void* param)
{
TokenMessage& tmsg = (TokenMessage&)msg;
// 忽略响应消息
if(tmsg.Reply) return true;
debug_printf("Message_SysTime Length=%d\r\n", msg.Length);
// 负载数据决定是读时间还是写时间
if(msg.Length >= 8)
{
// 写时间
ulong us = *(ulong*)msg.Data;
Time.SetTime(us);
}
// 读时间
ulong us2 = Time.Current();
msg.Length = 8;
*(ulong*)msg.Data = us2;
return true;
}
bool TokenClient::SysID(Message& msg, void* param)
{
TokenMessage& tmsg = (TokenMessage&)msg;
// 忽略响应消息
if(tmsg.Reply) return true;
debug_printf("Message_SysID Length=%d\r\n", msg.Length);
if(msg.Length == 0)
{
// 12字节ID4字节CPUID4字节设备ID
msg.SetData(Sys.ID, 5 << 2);
}
else
{
// 干脆直接输出Sys前面11个uint
msg.SetData((byte*)&Sys, 11 << 2);
}
return true;
}
bool TokenClient::SysMode(Message& msg, void* param)
{
TokenMessage& tmsg = (TokenMessage&)msg;
// 忽略响应消息
if(tmsg.Reply) return true;
byte mode = 0;
if(msg.Length > 0) mode = msg.Data[0];
debug_printf("Message_SysMode Length=%d Mode=%d\r\n", msg.Length, mode);
switch(mode)
{
case 1: // 系统软重启
Sys.Reset();
break;
}
msg.Length = 1;
msg.Data[0] = 0;
return true;
}*/