diff -r 73b88125830c -r b8d1455fddc0 testconns/statdesktop/desktop/source/lib/src/statsocket_block.cpp --- /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 +////////////////////////////////////////////////////////////////////////////////////////