--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecmgmt/ucc/GenericService/SyncService/src/CSyncService.cpp Mon Mar 08 15:04:18 2010 +0800
@@ -0,0 +1,591 @@
+/*
+* 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:
+* CSyncService.h
+*
+*/
+
+
+
+#include <stdio.h>
+#include <crtdbg.h>
+#include <time.h>
+
+#include "CSyncService.h"
+#include "CUCCIniFile.h"
+
+// Parameters names
+const char KSharedDataName[] = { "NAME" };
+const char KSharedDataValue[] = { "VALUE" };
+
+
+// Sync Service ini file
+const char KSyncServiceIni[] = { ".\\SyncService.ini" };
+const char KIniSectionName[] = { "SyncService" };
+const char KIniConnection[] = { "Connection" };
+const char KIniSerialPort[] = { "SerialPort" };
+const char KIniIPAddress[] = { "IPAddress" };
+const char KSerial[] = { "serial" };
+const char KInfrared[] = { "ir" };
+const char KBluetooth[] = { "bt" };
+const char KSocket[] = { "tcp" };
+const char KTimeout[] = { "Timeout" };
+const char KPoll[] = { "Poll" };
+const char KSTATLocation[] = { "STAT" };
+
+// Timeout defaults (in seconds)
+const int KDefaultTimeout = 120;
+const int KDefaultPollInterval = 10;
+
+// STAT DLL Location
+#ifdef _DEBUG
+const char KDefaultSTATDLLLocation[] = { "\\epoc32\\tools\\stat\\statd.dll" };
+#else
+const char KDefaultSTATDLLLocation[] = { "\\epoc32\\tools\\stat\\stat.dll" };
+#endif
+
+// STAT Sync calls
+const char KStartSyncTestCase[] = { "<B><OTEFStatus,4><E>" };
+const char KStartSyncComplete[] = { "<B><OTEFStatus,2><E>" };
+const char KRetrieveSyncTestCaseResult[] = { "<B><NTEFResult><E>" };
+const char KRetrieveSyncTestCaseStatus[] = { "<B><NTEFStatus><E>" };
+const char KSetSharedData[] = { "<B><O" };
+const char KCommandTerminate[] = { "><E>" };
+const char KComma[] = { "," };
+
+const int KMaxSharedDataLength = 2048;
+
+// Possible TEF synchronised test case error codes
+const int EPass = 0;
+const int EFail = 106;
+const int EInconclusive = 107;
+const int ETestSuiteError = 108;
+const int EAbort = 109;
+const int EIgnore = 110;
+
+// TEF Sync Status codes
+enum TSyncStatus
+ {
+ ETEFSyncUnknown = 0,
+ ETEFSyncRunning = 1,
+ ETEFSyncComplete = 2,
+ ETEFSyncWaiting = 3,
+ ETEFSyncContinue = 4,
+ ETEFRetrieveResult = 5
+ };
+
+CService* Service() { return new CSyncService(); }
+
+CSyncService::CSyncService()
+ : ihLib(NULL), iptrConnect(NULL), iptrDisconnect(NULL), iptrSendRawCommand(NULL),
+ iptrGetTEFSharedData(NULL), iConnection(0), iTimeout(KDefaultTimeout),
+ iPollInterval(KDefaultPollInterval), iSTATDLLLocation(KDefaultSTATDLLLocation)
+ {
+ }
+
+CSyncService::~CSyncService()
+ {
+ // Free the STAT DLL library
+ if( ihLib != NULL )
+ {
+ ::FreeLibrary( ihLib );
+ ihLib = NULL;
+ }
+ }
+
+bool CSyncService::Setup()
+ {
+ bool ret = true;
+
+ ret = RetrieveCommsInfo();
+ if(!ret)
+ return ret;
+
+ // Load the STAT DLL library.
+ ihLib = ::LoadLibrary( iSTATDLLLocation.c_str() );
+ iptrConnect = reinterpret_cast<PROC_CONNECT>(::GetProcAddress( ihLib, ProcConnect ));
+ iptrDisconnect = reinterpret_cast<PROC_DISCONNECT>(::GetProcAddress( ihLib, ProcDisconnect ));
+ iptrSendRawCommand = reinterpret_cast<PROC_SENDRAWCOMMAND>(::GetProcAddress( ihLib, ProcSendRawCommand ));
+ iptrGetTEFSharedData = reinterpret_cast<PROC_GETTEFSHAREDDATA>(::GetProcAddress( ihLib, ProcGetTEFSharedData ));
+
+ if( ihLib == NULL ||
+ iptrConnect == NULL ||
+ iptrDisconnect == NULL ||
+ iptrSendRawCommand == NULL ||
+ iptrGetTEFSharedData == NULL )
+ {
+ ret = false;
+ }
+ return ret;
+ }
+
+int CSyncService::RunCommand( const CCall& aCall )
+ {
+ int ret = ERR_NONE;
+
+ // Connect to the device via STAT
+ if( !iConnection )
+ {
+ if( iConnectionType == SymbianSerial ||
+ iConnectionType == SymbianInfrared ||
+ iConnectionType == SymbianBluetooth )
+ {
+ iConnection = (iptrConnect)(iConnectionType,iComPort.c_str(),NULL,NULL);
+ }
+ else if( iConnectionType == SymbianSocket )
+ {
+ iConnection = (iptrConnect)(iConnectionType,iIPAddress.c_str(),NULL,NULL);
+ }
+ }
+
+ if( !iConnection )
+ {
+ ret = ERR_STAT;
+ }
+
+ int callID = -1;
+ if( aCall.CallID( callID ) && ret == ERR_NONE )
+ {
+ switch( callID )
+ {
+ case 1: // StartSyncTestCase
+ {
+ ret = StartSyncTestCase( aCall );
+ }
+ break;
+ case 2: // RetrieveSyncTestCaseResult
+ {
+ ret = RetrieveSyncTestCaseResult( aCall );
+ }
+ break;
+ case 3: // SetSharedData
+ {
+ ret = SetSharedData( aCall );
+ }
+ break;
+ default:
+ {
+ #ifdef _DEBUG
+ printf( "Unknown CallID\n" );
+ #endif
+ ret = ERR_INVALID_CALL;
+ }
+ }
+ }
+ else
+ {
+ ret = ERR_GENERAL;
+ }
+
+ // Disconnect the device via STAT
+ if( iConnection )
+ {
+ int disconnectOK;
+ disconnectOK = (iptrDisconnect)(iConnection);
+ if( !disconnectOK )
+ {
+ ret = ERR_STAT;
+ }
+ else
+ {
+ iConnection = 0;
+ }
+ }
+
+ return ret;
+}
+
+bool CSyncService::RetrieveCommsInfo()
+ {
+ bool ret = false;
+
+ // Load the configuration information file
+ CUCCIniFile iniFile( KSyncServiceIni );
+
+ // Retrieve the connection type
+ string connectionType;
+ if( iniFile.KeyValue(KIniConnection, KIniSectionName, connectionType) )
+ {
+ if( connectionType == KSerial )
+ {
+ iConnectionType = SymbianSerial;
+ ret = true;
+ }
+ else if( connectionType == KInfrared )
+ {
+ iConnectionType = SymbianInfrared;
+ ret = true;
+ }
+ else if( connectionType == KBluetooth )
+ {
+ iConnectionType = SymbianBluetooth;
+ ret = true;
+ }
+ else if( connectionType == KSocket )
+ {
+ iConnectionType = SymbianSocket;
+ ret = true;
+ }
+ else
+ {
+ iConnectionType = SymbianInvalid;
+ }
+ }
+ else
+ {
+ ret = false;
+ }
+
+ // Retrieve either the com port or the ip address
+ if( ret )
+ {
+ if( iConnectionType == SymbianSerial ||
+ iConnectionType == SymbianInfrared ||
+ iConnectionType == SymbianBluetooth )
+ {
+ if( !iniFile.KeyValue(KIniSerialPort, KIniSectionName, iComPort) )
+ {
+ ret = false;
+ }
+ }
+ else if( iConnectionType == SymbianSocket )
+ {
+ if( !iniFile.KeyValue(KIniIPAddress, KIniSectionName, iIPAddress) )
+ {
+ ret = false;
+ }
+ }
+ }
+
+ // Finally retrieve the timeout, poll interval and STAT DLL location values (all optional)
+ if( ret )
+ {
+ // Timeout
+ int timeout = 0;
+ if( iniFile.KeyValue(KTimeout, KIniSectionName, timeout) )
+ {
+ if( timeout > 0 )
+ {
+ iTimeout = timeout;
+ }
+ }
+
+ // Poll Interval
+ int pollInterval = 0;
+ if( iniFile.KeyValue(KPoll, KIniSectionName, pollInterval) )
+ {
+ if( pollInterval > 0 )
+ {
+ iPollInterval = pollInterval;
+ }
+ }
+
+ // STAT DLL Location
+ string statDLLLocation;
+ if( iniFile.KeyValue(KSTATLocation, KIniSectionName, statDLLLocation) )
+ {
+ if( statDLLLocation.length() > 0 )
+ {
+ iSTATDLLLocation.erase();
+ iSTATDLLLocation = statDLLLocation;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+int CSyncService::StartSyncTestCase( const CCall& aCall )
+ {
+ int ret = ERR_NONE;
+
+ printf( "StartSyncTestCase call\n" );
+
+ // Wait until the status is set to WAITING
+ // ie. The next test case is waiting
+ // Make the RetrieveSyncTestCaseStatus call
+
+ // Poll for the TEF Sync Status
+ bool tefContinue = false;
+ int sendRawOK = (iptrSendRawCommand)( iConnection,
+ KRetrieveSyncTestCaseStatus,
+ NULL);
+
+ TSyncStatus TEFstatus = ETEFSyncUnknown;
+ if( sendRawOK == ITS_OK )
+ {
+ const char* result = (iptrGetTEFSharedData)( iConnection );
+ if( result != NULL )
+ {
+ TEFstatus = (TSyncStatus)atoi( result );
+ if( TEFstatus == ETEFSyncWaiting )
+ {
+ tefContinue = true;
+ }
+ }
+ }
+
+ // Poll for the test case status
+ time_t end_time, cur_time;
+ time(&cur_time);
+ end_time = cur_time + iTimeout;
+ while( !tefContinue && end_time-cur_time > 0 )
+ {
+ // Delay before next attempt
+ Sleep( iPollInterval * 1000 );
+
+ // Make the RetrieveSyncTestCaseStatus call (poll)
+ sendRawOK = (iptrSendRawCommand)( iConnection,
+ KRetrieveSyncTestCaseStatus,
+ NULL);
+ if( sendRawOK == ITS_OK )
+ {
+ const char* result = (iptrGetTEFSharedData)( iConnection );
+ if( result != NULL )
+ {
+ TEFstatus = (TSyncStatus)atoi( result );
+ if( TEFstatus == ETEFSyncWaiting )
+ {
+ tefContinue = true;
+ }
+ }
+ }
+
+ // Update the current time
+ time(&cur_time);
+ }
+
+ if( sendRawOK == ITS_OK && TEFstatus == ETEFSyncWaiting )
+ {
+ // Make the StartSyncTestCase call
+ int sendRawOK = (iptrSendRawCommand)( iConnection,
+ KStartSyncTestCase,
+ NULL);
+ if( sendRawOK != ITS_OK )
+ {
+ ret = ERR_STAT_START_SYNC_TEST_CASE;
+ }
+ }
+ else
+ {
+ ret = ERR_STAT_RETRIEVE_SYNC_TEST_STATUS;
+ }
+
+ return ret;
+ }
+
+int CSyncService::RetrieveSyncTestCaseResult( const CCall& aCall )
+ {
+ int ret = ERR_NONE;
+
+ printf( "RetrieveSyncTestCaseResult call\n" );
+
+ // Wait until the status is set to either COMPLETE or WAITING
+ // ie. The sync test case has completed or the next one is waiting
+ // Make the RetrieveSyncTestCaseStatus call
+
+ // Poll for the TEF Sync Status
+ bool tefContinue = false;
+ int sendRawOK = (iptrSendRawCommand)( iConnection,
+ KRetrieveSyncTestCaseStatus,
+ NULL);
+
+ TSyncStatus TEFstatus = ETEFSyncUnknown;
+ if( sendRawOK == ITS_OK )
+ {
+ const char* result = (iptrGetTEFSharedData)( iConnection );
+ if( result != NULL )
+ {
+ TEFstatus = (TSyncStatus)atoi( result );
+ if( TEFstatus == ETEFRetrieveResult )
+ {
+ tefContinue = true;
+ }
+ }
+ }
+
+ // Poll for the test case status
+ time_t end_time, cur_time;
+ time(&cur_time);
+ end_time = cur_time + iTimeout;
+ while( !tefContinue && (end_time-cur_time > 0) )
+ {
+ // Delay before next attempt
+ Sleep( iPollInterval * 1000 );
+
+ // Make the RetrieveSyncTestCaseStatus call (poll)
+ sendRawOK = (iptrSendRawCommand)( iConnection,
+ KRetrieveSyncTestCaseStatus,
+ NULL);
+ if( sendRawOK == ITS_OK )
+ {
+ const char* result = (iptrGetTEFSharedData)( iConnection );
+ if( result != NULL )
+ {
+ TEFstatus = (TSyncStatus)atoi( result );
+ if( TEFstatus == ETEFRetrieveResult )
+ {
+ tefContinue = true;
+ }
+ }
+ }
+
+ // Update the current time
+ time(&cur_time);
+ }
+
+ if( sendRawOK == ITS_OK && TEFstatus == ETEFRetrieveResult )
+ {
+ // Make the RetrieveSyncTestCaseResult call
+ int sendRawOK = (iptrSendRawCommand)( iConnection,
+ KRetrieveSyncTestCaseResult,
+ NULL);
+
+ // Check what was returned from TEF
+ if( sendRawOK == ITS_OK )
+ {
+ // Now retrieve the TEF Shared data from STAT
+ // In the is case the shared data stores the synchronised
+ // test case result as an integer.
+ // Set the ret value to equal to this.
+ const char* result = (iptrGetTEFSharedData)( iConnection );
+ int TEFret = EInconclusive;
+ if( result != NULL )
+ {
+ TEFret = atoi( result );
+ }
+
+ // Map the code onto the return value
+ switch( TEFret )
+ {
+ case EPass:
+ case EFail:
+ case EInconclusive:
+ case ETestSuiteError:
+ case EAbort:
+ case EIgnore:
+ {
+ ret = TEFret;
+ }
+ break;
+ default:
+ {
+ ret = EFail;
+ }
+ break;
+ }
+
+ // Update the status so TEF can continue
+ int sendRawOK = (iptrSendRawCommand)( iConnection,
+ KStartSyncComplete,
+ NULL);
+ if( sendRawOK != ITS_OK )
+ {
+ ret = ERR_STAT_START_SYNC_TEST_CASE;
+ }
+ }
+ else
+ {
+ ret = ERR_STAT_RETRIEVE_SYNC_TEST_RESULT;
+ }
+ }
+ else
+ {
+ ret = ERR_STAT_RETRIEVE_SYNC_TEST_STATUS;
+ }
+
+ return ret;
+ }
+
+int CSyncService::SetSharedData( const CCall& aCall )
+ {
+ int ret = ERR_NONE;
+
+ #ifdef _DEBUG
+ printf( "SetSharedData call\n" );
+ #endif
+
+ int numParams = 0;
+ bool callRet = aCall.Params( numParams );
+ if( numParams == 2 )
+ {
+ string paramName;
+ string sharedDataName;
+ string paramValue;
+ string sharedDataValue;
+
+ // Retrieve the shared data name
+ if( aCall.Name(0, paramName) && aCall.Value(0, sharedDataName) )
+ {
+ if( paramName != KSharedDataName )
+ {
+ ret = ERR_INVALIDARG;
+ }
+ }
+ else
+ {
+ ret = ERR_INVALIDARG;
+ }
+
+ // Retrieve the shared data value
+ if( ret == 0 )
+ {
+ if( aCall.Name(1, paramValue) && aCall.Value(1, sharedDataValue) )
+ {
+ if( paramValue != KSharedDataValue )
+ {
+ ret = ERR_INVALIDARG;
+ }
+ }
+ else
+ {
+ ret = ERR_INVALIDARG;
+ }
+ }
+
+ // Send the shared data (name and value) via STAT
+ if( ret == 0 )
+ {
+ if( sharedDataValue.size() > 0 )
+ {
+ // Construct the call
+ string sharedDataCall;
+ sharedDataCall += KSetSharedData;
+ sharedDataCall += sharedDataName;
+ sharedDataCall += KComma;
+ sharedDataCall += sharedDataValue;
+ sharedDataCall += KCommandTerminate;
+
+ // Make the SetSharedData call
+ int sendRawOK = (iptrSendRawCommand)( iConnection,
+ sharedDataCall.c_str(),
+ NULL);
+ if( sendRawOK != ITS_OK )
+ {
+ ret = ERR_STAT_SET_SHARED_DATA;
+ }
+ }
+ else
+ {
+ ret = ERR_INVALIDARG;
+ }
+ }
+ }
+ else
+ {
+ ret = ERR_INVALIDARG;
+ }
+
+ return ret;
+ }