1858 lines
45 KiB
C++
1858 lines
45 KiB
C++
#ifdef _WIN32
|
|
|
|
#define _CRT_SECURE_NO_WARNINGS
|
|
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
#include <io.h>
|
|
#pragma comment(lib, "ws2_32.lib")
|
|
#pragma comment(lib, "winmm.lib")
|
|
|
|
#else
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h> // sockaddr_in
|
|
#include <arpa/inet.h> // inet_ntoa()
|
|
#include <unistd.h> // close()
|
|
#include <netdb.h> // gethostbyname()
|
|
#include <fcntl.h> // F_GETFL, O_NONBLOCK
|
|
#include <netinet/tcp.h> // TCP_NODELAY
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
//#include <pthread.h>
|
|
#include <stdarg.h>
|
|
|
|
|
|
typedef int BOOL;
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
|
|
#define INVALID_SOCKET (SOCKET)(~0)
|
|
#define SOCKET_ERROR (-1)
|
|
|
|
#define SD_RECEIVE SHUT_RD
|
|
#define SD_SEND SHUT_WR
|
|
#define SD_BOTH SHUT_RDWR
|
|
|
|
typedef int SOCKET;
|
|
|
|
#define closesocket close
|
|
|
|
|
|
inline unsigned int timeGetTime()
|
|
{
|
|
#if 0
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL); // obsolescent at 2008
|
|
|
|
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
|
#else
|
|
//struct timespec ts;
|
|
//clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
|
|
//return (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
|
|
struct timespec ts;
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
|
|
uint64_t ms = (uint64_t)ts.tv_sec * 1000ULL +
|
|
(uint64_t)ts.tv_nsec / 1000000ULL;
|
|
|
|
return (unsigned int)ms; // 32bit wrap intentionally
|
|
#endif
|
|
}
|
|
#define GetTickCount timeGetTime
|
|
|
|
inline void Sleep(unsigned int nTime)
|
|
{
|
|
#if 0
|
|
struct timeval tv;
|
|
|
|
tv.tv_sec = nTime / 1000;
|
|
tv.tv_usec = (nTime % 1000) * 1000; // msec
|
|
|
|
select(0, NULL, NULL, NULL, &tv);
|
|
#else
|
|
struct timespec ts;
|
|
|
|
ts.tv_sec = nTime / 1000;
|
|
ts.tv_nsec = (nTime % 1000) * 1000000; // nsec
|
|
|
|
nanosleep(&ts, NULL);
|
|
#endif
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
|
|
#ifdef _DEBUG
|
|
#include <crtdbg.h>
|
|
#endif
|
|
|
|
#include <list>
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
inline int GetSockError()
|
|
{
|
|
#ifdef _WIN32
|
|
return WSAGetLastError();
|
|
#else
|
|
return errno;
|
|
#endif
|
|
}
|
|
|
|
int GetSockOptError(SOCKET sock)
|
|
{
|
|
int nOptVal;
|
|
socklen_t nOptLen = sizeof(int);
|
|
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)(&nOptVal), &nOptLen) < 0)
|
|
return GetSockError();
|
|
|
|
return nOptVal;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
VOID WINAPI FlsBufferFree(PVOID lpFlsData)
|
|
{
|
|
if (lpFlsData != NULL)
|
|
{
|
|
fprintf(stdout, "DEBUG, FlsBufferFree, lpFlsData = 0x%p\n", lpFlsData);
|
|
LocalFree(lpFlsData);
|
|
}
|
|
}
|
|
|
|
char * GetLocalStorageBuffer(DWORD nFlsIdx, size_t nSize)
|
|
{
|
|
char * pszBuffer = (char *)FlsGetValue(nFlsIdx);
|
|
if (pszBuffer == NULL)
|
|
{
|
|
pszBuffer = (char *)LocalAlloc(LPTR, nSize);
|
|
if (pszBuffer == NULL)
|
|
return NULL;
|
|
|
|
FlsSetValue(nFlsIdx, pszBuffer);
|
|
}
|
|
|
|
return pszBuffer;
|
|
}
|
|
#endif
|
|
|
|
|
|
const char * GetErrorStr(int nError)
|
|
{
|
|
#ifdef _WIN32
|
|
static DWORD nFlsIdx = FLS_OUT_OF_INDEXES;
|
|
if (nFlsIdx == FLS_OUT_OF_INDEXES)
|
|
nFlsIdx = FlsAlloc(FlsBufferFree);
|
|
|
|
char * pszBuffer = (char *)GetLocalStorageBuffer(nFlsIdx, 512);
|
|
if (pszBuffer == NULL)
|
|
return "[SystemError], Failed to LocalAlloc";
|
|
|
|
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
|
|
nError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), pszBuffer, 512, NULL) == 0)
|
|
{
|
|
sprintf(pszBuffer, "Unknown Error", nError);
|
|
}
|
|
|
|
return pszBuffer;
|
|
#else
|
|
return strerror(nError);
|
|
#endif
|
|
}
|
|
|
|
inline unsigned int TimeDiff(unsigned int nTimePrev, unsigned int nTimeCurr)
|
|
{
|
|
if (nTimePrev <= nTimeCurr)
|
|
return nTimeCurr - nTimePrev;
|
|
|
|
return nTimeCurr + (0xFFFFFFFFU - nTimePrev) + 1U;
|
|
}
|
|
|
|
// file //////////////////////////////////////////////////////////////////////
|
|
class CtFile
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
FMODE_CREATE = 0x0001,
|
|
FMODE_RDONLY = 0x0002,
|
|
FMODE_WRONLY = 0x0004,
|
|
FMODE_RW = 0x0008
|
|
};
|
|
|
|
static off_t GetSize(const char * pszFileName)
|
|
{
|
|
struct stat statTemp;
|
|
stat(pszFileName, &statTemp);
|
|
|
|
return statTemp.st_size;
|
|
}
|
|
|
|
////
|
|
|
|
CtFile()
|
|
{
|
|
m_nFile = -1;
|
|
}
|
|
|
|
~CtFile()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
int GetFile() { return m_nFile; }
|
|
|
|
bool Open(const char * pszFileName, int nMode, bool bIsBinary = true, bool bIsContinue = true)
|
|
{
|
|
int oflag = 0;
|
|
|
|
if ((nMode & FMODE_CREATE) == FMODE_CREATE)
|
|
oflag = O_CREAT;
|
|
|
|
if ((nMode & FMODE_RDONLY) == FMODE_RDONLY)
|
|
oflag |= O_RDONLY;
|
|
else if ((nMode & FMODE_WRONLY) == FMODE_WRONLY)
|
|
oflag |= O_WRONLY;
|
|
else
|
|
oflag |= O_RDWR;
|
|
|
|
if (bIsContinue == FALSE && ((nMode & FMODE_WRONLY) == FMODE_WRONLY || (nMode & FMODE_RW) == FMODE_RW))
|
|
oflag |= O_TRUNC;
|
|
|
|
#ifdef _WIN32
|
|
if (bIsBinary)
|
|
oflag |= O_BINARY;
|
|
else
|
|
oflag |= O_TEXT;
|
|
|
|
m_nFile = open(pszFileName, oflag, S_IREAD | S_IWRITE);
|
|
#else
|
|
m_nFile = open(pszFileName, oflag, S_IREAD | S_IWRITE | S_IRGRP | S_IROTH);
|
|
#endif
|
|
|
|
if (m_nFile == -1)
|
|
return false;
|
|
|
|
if (bIsContinue && ((nMode & FMODE_WRONLY) == FMODE_WRONLY || (nMode & FMODE_RW) == FMODE_RW))
|
|
lseek(m_nFile, 0L, SEEK_END);
|
|
|
|
return true;
|
|
}
|
|
|
|
void Close()
|
|
{
|
|
if (m_nFile != -1)
|
|
{
|
|
close(m_nFile);
|
|
m_nFile = -1;
|
|
}
|
|
}
|
|
|
|
int Read(void * buffer, unsigned int count)
|
|
{
|
|
return read(m_nFile, buffer, count);
|
|
}
|
|
|
|
int Write(const void * buffer, unsigned int count)
|
|
{
|
|
return write(m_nFile, buffer, count);
|
|
}
|
|
|
|
private:
|
|
int m_nFile;
|
|
};
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
class IompObject
|
|
{
|
|
public:
|
|
enum {
|
|
IOMP_DISABLE = 0,
|
|
IOMP_READY = 1,
|
|
IOMP_CONNECTING = 2,
|
|
IOMP_RECONNECTING = 3,
|
|
IOMP_LISTENING = 4,
|
|
IOMP_CLOSING = 5,
|
|
IOMP_REMOVE = 6
|
|
};
|
|
|
|
SOCKET m_sock;
|
|
int m_nState;
|
|
struct sockaddr_in m_sai; // remote or listen
|
|
unsigned int m_nPrevTick; // prev setted time
|
|
unsigned int m_nConnectTimeOut; // for connect timeout
|
|
unsigned int m_nAutoReconnectInterval; // 0: no reconnect, 1~ : msec, reconnect interval time
|
|
|
|
|
|
IompObject()
|
|
{
|
|
m_nState = IOMP_DISABLE;
|
|
memset(&m_sai, 0, sizeof(struct sockaddr_in)); // remote or listen
|
|
m_nPrevTick = 0;
|
|
m_nConnectTimeOut = 0;
|
|
m_nAutoReconnectInterval = 0;
|
|
}
|
|
|
|
int Create()
|
|
{
|
|
// create socket
|
|
m_sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (m_sock == INVALID_SOCKET)
|
|
{
|
|
fprintf(stderr, "[ERROR], Failed to socket()\n");
|
|
return -1;
|
|
}
|
|
|
|
// Set non blocking mode
|
|
#ifdef _WIN32
|
|
ULONG nNonBlock = 1;
|
|
if (ioctlsocket(m_sock, FIONBIO, &nNonBlock) == SOCKET_ERROR)
|
|
#else
|
|
int nFlags = fcntl(m_sock, F_GETFL, 0);
|
|
if (fcntl(m_sock, F_SETFL, nFlags | O_NONBLOCK) == -1)
|
|
#endif
|
|
{
|
|
int nSockError = GetSockError();
|
|
fprintf(stderr, "[ERROR], Failed to ioctlsocket. socket = %d, error = %s(%d)\n", m_sock, GetErrorStr(nSockError), nSockError);
|
|
closesocket(m_sock);
|
|
return -1;
|
|
}
|
|
|
|
int nBuffSize = 1024 * 1024 * 4; // 4Mbyte
|
|
if (setsockopt(m_sock, SOL_SOCKET, SO_SNDBUF, (const char *)&nBuffSize, sizeof(nBuffSize)) == SOCKET_ERROR)
|
|
fprintf(stderr, "[WARN], Failed to setsockopt SO_SNDBUF, socket = %d\n", m_sock);
|
|
|
|
if (setsockopt(m_sock, SOL_SOCKET, SO_RCVBUF, (const char *)&nBuffSize, sizeof(nBuffSize)) == SOCKET_ERROR)
|
|
fprintf(stderr, "[WARN], Failed to setsockopt SO_RCVBUF, socket = %d\n", m_sock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Bind(const char * pszIp, unsigned short nPort)
|
|
{
|
|
#define REUSEADDR_
|
|
#ifdef REUSEADDR_
|
|
int nOptVal = 1;
|
|
setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&nOptVal, sizeof(nOptVal)); // for multiple ip in UNIX
|
|
#endif
|
|
if (pszIp == NULL || pszIp[0] == '\0')
|
|
m_sai.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
else
|
|
m_sai.sin_addr.s_addr = inet_addr(pszIp);
|
|
|
|
m_sai.sin_family = AF_INET;
|
|
m_sai.sin_port = htons(nPort);
|
|
|
|
if (bind(m_sock, (struct sockaddr *)&m_sai, sizeof(struct sockaddr)) == -1)
|
|
{
|
|
int nSockError = GetSockError();
|
|
fprintf(stderr, "[ERROR], Failed to bind.(%s:%d) socket = %d, error = %s(%d)\n", inet_ntoa(m_sai.sin_addr), ntohs(m_sai.sin_port),
|
|
m_sock, GetErrorStr(nSockError), nSockError);
|
|
closesocket(m_sock);
|
|
return -1;
|
|
}
|
|
fprintf(stdout, "INFO, Succeeded to bind.(%s:%d), socket = %d\n", inet_ntoa(m_sai.sin_addr), ntohs(m_sai.sin_port), m_sock); // listen ip:port
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Listen(int nBackLog)
|
|
{
|
|
if (listen(m_sock, nBackLog) == -1)
|
|
{
|
|
int nSockError = GetSockError();
|
|
fprintf(stderr, "[ERROR], Failed to listen. socket = %d, error = %s(%d)\n", m_sock, GetErrorStr(nSockError), nSockError);
|
|
closesocket(m_sock);
|
|
return -1;
|
|
}
|
|
fprintf(stdout, "INFO, Succeeded to listen.(%s:%d), socket = %d\n", inet_ntoa(m_sai.sin_addr), ntohs(m_sai.sin_port), m_sock); // listen ip:port
|
|
|
|
m_nState = IOMP_LISTENING;
|
|
return 0;
|
|
}
|
|
|
|
int ConnectProc(unsigned int nCurrTick)
|
|
{
|
|
int nResult = connect(m_sock, (struct sockaddr *)&m_sai, sizeof(struct sockaddr));
|
|
|
|
#ifdef _WIN32
|
|
if (nResult == SOCKET_ERROR && GetSockError() != WSAEWOULDBLOCK)
|
|
#else
|
|
if (nResult == SOCKET_ERROR && errno != EWOULDBLOCK && errno != EINPROGRESS)
|
|
#endif
|
|
{
|
|
int nSockError = GetSockError();
|
|
fprintf(stderr, "[ERROR], Failed to connect. socket = %d, error = %s(%d)\n", m_sock, GetErrorStr(nSockError), nSockError);
|
|
closesocket(m_sock);
|
|
m_sock = INVALID_SOCKET;
|
|
return -1;
|
|
}
|
|
|
|
m_nPrevTick = nCurrTick;
|
|
m_nState = IOMP_CONNECTING;
|
|
fprintf(stdout, "INFO, TCP connecting... to %s:%d, socket = %d\n", inet_ntoa(m_sai.sin_addr), ntohs(m_sai.sin_port), m_sock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Connect(const char * pszIp, unsigned short nPort, unsigned int nTimeout, unsigned int nCurrTick = 0, unsigned int nAutoReconnectInterval = 0)
|
|
{
|
|
if (m_sock == INVALID_SOCKET)
|
|
{
|
|
fprintf(stderr, "[ERROR], This socket did not created.\n");
|
|
return -1;
|
|
}
|
|
|
|
m_sai.sin_addr.s_addr = inet_addr(pszIp);
|
|
m_sai.sin_family = AF_INET;
|
|
m_sai.sin_port = htons(nPort);
|
|
|
|
m_nConnectTimeOut = nTimeout;
|
|
m_nAutoReconnectInterval = nAutoReconnectInterval;
|
|
|
|
return ConnectProc(nCurrTick);
|
|
}
|
|
|
|
int Disconnect()
|
|
{
|
|
return shutdown(m_sock, SD_SEND);
|
|
}
|
|
|
|
bool IsConnectTimeout(unsigned int nCurrTick)
|
|
{
|
|
//fprintf(stdout, "DEBUG, m_nPrevTick = %d, nCurrTick = %d\n", m_nPrevTick, nCurrTick);
|
|
|
|
if (m_nPrevTick == 0)
|
|
{
|
|
m_nPrevTick = nCurrTick;
|
|
return false;
|
|
}
|
|
|
|
if (m_nConnectTimeOut <= 0)
|
|
return false;
|
|
|
|
if (m_nConnectTimeOut <= TimeDiff(m_nPrevTick, nCurrTick))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
int TcpCompleteSend(const char * pPacket, int nPacketSize)
|
|
{
|
|
off_t nSentSize;
|
|
const char * pszPacketOffset = pPacket;
|
|
while (nPacketSize > 0)
|
|
{
|
|
nSentSize = send(m_sock, pszPacketOffset, nPacketSize, 0);
|
|
if (nSentSize <= 0)
|
|
{
|
|
int nSockError = GetSockError();
|
|
fprintf(stderr, "[ERROR], Failed to send, sock = %d, error = %s(%d)\n", m_sock, GetErrorStr(nSockError), nSockError);
|
|
return -1;
|
|
}
|
|
|
|
nPacketSize -= nSentSize;
|
|
pszPacketOffset += nSentSize;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Receive(char * pBuffer, int nMaxSize)
|
|
{
|
|
int nReceived = recv(m_sock, pBuffer, nMaxSize, 0);
|
|
if (nReceived == -1)
|
|
{
|
|
int nSockError = GetSockError();
|
|
fprintf(stdout, "INFO, The virtual circuit was reset by the remote side executing a \"hard\" or \"abortive\" close, socket = %d, error = %s(%d)\n", m_sock, GetErrorStr(nSockError), nSockError);
|
|
shutdown(m_sock, SD_BOTH);
|
|
return -1;
|
|
}
|
|
else if (nReceived == 0)
|
|
{
|
|
fprintf(stdout, "INFO, The virtual circuit was reset by the remote side executing a \"gracefull\" shutdown, socket = %d\n", m_sock);
|
|
shutdown(m_sock, SD_SEND);
|
|
return -1;
|
|
}
|
|
|
|
return nReceived;
|
|
}
|
|
};
|
|
|
|
template<class _T>
|
|
class IompDispatcher
|
|
{
|
|
public:
|
|
IompDispatcher()
|
|
{
|
|
//m_nDispachInterval = 500; //msec, set timer
|
|
//m_nDispachInterval = 200; //msec, set timer
|
|
m_nDispachInterval = 0; //msec, set timer
|
|
m_bTerminate = false;
|
|
}
|
|
|
|
virtual ~IompDispatcher()
|
|
{
|
|
}
|
|
|
|
_T * AddSocket(_T & t)
|
|
{
|
|
m_listIomp.push_front(t);
|
|
return &m_listIomp.front();
|
|
}
|
|
|
|
int Dispatch()
|
|
{
|
|
fprintf(stdout, "INFO, IompDispatcher.Dispatch() started.\n");
|
|
|
|
fd_set fsRead, fsWrite, fsError;
|
|
int nSelectResult, nFdMax, nFdCount;
|
|
typename std::list<_T>::iterator iter;
|
|
struct timeval tvWait;
|
|
unsigned int nCurrTick = 0, nPrevTimerTick = 0;
|
|
|
|
while (m_bTerminate == false)
|
|
{
|
|
//#define TEST_TERMINATE_
|
|
#ifdef TEST_TERMINATE_ //TestCode
|
|
//static int nTestCount = 2000;
|
|
static int nTestCount = 1000;
|
|
if (nTestCount-- < 0)
|
|
break;
|
|
#endif
|
|
nCurrTick = GetTickCount();
|
|
|
|
if (m_nDispachInterval > 0 && m_nDispachInterval <= TimeDiff(nPrevTimerTick, nCurrTick))
|
|
{
|
|
OnDispatchTimer(nCurrTick);
|
|
nPrevTimerTick = nCurrTick;
|
|
}
|
|
|
|
FD_ZERO(&fsRead);
|
|
FD_ZERO(&fsWrite);
|
|
FD_ZERO(&fsError);
|
|
|
|
nFdMax = 0;
|
|
nFdCount = 0;
|
|
|
|
for (iter = m_listIomp.begin(); iter != m_listIomp.end(); iter++)
|
|
{
|
|
if (iter->m_nState == IompObject::IOMP_REMOVE)
|
|
{
|
|
OnIompDelete(&*iter, nCurrTick);
|
|
iter = m_listIomp.erase(iter);
|
|
if (m_listIomp.empty() || iter == m_listIomp.end())
|
|
break;
|
|
}
|
|
else if (iter->m_nState == IompObject::IOMP_CLOSING)
|
|
{
|
|
int nResult = OnIompClose(&*iter, nCurrTick);
|
|
iter->m_nPrevTick = nCurrTick;
|
|
closesocket(iter->m_sock);
|
|
|
|
if (iter->m_nAutoReconnectInterval > 0)
|
|
{
|
|
iter->m_sock = INVALID_SOCKET;
|
|
iter->m_nState = IompObject::IOMP_RECONNECTING;
|
|
}
|
|
else if (nResult == 0)
|
|
{
|
|
iter->m_nState = IompObject::IOMP_REMOVE;
|
|
}
|
|
else
|
|
{
|
|
iter->m_sock = INVALID_SOCKET;
|
|
iter->m_nState = IompObject::IOMP_DISABLE;
|
|
}
|
|
}
|
|
else if (iter->m_nState == IompObject::IOMP_RECONNECTING)
|
|
{
|
|
if (iter->m_nAutoReconnectInterval <= TimeDiff(iter->m_nPrevTick, nCurrTick))
|
|
{
|
|
if ((iter->Create()) == -1)
|
|
iter->m_nState = IompObject::IOMP_REMOVE;
|
|
else if (iter->ConnectProc(nCurrTick) == -1)
|
|
iter->m_nState = IompObject::IOMP_REMOVE;
|
|
}
|
|
}
|
|
else if (iter->m_nState == IompObject::IOMP_READY || iter->m_nState == IompObject::IOMP_LISTENING)
|
|
{
|
|
if (iter->m_nState == INVALID_SOCKET)
|
|
fprintf(stderr, "[ERROR_DEBUG], Invalid logic. socket = %d\n", iter->m_nState, iter->m_sock);
|
|
|
|
FD_SET(iter->m_sock, &fsRead);
|
|
//FD_SET(iter->m_sock, &fsError);
|
|
nFdCount++;
|
|
#ifndef _WIN32
|
|
if (nFdMax < iter->m_sock)
|
|
nFdMax = iter->m_sock;
|
|
#endif
|
|
}
|
|
else if (iter->m_nState == IompObject::IOMP_CONNECTING)
|
|
{
|
|
if (iter->IsConnectTimeout(nCurrTick))
|
|
{
|
|
fprintf(stdout, "[WARN], Failed to connect because of timeout. socket = %d\n", iter->m_sock);
|
|
OnIompConnect(&*iter, false, nCurrTick);
|
|
shutdown(iter->m_sock, SD_BOTH);
|
|
iter->m_nState = IompObject::IOMP_CLOSING;
|
|
}
|
|
else
|
|
{
|
|
if (iter->m_nState == INVALID_SOCKET)
|
|
fprintf(stderr, "[ERROR_DEBUG], Invalid logic. socket = %d\n", iter->m_nState, iter->m_sock);
|
|
|
|
FD_SET(iter->m_sock, &fsWrite);
|
|
nFdCount++;
|
|
#ifndef _WIN32
|
|
if (nFdMax < iter->m_sock)
|
|
nFdMax = iter->m_sock;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#if 0 // send buffer version
|
|
if (iter->m_nState != IompObject::IOMP_DISABLE && iter->m_nState != IompObject::IOMP_CLOSING && iter->m_nState != IompObject::IOMP_REMOVE &&
|
|
pSocket->GetSendBuffer()->empty() == false)
|
|
{
|
|
if (iter->m_nState == INVALID_SOCKET)
|
|
fprintf(stderr, "[ERROR_DEBUG], Invalid logic. socket = %d\n", iter->m_nState, iter->m_sock);
|
|
|
|
FD_SET(iter->m_sock, &fsWrite);
|
|
nFdCount++;
|
|
#ifndef _WIN32
|
|
if (nFdMax < iter->m_sock)
|
|
nFdMax = iter->m_sock;
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (m_listIomp.empty() || nFdCount == 0)
|
|
{
|
|
Sleep(5);
|
|
continue;
|
|
}
|
|
//#define TEST_INTERVAL_
|
|
#ifdef TEST_INTERVAL_
|
|
tvWait.tv_sec = 3; //TestCode
|
|
tvWait.tv_usec = 0;
|
|
#else
|
|
tvWait.tv_sec = 0;
|
|
tvWait.tv_usec = 50000; // 50 msec
|
|
#endif
|
|
//nSelectResult = select(nFdMax + 1, &fsRead, &fsWrite, &fsError, &tvWait);
|
|
nSelectResult = select(nFdMax + 1, &fsRead, &fsWrite, NULL, &tvWait);
|
|
//fprintf(stdout, "DEBUG, nSelectResult = %d\n", nSelectResult);
|
|
|
|
if (nSelectResult == 0)
|
|
{
|
|
continue; // timeout
|
|
}
|
|
else if (nSelectResult == -1)
|
|
{
|
|
int nSockError = GetSockError();
|
|
fprintf(stdout, "[WARN], Failed to select. error = %s(%d)\n", GetErrorStr(nSockError), nSockError);
|
|
Sleep(5);
|
|
continue;
|
|
}
|
|
|
|
for (iter = m_listIomp.begin(); iter != m_listIomp.end(); iter++)
|
|
{
|
|
if (iter->m_sock == INVALID_SOCKET ||
|
|
iter->m_nState == IompObject::IOMP_DISABLE || iter->m_nState == IompObject::IOMP_CLOSING || iter->m_nState == IompObject::IOMP_REMOVE)
|
|
continue;
|
|
|
|
if (FD_ISSET(iter->m_sock, &fsRead) != 0)
|
|
{
|
|
if (iter->m_nState == IompObject::IOMP_LISTENING)
|
|
{
|
|
_T iompSocket;
|
|
|
|
socklen_t len = sizeof(struct sockaddr);
|
|
if ((iompSocket.m_sock = accept(iter->m_sock, (struct sockaddr *)&iompSocket.m_sai, &len)) == INVALID_SOCKET)
|
|
{
|
|
int nSockError = GetSockError();
|
|
fprintf(stderr, "[ERROR], Failed to accept. socket = %d, error = %s(%d)\n", iter->m_sock, GetErrorStr(nSockError), nSockError);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stdout, "INFO, Succeeded to accept.(%s:%d), socket = %d\n", inet_ntoa(iter->m_sai.sin_addr), ntohs(iter->m_sai.sin_port), iter->m_sock); // listen ip:port
|
|
fprintf(stdout, "INFO, Accepted src address (%s:%d), socket = %d\n", inet_ntoa(iompSocket.m_sai.sin_addr), ntohs(iompSocket.m_sai.sin_port), iompSocket.m_sock); // remote ip:port
|
|
|
|
if (OnIompAccept(&iompSocket, nCurrTick) != -1)
|
|
{
|
|
// Set non blocking mode
|
|
#ifdef _WIN32
|
|
ULONG nNonBlock = 1;
|
|
if (ioctlsocket(iompSocket.m_sock, FIONBIO, &nNonBlock) == SOCKET_ERROR)
|
|
#else
|
|
int nFlags = fcntl(iompSocket.m_sock, F_GETFL, 0);
|
|
if (fcntl(iompSocket.m_sock, F_SETFL, nFlags | O_NONBLOCK) == -1)
|
|
#endif
|
|
{
|
|
int nSockError = GetSockError();
|
|
fprintf(stderr, "[ERROR], Failed to ioctlsocket. socket = %d, error = %s(%d)\n", iompSocket.m_sock, GetErrorStr(nSockError), nSockError);
|
|
closesocket(iompSocket.m_sock);
|
|
}
|
|
else
|
|
{
|
|
iompSocket.m_nState = IompObject::IOMP_READY;
|
|
iompSocket.m_nPrevTick = nCurrTick;
|
|
m_listIomp.push_front(iompSocket);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
closesocket(iompSocket.m_sock);
|
|
}
|
|
}
|
|
}
|
|
else if (iter->m_nState == IompObject::IOMP_READY)
|
|
{
|
|
if (OnIompReceive(&*iter, nCurrTick) == -1)
|
|
{
|
|
shutdown(iter->m_sock, SD_SEND);
|
|
iter->m_nState = IompObject::IOMP_CLOSING;
|
|
}
|
|
|
|
iter->m_nPrevTick = nCurrTick;
|
|
}
|
|
|
|
FD_CLR(iter->m_sock, &fsRead);
|
|
|
|
if (--nSelectResult <= 0)
|
|
break;
|
|
}
|
|
|
|
if (FD_ISSET(iter->m_sock, &fsWrite) != 0)
|
|
{
|
|
if (iter->m_nState == IompObject::IOMP_CONNECTING)
|
|
{
|
|
int nSocketOptError = GetSockOptError(iter->m_sock);
|
|
if (nSocketOptError != 0)
|
|
{
|
|
fprintf(stderr, "[ERROR], Failed to connect.(%s:%d) socket = %d, error = %s(%d)\n",
|
|
inet_ntoa(iter->m_sai.sin_addr), ntohs(iter->m_sai.sin_port), iter->m_sock, GetErrorStr(nSocketOptError), nSocketOptError);
|
|
OnIompConnect(&*iter, false, nCurrTick);
|
|
shutdown(iter->m_sock, SD_BOTH);
|
|
iter->m_nState = IompObject::IOMP_CLOSING;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stdout, "INFO, Succeeded to connect.(%s:%d) socket = %d\n",
|
|
inet_ntoa(iter->m_sai.sin_addr), ntohs(iter->m_sai.sin_port), iter->m_sock);
|
|
OnIompConnect(&*iter, true, nCurrTick);
|
|
iter->m_nState = IompObject::IOMP_READY;
|
|
}
|
|
iter->m_nPrevTick = nCurrTick;
|
|
}
|
|
//else if (iter->m_nState == IompObject::IOMP_READY)
|
|
//{
|
|
// if (pSocket->OnSendRetry() < 0) // remain packet send
|
|
// {
|
|
// HLOGF(15, "[TRACE], MpsDisp, Failed to OnSendRetry socket = %d\n", pSocket->GetSocket());
|
|
// pSocket->FinishTcp();
|
|
// }
|
|
//}
|
|
|
|
FD_CLR(iter->m_sock, &fsWrite);
|
|
|
|
if (--nSelectResult <= 0)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected:
|
|
virtual int OnIompConnect(_T * pIomp, bool bIsSuccess, unsigned int nCurrTick) { return 0; }
|
|
virtual int OnIompReceive(_T * pIomp, unsigned int nCurrTick) { return 0; }
|
|
virtual int OnIompAccept(_T * pIomp, unsigned int nCurrTick) { return 0; }
|
|
virtual int OnIompClose(_T * pIomp, unsigned int nCurrTick) { return 0; }
|
|
virtual int OnIompDelete(_T * pIomp, unsigned int nCurrTick) { return 0; }
|
|
virtual void OnDispatchTimer(unsigned int nCurrTick) {}
|
|
|
|
protected:
|
|
unsigned int m_nDispachInterval; //msec
|
|
bool m_bTerminate;
|
|
std::list<_T> m_listIomp;
|
|
};
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
void get_crc(unsigned char* data, int length, unsigned short* crc)
|
|
{
|
|
int i;
|
|
//unsigned temp;
|
|
unsigned short temp;
|
|
unsigned short SEED = 0x8005;
|
|
*crc = 0xffff;
|
|
do {
|
|
temp = *data++ & 0xff;
|
|
for (i = 0; i < 8; i++) {
|
|
if ((*crc & 0x0001) ^ (temp & 0x01))
|
|
*crc = (*crc >> 1) ^ SEED;
|
|
else
|
|
*crc >>= 1;
|
|
temp >>= 1;
|
|
}
|
|
} while (--length);
|
|
*crc = ~*crc;
|
|
temp = *crc;
|
|
*crc = (*crc << 8) | ((temp >> 8) & 0xff);
|
|
return;
|
|
}
|
|
|
|
int SendToKicc(IompObject * pIomp, unsigned short cmd, const char * pData, size_t nDataSize)
|
|
{
|
|
volatile unsigned char pPacket[8192];
|
|
memset((void *)pPacket, 0, 8192);
|
|
|
|
volatile unsigned char * ptr = pPacket;
|
|
*ptr++ = 0x02;
|
|
|
|
volatile unsigned char * LEN = ptr;
|
|
unsigned short nLen = htons(6 + nDataSize);
|
|
memcpy((void *)ptr, (void *)&nLen, sizeof(unsigned short));
|
|
|
|
#if 0
|
|
unsigned short tmpLen;
|
|
memcpy((void *)&tmpLen, (void *)ptr, sizeof(unsigned short));
|
|
printf("tmpLen = %d, %d\n", tmpLen, ntohs(tmpLen));
|
|
#endif
|
|
|
|
ptr += 2;
|
|
|
|
*ptr++ = 0;
|
|
|
|
*ptr++ = 0xFB;
|
|
*ptr++ = 0x14;
|
|
*ptr++ = cmd;
|
|
|
|
if (nDataSize > 0)
|
|
{
|
|
memcpy((void *)ptr, pData, nDataSize);
|
|
ptr += nDataSize;
|
|
}
|
|
|
|
*ptr++ = 0x03;
|
|
|
|
unsigned short * cic = (unsigned short *)ptr;
|
|
get_crc((unsigned char *)LEN, 7 + nDataSize, cic);
|
|
*cic = htons(*cic);
|
|
|
|
printf("DEBUG, SendToKicc, send = %d\n", 10 + nDataSize);
|
|
if (pIomp->TcpCompleteSend((char *)pPacket, 10 + nDataSize) == -1)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/// - log part ////////////////////////////////////////////
|
|
extern inline FILE * CtLogFilePtr(FILE * pNewFile = NULL)
|
|
{
|
|
static FILE * pFile = stdout;
|
|
if (pNewFile)
|
|
pFile = pNewFile;
|
|
|
|
return pFile;
|
|
}
|
|
|
|
extern inline void CtLog(int nLevel, const char *fmt, ...)
|
|
//void CtLog(int nLevel, const char * pszLog)
|
|
{
|
|
char szLogString[1024];
|
|
va_list vaList;
|
|
va_start(vaList, fmt);
|
|
|
|
#if defined(__ANDROID__) || defined(ANDROID)
|
|
if (vsnprintf(szLogString, 1023, fmt, vaList) > 1023)
|
|
szLogString[1023] = '\0';
|
|
va_end(vaList);
|
|
|
|
__android_log_print(ANDROID_LOG_ERROR, "CtSense", "%s", szLogString);
|
|
#else
|
|
time_t t = time(NULL);
|
|
struct tm * st = localtime(&t);
|
|
sprintf(szLogString, "%04d-%02d-%02d %02d:%02d:%02d ", 1900 + st->tm_year,
|
|
st->tm_mon + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
|
|
fputs(szLogString, CtLogFilePtr());
|
|
|
|
if (vsnprintf(szLogString, 1023, fmt, vaList) > 1023)
|
|
szLogString[1023] = '\0';
|
|
|
|
va_end(vaList);
|
|
|
|
fputs(szLogString, CtLogFilePtr());
|
|
#endif
|
|
}
|
|
/// - log part ////////////////////////////////////////////
|
|
|
|
|
|
///BeginHeader- protocol part /////////////////////////////////////////////////
|
|
struct CtProtocolRecvCallBack
|
|
{
|
|
virtual int OnRecvProtocol() = 0;
|
|
};
|
|
|
|
|
|
class CtProtocol
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
CP_STATE_EMPTY = 0,
|
|
CP_STATE_INVALID_PACKET = 1,
|
|
CP_STATE_HEADER_REMAIN = 2,
|
|
CP_STATE_BODY_REMAIN = 3,
|
|
CP_STATE_COMPLETE = 4,
|
|
CP_STATE_JOINED = 5,
|
|
};
|
|
|
|
public:
|
|
inline CtProtocol();
|
|
virtual inline ~CtProtocol();
|
|
|
|
inline int GetPacketSize() { return m_nPakcetSize; }
|
|
inline int GetBodySize() { return m_nBodySize; }
|
|
inline const unsigned char * GetPacketPtr() { return m_pBufPtr; }
|
|
inline const unsigned char * GetBodyPtr() { return m_pBodyPtr; }
|
|
|
|
inline unsigned char * GetBufRecvPtr() { return m_pBufRecvPtr; }
|
|
inline const int GetBufRemainSize() { return m_nBufRemainSize; }
|
|
inline const int MoveBufRecvPtr(int nSize);
|
|
|
|
inline int OnReceive(size_t nSize, CtProtocolRecvCallBack * pCallBack);
|
|
|
|
virtual void Clear() = 0;
|
|
virtual int Parse(const char * pPacket, int nSize) = 0;
|
|
virtual int MoveNext() = 0;
|
|
|
|
protected:
|
|
int m_nState;
|
|
|
|
int m_nPakcetSize;
|
|
int m_nBodySize;
|
|
unsigned char * m_pBodyPtr;
|
|
unsigned char * m_pBufPtr;
|
|
//int m_nNextSendPos;
|
|
|
|
int m_nBufRemainSize;
|
|
unsigned char * m_pBufRecvPtr;
|
|
};
|
|
///EndHeader- protocol part ///////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
///BeginSource- protocol part /////////////////////////////////////////////////
|
|
inline CtProtocol::CtProtocol()
|
|
{
|
|
m_nState = CP_STATE_EMPTY;
|
|
m_nPakcetSize = 0;
|
|
m_nBodySize = 0;
|
|
m_pBodyPtr = NULL;
|
|
m_pBufPtr = NULL;
|
|
m_nBufRemainSize = 0;
|
|
m_pBufRecvPtr = NULL;
|
|
}
|
|
|
|
inline CtProtocol::~CtProtocol()
|
|
{
|
|
}
|
|
|
|
inline const int CtProtocol::MoveBufRecvPtr(int nSize) {
|
|
if (m_nBufRemainSize < nSize)
|
|
return -1;
|
|
|
|
m_pBufRecvPtr += nSize;
|
|
m_nPakcetSize += nSize;
|
|
m_nBufRemainSize -= nSize;
|
|
|
|
return 0;
|
|
}
|
|
|
|
inline int CtProtocol::OnReceive(size_t nSize, CtProtocolRecvCallBack * pCallBack)
|
|
{
|
|
CtLog(15, "CtProtocol::OnReceive, nSize = %d\n", nSize);
|
|
CtLog(15, "CtProtocol::OnReceive, %x %x %x %x %x %x\n", m_pBufRecvPtr[0], m_pBufRecvPtr[1], m_pBufRecvPtr[2], m_pBufRecvPtr[3], m_pBufRecvPtr[4], m_pBufRecvPtr[5]);
|
|
|
|
if (MoveBufRecvPtr((int)nSize) < 0)
|
|
{
|
|
CtLog(1, "[ERROR], CtProtocol::MoveBufRecvPtr, Not enough buffer.\n");
|
|
return -1; // disconnect
|
|
}
|
|
|
|
for (;;)
|
|
{
|
|
#ifdef USE_COPY_BUFFER
|
|
int nState = Parse(m_pRecvBuf, nSize);
|
|
#else
|
|
int nState = Parse(NULL, 0);
|
|
#endif
|
|
if (nState == CP_STATE_COMPLETE || nState == CP_STATE_JOINED)
|
|
{
|
|
if (pCallBack->OnRecvProtocol() < 0)
|
|
return -1; // disconnect
|
|
|
|
if (nState == CP_STATE_COMPLETE)
|
|
{
|
|
Clear();
|
|
}
|
|
else if (nState == CP_STATE_JOINED)
|
|
{
|
|
MoveNext();
|
|
continue;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
Clear();
|
|
|
|
//return -1; //TestCode disconnect
|
|
return 0;
|
|
}
|
|
///EndSource- protocol part ///////////////////////////////////////////////////
|
|
|
|
|
|
class KiccProtocol : public CtProtocol
|
|
{
|
|
// STX: 1byte, 0x02 : Start of Transmission
|
|
// LEN: 2byte, ���� ��Ŷ ����(LEN���� DATA����)
|
|
// CNT: 1byte, ��Ŷ Counter. ��Ŷ�� �ۼ��� �� ������ 1�� �����ϸ�, 1���� 255���� ����. ������ 1�� Reset��.
|
|
// CMD: 1byte, �⺻ �ڵ�
|
|
// GCD: 1byte, �� �ڵ� ( ������ �� �ڵ� )
|
|
// JCD: 1byte, ���� �ڵ� ( ���� ���� �ڵ� )
|
|
// DATA: LEN byte, ���� ����. ���� �ڵ� ������ �����ϱ� ���� �ʿ��� ������ �ʵ�. ������ ������ Type���� ���۵Ǹ�, ASCII�� ��?���� ����.
|
|
// ETX: 1byte, End of Transmission
|
|
// CRC: 2byte, LEN���� ETX������ Check Code
|
|
public:
|
|
enum
|
|
{
|
|
CP_MAX_PACKET_SIZE = 8192,
|
|
CP_HEADER_SIZE = 3, // STX + LEN
|
|
CP_MAX_BODY_SIZE = CP_MAX_PACKET_SIZE - CP_HEADER_SIZE,
|
|
};
|
|
|
|
public:
|
|
inline KiccProtocol();
|
|
virtual inline ~KiccProtocol();
|
|
|
|
inline void Clear();
|
|
|
|
inline void Append(const char * pData, size_t nSize);
|
|
inline void SetHeader(unsigned short nBodySize);
|
|
inline void BuildHeader();
|
|
|
|
inline int Parse(const char * pPacket, int nSize);
|
|
inline int MoveNext();
|
|
|
|
protected:
|
|
unsigned char m_buffer[CP_MAX_PACKET_SIZE];
|
|
};
|
|
|
|
|
|
inline KiccProtocol::KiccProtocol()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
inline KiccProtocol::~KiccProtocol()
|
|
{
|
|
}
|
|
|
|
inline void KiccProtocol::Clear()
|
|
{
|
|
m_nState = CP_STATE_EMPTY;
|
|
m_nPakcetSize = 0;
|
|
m_nBodySize = 0;
|
|
m_pBodyPtr = m_buffer + CP_HEADER_SIZE;
|
|
m_pBufPtr = m_buffer;
|
|
m_nBufRemainSize = CP_MAX_PACKET_SIZE;
|
|
m_pBufRecvPtr = m_buffer;
|
|
}
|
|
|
|
inline void KiccProtocol::Append(const char * pData, size_t nSize)
|
|
{
|
|
memcpy(m_pBodyPtr + m_nBodySize, pData, nSize);
|
|
m_nBodySize += (int)nSize;
|
|
}
|
|
|
|
inline void KiccProtocol::SetHeader(unsigned short nBodySize)
|
|
{
|
|
// memcpy(m_buffer, ProtocolNamePtr(), 4);
|
|
unsigned short * pnBodySize = (unsigned short *)(m_buffer + 4);
|
|
*pnBodySize = htons(nBodySize);
|
|
m_nBodySize = nBodySize;
|
|
m_nPakcetSize = m_nBodySize + CP_HEADER_SIZE;
|
|
}
|
|
|
|
inline void KiccProtocol::BuildHeader()
|
|
{
|
|
// memcpy(m_buffer, ProtocolNamePtr(), 4);
|
|
unsigned short * pnBodySize = (unsigned short *)(m_buffer + 4);
|
|
*pnBodySize = htons(m_nBodySize);
|
|
m_nPakcetSize = m_nBodySize + CP_HEADER_SIZE;
|
|
m_nState = CP_STATE_COMPLETE;
|
|
}
|
|
|
|
inline int KiccProtocol::Parse(const char * pPacket, int nSize)
|
|
{
|
|
if (m_nState == CP_STATE_JOINED)
|
|
{
|
|
m_nState = CP_STATE_EMPTY;
|
|
}
|
|
else
|
|
{
|
|
if (pPacket != NULL && nSize != 0)
|
|
{
|
|
memcpy(m_buffer + m_nPakcetSize, pPacket, nSize);
|
|
m_nPakcetSize += nSize;
|
|
}
|
|
}
|
|
|
|
//fprintf(stdout, "DEBUG, Parse 1, %d, %d, %d, %d\n", nSize, m_nState, m_nPakcetSize, m_nBodySize);
|
|
|
|
if (m_nState == CP_STATE_EMPTY)
|
|
{
|
|
if (m_nPakcetSize < CP_HEADER_SIZE)
|
|
{
|
|
m_nState = CP_STATE_HEADER_REMAIN;
|
|
return m_nState;
|
|
}
|
|
}
|
|
else if (m_nState == CP_STATE_HEADER_REMAIN)
|
|
{
|
|
if (m_nPakcetSize < CP_HEADER_SIZE)
|
|
return m_nState;
|
|
}
|
|
else if (m_nState == CP_STATE_BODY_REMAIN)
|
|
{
|
|
if (m_nPakcetSize < CP_HEADER_SIZE + m_nBodySize)
|
|
return m_nState;
|
|
|
|
return CP_STATE_COMPLETE;
|
|
}
|
|
|
|
//fprintf(stdout, "DEBUG, Parse 2, %x, %x, %x\n", m_pBufPtr[0], m_pBufPtr[1], m_pBufPtr[2]);
|
|
|
|
// if (memcmp(m_pBufPtr, KiccProtocol::ProtocolNamePtr(), 4) != 0)
|
|
if (m_pBufPtr[0] != 0x02 && m_pBufPtr[0] != 0x06 && m_pBufPtr[0] != 0x14)
|
|
return CP_STATE_INVALID_PACKET;
|
|
else if (m_pBufPtr[0] == 0x06 && m_pBufPtr[1] == 0x06 && m_pBufPtr[2] == 0x06)
|
|
{
|
|
m_nBodySize = 0;
|
|
return CP_STATE_COMPLETE; //ACK
|
|
}
|
|
else if (m_pBufPtr[0] == 0x15 && m_pBufPtr[1] == 0x15 && m_pBufPtr[2] == 0x15)
|
|
{
|
|
m_nBodySize = 0;
|
|
return CP_STATE_COMPLETE; //NACK
|
|
}
|
|
|
|
//m_nBodySize = ntohs(*((unsigned short *)(m_pBufPtr + 4)));
|
|
unsigned short nBodySize;
|
|
memcpy(&nBodySize, m_pBufPtr + 1, sizeof(unsigned short));
|
|
m_nBodySize = ntohs(nBodySize);
|
|
|
|
if (m_nBodySize == 0)
|
|
{
|
|
m_nBodySize = 7; // CNT(1) + CMD(1) + GCD(1) + JCD(1) + ETX(1) + CRC(2)
|
|
|
|
if ((m_nBodySize - 7) > m_nPakcetSize - CP_HEADER_SIZE)
|
|
{
|
|
m_nState = CP_STATE_BODY_REMAIN;
|
|
return m_nState;
|
|
}
|
|
else if ((m_nBodySize - 7) < m_nPakcetSize - CP_HEADER_SIZE)
|
|
{
|
|
m_nState = CP_STATE_JOINED;
|
|
return m_nState;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_nBodySize++; // - LEN(2) + ETX(1) + CRC(2)
|
|
|
|
if ((m_nBodySize - 1) > m_nPakcetSize - CP_HEADER_SIZE)
|
|
{
|
|
m_nState = CP_STATE_BODY_REMAIN;
|
|
return m_nState;
|
|
}
|
|
else if ((m_nBodySize - 1) < m_nPakcetSize - CP_HEADER_SIZE)
|
|
{
|
|
m_nState = CP_STATE_JOINED;
|
|
return m_nState;
|
|
}
|
|
}
|
|
|
|
return CP_STATE_COMPLETE;
|
|
}
|
|
|
|
inline int KiccProtocol::MoveNext()
|
|
{
|
|
if (m_nState != CP_STATE_JOINED)
|
|
return -1;
|
|
|
|
m_pBufPtr += CP_HEADER_SIZE + m_nBodySize;
|
|
m_pBodyPtr = m_pBufPtr + CP_HEADER_SIZE;
|
|
m_nPakcetSize -= CP_HEADER_SIZE + m_nBodySize;
|
|
|
|
return 0;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
///BeginHeader- size only protocol part /////////////////////////////////////////////////
|
|
class CtSizeOnlyProtocol : public CtProtocol
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
CP_MAX_PACKET_SIZE = 8192,
|
|
CP_HEADER_SIZE = 4, // PROTOCOL_NAME + BODY_SIZE(2byte)
|
|
CP_MAX_BODY_SIZE = CP_MAX_PACKET_SIZE - CP_HEADER_SIZE,
|
|
};
|
|
|
|
public:
|
|
inline CtSizeOnlyProtocol();
|
|
virtual inline ~CtSizeOnlyProtocol();
|
|
|
|
inline void Clear();
|
|
|
|
inline void Append(const char * pData, size_t nSize);
|
|
inline void SetHeader(u_short nBodySize);
|
|
inline void BuildHeader();
|
|
|
|
inline int Parse(const char * pPacket, int nSize);
|
|
inline int MoveNext();
|
|
|
|
protected:
|
|
unsigned char m_buffer[CP_MAX_PACKET_SIZE];
|
|
};
|
|
///EndHeader- size only protocol part ///////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
///BeginSource- size only protocol part /////////////////////////////////////////////////
|
|
inline CtSizeOnlyProtocol::CtSizeOnlyProtocol()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
inline CtSizeOnlyProtocol::~CtSizeOnlyProtocol()
|
|
{
|
|
}
|
|
|
|
inline void CtSizeOnlyProtocol::Clear()
|
|
{
|
|
m_nState = CP_STATE_EMPTY;
|
|
m_nPakcetSize = 0;
|
|
m_nBodySize = 0;
|
|
m_pBodyPtr = m_buffer + CP_HEADER_SIZE;
|
|
m_pBufPtr = m_buffer;
|
|
m_nBufRemainSize = CP_MAX_PACKET_SIZE;
|
|
m_pBufRecvPtr = m_buffer;
|
|
}
|
|
|
|
inline void CtSizeOnlyProtocol::Append(const char * pData, size_t nSize)
|
|
{
|
|
memcpy(m_pBodyPtr + m_nBodySize, pData, nSize);
|
|
m_nBodySize += (int)nSize;
|
|
}
|
|
|
|
inline void CtSizeOnlyProtocol::SetHeader(u_short nBodySize)
|
|
{
|
|
//memcpy(m_buffer, ProtocolNamePtr(), 4);
|
|
unsigned short * pnBodySize = (unsigned short *)(m_buffer + 4);
|
|
*pnBodySize = htons(nBodySize);
|
|
m_nBodySize = nBodySize;
|
|
m_nPakcetSize = m_nBodySize + CP_HEADER_SIZE;
|
|
}
|
|
|
|
inline void CtSizeOnlyProtocol::BuildHeader()
|
|
{
|
|
//memcpy(m_buffer, ProtocolNamePtr(), 4);
|
|
unsigned short * pnBodySize = (unsigned short *)(m_buffer + 4);
|
|
*pnBodySize = htons(m_nBodySize);
|
|
m_nPakcetSize = m_nBodySize + CP_HEADER_SIZE;
|
|
m_nState = CP_STATE_COMPLETE;
|
|
}
|
|
|
|
inline int CtSizeOnlyProtocol::Parse(const char * pPacket, int nSize)
|
|
{
|
|
if (m_nState == CP_STATE_JOINED)
|
|
{
|
|
m_nState = CP_STATE_EMPTY;
|
|
}
|
|
else
|
|
{
|
|
if (pPacket != NULL && nSize != 0)
|
|
{
|
|
memcpy(m_buffer + m_nPakcetSize, pPacket, nSize);
|
|
m_nPakcetSize += nSize;
|
|
}
|
|
}
|
|
|
|
if (m_nState == CP_STATE_EMPTY)
|
|
{
|
|
if (m_nPakcetSize < CP_HEADER_SIZE)
|
|
{
|
|
m_nState = CP_STATE_HEADER_REMAIN;
|
|
return m_nState;
|
|
}
|
|
}
|
|
else if (m_nState == CP_STATE_HEADER_REMAIN)
|
|
{
|
|
if (m_nPakcetSize < CP_HEADER_SIZE)
|
|
return m_nState;
|
|
}
|
|
else if (m_nState == CP_STATE_BODY_REMAIN)
|
|
{
|
|
if (m_nPakcetSize < CP_HEADER_SIZE + m_nBodySize)
|
|
return m_nState;
|
|
|
|
return CP_STATE_COMPLETE;
|
|
}
|
|
|
|
//if (memcmp(m_pBufPtr, CtSizeOnlyProtocol::ProtocolNamePtr(), 4) != 0)
|
|
// return CP_STATE_INVALID_PACKET;
|
|
|
|
//m_nBodySize = ntohs(*((u_short *)(m_pBufPtr + 4)));
|
|
unsigned short nBodySize;
|
|
memcpy(&nBodySize, m_pBufPtr + 2, sizeof(unsigned short));
|
|
m_nBodySize = ntohs(nBodySize);
|
|
|
|
if (m_nBodySize > m_nPakcetSize - CP_HEADER_SIZE)
|
|
{
|
|
m_nState = CP_STATE_BODY_REMAIN;
|
|
return m_nState;
|
|
}
|
|
else if (m_nBodySize < m_nPakcetSize - CP_HEADER_SIZE)
|
|
{
|
|
m_nState = CP_STATE_JOINED;
|
|
return m_nState;
|
|
}
|
|
|
|
return CP_STATE_COMPLETE;
|
|
}
|
|
|
|
inline int CtSizeOnlyProtocol::MoveNext()
|
|
{
|
|
if (m_nState != CP_STATE_JOINED)
|
|
return -1;
|
|
|
|
m_pBufPtr += CP_HEADER_SIZE + m_nBodySize;
|
|
m_nPakcetSize -= CP_HEADER_SIZE + m_nBodySize;
|
|
|
|
return 0;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
class KiccDispatcher;
|
|
|
|
|
|
class KiccRecvCallBack : public CtProtocolRecvCallBack
|
|
{
|
|
public:
|
|
KiccRecvCallBack() {}
|
|
virtual ~KiccRecvCallBack() {}
|
|
|
|
void SetDepends(KiccProtocol * pKiccProtocol, KiccDispatcher * pKiccDispatcher)
|
|
{
|
|
m_pKiccProtocol = pKiccProtocol;
|
|
m_pKiccDispatcher = pKiccDispatcher;
|
|
}
|
|
|
|
virtual int OnRecvProtocol();
|
|
|
|
protected:
|
|
KiccProtocol * m_pKiccProtocol;
|
|
KiccDispatcher * m_pKiccDispatcher;
|
|
};
|
|
|
|
class RemoteRecvCallBack : public CtProtocolRecvCallBack
|
|
{
|
|
public:
|
|
RemoteRecvCallBack() {}
|
|
virtual ~RemoteRecvCallBack() {}
|
|
|
|
void SetDepends(CtSizeOnlyProtocol * pSoProtocol, KiccDispatcher * pKiccDispatcher)
|
|
{
|
|
m_pSoProtocol = pSoProtocol;
|
|
m_pKiccDispatcher = pKiccDispatcher;
|
|
}
|
|
|
|
virtual int OnRecvProtocol();
|
|
|
|
protected:
|
|
CtSizeOnlyProtocol * m_pSoProtocol;
|
|
KiccDispatcher * m_pKiccDispatcher;
|
|
};
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
class KiccIompObject: public IompObject
|
|
{
|
|
public:
|
|
//KiccIompObject * m_pPair;
|
|
|
|
public:
|
|
KiccIompObject()
|
|
{
|
|
//m_pPair = NULL;
|
|
}
|
|
|
|
~KiccIompObject() {}
|
|
};
|
|
|
|
#if 0
|
|
typedef struct TTerminalInfo
|
|
{
|
|
unsigned char nRespCode;
|
|
char arrModelCode[4];
|
|
char arrModelVer[4];
|
|
char arrSerialNo[12];
|
|
char arrCertNo[16];
|
|
char arrTid[10];
|
|
char arrTerminalNo[3];
|
|
char arrTerminalIpPort[30];
|
|
char * pSpecialInfo;
|
|
} TTerminalInfo;
|
|
#endif
|
|
|
|
class KiccDispatcher : public IompDispatcher<KiccIompObject>
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
KD_KICC_STATE_STARTED = 0,
|
|
KD_KICC_STATE_WAIT_CONNECT = 1,
|
|
KD_KICC_STATE_CONNECTED = 2
|
|
};
|
|
|
|
enum
|
|
{
|
|
KD_REMOTE_STATE_STARTED = 0,
|
|
KD_REMOTE_STATE_WAIT_CONNECT = 1,
|
|
KD_REMOTE_STATE_WAIT_LOGIN_OK = 2,
|
|
KD_REMOTE_STATE_LOGGED_IN = 3,
|
|
};
|
|
|
|
protected:
|
|
//int m_nState;
|
|
int m_nKiccState;
|
|
int m_nRemoteState;
|
|
char m_szTid[16];
|
|
|
|
KiccIompObject * m_pKiccIompObject;
|
|
KiccIompObject * m_pRemoteIompObject;
|
|
|
|
KiccProtocol m_kiccProtocol;
|
|
KiccRecvCallBack m_kiccRecvCallBack;
|
|
|
|
CtSizeOnlyProtocol m_remoteProtocol;
|
|
RemoteRecvCallBack m_remoteRecvCallBack;
|
|
|
|
public:
|
|
KiccDispatcher()
|
|
{
|
|
m_nKiccState = KD_KICC_STATE_STARTED;
|
|
m_nRemoteState = KD_REMOTE_STATE_STARTED;
|
|
m_szTid[0] = '\0';
|
|
}
|
|
|
|
virtual ~KiccDispatcher()
|
|
{
|
|
}
|
|
|
|
void SetTimer(unsigned int nIntervalTime) //msec
|
|
{
|
|
m_nDispachInterval = nIntervalTime;
|
|
}
|
|
|
|
void KillTimer()
|
|
{
|
|
m_nDispachInterval = 0;
|
|
}
|
|
|
|
void SendToRemote(int nType, const char * pData, int nDataSize)
|
|
{
|
|
char packet[8192];
|
|
char * ptrBodySize = (char *)packet + 2;
|
|
char * ptrBody = ptrBodySize + 2;
|
|
|
|
ptrBody[0] = nType; // 1: Command Protocol, 2: KICC protocol
|
|
|
|
unsigned short nBodySize = nDataSize;
|
|
memcpy(ptrBody + 1, pData, nBodySize);
|
|
nBodySize += 1;
|
|
|
|
unsigned short nTemp = htons(nBodySize);
|
|
memcpy(ptrBodySize, &nTemp, sizeof(unsigned short));
|
|
|
|
fprintf(stdout, "DEBUG, SendToRemote, size = %d, \n", nBodySize + 4);
|
|
m_pRemoteIompObject->TcpCompleteSend(packet, nBodySize + 4); // send kicc protocol to server
|
|
}
|
|
|
|
void SendTest1ToRemote(int nType)
|
|
{
|
|
char szFileName[128];
|
|
sprintf(szFileName, "pay%.2d.raw", nType);
|
|
|
|
CtFile file;
|
|
if (file.Open(szFileName, CtFile::FMODE_RDONLY) == false)
|
|
return;
|
|
|
|
char buffer[8192];
|
|
size_t nRecvSize = file.Read(buffer, 8192);
|
|
if (nRecvSize <= 0)
|
|
return;
|
|
|
|
SendToRemote(2, buffer, nRecvSize);
|
|
}
|
|
|
|
int OnRecvKiccProtocol() // m_nKiccState == KD_KICC_STATE_CONNECTED
|
|
{
|
|
if ((m_kiccProtocol.GetPacketPtr()[0] == 0x06 && m_kiccProtocol.GetPacketPtr()[1] == 0x06 && m_kiccProtocol.GetPacketPtr()[2] == 0x06) ||
|
|
m_kiccProtocol.GetPacketPtr()[0] == 0x15 && m_kiccProtocol.GetPacketPtr()[1] == 0x15 && m_kiccProtocol.GetPacketPtr()[2] == 0x15) // ACK
|
|
{
|
|
fprintf(stdout, "DEBUG, OnRecvKiccProtocol, ACK/NACK, 0x%x, size = %d\n", m_kiccProtocol.GetPacketPtr()[0], m_kiccProtocol.GetPacketSize());
|
|
|
|
if (m_nRemoteState == KD_REMOTE_STATE_LOGGED_IN)
|
|
{
|
|
SendToRemote(2, (const char *)m_kiccProtocol.GetPacketPtr(), m_kiccProtocol.GetPacketSize());
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
fprintf(stdout, "DEBUG, OnRecvKiccProtocol, body size = %d, 0x%.2d, 0x%.2d, 0x%.2d\n", m_kiccProtocol.GetBodySize(), m_kiccProtocol.GetBodyPtr()[0], m_kiccProtocol.GetBodyPtr()[1], m_kiccProtocol.GetBodyPtr()[2]);
|
|
|
|
unsigned char ack[4];
|
|
ack[0] = 0x06;
|
|
ack[1] = 0x06;
|
|
ack[2] = 0x06;
|
|
m_pKiccIompObject->TcpCompleteSend((const char *)ack, 3); // response ack
|
|
|
|
if (m_nRemoteState == KD_REMOTE_STATE_STARTED)
|
|
{
|
|
const char * ptrTid = (const char *)m_kiccProtocol.GetBodyPtr() + 41;
|
|
int j = 0;
|
|
for (int i = 0; i < 10; i++) // front trim
|
|
{
|
|
if (ptrTid[i] == ' ')
|
|
continue;
|
|
|
|
m_szTid[j++] = ptrTid[i];
|
|
}
|
|
m_szTid[j] = '\0';
|
|
|
|
fprintf(stdout, "DEBUG, OnRecvKiccProtocol, Tid = %s\n", m_szTid);
|
|
|
|
if (m_szTid[0] == '\0')
|
|
{
|
|
//...
|
|
SendToKicc(m_pKiccIompObject, 0x02, NULL, 0); // get info
|
|
return 0;
|
|
}
|
|
|
|
|
|
KiccIompObject iompObject;
|
|
if (iompObject.Create() == -1)
|
|
return 0;
|
|
|
|
//if (iompObject.Connect("192.168.219.150", 17856, 7000, 0, 5000) == -1)
|
|
if (iompObject.Connect("43.201.46.125", 17856, 7000, 0, 5000) == -1)
|
|
return 0;
|
|
|
|
m_remoteRecvCallBack.SetDepends(&m_remoteProtocol, this);
|
|
m_pRemoteIompObject = AddSocket(iompObject);
|
|
|
|
m_nRemoteState = KD_REMOTE_STATE_WAIT_CONNECT;
|
|
|
|
return 0;
|
|
}
|
|
else if (m_nRemoteState == KD_REMOTE_STATE_WAIT_CONNECT)
|
|
{
|
|
//...
|
|
}
|
|
else if (m_nRemoteState == KD_REMOTE_STATE_WAIT_LOGIN_OK)
|
|
{
|
|
//...
|
|
}
|
|
else if (m_nRemoteState == KD_REMOTE_STATE_LOGGED_IN)
|
|
{
|
|
SendToRemote(2, (const char *)m_kiccProtocol.GetPacketPtr(), m_kiccProtocol.GetPacketSize());
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int OnRecvRemoteProtocol() // m_nRemoteState == KD_REMOTE_STATE_WAIT_LOGIN_OK or KD_REMOTE_STATE_LOGGED_IN
|
|
{
|
|
fprintf(stdout, "DEBUG, OnRecvRemoteProtocol, body size = %d, 0x%.2d, 0x%.2d\n", m_remoteProtocol.GetBodySize(), m_remoteProtocol.GetBodyPtr()[0], m_remoteProtocol.GetBodyPtr()[1]);
|
|
const unsigned char * pPacket = m_remoteProtocol.GetPacketPtr();
|
|
|
|
fprintf(stdout, "DEBUG, %x %x %x %x %x\n", pPacket[0], pPacket[1], pPacket[2], pPacket[3], pPacket[4], pPacket[5]);
|
|
|
|
if (m_nRemoteState == KD_REMOTE_STATE_WAIT_LOGIN_OK)
|
|
{
|
|
if (m_remoteProtocol.GetBodyPtr()[0] == 1 && // smart service protocol
|
|
m_remoteProtocol.GetBodyPtr()[1] == 1) // login ok
|
|
{
|
|
fprintf(stdout, "DEBUG, OnRecvRemoteProtocol, login success\n");
|
|
m_nRemoteState = KD_REMOTE_STATE_LOGGED_IN;
|
|
return 0;
|
|
}
|
|
|
|
//login failed
|
|
return -1; // disconnect
|
|
}
|
|
|
|
if (m_nKiccState == KD_KICC_STATE_WAIT_CONNECT)
|
|
{
|
|
//...
|
|
return 0;
|
|
}
|
|
else if (m_nKiccState == KD_KICC_STATE_CONNECTED)
|
|
{
|
|
if (m_remoteProtocol.GetBodyPtr()[0] == 1) // remote server protocol
|
|
{
|
|
if (m_remoteProtocol.GetBodyPtr()[1] == 2) // keep-alive
|
|
{
|
|
fprintf(stdout, "DEBUG, OnRecvRemoteProtocol, keep-alive\n");
|
|
SendToRemote(1, "3", 1); // keep-alive ack
|
|
}
|
|
else if (m_remoteProtocol.GetBodyPtr()[1] == 99) // test packet
|
|
{
|
|
SendTest1ToRemote(m_remoteProtocol.GetBodyPtr()[2]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
else if (m_remoteProtocol.GetBodyPtr()[0] == 2) // kicc protocol
|
|
{
|
|
const char * pBody = (const char *)m_remoteProtocol.GetBodyPtr();
|
|
m_pKiccIompObject->TcpCompleteSend(pBody + 1, m_remoteProtocol.GetBodySize() - 1); // remove protocol type
|
|
return 0;
|
|
}
|
|
|
|
return 0; // disconnect
|
|
}
|
|
|
|
return -1; // disconnect
|
|
}
|
|
|
|
protected:
|
|
int OnIompConnect(KiccIompObject * pIomp, bool bIsSuccess, unsigned int nCurrTick)
|
|
{
|
|
fprintf(stdout, "DEBUG, OnIompConnect, %s, state = %d, sock = %d\n", bIsSuccess ? "true" : "false", m_nKiccState, m_nRemoteState, pIomp->m_sock);
|
|
if (bIsSuccess == false)
|
|
return 0;
|
|
|
|
if (m_pKiccIompObject == pIomp)
|
|
{
|
|
if (m_szTid[0] == '\0')
|
|
{
|
|
SendToKicc(pIomp, 0x02, NULL, 0); // get info
|
|
}
|
|
|
|
m_nKiccState = KD_KICC_STATE_CONNECTED;
|
|
}
|
|
else if (m_pRemoteIompObject == pIomp)
|
|
{
|
|
//
|
|
char packet[8192];
|
|
char * ptrBodySize = (char *)packet + 2;
|
|
char * ptrBody = ptrBodySize + 2;
|
|
|
|
ptrBody[0] = 1; // 1: Command Protocol, 2: KICC protocol
|
|
ptrBody[1] = 1; // 1: Login
|
|
|
|
//int nBodySize = sprintf(ptrBody + 2, "%s", m_szTid);
|
|
unsigned int nBodySize = strlen(m_szTid);
|
|
memcpy(ptrBody + 2, m_szTid, nBodySize);
|
|
|
|
nBodySize += 2;
|
|
unsigned short nTemp = htons(nBodySize);
|
|
memcpy(ptrBodySize, &nTemp, sizeof(unsigned short));
|
|
|
|
fprintf(stdout, "DEBUG, Send, size = %d, \n", nBodySize + 4);
|
|
m_pRemoteIompObject->TcpCompleteSend(packet, nBodySize + 4); // send login
|
|
//
|
|
|
|
m_nRemoteState = KD_REMOTE_STATE_WAIT_LOGIN_OK;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int OnIompReceive(KiccIompObject * pIomp, unsigned int nCurrTick)
|
|
{
|
|
if (m_pKiccIompObject == pIomp)
|
|
{
|
|
int nReceived = pIomp->Receive((char *)m_kiccProtocol.GetBufRecvPtr(), m_kiccProtocol.GetBufRemainSize());
|
|
if (nReceived == -1)
|
|
return -1;
|
|
|
|
return m_kiccProtocol.OnReceive(nReceived, &m_kiccRecvCallBack);
|
|
}
|
|
else if (m_pRemoteIompObject == pIomp)
|
|
{
|
|
int nReceived = pIomp->Receive((char *)m_remoteProtocol.GetBufRecvPtr(), m_remoteProtocol.GetBufRemainSize());
|
|
if (nReceived == -1)
|
|
return -1;
|
|
|
|
return m_remoteProtocol.OnReceive(nReceived, &m_remoteRecvCallBack);
|
|
}
|
|
|
|
return -1; // disconnect
|
|
}
|
|
|
|
int OnIompAccept(KiccIompObject * pIomp, unsigned int nCurrTick)
|
|
{
|
|
fprintf(stdout, "DEBUG, OnIompAccept, sock = %d\n", pIomp->m_sock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int OnIompClose(KiccIompObject * pIomp, unsigned int nCurrTick)
|
|
{
|
|
fprintf(stdout, "DEBUG, OnIompClose, sock = %d\n", pIomp->m_sock);
|
|
|
|
if (m_pKiccIompObject == pIomp)
|
|
{
|
|
m_kiccProtocol.Clear();
|
|
m_nKiccState = KD_KICC_STATE_WAIT_CONNECT;
|
|
}
|
|
else if (m_pRemoteIompObject == pIomp)
|
|
{
|
|
m_remoteProtocol.Clear();
|
|
m_nRemoteState = KD_REMOTE_STATE_WAIT_CONNECT;
|
|
}
|
|
|
|
return 0; //default, remove from dispatch list
|
|
//return -1; //!!! no remove from dispatch list
|
|
}
|
|
|
|
int OnIompDelete(KiccIompObject * pIomp, unsigned int nCurrTick)
|
|
{
|
|
fprintf(stdout, "DEBUG, OnIompDelete, sock = %d\n", pIomp->m_sock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void OnDispatchTimer(unsigned int nCurrTick)
|
|
{
|
|
fprintf(stdout, "DEBUG, %u, OnDispatchTimer, m_listIomp.size() = %ld\n", nCurrTick, m_listIomp.size());
|
|
|
|
if (m_nKiccState == KD_KICC_STATE_STARTED)
|
|
{
|
|
KiccIompObject iompObject;
|
|
if (iompObject.Create() == -1)
|
|
return;
|
|
|
|
if (iompObject.Connect("127.0.0.1", 13189, 7000, nCurrTick, 5000) == -1)
|
|
//if (iompObject.Connect("192.168.219.150", 13189, 7000, 5000) == -1)
|
|
return;
|
|
|
|
m_kiccRecvCallBack.SetDepends(&m_kiccProtocol, this);
|
|
m_pKiccIompObject = AddSocket(iompObject);
|
|
|
|
m_nKiccState = KD_KICC_STATE_WAIT_CONNECT; // local connecting...
|
|
KillTimer();
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
int KiccRecvCallBack::OnRecvProtocol()
|
|
{
|
|
return m_pKiccDispatcher->OnRecvKiccProtocol();
|
|
}
|
|
|
|
int RemoteRecvCallBack::OnRecvProtocol()
|
|
{
|
|
return m_pKiccDispatcher->OnRecvRemoteProtocol();
|
|
}
|
|
|
|
|
|
|
|
int main (int argc, char * argv[])
|
|
{
|
|
//if (argc < 3)
|
|
//{
|
|
// printf("Usage: hdtermd [IP] [Port]\n"
|
|
// "ex) hdtermd 192.168.1.4 7788\n");
|
|
// return 0;
|
|
//}
|
|
|
|
#if defined(_WIN32) && defined(_DEBUG)
|
|
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
|
|
//_CrtSetBreakAlloc(631);
|
|
#endif // _DEBUG
|
|
|
|
#ifdef _WIN32
|
|
WSADATA wsaData;
|
|
WORD wVersionRequested = MAKEWORD(2, 2);
|
|
if (WSAStartup(wVersionRequested, &wsaData) != 0)
|
|
{
|
|
printf("[ERROR], Windows sockets initialization failed., WSAGetLastError = %d\n", WSAGetLastError());
|
|
return -1;
|
|
}
|
|
|
|
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
|
|
{
|
|
printf("[ERROR], Could not find a usable WinSock DLL.\n");
|
|
WSACleanup();
|
|
return -1;
|
|
}
|
|
#endif // _WIN32
|
|
|
|
fprintf(stdout, "hdtermd version 1.0.2\n");
|
|
|
|
// verify date
|
|
for (;;)
|
|
{
|
|
time_t now;
|
|
struct tm *local;
|
|
|
|
time(&now);
|
|
local = localtime(&now);
|
|
|
|
int year = local->tm_year + 1900;
|
|
|
|
if (year < 2026)
|
|
{
|
|
fprintf(stderr, "[ERROR], Invalid date, = %ld\n", year);
|
|
Sleep(5000);
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
//
|
|
|
|
KiccDispatcher iompDispatcher;
|
|
iompDispatcher.SetTimer(2000);
|
|
iompDispatcher.Dispatch(); // loop
|
|
|
|
return 0;
|
|
}
|