testtoolsconn/stat/desktop/source/lib/src/statsocket_block.cpp
changeset 0 3da2a79470a7
equal deleted inserted replaced
-1:000000000000 0:3da2a79470a7
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "stdafx.h"
       
    22 #include "statsocket_block.h"
       
    23 
       
    24 ////////////////////////////////////////////////////////////////////////////////////////
       
    25 // Constructor
       
    26 CSTATSocket::CSTATSocket() : pBuffer(NULL), iBufferLength(0)
       
    27 {
       
    28 }
       
    29 
       
    30 
       
    31 ////////////////////////////////////////////////////////////////////////////////////////
       
    32 // Destructor
       
    33 CSTATSocket::~CSTATSocket()
       
    34 {
       
    35 	Disconnect();
       
    36 	Release();
       
    37 }
       
    38 
       
    39 
       
    40 ////////////////////////////////////////////////////////////////////////////////////////
       
    41 // Initialise
       
    42 int CSTATSocket::Initialise(void)
       
    43 {
       
    44 	WORD version;
       
    45 	WSADATA wsaData;
       
    46 
       
    47 	// start the windows socket server
       
    48 	version = MAKEWORD( 2, 2 );
       
    49 	if (WSAStartup( version, &wsaData ))
       
    50 		return E_SOCKETSTARTUP;
       
    51 
       
    52 	return ITS_OK;
       
    53 }
       
    54 
       
    55 
       
    56 ////////////////////////////////////////////////////////////////////////////////////////
       
    57 // Connect
       
    58 int CSTATSocket::Connect(const char *pAddress)
       
    59 {
       
    60 	int iPort = ST_DEFAULTDEVICEPORT;
       
    61 
       
    62 	// parameter will either be MACHINE_NAME:PORT_NUMBER if connecting
       
    63 	// or just PORT_NUMBER if listening
       
    64 	char *p = strrchr(pAddress, ':');
       
    65 	char *q = p;
       
    66 	if (p)
       
    67 	{
       
    68 		(*p) = (char)0;
       
    69 
       
    70 		p++;
       
    71 		if (p && *p)
       
    72 			iPort = atoi(p);
       
    73 
       
    74 		// local address
       
    75 		struct hostent *hp;
       
    76 		memset(&sin,0,sizeof(sin));
       
    77 		sin.sin_family = AF_INET;
       
    78 		sin.sin_port = htons((unsigned short)iPort);
       
    79 		hp = gethostbyname(pAddress);
       
    80 
       
    81 		// put this back to restore original string
       
    82 		*q = ':';
       
    83 
       
    84 		if (hp)
       
    85 		{
       
    86 
       
    87 			// create a client socket
       
    88 			sock = socket( AF_INET, SOCK_STREAM, 0 ) ;
       
    89 			if( sock == INVALID_SOCKET )
       
    90 				return E_SOCKETCREATE;
       
    91 
       
    92 			memcpy(&(sin.sin_addr),hp->h_addr,hp->h_length);
       
    93 
       
    94 			// connect to server
       
    95 			if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0)
       
    96 				return E_SOCKETCONNECT;
       
    97 
       
    98 			// Set the socket I/O mode
       
    99 			// FIONBIO enables or disables the blocking mode for the 
       
   100 			// socket:
       
   101 			// 0   => blocking is enabled; 
       
   102 			// !=0 => non-blocking mode is enabled.
       
   103 			u_long mode = 1;
       
   104 			ioctlsocket(sock, FIONBIO, &mode);
       
   105 
       
   106 		}
       
   107 		else
       
   108 			return E_SOCKETHOSTNAME;
       
   109 	}
       
   110 	else
       
   111 	{
       
   112 		// create a listener socket
       
   113 		listener = socket(AF_INET, SOCK_STREAM, 0);
       
   114 		if( listener == INVALID_SOCKET )
       
   115 			return E_SOCKETCREATE;
       
   116 
       
   117 		iPort = atoi(pAddress);
       
   118 		if (!iPort)
       
   119 			iPort = ST_DEFAULTDEVICEPORT;
       
   120 
       
   121 		sin.sin_family = AF_INET;
       
   122 		sin.sin_port = htons((unsigned short)iPort);
       
   123 		sin.sin_addr.s_addr = INADDR_ANY;
       
   124 
       
   125 		if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) != 0)
       
   126 			return E_SOCKETBIND;
       
   127 
       
   128 		if (listen(listener, 1) != 0)
       
   129 			return E_SOCKETLISTEN;
       
   130 
       
   131 		int sin_size = sizeof(remote_sin);
       
   132 		memset((void *)&remote_sin, 0, sizeof(remote_sin));
       
   133 		sock = accept(listener, (struct sockaddr*)&remote_sin, &sin_size);
       
   134 
       
   135 		// shut down the listener now we have our connection
       
   136 		shutdown(listener, SD_SEND);
       
   137 		shutdown(listener, SD_RECEIVE);
       
   138 		closesocket(listener);
       
   139 
       
   140 		if (sock == INVALID_SOCKET)
       
   141 			return E_OUTOFMEM;
       
   142 	}
       
   143 
       
   144 	return ITS_OK;
       
   145 }
       
   146 
       
   147 
       
   148 ////////////////////////////////////////////////////////////////////////////////////////
       
   149 // Send
       
   150 int CSTATSocket::Send(const char cIdentifier, const char *pData, const unsigned long ulLength)
       
   151 {
       
   152 	int ret = ITS_OK;
       
   153 	unsigned long ID = htonl(cIdentifier);
       
   154 	unsigned long Length = htonl(ulLength);
       
   155 
       
   156 	// send the identifier
       
   157 	ret = send( sock, (char*)&ID, sizeof(unsigned long), 0 );
       
   158 	if (ret != sizeof(unsigned long))
       
   159 		return E_SOCKETSEND;
       
   160 
       
   161 	// send the length
       
   162 	ret = send( sock, (char*)&Length, sizeof(unsigned long), 0 );
       
   163 	if (ret != sizeof(unsigned long))
       
   164 		return E_SOCKETSEND;
       
   165 
       
   166 	if (pData && ulLength && (ulLength <= GetMaxPacketSize( )) )
       
   167 	{
       
   168 		char *pSendData = new char[ulLength + 1];
       
   169 		if (pSendData)
       
   170 		{
       
   171 			memset(pSendData, 0, ulLength + 1);
       
   172 			memcpy(pSendData, pData, ulLength);
       
   173 		}
       
   174 		else
       
   175 			return E_OUTOFMEM;
       
   176 
       
   177 		// send the length
       
   178 		ret = send( sock, pSendData, ulLength, 0 );
       
   179 
       
   180 		if (pSendData)
       
   181 			delete [] pSendData;
       
   182 
       
   183 		if (ret != (int)ulLength)
       
   184 			return E_SOCKETSEND;
       
   185 	}
       
   186 
       
   187 	return ITS_OK;
       
   188 }
       
   189 
       
   190 
       
   191 ////////////////////////////////////////////////////////////////////////////////////////
       
   192 // Receive
       
   193 int CSTATSocket::Receive(char *cIdentifier, char **ppData, unsigned long *pLength)
       
   194 {
       
   195 	int ret = ITS_OK;
       
   196 	unsigned long ID = 0;
       
   197 	unsigned long Length = 0;
       
   198 
       
   199 	TIMEVAL timeout;
       
   200 	timeout.tv_sec = SOCKETTIMEOUT;
       
   201 	timeout.tv_usec = 0;
       
   202 
       
   203 	FD_SET reader;
       
   204 	
       
   205 	FD_ZERO(&reader);
       
   206 	FD_SET(sock, &reader);
       
   207 
       
   208 	// receive the identifier
       
   209 
       
   210 	if(select(0, &reader, NULL, NULL, &timeout)==0)
       
   211 	{
       
   212 		return E_SOCKETRECV;
       
   213 	}
       
   214 
       
   215 	ret = recv( sock, (char*)&ID, sizeof(unsigned long), 0 );
       
   216 	if (ret != sizeof(unsigned long))
       
   217 		return E_SOCKETRECV;
       
   218 
       
   219 
       
   220 	if(select(0, &reader, NULL, NULL, &timeout)==0)
       
   221 	{
       
   222 		return E_SOCKETRECV;
       
   223 	}
       
   224 
       
   225 	// receive the length
       
   226 	ret = recv( sock, (char*)&Length, sizeof(unsigned long), 0 );
       
   227 	if (ret != sizeof(unsigned long))
       
   228 		return E_SOCKETRECV;
       
   229 
       
   230 	(*cIdentifier) = (char)ntohl(ID);
       
   231 	(*pLength) = ntohl(Length);
       
   232 
       
   233 	// if the length is zero then there is no more to do
       
   234 	if( *pLength == 0 ) {
       
   235 		return ITS_OK;
       
   236 	}
       
   237 
       
   238 	if( *pLength > GetMaxPacketSize( ) ) {
       
   239 		SetError( "Received command ID: %c successfully length %d", (*cIdentifier), *pLength );
       
   240 		return ITS_OK;
       
   241 	}
       
   242 
       
   243 	if (*pLength)
       
   244 	{
       
   245 		if( *pLength > iBufferLength )
       
   246 		{
       
   247 			if( pBuffer ) {
       
   248 				delete [] pBuffer;
       
   249 				pBuffer = NULL;
       
   250 				iBufferLength = 0;
       
   251 			}
       
   252 			pBuffer = new char [*pLength + 1];
       
   253 			if( pBuffer == NULL ) {
       
   254 				SetError( "Unable to allocate %ld bytes of memory to hold data", *pLength );
       
   255 				return E_OUTOFMEM;
       
   256 			}
       
   257 			memset(pBuffer, 0, (*pLength) + 1);
       
   258 			iBufferLength = *pLength;
       
   259 		}
       
   260 
       
   261 		char *p = pBuffer;
       
   262 
       
   263 		// receive the data
       
   264 		int iThisAmount = 0;
       
   265 		int iTotalReceived = 0;
       
   266 		while (iTotalReceived < (int)(*pLength))
       
   267 		{
       
   268 
       
   269 			if(select(0, &reader, NULL, NULL, &timeout)==0)
       
   270 			{
       
   271 				return E_SOCKETRECV;
       
   272 			}
       
   273 
       
   274 			iThisAmount = recv( sock, p, (*pLength) - iTotalReceived, 0 );
       
   275 			if (iThisAmount == SOCKET_ERROR)
       
   276 				return E_SOCKETRECV;
       
   277 
       
   278 			iTotalReceived += iThisAmount;
       
   279 			p += iThisAmount;
       
   280 			Sleep(100);
       
   281 		}
       
   282 
       
   283 		(*ppData) = pBuffer;
       
   284 	}
       
   285 
       
   286 	return ITS_OK;
       
   287 }
       
   288 	
       
   289 	
       
   290 ////////////////////////////////////////////////////////////////////////////////////////
       
   291 // Disconnect
       
   292 int CSTATSocket::Disconnect(void)
       
   293 {
       
   294 	// release previous resources
       
   295 	if (pBuffer)
       
   296 	{
       
   297 		delete [] pBuffer;
       
   298 		pBuffer = NULL;
       
   299 		iBufferLength = 0;
       
   300 	}
       
   301 
       
   302 	shutdown(sock, SD_SEND);
       
   303 	shutdown(sock, SD_RECEIVE);
       
   304 
       
   305 	if (closesocket(sock) == SOCKET_ERROR)
       
   306 		return E_SOCKETCLOSE;
       
   307 
       
   308 	return ITS_OK;
       
   309 }
       
   310 
       
   311 
       
   312 ////////////////////////////////////////////////////////////////////////////////////////
       
   313 // 
       
   314 int CSTATSocket::Release(void)
       
   315 {
       
   316 	if (WSACleanup() == SOCKET_ERROR)
       
   317 		return E_SOCKETSHUTDOWN;
       
   318 
       
   319 	return ITS_OK;
       
   320 }
       
   321 
       
   322 
       
   323 ////////////////////////////////////////////////////////////////////////////////////////
       
   324 //	PRIVATE FUNCTIONS
       
   325 ////////////////////////////////////////////////////////////////////////////////////////