--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecmgmt/ucc/Source/CSProtocolLibrary/sprotocol/CXServer.cpp Mon Mar 08 15:04:18 2010 +0800
@@ -0,0 +1,455 @@
+/*
+* 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:
+* Filename: CXServer.cpp
+* Author: Sanjeet Matharu
+* This is the server side of the protocol which takes name/value pairs and does stuff
+* System Includes
+*
+*/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <memory.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef WIN32
+#include <winsock2.h>
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#endif
+
+/*******************************************************************************
+ *
+ * Local Includes
+ *
+ ******************************************************************************/
+#include "cxserver.h"
+
+#define TIMEOUTPERIOD 15 //seconds
+
+//------------------------------------------------------------------------------
+//constructor
+CXServer::CXServer()
+{
+ iStatus = RECEIVE_HELLO; //initialise to RECEIVE_HELLO
+
+ //initialise the name and value pairs
+ for(int i = 0; i < MAXLISTLENGTH; i++)
+ {
+ memset( iList[i].iName, 0, MAXBUFFERLEN );
+ memset( iList[i].iValue, 0, MAXBUFFERLEN );
+ }
+
+ iListPtr = NULL; //this is used to point to either the name or the value in the list
+ timeout.tv_sec = TIMEOUTPERIOD; //set up socket timeout period
+ timeout.tv_usec = 0;
+}
+
+//------------------------------------------------------------------------------
+//destructor
+CXServer::~CXServer()
+{
+ iStatus = RECEIVE_HELLO; //end on RECEIVE_HELLO
+
+ iListPtr = NULL;
+
+ //clear the name and value pairs
+ for(int i = 0; i < MAXLISTLENGTH; i++)
+ {
+ memset( iList[i].iName, 0, MAXBUFFERLEN );
+ memset( iList[i].iValue, 0, MAXBUFFERLEN );
+ }
+}
+
+//------------------------------------------------------------------------------
+//this function adds the specified value into the list of name value pairs
+int CXServer::OnExecute(int handle, int handletype)
+{
+ int err = 0;
+ int buff = -1;
+
+ //check the list for the next available space
+ for(int i = 0; i < MAXLISTLENGTH; i++ )
+ {
+ if( *iList[i].iName == 0 )
+ {
+ buff = i;
+ break;
+ }
+ }
+
+ // check that a slot was found, return error if not
+ if( buff == -1 )
+ {
+ return CSP_LISTFULL;
+ }
+
+ //if we get here and the status is value there is a problem and we'd loop like forever
+ while( iStatus != RECEIVE_VALUE )
+ {
+ switch( iStatus )
+ {
+ case RECEIVE_HELLO:
+
+ err = CheckForHello(handle, handletype, buff);
+
+ //the was a problem with the socket connection
+ if(err != 1)
+ {
+ return err;
+ }
+
+ break;
+
+ case RECEIVE_NAME:
+
+ err = CheckForData(handle, handletype, buff);
+
+ if(err != 0)
+ {
+ return err;
+ }
+
+ break;
+
+ case RECEIVE_GOODBYE:
+
+ iStatus = RECEIVE_HELLO;
+ break;
+
+ default:
+
+ break;
+ }
+ }
+
+ // done
+ return err;
+}
+
+//------------------------------------------------------------------------------
+// This function checks to see whether the Hello call has been made by the client
+// it returns OK or ERROR accordingly
+int CXServer::CheckForHello(int handle, int handletype, int freeslot)
+{
+ char c;
+ int counter = 0;
+ int err;
+ int buff = -1;
+ int bufflen = 0;
+
+ //initialisation
+ sprintf(&c, "%c", "");
+ sprintf(iHellobuffer, "%s", "HELLO");
+
+ //ensure that there are some free slots available in the list
+ assert(freeslot != -1);
+
+ buff = freeslot;
+
+ //set the pointer to point to the name element
+ iListPtr = iList[buff].iName;
+
+ while( 1 )
+ {
+ // receive the next byte
+ err = Read( handle, handletype, &c );
+
+ //if something has been read from the socket
+ if( ( err == 1 ) )
+ {
+ //...and the character received is zero
+ if( strcmp( &c, "" ) == 0)
+ {
+ //we have the complete string so compare with our buffer
+ if(strcmp(iHellobuffer, iListPtr) != 0)
+ {
+ Write(handle, handletype, REPLY_ERROR, strlen(REPLY_ERROR) );
+ //clear the buffer
+ memset( iListPtr, 0, MAXBUFFERLEN );
+ //reset bufferlen counter so that writing can start from the beginning next time
+ bufflen = 0;
+ }
+ else //data is ok
+ {
+ Write( handle, handletype, iListPtr, strlen(iListPtr) );
+ Write( handle, HT_SOCKET, "", 1 );
+ break;
+ }
+ }
+ else
+ {
+ // add the byte to the buffer
+ iListPtr[bufflen++] = c;
+ }
+ }
+ else //if
+ {
+ //if there was a dodgy read then the socket link is broken
+ memset( iListPtr, 0, MAXBUFFERLEN );
+ bufflen = 0;
+ err = GetLastError();
+ printf( "Data could not be read. Error code is %d...\n", err);
+ return err;
+ }
+ } //while
+
+ //update the status
+ iStatus = RECEIVE_NAME;
+
+ //since the first element in the list will have HELLO in it, it should be reinitialised for use later on
+ memset( iListPtr, 0, MAXBUFFERLEN );
+
+ return err;
+}
+
+//------------------------------------------------------------------------------
+//this checks the socket for data
+int CXServer::CheckForData(int handle, int handletype, int freeslot)
+{
+ int bufflen = 0;
+ int buff = 0;
+ int err = 0;
+ char c;
+
+ assert( iStatus == RECEIVE_NAME);
+
+ buff = freeslot;
+
+ //check for data on the socket
+ if( CheckForTimeout(handle) != 0 )
+ {
+ //revert status to previous as we received no data within the alloted time
+ iStatus = RECEIVE_HELLO;
+ Write(handle, handletype, REPLY_TIMEOUT, strlen(REPLY_TIMEOUT) );
+ return err;
+ }
+
+ // the client should send the list of arguments - this is the name and value receiving section!!!!
+ // this section will continue to loop until the the goodbye message has been received
+ while( iStatus != RECEIVE_GOODBYE )
+ {
+ //need to do the timeout thing here for value data
+ if( iStatus == RECEIVE_VALUE )
+ {
+ if( CheckForTimeout(handle) != 0 )
+ {
+ //revert status to previous as we received no data within the alloted time
+ iStatus = RECEIVE_NAME;
+ //point to the previous name element in the array so that the last bit of data is overwritten
+ iListPtr = iList[buff].iName;
+ bufflen = 0;
+ Write( handle, handletype, REPLY_TIMEOUT, strlen(REPLY_TIMEOUT) );
+ return err;
+ }
+ }
+
+ // receive the next byte
+ err = Read( handle, handletype, &c );
+
+ //if something has been read from the socket
+ if( ( err == 1 ) )
+ {
+ //need to check for available data space
+ if( buff > (MAXLISTLENGTH - 1) )
+ {
+ Write(handle, handletype, REPLY_ERROR, strlen(REPLY_ERROR));
+ return CSP_LISTFULL;
+ }
+
+ // if the data buffer is full then we have an error
+ if( bufflen == (MAXBUFFERLEN - 1) )
+ {
+ Write(handle, handletype, REPLY_ERROR, strlen(REPLY_ERROR));
+ return CSP_BUFFERFULL;
+ }
+
+ //...or the character received is zero
+ if( strcmp( &c,"" ) == 0)
+ {
+ //reply to say that we got the data ok
+ Write( handle, handletype, iListPtr, strlen(iListPtr) );
+ Write( handle, HT_SOCKET, "", 1 );
+
+ CheckForGoodbye(handle, handletype, buff);
+
+ //if GOODBYE has not been received and the status has not changed
+ if( iStatus != RECEIVE_GOODBYE )
+ {
+ //change the status from name -> value or vice versa
+ if( iListPtr == iList[buff].iName )
+ {
+ iListPtr = iList[buff].iValue;
+ //reset bufferlen counter so that writing can start from the beginning
+
+ bufflen = 0;
+
+ iStatus = RECEIVE_VALUE;
+ }
+ else
+ {
+ //move onto the next element in the list
+ iListPtr = iList[++buff].iName;
+
+ //reset bufferlen counter so that writing can start from the beginning
+ bufflen = 0;
+
+ iStatus = RECEIVE_NAME;
+ } //else
+ } //if (iStatus != ...)
+ } //if (c == 0)
+ else
+ {
+ // add the byte to the buffer
+ iListPtr[bufflen++] = c;
+ }
+ } //if
+ else
+ {
+ //if there was a dodgy read
+ Write(handle, handletype, REPLY_ERROR, strlen(REPLY_ERROR));
+ memset( iListPtr, 0, MAXBUFFERLEN );
+
+ //reset bufferlen counter so that writing can start from the beginning next time
+ bufflen = 0;
+
+ //and if status was VALUE then go back to NAME
+ if(iStatus = RECEIVE_VALUE)
+ {
+ iStatus = RECEIVE_NAME;
+ iListPtr = iList[buff].iName;
+ return err;
+ }
+ }
+ }
+
+ //change status back to receive hello
+ iStatus = RECEIVE_HELLO;
+
+ //everthing should be ok at this stage so reset err
+ err = 0;
+
+ return err;
+}
+
+//------------------------------------------------------------------------------
+//this function checks for the GOODBYE message. If it has been set then it changes the status
+void CXServer::CheckForGoodbye(int handle, int handletype, int latestposition)
+{
+
+ sprintf(iGoodbyebuffer, "%s", "GOODBYE");
+
+ //if an exact match is found
+ if(strcmp(iGoodbyebuffer, iListPtr) == 0)
+ {
+ //change status
+ iStatus = RECEIVE_GOODBYE;
+
+ //reset the data in the name/value slot
+ memset( iListPtr, 0, MAXBUFFERLEN );
+
+ printf( "Expecting HELLO from client side...\n" );
+ }
+}
+//------------------------------------------------------------------------------
+//this function reads data from a specific port
+int CXServer::Read(int handle, int handletype, char* c)
+{
+ int err = 0;
+
+ assert( c != NULL );
+
+ // socket handles
+ if( handletype == HT_SOCKET )
+ {
+ err = recv( handle, c, 1, 0 );
+ if( err != 1 ) //if the single char has not been received
+ {
+ err = GetLastError();
+ return err;
+ }
+ }
+
+ return err;
+}
+
+//------------------------------------------------------------------------------
+//this function writes on a specific port
+int CXServer::Write(int handle, int handletype, char *buff, int bufflen)
+{
+ int err;
+
+ assert( buff != NULL );
+
+ // socket handles
+ if( handletype == HT_SOCKET )
+ {
+ err = send( handle, buff, bufflen, 0 );
+ if( err != bufflen )
+ {
+ err = GetLastError();
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+//this function waits for input to be received on the specified socket for a specific time
+int CXServer::CheckForTimeout(int handle)
+{
+ int live = 0;
+ int err = 0;
+
+ while( 1 )
+ {
+ //set up socket timer structure
+ FD_ZERO( &iReadSocketSet );
+ FD_SET( (unsigned)handle, &iReadSocketSet );
+
+ //wait for some input
+ live = select(NULL, &iReadSocketSet, NULL, NULL, &timeout);
+
+ //if there is some input
+ if( live < 0 )
+ {
+ printf( "Call to select() failed...\n" );
+ return live;
+ }
+ else if ( live == 0 )
+ {
+ printf( "No descriptors ready...\n" );
+ printf( "Timed out...\n" );
+ err = -1;
+ return err;
+ }
+ else //something is ready
+ {
+ FD_ISSET( handle, &iReadSocketSet );
+ printf( "Data read...\n" );
+ return err;
+ }
+ }
+
+ return err;
+}
+//------------------------------------------------------------------------------