testconns/statdesktop/desktop/source/lib/src/statsocket_block.cpp
changeset 4 b8d1455fddc0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testconns/statdesktop/desktop/source/lib/src/statsocket_block.cpp	Mon Oct 04 02:58:21 2010 +0300
@@ -0,0 +1,325 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+
+
+#include "stdafx.h"
+#include "statsocket_block.h"
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Constructor
+CSTATSocket::CSTATSocket() : pBuffer(NULL), iBufferLength(0)
+{
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Destructor
+CSTATSocket::~CSTATSocket()
+{
+	Disconnect();
+	Release();
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Initialise
+int CSTATSocket::Initialise(void)
+{
+	WORD version;
+	WSADATA wsaData;
+
+	// start the windows socket server
+	version = MAKEWORD( 2, 2 );
+	if (WSAStartup( version, &wsaData ))
+		return E_SOCKETSTARTUP;
+
+	return ITS_OK;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Connect
+int CSTATSocket::Connect(const char *pAddress)
+{
+	int iPort = ST_DEFAULTDEVICEPORT;
+
+	// parameter will either be MACHINE_NAME:PORT_NUMBER if connecting
+	// or just PORT_NUMBER if listening
+	char *p = strrchr(pAddress, ':');
+	char *q = p;
+	if (p)
+	{
+		(*p) = (char)0;
+
+		p++;
+		if (p && *p)
+			iPort = atoi(p);
+
+		// local address
+		struct hostent *hp;
+		memset(&sin,0,sizeof(sin));
+		sin.sin_family = AF_INET;
+		sin.sin_port = htons((unsigned short)iPort);
+		hp = gethostbyname(pAddress);
+
+		// put this back to restore original string
+		*q = ':';
+
+		if (hp)
+		{
+
+			// create a client socket
+			sock = socket( AF_INET, SOCK_STREAM, 0 ) ;
+			if( sock == INVALID_SOCKET )
+				return E_SOCKETCREATE;
+
+			memcpy(&(sin.sin_addr),hp->h_addr,hp->h_length);
+
+			// connect to server
+			if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0)
+				return E_SOCKETCONNECT;
+
+			// Set the socket I/O mode
+			// FIONBIO enables or disables the blocking mode for the 
+			// socket:
+			// 0   => blocking is enabled; 
+			// !=0 => non-blocking mode is enabled.
+			u_long mode = 1;
+			ioctlsocket(sock, FIONBIO, &mode);
+
+		}
+		else
+			return E_SOCKETHOSTNAME;
+	}
+	else
+	{
+		// create a listener socket
+		listener = socket(AF_INET, SOCK_STREAM, 0);
+		if( listener == INVALID_SOCKET )
+			return E_SOCKETCREATE;
+
+		iPort = atoi(pAddress);
+		if (!iPort)
+			iPort = ST_DEFAULTDEVICEPORT;
+
+		sin.sin_family = AF_INET;
+		sin.sin_port = htons((unsigned short)iPort);
+		sin.sin_addr.s_addr = INADDR_ANY;
+
+		if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) != 0)
+			return E_SOCKETBIND;
+
+		if (listen(listener, 1) != 0)
+			return E_SOCKETLISTEN;
+
+		int sin_size = sizeof(remote_sin);
+		memset((void *)&remote_sin, 0, sizeof(remote_sin));
+		sock = accept(listener, (struct sockaddr*)&remote_sin, &sin_size);
+
+		// shut down the listener now we have our connection
+		shutdown(listener, SD_SEND);
+		shutdown(listener, SD_RECEIVE);
+		closesocket(listener);
+
+		if (sock == INVALID_SOCKET)
+			return E_OUTOFMEM;
+	}
+
+	return ITS_OK;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Send
+int CSTATSocket::Send(const char cIdentifier, const char *pData, const unsigned long ulLength)
+{
+	int ret = ITS_OK;
+	unsigned long ID = htonl(cIdentifier);
+	unsigned long Length = htonl(ulLength);
+
+	// send the identifier
+	ret = send( sock, (char*)&ID, sizeof(unsigned long), 0 );
+	if (ret != sizeof(unsigned long))
+		return E_SOCKETSEND;
+
+	// send the length
+	ret = send( sock, (char*)&Length, sizeof(unsigned long), 0 );
+	if (ret != sizeof(unsigned long))
+		return E_SOCKETSEND;
+
+	if (pData && ulLength && (ulLength <= GetMaxPacketSize( )) )
+	{
+		char *pSendData = new char[ulLength + 1];
+		if (pSendData)
+		{
+			memset(pSendData, 0, ulLength + 1);
+			memcpy(pSendData, pData, ulLength);
+		}
+		else
+			return E_OUTOFMEM;
+
+		// send the length
+		ret = send( sock, pSendData, ulLength, 0 );
+
+		if (pSendData)
+			delete [] pSendData;
+
+		if (ret != (int)ulLength)
+			return E_SOCKETSEND;
+	}
+
+	return ITS_OK;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Receive
+int CSTATSocket::Receive(char *cIdentifier, char **ppData, unsigned long *pLength)
+{
+	int ret = ITS_OK;
+	unsigned long ID = 0;
+	unsigned long Length = 0;
+
+	TIMEVAL timeout;
+	timeout.tv_sec = SOCKETTIMEOUT;
+	timeout.tv_usec = 0;
+
+	FD_SET reader;
+	
+	FD_ZERO(&reader);
+	FD_SET(sock, &reader);
+
+	// receive the identifier
+
+	if(select(0, &reader, NULL, NULL, &timeout)==0)
+	{
+		return E_SOCKETRECV;
+	}
+
+	ret = recv( sock, (char*)&ID, sizeof(unsigned long), 0 );
+	if (ret != sizeof(unsigned long))
+		return E_SOCKETRECV;
+
+
+	if(select(0, &reader, NULL, NULL, &timeout)==0)
+	{
+		return E_SOCKETRECV;
+	}
+
+	// receive the length
+	ret = recv( sock, (char*)&Length, sizeof(unsigned long), 0 );
+	if (ret != sizeof(unsigned long))
+		return E_SOCKETRECV;
+
+	(*cIdentifier) = (char)ntohl(ID);
+	(*pLength) = ntohl(Length);
+
+	// if the length is zero then there is no more to do
+	if( *pLength == 0 ) {
+		return ITS_OK;
+	}
+
+	if( *pLength > GetMaxPacketSize( ) ) {
+		SetError( "Received command ID: %c successfully length %d", (*cIdentifier), *pLength );
+		return ITS_OK;
+	}
+
+	if (*pLength)
+	{
+		if( *pLength > iBufferLength )
+		{
+			if( pBuffer ) {
+				delete [] pBuffer;
+				pBuffer = NULL;
+				iBufferLength = 0;
+			}
+			pBuffer = new char [*pLength + 1];
+			if( pBuffer == NULL ) {
+				SetError( "Unable to allocate %ld bytes of memory to hold data", *pLength );
+				return E_OUTOFMEM;
+			}
+			memset(pBuffer, 0, (*pLength) + 1);
+			iBufferLength = *pLength;
+		}
+
+		char *p = pBuffer;
+
+		// receive the data
+		int iThisAmount = 0;
+		int iTotalReceived = 0;
+		while (iTotalReceived < (int)(*pLength))
+		{
+
+			if(select(0, &reader, NULL, NULL, &timeout)==0)
+			{
+				return E_SOCKETRECV;
+			}
+
+			iThisAmount = recv( sock, p, (*pLength) - iTotalReceived, 0 );
+			if (iThisAmount == SOCKET_ERROR)
+				return E_SOCKETRECV;
+
+			iTotalReceived += iThisAmount;
+			p += iThisAmount;
+			Sleep(100);
+		}
+
+		(*ppData) = pBuffer;
+	}
+
+	return ITS_OK;
+}
+	
+	
+////////////////////////////////////////////////////////////////////////////////////////
+// Disconnect
+int CSTATSocket::Disconnect(void)
+{
+	// release previous resources
+	if (pBuffer)
+	{
+		delete [] pBuffer;
+		pBuffer = NULL;
+		iBufferLength = 0;
+	}
+
+	shutdown(sock, SD_SEND);
+	shutdown(sock, SD_RECEIVE);
+
+	if (closesocket(sock) == SOCKET_ERROR)
+		return E_SOCKETCLOSE;
+
+	return ITS_OK;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// 
+int CSTATSocket::Release(void)
+{
+	if (WSACleanup() == SOCKET_ERROR)
+		return E_SOCKETSHUTDOWN;
+
+	return ITS_OK;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+//	PRIVATE FUNCTIONS
+////////////////////////////////////////////////////////////////////////////////////////