diff -r 000000000000 -r 3da2a79470a7 testexecmgmt/ucc/GenericService/SyncService/src/CSyncService.cpp --- /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 +#include +#include + +#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[] = { "" }; +const char KStartSyncComplete[] = { "" }; +const char KRetrieveSyncTestCaseResult[] = { "" }; +const char KRetrieveSyncTestCaseStatus[] = { "" }; +const char KSetSharedData[] = { "" }; +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(::GetProcAddress( ihLib, ProcConnect )); + iptrDisconnect = reinterpret_cast(::GetProcAddress( ihLib, ProcDisconnect )); + iptrSendRawCommand = reinterpret_cast(::GetProcAddress( ihLib, ProcSendRawCommand )); + iptrGetTEFSharedData = reinterpret_cast(::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; + }