S60 3rd Edition SDK for Symbian OS
Example Applications Guide

LBSPositionRequestor.cpp

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

Back to top