diff -r 000000000000 -r 14df0fbfcc4e sapi_location/locationservice/src/locationservice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sapi_location/locationservice/src/locationservice.cpp Mon Mar 30 12:51:10 2009 +0300 @@ -0,0 +1,386 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Implements location SAPI core ;works as wrapper +* around core implementaion. +* +*/ + + + +#include "locationcoreimp.h" +#include "locationservice.h" + +/** + * Maximum number of active objects that can be created : at present only each corresponding + * to location-asynch and trace + */ +const TInt KMAXAO = 2; + + + + +/** + * Default constructor + */ + + +EXPORT_C CLocationService :: CLocationService() + { + //No Implementation Required Here + } + + +/** + * Destructor + */ + +EXPORT_C CLocationService :: ~CLocationService() + { + iPositioner.Close(); + + + //Destroy all the contents of the registration table + for(TInt iter = 0 ; iter < iRegTable.Count() ; ++iter) + { + if(iRegTable[iter]) + { + if(iRegTable[iter]->IsActive()) + { + iRegTable[iter]->Deque() ; + } + delete iRegTable[iter]; + iRegTable[iter] = NULL ; + + } + } + iPosServer.Close(); + iRegTable.Close(); + + } + +/** + * CLocationService::NewL + * Two-phased constructor. + */ + + +EXPORT_C CLocationService *CLocationService :: NewL() + { + CLocationService *self = new(ELeave)CLocationService() ; + CleanupStack::PushL(self); + self->ConstructL() ; + CleanupStack::Pop(self) ; + return self ; + + } + +/** + * CLocationService::ConstructL + * Symbian 2nd phase constructor can leave. + */ + +void CLocationService::ConstructL() + { + + DoInitialiseL(); + } + + + +/** + * CLocationService::DoInitialiseL + * Initialises position server and positioner and + * begins the position request sequence. + */ + +EXPORT_C void CLocationService :: DoInitialiseL() + { + TInt error = iPosServer.Connect( ); + // The connection failed + + User :: LeaveIfError(error) ; + + // Open subsession to the position server + error = iPositioner.Open(iPosServer); + + // The opening of a subsession failed + if ( KErrNone != error ) + { + iPosServer.Close(); + User :: Leave( error ); + } + + + //setting identity for this requestor + User::LeaveIfError( iPositioner.SetRequestor( CRequestor::ERequestorService, + CRequestor::EFormatApplication, + KIdentity ) ); + + //Initialise index which means there is no + //active object created yet + iIndex = 0 ; + //Initialising array pointer to NULL + + for ( TInt count = 0;count < KMAXAO;count++) + { + iRegTable.Insert(NULL,count); + } + + + //Getthe module id used by location server for sapi location calls. + error = iPosServer.GetDefaultModuleId(iModuleId); + + User :: LeaveIfError(error) ; + + } + + +/** + * CLocationService :: GetLocationL with update options, this function gets users current location + * returns 0 on success and Symbian specific error codes on failure + */ + +EXPORT_C TInt CLocationService :: GetLocationL( TPositionInfoBase* aInfoBase , const TPositionUpdateOptions* aUpdateOpts ) + { + + TRequestStatus status ; + + if(aUpdateOpts) + { + TInt error; + error = iPositioner.SetUpdateOptions(*aUpdateOpts); + if( error) + { + return error ; + } + + } + else + { + TPositionUpdateOptions updateopts ; + + // Set update interval to one second to receive one position data per second + updateopts.SetUpdateInterval(TTimeIntervalMicroSeconds(KSUpdateInterval)); + + // If position server could not get position + // In two minutes it will terminate the position request + updateopts.SetUpdateTimeOut(TTimeIntervalMicroSeconds(KSUpdateTimeOut)); + + // Positions which have time stamp below KMaxAge can be reused + updateopts.SetMaxUpdateAge(TTimeIntervalMicroSeconds(KSMaxAge)); + + // Enables location framework to send partial position data + updateopts.SetAcceptPartialUpdates(FALSE); + + + iPositioner.SetUpdateOptions(updateopts) ; + } + + + iPositioner.NotifyPositionUpdate( *aInfoBase, status ); + User :: WaitForRequest(status) ; + + return status.Int() ; + } + +/** + * CLocationService::ModuleInfo, gets information about the location moudleid of currently used + * positioning moulde, currently this methods only supports info of default module indentifier + */ + + EXPORT_C TInt CLocationService :: GetModuleInfo( TPositionModuleInfoBase& aModuleInfo ) const + { + return iPosServer.GetModuleInfoById(iModuleId , aModuleInfo) ; + + } + + + +/** + * Function Name : GetLocation Asynchronous + * This function gets users current location + * returns status of job submitted + */ +EXPORT_C TInt CLocationService :: GetLocationL( MLocationCallBack* aCallBackObj , + TInt aLocationInfoCategory, + TPositionFieldIdList aFieldList , + const TPositionUpdateOptions* aUpateOptions + ) + { + + if(iRegTable[KARRAY_INDEX_GETLOCATION]) + { + if(iRegTable[KARRAY_INDEX_GETLOCATION]->IsActive()) + { + return KErrInUse ; //Return Error is Already registred + } + + delete iRegTable[KARRAY_INDEX_GETLOCATION] ; + iRegTable[KARRAY_INDEX_GETLOCATION] = NULL ; + + } + + CGetLoc *activeGetLoc = CGetLoc :: NewL(iPosServer , + aFieldList , + KGetLocationRequest, + aLocationInfoCategory ) ; + //after creation of each active object increment counter by 1 + + TInt err = activeGetLoc->GetLocation(aCallBackObj , aUpateOptions) ; + + if ( KErrNone == err ) + { + + iIndex = KARRAY_INDEX_GETLOCATION; //for getlocation we are storing the pointer in 0th slot + iRegTable[KARRAY_INDEX_GETLOCATION] = activeGetLoc ; + } + + else + { + delete activeGetLoc ; //Clean up + } + + return err; + } + + + +/** + * CLocationService :: TraceL Notifies user if any changes occurs to his current position, + * types of updates required are specified as part of Updateoptions. + * Returns 0 on success and symbian specific error codes on failures + */ + +EXPORT_C TInt CLocationService :: TraceL( MLocationCallBack* aCallBackObj , + TInt aLocationInfoCategory, + TPositionFieldIdList aFiledList , + const TPositionUpdateOptions* aUpateOptions ) + { + + if(iRegTable[KARRAY_INDEX_TRACE]) //Return Error to user is the reg table slot is not free + { + if(iRegTable[KARRAY_INDEX_TRACE]->IsAdded()) + { + return KErrInUse ; + } + //Reuse the existing inactive object + delete iRegTable[KARRAY_INDEX_TRACE] ; //Activate this asynchronous job + iRegTable[KARRAY_INDEX_TRACE] = NULL ; + + } + + CGetLoc *activeTrace = CGetLoc :: NewL(iPosServer , + aFiledList , + KTraceRequest, + aLocationInfoCategory) ; + + TInt ret = activeTrace->GetLocationUpdates(aCallBackObj , aUpateOptions) ; + + if (ret == KErrNone) + { + iIndex = KARRAY_INDEX_TRACE; + iRegTable[KARRAY_INDEX_TRACE] = activeTrace ; + } + else + { //Cleanup the allocated object + delete activeTrace ; + } + + return ret; + } + +/** + * MathOparation to find distance and bearingto between two coordinates,and to move + * (Translate) + * one coordinate to another. + * Before decoding result of a particular requested service consumer code must check + * for the returned error code. Result field will be valid only when return code is + * KErrNone. + */ + +EXPORT_C TInt CLocationService :: MathOperation( inpparam& aInput ) + { + if ( aInput.servicechoice == EDistance ) //find distance between two location + { + //get the distance between two specified position + TInt error = aInput.source.Distance(aInput.destination , aInput.result); + return error; + + } + else if ( aInput.servicechoice == EBearingTo ) + { + //get the bearingTo between specified coordinates + TInt error = aInput.source.BearingTo(aInput.destination,aInput.result); + return error; + } + else if ( aInput.servicechoice == EMove ) + { + //Translate the source coordinate to the target coordinate by specified bearing and distance + TInt error = aInput.source.Move(aInput.bearing,aInput.distance); + return error; + } + //In case service asked is not supported + return KErrNotSupported; + } + + +/** + * Synchronous function which returns users last known position + */ + +TInt CLocationService :: GetLastKnownLoc( TPosition& aResultPos ) + { + TRequestStatus Status = KRequestPending ; + TPositionInfo posinfo ; + TPositionInfoBase *posinfoBase = &posinfo ; + + iPositioner.GetLastKnownPosition(*posinfoBase,Status); + User::WaitForRequest(Status); + posinfo.GetPosition(aResultPos) ; + + return Status.Int() ; + + } + +/** + * CancelOnGoingService : Cancells Requested asynchronous requests, + * Input : Type of request to be cancelled(Trace , Getlocation), + * Returns success(KErrNone) if service cancelled or else error if + * input parameter is invalid + */ +EXPORT_C TInt CLocationService::CancelOnGoingService( TInt aCancelparam ) + { + if ( (aCancelparam == ECancelGetLocation ) || (aCancelparam == ECancelTrace)) + { + CGetLoc* ptr = iRegTable[aCancelparam]; + if(iRegTable[aCancelparam]) + { + if(iRegTable[aCancelparam]->IsAdded()) + { + iRegTable[aCancelparam]->Deque() ; + } + if( ( aCancelparam == ECancelTrace ) ) + iRegTable[aCancelparam]->SetStatusComplete(); + delete iRegTable[aCancelparam] ; + iRegTable[aCancelparam] = NULL ; + return KErrNone; + } + return KErrNotFound ; + + } + + return KErrArgument; + + } +