// UdpAsySk.cpp : implementation file
//

#include "stdafx.h"
#include "UDpAsySk.h"
#include "NetFindDpp.h"
#include "NetFindDppDlg.h"
#include "NetFinder.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CUdpAsySk

CUdpAsySk::CUdpAsySk(CDialog* pDlg)
{
	m_pDlg = pDlg;
	m_sendBuffer = "";   //for async send
	m_nBytesSent = 0;
	m_nBytesBufferSize = 0;
}

CUdpAsySk::~CUdpAsySk()
{
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CUdpAsySk, CAsyncSocket)
	//{{AFX_MSG_MAP(CUdpAsySk)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// CUdpAsySk member functions

void CUdpAsySk::OnAccept(int nErrorCode) 
{
	OutputDebugString("CUdpAsySk::OnAccept\n");
	
	CAsyncSocket::OnAccept(nErrorCode);
}

void CUdpAsySk::OnClose(int nErrorCode) 
{
	OutputDebugString("CUdpAsySk::OnClose\n");
	((CNetFindDppDlg*)m_pDlg)->m_pUDPSocket = NULL;
	
	CAsyncSocket::OnClose(nErrorCode);
	delete this;
}

void CUdpAsySk::OnConnect(int nErrorCode) 
{
	OutputDebugString("CUdpAsySk::OnConnect\n");
	
	CAsyncSocket::OnConnect(nErrorCode);
}

void CUdpAsySk::OnOutOfBandData(int nErrorCode) 
{
	OutputDebugString("CUdpAsySk::OnOutOfBandData\n");
	
	CAsyncSocket::OnOutOfBandData(nErrorCode);
}

void CUdpAsySk::OnReceive(int nErrorCode) 
{
	OutputDebugString("CUdpAsySk::OnReceive\n");
	TCHAR buff[70000];
	BYTE buffer[70000];
	int nRead;
	CNetFinder FindDpp;


	((CNetFindDppDlg*)m_pDlg)->UpdateData(TRUE);
	nRead = ReceiveFrom(buff, 69999, ((CNetFindDppDlg*)m_pDlg)->m_strRemote, ((CNetFindDppDlg*)m_pDlg)->m_remoteport); //make it smaller so we can experiment mulitple notifications
	switch (nRead)
	{
	case 0:
		Close();
		break;

	case SOCKET_ERROR:
		if (GetLastError() != WSAEWOULDBLOCK) 
		{
			if (GetLastError() != WSAEMSGSIZE)
			{
				TCHAR szError[256];
				wsprintf(szError, "OnReceive error: %d", GetLastError());
				AfxMessageBox (szError);
			}
			else
			{
				AfxMessageBox ("The datagram was too large and was truncated");
				CString szTemp(buff);
				((CNetFindDppDlg*)m_pDlg)->m_strReceive += szTemp;
				((CNetFindDppDlg*)m_pDlg)->UpdateData(FALSE);
			}
		}
		break;

	default:
		if (nRead != SOCKET_ERROR && nRead != 0 )
		{
			TCHAR szError[256];
			wsprintf(szError, "OnReceive bytes: %d", nRead);
			buff[nRead] = 0; //terminate the string
			if (nRead > 6) {
				memset(&buffer, 0, sizeof(buffer));
				for(int idx=0;idx<nRead;idx++) {
					buffer[idx] = (BYTE)buff[idx];
				}	
				FindDpp.InitAllEntries();
				FindDpp.InitEntry(&FindDpp.DppEntries[0]);
				FindDpp.AddEntry(&FindDpp.DppEntries[0], buffer, 3040);
				//CString szTemp(buff);
				CString szTemp("");
				szTemp = FindDpp.DppEntries[0].str_display;
				szTemp += "\r\n";
				((CNetFindDppDlg*)m_pDlg)->m_strReceive += szTemp;
				((CNetFindDppDlg*)m_pDlg)->UpdateData(FALSE);
			}
			//wsprintf(szError, "%s %d \r\n",((CNetFindDppDlg*)m_pDlg)->m_strRemote, nRead);
			//AfxMessageBox(szError);

		}	
	}
	
	CAsyncSocket::OnReceive(nErrorCode);
}

void CUdpAsySk::OnSend(int nErrorCode) 
{
	OutputDebugString("CUdpAsySk::OnSend\n");
	DoAsyncSendBuff();	
	CAsyncSocket::OnSend(nErrorCode);
}

int CUdpAsySk::Receive(void* lpBuf, int nBufLen, int nFlags) 
{
	OutputDebugString("CUdpAsySk::Receive\n");
	return CAsyncSocket::Receive(lpBuf, nBufLen, nFlags);
}

int CUdpAsySk::Send(const void* lpBuf, int nBufLen, int nFlags) 
{
	// TODO: Add your specialized code here and/or call the base class
	OutputDebugString("CUdpAsySk::Send\n");
	return CAsyncSocket::Send(lpBuf, nBufLen, nFlags);
}

void CUdpAsySk::DoAsyncSendBuff()
{
	 
	while (m_nBytesSent < m_nBytesBufferSize)  //m_nBytesBufferSize should be m_sendBuffer.GetLength() +1
	{
		int dwBytes;

		SOCKADDR_IN remoteAddr;
		remoteAddr.sin_family = AF_INET;
		remoteAddr.sin_port = htons(((CNetFindDppDlg*)m_pDlg)->m_remoteport);
		remoteAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
		dwBytes = SendTo((LPCTSTR)m_sendBuffer + m_nBytesSent, m_nBytesBufferSize - m_nBytesSent, (const SOCKADDR* )&remoteAddr, sizeof(remoteAddr));

		if (dwBytes == SOCKET_ERROR)
		{
			if (GetLastError() == WSAEWOULDBLOCK) break;
			else
			{
				TCHAR szError[256];
				wsprintf(szError, "Server Socket failed to send: %d", GetLastError());
				Close();
				AfxMessageBox (szError);
				break;
			}

		}
		else
		{
			m_nBytesSent += dwBytes;
		}
	}

	if (m_nBytesSent == m_nBytesBufferSize)
	{
		m_nBytesSent = m_nBytesBufferSize = 0;
		m_sendBuffer = "";
	}
}

