serviceproviders/sapi_location/locationservice/src/locationservice.cpp
changeset 22 fc9cf246af83
parent 19 989d2f495d90
child 32 8d692d9f828f
equal deleted inserted replaced
19:989d2f495d90 22:fc9cf246af83
    19 
    19 
    20 
    20 
    21 #include "locationcoreimp.h"
    21 #include "locationcoreimp.h"
    22 #include "locationservice.h"
    22 #include "locationservice.h"
    23 
    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 
    24 
    30 
    25 
    31 
    26 
    32 
    27 
    33 /**
    28 /**
    58                 if(iRegTable[iter]->IsActive())
    53                 if(iRegTable[iter]->IsActive())
    59                     {
    54                     {
    60                     iRegTable[iter]->Deque() ;
    55                     iRegTable[iter]->Deque() ;
    61                     }
    56                     }
    62                 delete iRegTable[iter];
    57                 delete iRegTable[iter];
    63                 iRegTable[iter] = NULL ;
       
    64 
    58 
    65                 }
    59                 }
    66         }
    60         }
    67     iPosServer.Close();
    61     iPosServer.Close();
    68     iRegTable.Close();
    62     iRegTable.Close();
    86     }
    80     }
    87  
    81  
    88 /**
    82 /**
    89  * CLocationService::ConstructL
    83  * CLocationService::ConstructL
    90  * Symbian 2nd phase constructor can leave.
    84  * 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
    85  * Initialises position server and positioner and
   104  * begins the position request sequence.
    86  * begins the position request sequence.
   105  */
    87  */
   106 
    88 
   107 EXPORT_C void CLocationService :: DoInitialiseL()
    89 void CLocationService::ConstructL()
   108     {
    90     {
   109     TInt error = iPosServer.Connect( );
    91     User :: LeaveIfError(iPosServer.Connect());
   110     // The connection failed
    92     CleanupClosePushL(iPosServer);
   111   
    93     
   112     User :: LeaveIfError(error) ;
    94     //Get the module id of the default module available
   113     
    95     User :: LeaveIfError(iPosServer.GetDefaultModuleId(iModuleId));
       
    96 
       
    97     CleanupStack::Pop(&iPosServer);
       
    98     }
       
    99 
       
   100 /**
       
   101  * CLocationService::GetHighAccuracyModule
       
   102  * This function returns the module id of highest accuracy 
       
   103  * module that is available on the phone currently.
       
   104  */
       
   105 void CLocationService::GetHighAccuracyModuleL(TPositionModuleId* aModId)
       
   106     {
       
   107     TPositionModuleId moduleId;
       
   108     TPositionModuleInfo modInfo;
       
   109     TUint numOfModules = 0;
       
   110 
       
   111     //Flags used for indicating if a particular module is found
       
   112     TInt termInternalFlag = 0;   
       
   113     TInt termFlag = 0 ,assisFlag = 0 ,networkFlag = 0,unknownFlag = 0;
       
   114     TInt err;
       
   115     
       
   116     User::LeaveIfError(iPosServer.GetNumModules(numOfModules));
       
   117         
       
   118 
       
   119     for( TInt i=0;i< numOfModules;i++ )
       
   120         {
       
   121         iPosServer.GetModuleInfoByIndex(i,modInfo);
       
   122 
       
   123 				if( modInfo.TechnologyType() == modInfo.ETechnologyAssisted  && 
       
   124                  modInfo.IsAvailable())
       
   125             {
       
   126 
       
   127             assisFlag = 1;
       
   128             moduleId = modInfo.ModuleId();
       
   129 						break;
       
   130             }
       
   131             
       
   132         if( modInfo.TechnologyType() == modInfo.ETechnologyTerminal  && 
       
   133                 !assisFlag && !termInternalFlag && modInfo.IsAvailable() )
       
   134             {
       
   135 
       
   136             termFlag = 1;
       
   137             moduleId = modInfo.ModuleId();
       
   138 
       
   139             //Internal Module takes higher priority than External module 
       
   140             if(modInfo.DeviceLocation() == modInfo.EDeviceInternal)
       
   141                 {
       
   142                 termInternalFlag = 1;                
       
   143                 }
       
   144 
       
   145             }
       
   146 
       
   147         if(modInfo.TechnologyType() == modInfo.ETechnologyNetwork && 
       
   148                 !assisFlag  && !termFlag && modInfo.IsAvailable())
       
   149             {
       
   150 
       
   151             networkFlag = 1;
       
   152             moduleId = modInfo.ModuleId();
       
   153 
       
   154             }
       
   155 
       
   156         if( modInfo.TechnologyType() == modInfo.ETechnologyUnknown && 
       
   157                 !assisFlag  && !termFlag && 
       
   158                 !networkFlag && modInfo.IsAvailable() )
       
   159             {
       
   160 
       
   161             unknownFlag = 1;
       
   162             moduleId = modInfo.ModuleId();                            
       
   163             }
       
   164         }
       
   165     *aModId =  moduleId;
       
   166     }
       
   167 
       
   168 /**
       
   169  * CLocationService :: GetLocationL with update options, this function gets users current location
       
   170  * returns 0 on success and Symbian specific error codes on failure
       
   171  */
       
   172 
       
   173 EXPORT_C void  CLocationService :: GetLocationL( TPositionInfoBase* aInfoBase ,
       
   174         const TPositionUpdateOptions* aUpdateOpts,TBool aEnableHighAcc )
       
   175     {
   114     // Open subsession to the position server
   176     // Open subsession to the position server
   115     error = iPositioner.Open(iPosServer);
   177     TPositionModuleId ModuleId;
   116 
   178     TInt error;
   117     // The opening of a subsession failed
   179     if(aEnableHighAcc)
   118     if ( KErrNone != error )
   180         {
   119         {
   181         GetHighAccuracyModuleL(&ModuleId);
   120         iPosServer.Close();
   182        
   121         User :: Leave( error );
   183         User::LeaveIfError(iPositioner.Open(iPosServer,ModuleId));
   122         }
   184         
   123 
   185         }
       
   186     else
       
   187         {
       
   188         User::LeaveIfError(iPositioner.Open(iPosServer));
       
   189         }
       
   190 
       
   191     
       
   192     CleanupClosePushL(iPositioner);
   124 
   193 
   125     //setting identity for this requestor
   194     //setting identity for this requestor
   126     User::LeaveIfError( iPositioner.SetRequestor( CRequestor::ERequestorService,
   195     User::LeaveIfError( iPositioner.SetRequestor( CRequestor::ERequestorService,
   127 												  CRequestor::EFormatApplication,
   196             CRequestor::EFormatApplication,
   128 												  KIdentity ) );
   197             KIdentity ) );
   129     
   198 
   130     //Initialise index which means there is no 
   199     TRequestStatus status;
   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 
   200 
   159     if(aUpdateOpts)
   201     if(aUpdateOpts)
   160         {
   202         {
   161         TInt error;
   203         User::LeaveIfError(iPositioner.SetUpdateOptions(*aUpdateOpts));
   162         error = iPositioner.SetUpdateOptions(*aUpdateOpts);
   204         }
   163         if( error)
   205 
   164 	    	{
       
   165             return error ;
       
   166             }
       
   167         
       
   168         }
       
   169     else
   206     else
   170         {
   207         {
   171         TPositionUpdateOptions updateopts ;
   208         TPositionUpdateOptions updateopts ;
   172         
   209 
   173         // Set update interval to one second to receive one position data per second
   210         // Set update interval to one second to receive one position data per second
   174 	    updateopts.SetUpdateInterval(TTimeIntervalMicroSeconds(KSUpdateInterval));
   211         updateopts.SetUpdateInterval(TTimeIntervalMicroSeconds(KSUpdateInterval));
   175 
   212 
   176 	    // If position server could not get position
   213         // If position server could not get position
   177 	    // In two minutes it will terminate the position request
   214         // In two minutes it will terminate the position request
   178 	    updateopts.SetUpdateTimeOut(TTimeIntervalMicroSeconds(KSUpdateTimeOut));
   215         updateopts.SetUpdateTimeOut(TTimeIntervalMicroSeconds(KSUpdateTimeOut));
   179 
   216 
   180 	    // Positions which have time stamp below KMaxAge can be reused
   217         // Positions which have time stamp below KMaxAge can be reused
   181 	    updateopts.SetMaxUpdateAge(TTimeIntervalMicroSeconds(KSMaxAge));
   218         updateopts.SetMaxUpdateAge(TTimeIntervalMicroSeconds(KSMaxAge));
   182 
   219 
   183 	    // Enables location framework to send partial position data
   220         // Enables location framework to send partial position data
   184 	    updateopts.SetAcceptPartialUpdates(FALSE);
   221         updateopts.SetAcceptPartialUpdates(FALSE);
   185 
   222 
   186         
   223 
   187         iPositioner.SetUpdateOptions(updateopts) ;
   224         iPositioner.SetUpdateOptions(updateopts) ;
   188         }
   225         }
   189 
   226 
   190 
   227 
   191     iPositioner.NotifyPositionUpdate( *aInfoBase, status );
   228     iPositioner.NotifyPositionUpdate( *aInfoBase, status );
   192     User :: WaitForRequest(status) ;
   229     User :: WaitForRequest(status) ;
   193 
   230     CleanupStack::PopAndDestroy(&iPositioner);
   194     return status.Int() ;
   231     
       
   232     User::LeaveIfError(status.Int());
   195     }
   233     }
   196 
   234 
   197 /**
   235 /**
   198  * CLocationService::ModuleInfo, gets information about the location moudleid of currently used
   236  * CLocationService::ModuleInfo, gets information about the location moudleid of currently used
   199  * positioning moulde, currently this methods only supports info of default module indentifier
   237  * positioning moulde, currently this methods only supports info of default module indentifier
   210 /**
   248 /**
   211  * Function Name : GetLocation Asynchronous
   249  * Function Name : GetLocation Asynchronous
   212  * This function gets users current location
   250  * This function gets users current location
   213  * returns status of job submitted 
   251  * returns status of job submitted 
   214  */
   252  */
   215 EXPORT_C TInt CLocationService :: GetLocationL( MLocationCallBack* aCallBackObj ,
   253 EXPORT_C void CLocationService :: GetLocationL( MLocationCallBack* aCallBackObj ,
   216 													TInt aLocationInfoCategory, 
   254         TInt aLocationInfoCategory,
   217 													TPositionFieldIdList aFieldList ,
   255         TPositionFieldIdList aFieldList ,
   218 													const TPositionUpdateOptions* aUpateOptions
   256         const TPositionUpdateOptions* aUpateOptions,
   219 													 )
   257         TBool aEnableHighAcc 
   220     {
   258 )
   221 
   259     {  
   222     if(iRegTable[KARRAY_INDEX_GETLOCATION])
   260     TPositionModuleId ModuleId;
   223         {
   261     if(aEnableHighAcc)
   224         if(iRegTable[KARRAY_INDEX_GETLOCATION]->IsActive())
   262         {
   225             {
   263         GetHighAccuracyModuleL(&ModuleId);
   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         
   264         
   249     else 
   265         }
   250         {
   266     else
   251         delete activeGetLoc ;	//Clean up
   267         {
   252         }	
   268         //Indicates that when opening the subsession ,moudleId need not be specified
   253 
   269         ModuleId.iUid = 0;       
   254     return err;	
   270         }
       
   271 
       
   272     TInt err = KErrGeneral;
       
   273 
       
   274     CGetLoc* activeGetLoc = CGetLoc :: NewL(iPosServer ,
       
   275             aFieldList ,
       
   276             KGetLocationRequest,
       
   277             aLocationInfoCategory,
       
   278             ModuleId) ;
       
   279 
       
   280     err = activeGetLoc->GetLocationUpdates(this,aCallBackObj,aUpateOptions);
       
   281 
       
   282     if ( KErrNone == err )
       
   283         {
       
   284         iRegTable.Append(activeGetLoc);
       
   285         }
       
   286     else
       
   287         {
       
   288         delete activeGetLoc; //Clean up
       
   289         User::Leave(err);
       
   290         }
   255     }
   291     }
   256 
   292 
   257 
   293 
   258 
   294 
   259 /**
   295 /**
   260  * CLocationService :: TraceL  Notifies user if any changes occurs to his  current position, 
   296  * CLocationService :: TraceL  Notifies user if any changes occurs to his  current position, 
   261  * types of updates required are specified as part of Updateoptions.
   297  * types of updates required are specified as part of Updateoptions.
   262  * Returns 0 on success and symbian specific error codes on failures
   298  * Returns 0 on success and symbian specific error codes on failures
   263  */
   299  */
   264 
   300 
   265 EXPORT_C TInt CLocationService :: TraceL( MLocationCallBack* aCallBackObj ,
   301 EXPORT_C void CLocationService :: TraceL( MLocationCallBack* aCallBackObj ,
   266 												TInt aLocationInfoCategory, 
   302         TInt aLocationInfoCategory,
   267 												TPositionFieldIdList aFiledList ,
   303         TPositionFieldIdList aFiledList ,
   268 												const TPositionUpdateOptions* aUpateOptions )
   304         const TPositionUpdateOptions* aUpateOptions,
   269     {
   305         TBool aEnableHighAcc )
   270 
   306     {
   271     if(iRegTable[KARRAY_INDEX_TRACE]) //Return Error to user is the reg table slot is not free
   307     TPositionModuleId ModuleId;
   272         {
   308     if(aEnableHighAcc)
   273         if(iRegTable[KARRAY_INDEX_TRACE]->IsAdded())  
   309         {
   274             {
   310         GetHighAccuracyModuleL(&ModuleId);
   275             return KErrInUse ;            
   311         if(ModuleId.iUid == NULL)
       
   312             {
       
   313             User::Leave(KErrGeneral);
   276             }
   314             }
   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         }
   315         }
   295     else
   316     else
   296         {         //Cleanup the allocated object
   317         {
   297         delete activeTrace ;
   318         //Indicates that when opening the subsession ,moudleId need not be specified
   298         }	
   319         ModuleId.iUid = 0;          
   299        
   320         }
   300     return ret;
   321     
       
   322     CGetLoc* activeTrace = CGetLoc :: NewL(iPosServer ,
       
   323             aFiledList ,
       
   324             KTraceRequest,
       
   325             aLocationInfoCategory,
       
   326             ModuleId) ;
       
   327 
       
   328     TInt ret = activeTrace->GetLocationUpdates(this,aCallBackObj , aUpateOptions);
       
   329 
       
   330     if (ret == KErrNone)
       
   331         {        
       
   332         iRegTable.Append(activeTrace);
       
   333         }
       
   334     else
       
   335         { 
       
   336         //Cleanup the allocated object
       
   337         delete activeTrace;
       
   338         User::Leave(ret);
       
   339         }
       
   340 
   301     }
   341     }
   302 
   342 
   303 /**
   343 /**
   304  * MathOparation to find distance and bearingto  between two coordinates,and to move
   344  * MathOparation to find distance and bearingto  between two coordinates,and to move
   305  * (Translate)
   345  * (Translate)
   337 
   377 
   338 /**
   378 /**
   339  * Synchronous function which returns users last known position
   379  * Synchronous function which returns users last known position
   340  */
   380  */
   341 
   381 
   342 TInt CLocationService :: GetLastKnownLoc( TPosition& aResultPos )
   382 EXPORT_C TInt CLocationService :: GetLastKnownLoc( TPosition& aResultPos )
   343     {
   383     {
       
   384     TInt error = iPositioner.Open(iPosServer);
       
   385 
       
   386 
       
   387     // The opening of a subsession failed
       
   388     if ( KErrNone != error )
       
   389         {
       
   390         iPosServer.Close();
       
   391         return error ;
       
   392         }
       
   393 		
       
   394     //setting identity for this requestor
       
   395     error = iPositioner.SetRequestor( CRequestor::ERequestorService,
       
   396             CRequestor::EFormatApplication,
       
   397             KIdentity ) ;
       
   398 
       
   399 	  if ( KErrNone != error )
       
   400         {
       
   401         iPositioner.Close();
       
   402         return error ;
       
   403         }
       
   404 	
   344     TRequestStatus Status  = KRequestPending ;
   405     TRequestStatus Status  = KRequestPending ;
   345     TPositionInfo  posinfo  ;
   406     TPositionInfo  posinfo  ;
   346     TPositionInfoBase *posinfoBase =  &posinfo ;	
   407     TPositionInfoBase *posinfoBase =  &posinfo ;	
   347 
   408 
   348     iPositioner.GetLastKnownPosition(*posinfoBase,Status);
   409     iPositioner.GetLastKnownPosition(*posinfoBase,Status);
   349     User::WaitForRequest(Status);
   410     User::WaitForRequest(Status);
   350     posinfo.GetPosition(aResultPos) ;
   411     posinfo.GetPosition(aResultPos) ;
   351 
   412     
       
   413     iPositioner.Close();
   352     return Status.Int() ;
   414     return Status.Int() ;
   353 
   415 
   354     }
   416     }
   355 
   417 
   356 /**
   418 /**
   361  */
   423  */
   362 EXPORT_C TInt CLocationService::CancelOnGoingService( TInt aCancelparam )
   424 EXPORT_C TInt CLocationService::CancelOnGoingService( TInt aCancelparam )
   363     {
   425     {
   364     if ( (aCancelparam == ECancelGetLocation ) || (aCancelparam == ECancelTrace))
   426     if ( (aCancelparam == ECancelGetLocation ) || (aCancelparam == ECancelTrace))
   365         {
   427         {
   366         CGetLoc* ptr = iRegTable[aCancelparam];
   428         TInt i;
   367         if(iRegTable[aCancelparam])
   429         for( i = 0; i< iRegTable.Count(); i++)
   368             {
   430             {
   369             if(iRegTable[aCancelparam]->IsAdded())
   431             if(iRegTable[i] )
   370                 {
   432                 {
   371                 iRegTable[aCancelparam]->Deque() ;
   433 
       
   434                 if((((iRegTable[i]->GetCallBackobj())->GetRequestType()) == 
       
   435                 KGetLocationReq) && (aCancelparam == ECancelGetLocation ))              
       
   436                     {                  
       
   437                     if(iRegTable[i]->IsAdded())
       
   438                         {         
       
   439                         iRegTable[i]->Deque();
       
   440                         }
       
   441 
       
   442 
       
   443                     delete iRegTable[i];
       
   444                     iRegTable[i] = NULL;
       
   445                     return KErrNone;
       
   446                     }
       
   447 
       
   448                 else if ((((iRegTable[i]->GetCallBackobj())->GetRequestType()) == 
       
   449                 KTraceReq) &&  (aCancelparam == ECancelTrace ))
       
   450                     {
       
   451                     if(iRegTable[i]->IsAdded())
       
   452                         {
       
   453                         iRegTable[i]->Deque();
       
   454                         }
       
   455 
       
   456                     iRegTable[i]->SetStatusComplete();
       
   457 
       
   458                     delete iRegTable[i];
       
   459                     iRegTable[i] = NULL;
       
   460                     return KErrNone;
       
   461                     }
       
   462                 }  
       
   463             }    
       
   464         return KErrNotFound;
       
   465         }
       
   466 
       
   467     return KErrArgument;
       
   468     }
       
   469 
       
   470 /**
       
   471  * CancelService : Cancels Requested asynchronous requests,
       
   472  * Input : TransactionId returned by the Async request,
       
   473  * Returns success(KErrNone) if service canceled or else error if 
       
   474  * input parameter is invalid
       
   475  */
       
   476 EXPORT_C TInt CLocationService::CancelService( TInt aTransId)
       
   477     {
       
   478     TInt i;
       
   479     for( i = 0; i< iRegTable.Count(); i++)
       
   480         {
       
   481         if(iRegTable[i])
       
   482             {
       
   483             if(aTransId == 
       
   484             (iRegTable[i]->GetCallBackobj())->GetTransactionId())
       
   485                 {
       
   486                 if(iRegTable[i]->IsAdded())
       
   487                     {
       
   488                     iRegTable[i]->Deque();
       
   489                     }
       
   490                 if(((iRegTable[i]->GetCallBackobj())->GetRequestType()) == 
       
   491                 KTraceReq)
       
   492                     {
       
   493                     iRegTable[i]->SetStatusComplete();
       
   494                     }
       
   495                 delete iRegTable[i];
       
   496                 iRegTable[i] = NULL;
       
   497                 return KErrNone;
   372                 }
   498                 }
   373             if( ( aCancelparam == ECancelTrace ) )
       
   374             	iRegTable[aCancelparam]->SetStatusComplete();
       
   375             	delete iRegTable[aCancelparam] ;
       
   376             iRegTable[aCancelparam] = NULL ;
       
   377             return KErrNone;
       
   378             }
   499             }
   379         return KErrNotFound ;
   500         }
   380 
   501 
   381         }
   502     return KErrNotFound;
   382 
   503     }
   383     return KErrArgument;
       
   384 
       
   385     }
       
   386