sapi_location/locationservice/src/locationservice.cpp
changeset 0 14df0fbfcc4e
equal deleted inserted replaced
-1:000000000000 0:14df0fbfcc4e
       
     1 /*
       
     2 * Copyright (c) 2006-2007 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 the License "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:  Implements location SAPI core ;works as wrapper
       
    15 *   around core implementaion.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include "locationcoreimp.h"
       
    22 #include "locationservice.h"
       
    23 
       
    24 /**
       
    25  * Maximum number of active objects that can be created : at present only each corresponding
       
    26  * to location-asynch and trace
       
    27  */
       
    28 const TInt  KMAXAO = 2;
       
    29 
       
    30 
       
    31 
       
    32 
       
    33 /**
       
    34  * Default constructor
       
    35  */
       
    36  
       
    37  
       
    38 EXPORT_C CLocationService :: CLocationService()
       
    39     {
       
    40 	//No Implementation Required Here
       
    41     }
       
    42 
       
    43 
       
    44 /**
       
    45  * Destructor
       
    46  */
       
    47 
       
    48 EXPORT_C CLocationService :: ~CLocationService()
       
    49     {
       
    50     iPositioner.Close();	
       
    51     
       
    52     
       
    53     //Destroy all the contents of the registration table 
       
    54     for(TInt iter = 0 ; iter < iRegTable.Count() ; ++iter)
       
    55         {
       
    56             if(iRegTable[iter])
       
    57                 {
       
    58                 if(iRegTable[iter]->IsActive())
       
    59                     {
       
    60                     iRegTable[iter]->Deque() ;
       
    61                     }
       
    62                 delete iRegTable[iter];
       
    63                 iRegTable[iter] = NULL ;
       
    64 
       
    65                 }
       
    66         }
       
    67     iPosServer.Close();
       
    68     iRegTable.Close();
       
    69 
       
    70     }
       
    71  
       
    72 /**
       
    73  * CLocationService::NewL
       
    74  * Two-phased constructor.
       
    75  */
       
    76 
       
    77 
       
    78 EXPORT_C  CLocationService *CLocationService :: NewL()
       
    79     {
       
    80     CLocationService *self = new(ELeave)CLocationService() ;
       
    81     CleanupStack::PushL(self);
       
    82     self->ConstructL() ;
       
    83     CleanupStack::Pop(self) ;
       
    84     return self ;
       
    85 
       
    86     }
       
    87  
       
    88 /**
       
    89  * CLocationService::ConstructL
       
    90  * Symbian 2nd phase constructor can leave.
       
    91  */
       
    92 
       
    93 void CLocationService::ConstructL()
       
    94     {
       
    95 
       
    96     DoInitialiseL();
       
    97     }
       
    98 
       
    99 
       
   100 
       
   101 /**
       
   102  * CLocationService::DoInitialiseL
       
   103  * Initialises position server and positioner and
       
   104  * begins the position request sequence.
       
   105  */
       
   106 
       
   107 EXPORT_C void CLocationService :: DoInitialiseL()
       
   108     {
       
   109     TInt error = iPosServer.Connect( );
       
   110     // The connection failed
       
   111   
       
   112     User :: LeaveIfError(error) ;
       
   113     
       
   114     // Open subsession to the position server
       
   115     error = iPositioner.Open(iPosServer);
       
   116 
       
   117     // The opening of a subsession failed
       
   118     if ( KErrNone != error )
       
   119         {
       
   120         iPosServer.Close();
       
   121         User :: Leave( error );
       
   122         }
       
   123 
       
   124 
       
   125     //setting identity for this requestor
       
   126     User::LeaveIfError( iPositioner.SetRequestor( CRequestor::ERequestorService,
       
   127 												  CRequestor::EFormatApplication,
       
   128 												  KIdentity ) );
       
   129     
       
   130     //Initialise index which means there is no 
       
   131     //active object created yet
       
   132     iIndex = 0 ;
       
   133     //Initialising array pointer to NULL 
       
   134 
       
   135     for ( TInt count = 0;count < KMAXAO;count++)
       
   136         {
       
   137         iRegTable.Insert(NULL,count);
       
   138         }
       
   139     
       
   140        
       
   141      //Getthe module id used by location server for sapi location calls.
       
   142     error = iPosServer.GetDefaultModuleId(iModuleId);
       
   143 
       
   144     User :: LeaveIfError(error) ;
       
   145 
       
   146     }
       
   147 
       
   148 
       
   149 /**
       
   150  * CLocationService :: GetLocationL with update options, this function gets users current location
       
   151  * returns 0 on success and Symbian specific error codes on failure
       
   152  */
       
   153 
       
   154 EXPORT_C TInt  CLocationService :: GetLocationL( TPositionInfoBase* aInfoBase , const TPositionUpdateOptions* aUpdateOpts )
       
   155     {
       
   156 
       
   157     TRequestStatus status  ;
       
   158 
       
   159     if(aUpdateOpts)
       
   160         {
       
   161         TInt error;
       
   162         error = iPositioner.SetUpdateOptions(*aUpdateOpts);
       
   163         if( error)
       
   164 	    	{
       
   165             return error ;
       
   166             }
       
   167         
       
   168         }
       
   169     else
       
   170         {
       
   171         TPositionUpdateOptions updateopts ;
       
   172         
       
   173         // Set update interval to one second to receive one position data per second
       
   174 	    updateopts.SetUpdateInterval(TTimeIntervalMicroSeconds(KSUpdateInterval));
       
   175 
       
   176 	    // If position server could not get position
       
   177 	    // In two minutes it will terminate the position request
       
   178 	    updateopts.SetUpdateTimeOut(TTimeIntervalMicroSeconds(KSUpdateTimeOut));
       
   179 
       
   180 	    // Positions which have time stamp below KMaxAge can be reused
       
   181 	    updateopts.SetMaxUpdateAge(TTimeIntervalMicroSeconds(KSMaxAge));
       
   182 
       
   183 	    // Enables location framework to send partial position data
       
   184 	    updateopts.SetAcceptPartialUpdates(FALSE);
       
   185 
       
   186         
       
   187         iPositioner.SetUpdateOptions(updateopts) ;
       
   188         }
       
   189 
       
   190 
       
   191     iPositioner.NotifyPositionUpdate( *aInfoBase, status );
       
   192     User :: WaitForRequest(status) ;
       
   193 
       
   194     return status.Int() ;
       
   195     }
       
   196 
       
   197 /**
       
   198  * CLocationService::ModuleInfo, gets information about the location moudleid of currently used
       
   199  * positioning moulde, currently this methods only supports info of default module indentifier
       
   200  */
       
   201 
       
   202  EXPORT_C TInt CLocationService :: GetModuleInfo( TPositionModuleInfoBase& aModuleInfo )   const
       
   203     {
       
   204     return  iPosServer.GetModuleInfoById(iModuleId , aModuleInfo) ;
       
   205 
       
   206     }
       
   207 
       
   208 
       
   209 
       
   210 /**
       
   211  * Function Name : GetLocation Asynchronous
       
   212  * This function gets users current location
       
   213  * returns status of job submitted 
       
   214  */
       
   215 EXPORT_C TInt CLocationService :: GetLocationL( MLocationCallBack* aCallBackObj ,
       
   216 													TInt aLocationInfoCategory, 
       
   217 													TPositionFieldIdList aFieldList ,
       
   218 													const TPositionUpdateOptions* aUpateOptions
       
   219 													 )
       
   220     {
       
   221 
       
   222     if(iRegTable[KARRAY_INDEX_GETLOCATION])
       
   223         {
       
   224         if(iRegTable[KARRAY_INDEX_GETLOCATION]->IsActive())
       
   225             {
       
   226             return KErrInUse ;                //Return Error is Already registred 
       
   227             }
       
   228 
       
   229         delete iRegTable[KARRAY_INDEX_GETLOCATION] ;
       
   230         iRegTable[KARRAY_INDEX_GETLOCATION] = NULL ;
       
   231 
       
   232         }
       
   233 
       
   234     CGetLoc *activeGetLoc = CGetLoc :: NewL(iPosServer ,
       
   235     									    aFieldList ,	
       
   236                                             KGetLocationRequest,
       
   237                                             aLocationInfoCategory ) ;
       
   238     	//after creation of each active object increment counter by 1
       
   239     
       
   240     TInt err = 	activeGetLoc->GetLocation(aCallBackObj , aUpateOptions) ;
       
   241     	
       
   242     if ( KErrNone == err  )
       
   243         {
       
   244 
       
   245         iIndex = KARRAY_INDEX_GETLOCATION;  //for getlocation we are storing the pointer in 0th slot
       
   246         iRegTable[KARRAY_INDEX_GETLOCATION] = activeGetLoc ;
       
   247         }
       
   248         
       
   249     else 
       
   250         {
       
   251         delete activeGetLoc ;	//Clean up
       
   252         }	
       
   253 
       
   254     return err;	
       
   255     }
       
   256 
       
   257 
       
   258 
       
   259 /**
       
   260  * CLocationService :: TraceL  Notifies user if any changes occurs to his  current position, 
       
   261  * types of updates required are specified as part of Updateoptions.
       
   262  * Returns 0 on success and symbian specific error codes on failures
       
   263  */
       
   264 
       
   265 EXPORT_C TInt CLocationService :: TraceL( MLocationCallBack* aCallBackObj ,
       
   266 												TInt aLocationInfoCategory, 
       
   267 												TPositionFieldIdList aFiledList ,
       
   268 												const TPositionUpdateOptions* aUpateOptions )
       
   269     {
       
   270 
       
   271     if(iRegTable[KARRAY_INDEX_TRACE]) //Return Error to user is the reg table slot is not free
       
   272         {
       
   273         if(iRegTable[KARRAY_INDEX_TRACE]->IsAdded())  
       
   274             {
       
   275             return KErrInUse ;            
       
   276             }
       
   277         //Reuse the existing inactive object
       
   278         delete iRegTable[KARRAY_INDEX_TRACE]  ; //Activate this asynchronous job
       
   279         iRegTable[KARRAY_INDEX_TRACE] = NULL ;
       
   280 
       
   281         }
       
   282 
       
   283     CGetLoc *activeTrace = CGetLoc :: NewL(iPosServer ,
       
   284                                            aFiledList , 
       
   285                                            KTraceRequest,
       
   286                                            aLocationInfoCategory) ;
       
   287 
       
   288     TInt ret  = activeTrace->GetLocationUpdates(aCallBackObj , aUpateOptions) ;
       
   289 
       
   290     if (ret == KErrNone)  
       
   291         {
       
   292         iIndex = KARRAY_INDEX_TRACE;	
       
   293         iRegTable[KARRAY_INDEX_TRACE] = activeTrace ;
       
   294         }
       
   295     else
       
   296         {         //Cleanup the allocated object
       
   297         delete activeTrace ;
       
   298         }	
       
   299        
       
   300     return ret;
       
   301     }
       
   302 
       
   303 /**
       
   304  * MathOparation to find distance and bearingto  between two coordinates,and to move
       
   305  * (Translate)
       
   306  * one coordinate to another.
       
   307  * Before decoding result of a particular requested service consumer code must check
       
   308  * for the returned error code. Result field will be valid only when return code is
       
   309  * KErrNone.
       
   310  */
       
   311 
       
   312 EXPORT_C TInt CLocationService :: MathOperation( inpparam& aInput )
       
   313 	{
       
   314 	if ( aInput.servicechoice == EDistance )  //find distance between two location
       
   315 		{
       
   316 		//get the distance between two specified position
       
   317 		TInt error = aInput.source.Distance(aInput.destination , aInput.result);
       
   318 		return error;
       
   319 
       
   320 		}
       
   321 	else if ( aInput.servicechoice == EBearingTo )
       
   322 		{
       
   323 		//get the bearingTo	between specified coordinates
       
   324 		TInt error = aInput.source.BearingTo(aInput.destination,aInput.result);
       
   325 		return error;
       
   326 		}
       
   327 	else if ( aInput.servicechoice == EMove )	
       
   328 		{
       
   329 		//Translate the source coordinate to the target coordinate by specified bearing and distance
       
   330 		TInt error = aInput.source.Move(aInput.bearing,aInput.distance);
       
   331 		return error;			
       
   332 		}
       
   333 	//In case service asked is not supported 
       
   334 	return KErrNotSupported;	
       
   335 	}
       
   336 
       
   337 
       
   338 /**
       
   339  * Synchronous function which returns users last known position
       
   340  */
       
   341 
       
   342 TInt CLocationService :: GetLastKnownLoc( TPosition& aResultPos )
       
   343     {
       
   344     TRequestStatus Status  = KRequestPending ;
       
   345     TPositionInfo  posinfo  ;
       
   346     TPositionInfoBase *posinfoBase =  &posinfo ;	
       
   347 
       
   348     iPositioner.GetLastKnownPosition(*posinfoBase,Status);
       
   349     User::WaitForRequest(Status);
       
   350     posinfo.GetPosition(aResultPos) ;
       
   351 
       
   352     return Status.Int() ;
       
   353 
       
   354     }
       
   355 
       
   356 /**
       
   357  * CancelOnGoingService : Cancells Requested asynchronous requests,
       
   358  * Input : Type of request to be cancelled(Trace , Getlocation),
       
   359  * Returns success(KErrNone) if service cancelled or else error if 
       
   360  * input parameter is invalid
       
   361  */
       
   362 EXPORT_C TInt CLocationService::CancelOnGoingService( TInt aCancelparam )
       
   363     {
       
   364     if ( (aCancelparam == ECancelGetLocation ) || (aCancelparam == ECancelTrace))
       
   365         {
       
   366         CGetLoc* ptr = iRegTable[aCancelparam];
       
   367         if(iRegTable[aCancelparam])
       
   368             {
       
   369             if(iRegTable[aCancelparam]->IsAdded())
       
   370                 {
       
   371                 iRegTable[aCancelparam]->Deque() ;
       
   372                 }
       
   373             if( ( aCancelparam == ECancelTrace ) )
       
   374             	iRegTable[aCancelparam]->SetStatusComplete();
       
   375             	delete iRegTable[aCancelparam] ;
       
   376             iRegTable[aCancelparam] = NULL ;
       
   377             return KErrNone;
       
   378             }
       
   379         return KErrNotFound ;
       
   380 
       
   381         }
       
   382 
       
   383     return KErrArgument;
       
   384 
       
   385     }
       
   386