JD2022-TU1/main/extern/ITNetwork/gear/private/tools/hio2pcproxy/hio2proxy.h

193 lines
5.6 KiB
C++

#pragma once
#include <gear.h>
#include <revolution/hio2.h>
// RULE FOR MOST APPL
// RESERVE 1024 first bytes FROM NDEV
// RESERVE the following 1024 bytes TO NDEV
#define GEAR_NDEVWIIMOTE_HIO2_DATAADDR_FROM_NDEV 0
#define GEAR_NDEVWIIMOTE_HIO2_DATAADDR_TO_NDEV GEAR_KB(1)
// Id of message sent from the NDEV
#define GEAR_NDEVWIIMOTE_HIO2_FROM_NDEV 4501
// Id of message sent to the NDEV
#define GEAR_NDEVWIIMOTE_HIO2_TO_NDEV 4502
#define GEAR_NDEVWIIMOTE_TIMEOUT_SEC 5
// Singleton
// Start HIO2, ConnectionThread, StatusThread
// Act as a server which a PC application can connect and get data from a connected NDEV
// with HIO2. With the HIO2 callback it receive information and sent it back to the PC via TCP.
class Hio2Proxy
{
public:
static inline Hio2Proxy* GetInstance()
{
if (!m_Instance)
{
m_Instance = GEAR_ALLOC(Hio2Proxy, 1, GEAR_NS::DefaultAllocator(), 0, "Hio2Proxy");
new(m_Instance) Hio2Proxy;
}
return m_Instance;
}
static inline void Shutdown()
{
if (m_Instance)
{
m_Instance->~Hio2Proxy();
GEAR_FREE(m_Instance);
}
}
inline GEAR_NS::Bool GetFinish()
{
// Error or finish message from either one of these trigger the end of the application.
return m_Finish || m_ConnectionThread.IsFinish();
}
inline HIO2Handle GetHandle()
{
return m_Handle;
}
inline void SetConnectionPort(GEAR_NS::U16 port)
{
m_ConnectionThread.SetPort(port);
}
// Init thread and HIO2
void Init();
void SetDevice(HIO2DevicePath device);
void Receive(HIO2Handle handle);
void UpdateStatus();
// HIO2 Callbacks
static BOOL __hio2EnumDevicesCB( HIO2DevicePath pathName, LPVOID param );
static void __hio2ReceiveCB( HIO2Handle handle );
static int __hio2NotifyCB( HIO2NotifyEvent event, LPVOID param );
private:
// This is the server thread which a PC application can connect.
class ConnectionThread : public GEAR_NS::Thread
{
public:
ConnectionThread();
~ConnectionThread();
virtual void Run();
// Basic TCP send
GEAR_NS::Bool Send(const GEAR_NS::Char* buffer, GEAR_NS::U32 len)
{
if (m_ClientSocket)
{
GEAR_NS::S32 bytesSent = m_ClientSocket->Send(buffer, len);
if (m_ClientSocket->GetError() != GEAR_NS::Socket::EOk &&
m_ClientSocket->GetError() != GEAR_NS::Socket::ETimedOut &&
m_ClientSocket->GetError() != GEAR_NS::Socket::EWouldBlock)
return GEAR_NS::False;
if (bytesSent < 0)
return GEAR_NS::False;
return GEAR_NS::True;
}
return GEAR_NS::False;
}
inline GEAR_NS::Bool IsConnected()
{
return m_IsConnected;
}
inline GEAR_NS::Bool IsFinish()
{
return m_Finish;
}
inline void SetFinish()
{
m_Finish = GEAR_NS::True;
}
inline void SetPort(GEAR_NS::U16 port)
{
m_Port = port;
}
private:
GEAR_NS::Bool m_IsConnected;
GEAR_NS::Bool m_Finish;
GEAR_NS::TcpSocket m_ServerSocket;
GEAR_NS::TcpSocket* m_ClientSocket;
GEAR_NS::Char* m_WriteBuffer;
GEAR_NS::U16 m_Port;
};
// Because HIO2 is not a so great library we need to have a thread
// that read the HIO2 mailbox constantly when where not connected.
// That way if the NDEV write mailbox and there nobody to read it
// it will not fill the mailbox yeilding to many error on the NDEV
// side.
class StatusThread : public GEAR_NS::Thread
{
public:
inline StatusThread() : m_Finish(GEAR_NS::False) {}
inline ~StatusThread() {}
virtual void Run();
inline GEAR_NS::Bool IsFinish()
{
return m_Finish;
}
inline void SetFinish()
{
m_Finish = GEAR_NS::True;
}
private:
GEAR_NS::Bool m_Finish;
};
private:
Hio2Proxy();
~Hio2Proxy();
// Uninit thread and HIO2
void UnInit();
// Basic send to HIO2. Length is the real length, it will be rounded to
// the next multiple of 32. The data must be after the first 4 bytes of
// buffer (start at &buffer[sizeof(GEAR_NS::U32)]). Since we will put
// the length in those first 4 bytes.
GEAR_NS::Bool SendMessageToNDev(GEAR_NS::Char* buffer, GEAR_NS::U32 length);
GEAR_NS::Bool m_Finish;
HIO2Handle m_Handle;
GEAR_NS::GearString m_DevicePath;
// 32 bytes align
GEAR_NS::Char* m_ReceiveBuffer;
// last message from the NDEV, for now we will ignore all message except GEAR_NDEVWIIMOTE_HIO2_FROM_NDEV
u32 m_LastMsg;
ConnectionThread m_ConnectionThread;
StatusThread m_UpdateStatus;
static Hio2Proxy* m_Instance;
};