// ServerControl.cpp: implementation of the CServerControl class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ServerControl.h"
#include "NetViewXCtl.h"


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static void WINAPI serialdatacallback(LONG hHandle,char *pBuffer,int size,void *userdata)
{
	int i = 0;
	CServerControl *pcontrol = (CServerControl*)userdata;
	if(size > 0)
	{
		WaitForSingleObject(pcontrol->m_RecvMutex,-1);
		TRACE("serial recv data:%d",size);
		for(i=0;i<size;i++)
		{
			TRACE(" %x",(unsigned char)pBuffer[i]);
		}
		TRACE("\n");
		pcontrol->m_RecvLength = pcontrol->m_RecvLength + size > SERIAL_MAXRECVSIZE ? 0 : pcontrol->m_RecvLength;
		memcpy(pcontrol->m_RecvData + pcontrol->m_RecvLength,pBuffer,size);
		pcontrol->m_RecvLength += size;
		ReleaseMutex(pcontrol->m_RecvMutex);
	}
	else
	{
		pcontrol->m_hSerialError = FALSE;
	}
}
static DWORD WINAPI s_connecttask(void *param)
{
	char url[40];
	char sername[40];
	char username[40],password[40];
	WORD port;
	CServerControl *pserver = (CServerControl*)param;

	while(pserver->m_ConnectRun)
	{
		if(WaitForSingleObject(pserver->m_ThreadEvent,5000) == WAIT_OBJECT_0)
			continue;
		pserver->m_server->GetInfo(url,sername,username,password,&port);

		if(VSNET_ClientAffirmUser(sername,url,username,password,port) != 0)
			continue;
		pserver->m_hSerialHandle = VSNET_ClientSerialStart(sername,url,
			username,password,pserver->m_iSerialPort,&pserver->m_SerialInfo,
			serialdatacallback,pserver,port);

		if(pserver->m_hSerialHandle <= 0)
		{
			pserver->m_hSerialHandle = -1;
			continue;
		}			

		pserver->m_hSerialError = TRUE;
		pserver->m_RecvLength = 0;
	
// 		flag = 0;
// 		pserver->FAD_HTM1000SetAddr(0);
		while (pserver->m_hSerialError && pserver->m_ConnectRun)
		{
			if (!pserver->m_hSerialError)
            {
				break;
            }

			if (WaitForSingleObject(pserver->m_ThreadEvent, 2 * 1000) == WAIT_OBJECT_0)
            {
				continue;
            }

// 			if(flag != 0)
// 			{
// 				data = pserver->FAD_HTM1000GetAlarmData();
// 				if(data != -1)
// 				{
// 					::PostMessage(pserver->m_server->m_hWnd, WM_SERIAL, flag, data);
// 				}
// 			}

			pserver->ClearData();
            pserver->SendData();
            
//             if (pserver->m_server->m_SerialRecvLen > 0)
//             {
//                 ::PostMessage(pserver->m_server->m_hWnd, WM_SERIAL, 0, 0);
//             }

// 			if(flag == 0 || flag == 2)
// 			{
// 				pserver->FAD_HTM1000QueryTemData(0);
// 				flag = 1;
// 			}
// 			else
// 			{
// 				pserver->FAD_HTM1000QueryHumData(0);
// 				flag = 2;
// 			}
		}
		if(pserver->m_hSerialHandle != -1)
		{
			VSNET_ClientSerialStop(pserver->m_hSerialHandle);
			pserver->m_hSerialHandle = -1;
		}
	}
	return 0;
}

CServerControl::CServerControl()
{
	memset(m_RecvData, 0, sizeof(m_RecvData));
    memset(m_SendData, 0, sizeof(m_SendData));
    memset(&m_SerialInfo, 0, sizeof(m_SerialInfo));
	m_hSerialHandle = -1;
	m_server = NULL;
	m_ConnectHandle = NULL;
	m_ConnectRun = FALSE;
	m_ConnectID = 0;
	m_hSerialError = FALSE;
	m_RecvLength = 0;
    m_SendLength = 0;
    m_iSerialPort = 0;
	m_RecvMutex = CreateMutex(0,FALSE,0);
	m_ThreadEvent = CreateEvent(0,FALSE,FALSE,0);
}	

CServerControl::~CServerControl()
{
	StartThread(FALSE);
	if(m_RecvMutex)
	{
		CloseHandle(m_RecvMutex);
		m_RecvMutex = NULL;
	}
	if(m_ThreadEvent)
	{
		CloseHandle(m_ThreadEvent);
		m_ThreadEvent = NULL;
	}
}

int CServerControl::StartThread(BOOL start)
{
	if(start)
	{
		if(m_ConnectHandle)	return 0;
		m_RecvLength = 0;
		memset(m_RecvData,0,sizeof(m_RecvData));
		m_ConnectRun = TRUE;
		m_ConnectHandle = CreateThread(0,0,s_connecttask,this,0,&m_ConnectID);
	}
	else
	{
		m_ConnectRun = FALSE;
		if(m_ThreadEvent) SetEvent(m_ThreadEvent);
		if(m_ConnectHandle)
		{
			WaitForSingleObject(m_ConnectHandle,-1);
			CloseHandle(m_ConnectHandle);
			m_ConnectHandle = NULL;
		}
	}
	return 0;
}

void CServerControl::FAD_HTM1000SetAddr(int addr)
{
	char pbuff[10];

	pbuff[0] = (char)0xFE;
	pbuff[1] = (char)addr;
	pbuff[2] = (char)(pbuff[0] ^ pbuff[1]);
	if(m_hSerialHandle != -1)
	{
		VSNET_ClientSerialSendNew(m_hSerialHandle,pbuff,3);
	}
}

void CServerControl::FAD_HTM1000QueryTemData(int addr)
{
	char pbuff[10];

	pbuff[0] = (char)addr;
	pbuff[1] = (char)0X93;
	pbuff[2] = (char)(pbuff[0] ^ pbuff[1]);
	if(m_hSerialHandle != -1)
	{
		VSNET_ClientSerialSendNew(m_hSerialHandle,pbuff,3);
	}
}
void CServerControl::FAD_HTM1000QueryHumData(int addr)
{
	char pbuff[10];

	pbuff[0] = (char)addr;
	pbuff[1] = (char)0X94;
	pbuff[2] = (char)(pbuff[0] ^ pbuff[1]);
	if(m_hSerialHandle != -1)
	{
		VSNET_ClientSerialSendNew(m_hSerialHandle,pbuff,3);
	}
}

int CServerControl::FAD_HTM1000GetAlarmData()
{
	int data = 0;

	WaitForSingleObject(m_RecvMutex,-1);
	if(m_RecvLength == 3 && m_RecvData[2] == (char)(m_RecvData[0] ^ m_RecvData[1]))
	{
		data = (m_RecvData[0] << 8) + m_RecvData[1];
		ReleaseMutex(m_RecvMutex);
		return data;
	}
	ReleaseMutex(m_RecvMutex);
	return -1;
}

void CServerControl::SendData()
{
    if(m_hSerialHandle != -1 && m_SendLength > 0)
    {
        VSNET_ClientSerialSendNew(m_hSerialHandle, (char *)m_SendData, m_SendLength);
	}
    m_SendLength = 0;
}

void CServerControl::ClearData()
{
	WaitForSingleObject(m_RecvMutex,-1);
	if(m_RecvLength > 0)
	{
        ::SendMessage(m_server->m_hWnd, WM_SERIAL, (WPARAM)m_RecvData, m_RecvLength);
    }
    m_RecvLength = 0;
    ReleaseMutex(m_RecvMutex);
}
