|
S60 3rd Edition SDK for Symbian OS Example Applications Guide |
00001 /* 00002 * ============================================================================== 00003 * Name : LbsPositionRequestor.cpp 00004 * Part of : LBSReference example application 00005 * Interface : 00006 * Description : Position requestor handles the position requesting process 00007 * Version : 1.0 00008 * 00009 * Copyright (c) 2005-2006 Nokia Corporation. 00010 * This material, including documentation and any related 00011 * computer programs, is protected by copyright controlled by 00012 * Nokia Corporation. 00013 * ============================================================================== 00014 */ 00015 00016 // INCLUDE FILES 00017 #include <Lbs.h> 00018 #include "LBSPositionRequestor.h" 00019 #include "LBSPositionlistener.h" 00020 00021 // CONSTANTS 00022 00023 //Second 00024 const TInt KSecond = 1000000; 00025 00026 //Update interval 00027 const TInt KUpdateInterval = KSecond; 00028 00029 //Update time out 00030 const TInt KUpdateTimeOut = 15*KSecond; 00031 00032 //MaxAge 00033 const TInt KMaxAge = 500000; 00034 00035 // Unknown string used when module name is not known 00036 _LIT(KUnknown,"Unknown"); 00037 00038 //The name of the requestor 00039 _LIT(KRequestor,"Location Reference Application"); 00040 00041 // Event messages 00042 _LIT(KLastPosUnknown,"Last known position unknown."); 00043 00044 //Error messages 00045 _LIT(KLbsErrLocRequest, "Request error: %d."); 00046 _LIT(KLbsErrAccess, "Access denied: %d."); 00047 _LIT(KLbsErrPosServConn, "Connecting to server: %d."); 00048 _LIT(KLbsErrOpenPos, "Opening a positioner: %d."); 00049 _LIT(KLbsErrSetRequestor, "Setting requestor: %d."); 00050 _LIT(KLbsErrSetUpOpt, "Setting update options: %d."); 00051 _LIT(KLbsErrCanceled, "Location request canceled."); 00052 _LIT(KLbsErrQualityLoss, "KPositionQualityLoss."); 00053 _LIT(KLbsErrTimedout, "Timed out."); 00054 00055 // ============================ MEMBER FUNCTIONS =============================== 00056 00057 // ----------------------------------------------------------------------------- 00058 // CLbsPositionRequestor::CLbsPositionRequestor 00059 // C++ default constructor can NOT contain any code, that 00060 // might leave. 00061 // ----------------------------------------------------------------------------- 00062 // 00063 CLbsPositionRequestor::CLbsPositionRequestor( MLbsPositionListener& aPositionListener ) 00064 : CActive(CActive::EPriorityStandard), 00065 iPositionListener( aPositionListener ), 00066 iPosInfoBase( &iPositionInfo ), 00067 iGettingLastknownPosition( ETrue ) 00068 { 00069 // Set update interval to one second to receive one position data per second 00070 iUpdateops.SetUpdateInterval(TTimeIntervalMicroSeconds(KUpdateInterval)); 00071 00072 // If position server could not get position 00073 // In two minutes it will terminate the position request 00074 iUpdateops.SetUpdateTimeOut(TTimeIntervalMicroSeconds(KUpdateTimeOut)); 00075 00076 // Positions which have time stamp below KMaxAge can be reused 00077 iUpdateops.SetMaxUpdateAge(TTimeIntervalMicroSeconds(KMaxAge)); 00078 00079 // Enables location framework to send partial position data 00080 iUpdateops.SetAcceptPartialUpdates(ETrue); 00081 00082 // Add this position requestor to the active scheduler 00083 CActiveScheduler::Add( this ); 00084 } 00085 00086 // ----------------------------------------------------------------------------- 00087 // CLbsPositionRequestor::ConstructL 00088 // Symbian 2nd phase constructor can leave. 00089 // ----------------------------------------------------------------------------- 00090 // 00091 void CLbsPositionRequestor::ConstructL() 00092 { 00093 // Initialise the position request sequence 00094 DoInitialiseL(); 00095 } 00096 00097 // ----------------------------------------------------------------------------- 00098 // CLbsPositionRequestor::NewL 00099 // Two-phased constructor. 00100 // ----------------------------------------------------------------------------- 00101 // 00102 CLbsPositionRequestor* CLbsPositionRequestor::NewL( 00103 MLbsPositionListener& aPositionListener ) 00104 { 00105 //Create the object 00106 CLbsPositionRequestor* self = new( ELeave ) CLbsPositionRequestor( 00107 aPositionListener); 00108 00109 //Push to the cleanup stack 00110 CleanupStack::PushL( self ); 00111 00112 //Construct the object 00113 self->ConstructL(); 00114 00115 //Remove from cleanup stack 00116 CleanupStack::Pop( self ); 00117 00118 //Return pointer to the created object 00119 return self; 00120 } 00121 00122 // ----------------------------------------------------------------------------- 00123 // CLbsPositionRequestor::~CLbsPositionRequestor 00124 // Destructor 00125 // ----------------------------------------------------------------------------- 00126 // 00127 CLbsPositionRequestor::~CLbsPositionRequestor() 00128 { 00129 // Cancel active object 00130 Cancel(); 00131 00132 // Close the positioner 00133 iPositioner.Close(); 00134 00135 // Close the session to the position server 00136 iPosServer.Close(); 00137 } 00138 00139 // ----------------------------------------------------------------------------- 00140 // DoCancel() implements CActive DoCancel() 00141 // Implements the cancellation of an outstanding request. 00142 // ----------------------------------------------------------------------------- 00143 // 00144 void CLbsPositionRequestor::DoCancel() 00145 { 00146 // When a client application wishes to close one of its connections to Location 00147 // Server, there can be no outstanding requests on that particular connection 00148 // If a client application attempts to close a connection before outstanding 00149 // requests have been cancelled or completed, it is panicked 00150 00151 //If we are getting the last known position 00152 if ( iGettingLastknownPosition ) 00153 { 00154 //Cancel the last known position request 00155 iPositioner.CancelRequest(EPositionerGetLastKnownPosition); 00156 } 00157 else 00158 { 00159 iPositioner.CancelRequest(EPositionerNotifyPositionUpdate); 00160 } 00161 } 00162 00163 // ----------------------------------------------------------------------------- 00164 // RunL() implements CActive RunL() 00165 // Handles an active object’s request completion event. 00166 // ----------------------------------------------------------------------------- 00167 // 00168 void CLbsPositionRequestor::RunL() 00169 { 00170 TBuf<KPositionMaxModuleName> buffer; 00171 00172 switch ( iStatus.Int() ) 00173 { 00174 // The fix is valid 00175 case KErrNone: 00176 // The fix has only partially valid information. 00177 // It is guaranteed to only have a valid timestamp 00178 case KPositionPartialUpdate: 00179 { 00180 00181 // Pre process the position information 00182 PositionUpdatedL(); 00183 00184 break; 00185 } 00186 // The data class used was not supported 00187 case KErrArgument: 00188 { 00189 // Set info base to position info 00190 iPosInfoBase = &iPositionInfo; 00191 00192 // Request next position 00193 iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus ); 00194 00195 // Set this object active 00196 SetActive(); 00197 break; 00198 } 00199 // The position data could not be delivered 00200 case KPositionQualityLoss: 00201 { 00202 // Send event to position listener 00203 iPositionListener.ShowErrorL( KLbsErrQualityLoss ); 00204 00205 if ( iGettingLastknownPosition ) 00206 { 00207 //Change the data class type 00208 iPosInfoBase = &iSatelliteInfo; 00209 } 00210 00211 // Request position 00212 iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus ); 00213 00214 // Set this object active 00215 SetActive(); 00216 break; 00217 } 00218 // Access is denied 00219 case KErrAccessDenied: 00220 { 00221 // Send error to position listener 00222 buffer.Format(KLbsErrAccess, iStatus.Int()); 00223 iPositionListener.ShowErrorL(buffer); 00224 break; 00225 } 00226 // Request timed out 00227 case KErrTimedOut: 00228 { 00229 // Send error to position listener 00230 iPositionListener.ShowErrorL(KLbsErrTimedout); 00231 00232 if ( iGettingLastknownPosition ) 00233 { 00234 //Change the data class type 00235 iPosInfoBase = &iSatelliteInfo; 00236 } 00237 00238 // Request position 00239 iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus ); 00240 00241 // Set this object active 00242 SetActive(); 00243 break; 00244 } 00245 // The request was canceled 00246 case KErrCancel: 00247 { 00248 // Send error to position listener 00249 iPositionListener.ShowErrorL( KLbsErrCanceled ); 00250 break; 00251 } 00252 // There is no last known position 00253 case KErrUnknown: 00254 { 00255 // Send event to position listener 00256 iPositionListener.ShowMessageL(KLastPosUnknown); 00257 00258 if ( iGettingLastknownPosition ) 00259 { 00260 //Change the data class type 00261 iPosInfoBase = &iSatelliteInfo; 00262 00263 //Mark that we are not requesting NotifyPositionUpdate 00264 iGettingLastknownPosition = EFalse; 00265 } 00266 00267 // Request next position 00268 iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus ); 00269 00270 // Set this object active 00271 SetActive(); 00272 break; 00273 } 00274 // Unrecoverable errors. 00275 default: 00276 { 00277 // Send error to position listener 00278 buffer.Format(KLbsErrLocRequest, iStatus.Int()); 00279 iPositionListener.ShowErrorL( buffer ); 00280 break; 00281 } 00282 } 00283 00284 //We are not going to query the last known position anymore. 00285 if ( iGettingLastknownPosition ) 00286 { 00287 //Mark that we are not requesting NotifyPositionUpdate 00288 iGettingLastknownPosition = EFalse; 00289 } 00290 } 00291 00292 00293 // ----------------------------------------------------------------------------- 00294 // CLbsPositionRequestor::DoInitialiseL 00295 // Initialises position server and positioner and 00296 // begins the position request sequence. 00297 // ----------------------------------------------------------------------------- 00298 // 00299 void CLbsPositionRequestor::DoInitialiseL() 00300 { 00301 // Connect to the position server 00302 TInt error = iPosServer.Connect( ); 00303 TBuf<100> buffer; 00304 00305 // The connection failed 00306 if ( KErrNone != error ) 00307 { 00308 // Show error to the user and leave 00309 buffer.Format(KLbsErrPosServConn, error); 00310 iPositionListener.ShowErrorL( buffer ); 00311 return; 00312 } 00313 00314 // Open subsession to the position server 00315 error = iPositioner.Open(iPosServer); 00316 00317 // The opening of a subsession failed 00318 if ( KErrNone != error ) 00319 { 00320 // Show error to the user and leave 00321 buffer.Format(KLbsErrOpenPos, error); 00322 iPositionListener.ShowErrorL( buffer ); 00323 iPosServer.Close(); 00324 return; 00325 } 00326 00327 // Set position requestor 00328 error = iPositioner.SetRequestor( CRequestor::ERequestorService , 00329 CRequestor::EFormatApplication , KRequestor ); 00330 00331 // The requestor could not be set 00332 if ( KErrNone != error ) 00333 { 00334 // Show error to the user and leave 00335 00336 buffer.Format(KLbsErrSetRequestor, error); 00337 iPositionListener.ShowErrorL( buffer ); 00338 iPositioner.Close(); 00339 iPosServer.Close(); 00340 return; 00341 } 00342 00343 // Set update options 00344 error = iPositioner.SetUpdateOptions( iUpdateops ); 00345 00346 // The options could not be updated 00347 if ( KErrNone != error ) 00348 { 00349 // Show error to the user and leave 00350 buffer.Format(KLbsErrSetUpOpt, error); 00351 iPositionListener.ShowErrorL( buffer ); 00352 iPositioner.Close(); 00353 iPosServer.Close(); 00354 return; 00355 } 00356 00357 // Get last known position. The processing of the result 00358 // is done in RunL method 00359 iPositioner.GetLastKnownPosition(*iPosInfoBase,iStatus); 00360 00361 // Set this active object active 00362 SetActive(); 00363 } 00364 00365 // ----------------------------------------------------------------------------- 00366 // CLbsPositionRequestor::GetModuleName 00367 // Gets the name of the positioning module by id. 00368 // ----------------------------------------------------------------------------- 00369 // 00370 void CLbsPositionRequestor::GetModuleName(const TPositionModuleId& aModuleId) 00371 { 00372 // Module information of the position module 00373 TPositionModuleInfo modInfo; 00374 00375 // Get module info by module id 00376 TInt error = iPosServer.GetModuleInfoById( *&aModuleId, modInfo ); 00377 00378 // If error occured 00379 if ( KErrNone != error ) 00380 { 00381 // Set the name of the module to 'Unknown' 00382 iModuleName = KUnknown; 00383 } 00384 else 00385 { 00386 // Get the name of the position module 00387 modInfo.GetModuleName(iModuleName); 00388 } 00389 } 00390 00391 00392 // ----------------------------------------------------------------------------- 00393 // CLbsPositionRequestor::PositionUpdatedL 00394 // Pre process the position information 00395 // ----------------------------------------------------------------------------- 00396 // 00397 void CLbsPositionRequestor::PositionUpdatedL() 00398 { 00399 //If we are getting the last known position 00400 if ( iGettingLastknownPosition ) 00401 { 00402 // Set the module name to 'Unknown' because last 00403 // known position has no module name 00404 iModuleName = KUnknown; 00405 00406 // Send position information to registered listener 00407 iPositionListener.PositionInfoUpdatedL(*iPosInfoBase,iModuleName); 00408 00409 //Change the data class type 00410 iPosInfoBase = &iSatelliteInfo; 00411 00412 // Request next position 00413 iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus ); 00414 00415 // Set this object active 00416 SetActive(); 00417 } 00418 else 00419 { 00420 // Check if the id of the used PSY is 0 00421 if ( 0 == iUsedPsy.iUid) 00422 { 00423 // Set the id of the currently used PSY 00424 iUsedPsy = iPosInfoBase->ModuleId(); 00425 } 00426 // Check if the position module has changed 00427 else if ( iPosInfoBase->ModuleId() != iUsedPsy ) 00428 { 00429 // Set the id of the currently used PSY 00430 iUsedPsy = iPosInfoBase->ModuleId(); 00431 00432 //Position module info of new module 00433 TPositionModuleInfo moduleInfo; 00434 00435 // Get module info 00436 iPosServer.GetModuleInfoById(iUsedPsy,moduleInfo); 00437 00438 // Get classes supported 00439 TInt32 moduleInfoFamily = moduleInfo.ClassesSupported(EPositionInfoFamily); 00440 00441 iPosInfoBase = &iSatelliteInfo; 00442 00443 // Check if the new module supports 00444 // TPositionSatelliteInfo class 00445 if ( EPositionSatelliteInfoClass & moduleInfoFamily ) 00446 { 00447 // Set info base to satellite info 00448 iPosInfoBase = &iSatelliteInfo; 00449 } 00450 // The position module must support atleast 00451 // TPositionInfo class 00452 else 00453 { 00454 // Set info base to position info 00455 iPosInfoBase = &iPositionInfo; 00456 } 00457 } 00458 00459 // Process the position information 00460 // and request next position 00461 00462 // Get module name 00463 GetModuleName(iUsedPsy); 00464 00465 // Send position information to registered listener 00466 iPositionListener.PositionInfoUpdatedL(*iPosInfoBase,iModuleName); 00467 00468 // Request next position 00469 iPositioner.NotifyPositionUpdate( *iPosInfoBase, iStatus ); 00470 00471 // Set this object active 00472 SetActive(); 00473 } 00474 } 00475 00476 // End of File
|
© Nokia 2006 |