82 // Symbian 2nd phase constructor can leave. |
81 // Symbian 2nd phase constructor can leave. |
83 // ----------------------------------------------------------------------------- |
82 // ----------------------------------------------------------------------------- |
84 // |
83 // |
85 void CGPSWatcher::ConstructL() |
84 void CGPSWatcher::ConstructL() |
86 { |
85 { |
|
86 TRequestStatus* status = &iStatus; |
87 CTimer::ConstructL(); |
87 CTimer::ConstructL(); |
88 |
88 |
89 User::LeaveIfError(iPosServer.Connect()); |
89 // Create the status updater |
90 |
90 iStatusUpdater = CPosIntGpsHwStatus::NewL(*this); |
91 // Immediately subscribe for module status events |
91 |
92 iStatusEvent.SetRequestedEvents(TPositionModuleStatusEventBase::EEventDeviceStatus); |
92 // Get the status manually, if we can, it's ok if we cant |
93 Subscribe(); |
93 TRAP_IGNORE( iStatusUpdater->GetStatusL( iGpsStatus ) ); |
94 |
94 |
95 // Check initial state |
95 if( !IsActive() ) |
96 CheckModules(); |
96 { |
97 } |
97 SetActive(); |
98 |
98 } |
99 // ----------------------------------------------------------------------------- |
99 |
100 // CGPSWatcher::Subscribe |
100 User::RequestComplete(status, KErrNone); |
101 // Subscribe to position events |
101 } |
102 // ----------------------------------------------------------------------------- |
102 |
103 // |
103 // ----------------------------------------------------------------------------- |
104 void CGPSWatcher::Subscribe() |
104 // CGPSWatcher::OnStatusUpdateEvent |
105 { |
105 // Inherited from MPosIntGpsHwStatusObserver |
106 iPosServer.NotifyModuleStatusEvent(iStatusEvent, iStatus); |
106 // ----------------------------------------------------------------------------- |
107 SetActive(); |
107 // |
108 } |
108 void CGPSWatcher::OnStatusUpdateEvent(CPosIntGpsHwStatus::TIntGpsHwStatus aStatus, TInt aError) |
|
109 { |
|
110 TRequestStatus* status = &iStatus; |
|
111 |
|
112 // store the status from the Gps: |
|
113 iGpsStatus = aStatus; |
|
114 |
|
115 User::RequestComplete(status, aError); |
|
116 |
|
117 if( !IsActive() ) |
|
118 { |
|
119 SetActive(); |
|
120 } |
|
121 } |
109 |
122 |
110 // ----------------------------------------------------------------------------- |
123 // ----------------------------------------------------------------------------- |
111 // CGPSWatcher::RunL |
124 // CGPSWatcher::RunL |
112 // Inherited from CActive |
125 // Inherited from CActive |
113 // ----------------------------------------------------------------------------- |
126 // ----------------------------------------------------------------------------- |
114 // |
127 // |
115 void CGPSWatcher::RunL() |
128 void CGPSWatcher::RunL() |
116 { |
129 { |
|
130 TInt error = KErrNone; |
|
131 |
117 // If there are errors just leave and stop watching: |
132 // If there are errors just leave and stop watching: |
118 DRMLOG2(_L("CGPSWatcher::RunL: error: '%d'"), iStatus.Int()); |
133 DRMLOG2(_L("CGPSWatcher::RunL: status: '%d'"), iStatus.Int()); |
119 |
134 |
120 // If we already updated the time: |
135 switch( iGpsStatus ) |
121 if( iTimeUpdater && iTimeUpdater->TimeReceived() ) |
|
122 { |
|
123 DRMLOG( _L("CGPSWatcher::RunL: time updater exists, time received, deleting")); |
|
124 iClock->Notify( CDRMClock::ENotifyGPSTimeReceived ); |
|
125 DRMLOG( _L("CGPSWatcher::RunL: object deleted, returning")); |
|
126 return; |
|
127 } |
|
128 |
|
129 // The server was killed: |
|
130 if( iStatus.Int() == KErrServerTerminated ) |
|
131 { |
136 { |
132 if( iRetryCounter > KMaxRetryCounter ) |
137 // GPS HW is used and is receiving location fixes. |
133 { |
138 case CPosIntGpsHwStatus::EStatusOn: |
134 DRMLOG( _L("CGPSWatcher::RunL: Maximum retries reached, stopping watcher.") ); |
139 DRMLOG(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: Checking modules")); |
135 iClock->Notify( CDRMClock::ENotifyGPSTimeReceived ); |
140 // No active modules, check again: |
136 return; |
141 if( !iActiveSatelliteModules.Count() ) |
137 } |
142 { |
138 // If there are errors just leave and stop watching: |
143 DRMLOG(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: No active modules in list Checking modules")); |
139 DRMLOG2(_L("CGPSWatcher::RunL: server terminated, waiting '%d' microseconds"), KGpsDefaultWaitTime); |
144 error = CheckModules(); |
140 After( TTimeIntervalMicroSeconds32(KGpsDefaultWaitTime) ); |
145 } |
141 return; |
146 |
142 } |
147 // if we have some or found some check the satellites for updates: |
143 |
148 if( !error && iActiveSatelliteModules.Count() ) |
144 Subscribe(); |
149 { |
145 TPositionModuleStatusEventBase::TModuleEvent occurredEvents = iStatusEvent.OccurredEvents(); |
150 DRMLOG2(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: Active modules available (%d), check satellites"), iActiveSatelliteModules.Count()); |
146 DRMLOG2(_L("CGPSWatcher::RunL: occurredEvents = 0x%X"), occurredEvents); |
151 // Get the time update: |
147 |
152 CheckSatellites(); |
148 |
153 } |
149 // If time updater is not running, check module statuses |
154 else |
150 if(!iTimeUpdater) |
155 { |
151 CheckModules(); |
156 DRMLOG2(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: Still no active modules in list or error (%d) occurred"), error); |
|
157 } |
|
158 break; |
|
159 // GPS HW is used and is searching for location. |
|
160 case CPosIntGpsHwStatus::EStatusActive: |
|
161 // Get a list of active GPS modules: |
|
162 DRMLOG(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusActive: Checking modules")); |
|
163 |
|
164 // return value not important: |
|
165 CheckModules(); |
|
166 break; |
|
167 case CPosIntGpsHwStatus::EStatusUnknown: |
|
168 case CPosIntGpsHwStatus::EStatusOff: |
|
169 // Clear the list of modules: |
|
170 DRMLOG2(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusUnknown,Off or default: (%d) Checking modules"), iGpsStatus); |
|
171 iActiveSatelliteModules.ResetAndDestroy(); |
|
172 iTimeUpdaters.ResetAndDestroy(); |
|
173 default: |
|
174 // Do nothing |
|
175 break; |
|
176 } |
152 } |
177 } |
153 |
178 |
154 |
179 |
155 // ----------------------------------------------------------------------------- |
180 // ----------------------------------------------------------------------------- |
156 // CGPSWatcher::DoCancel |
181 // CGPSWatcher::DoCancel |
157 // Inherited from CActive |
182 // Inherited from CActive |
158 // ----------------------------------------------------------------------------- |
183 // ----------------------------------------------------------------------------- |
159 // |
184 // |
160 void CGPSWatcher::DoCancel() |
185 void CGPSWatcher::DoCancel() |
161 { |
186 { |
162 iPosServer.CancelRequest(EPositionServerNotifyModuleStatusEvent); |
|
163 } |
187 } |
164 |
188 |
165 // ----------------------------------------------------------------------------- |
189 // ----------------------------------------------------------------------------- |
166 // CGPSWatcher::RunError |
190 // CGPSWatcher::RunError |
167 // Inherited from CActive |
191 // Inherited from CActive |
176 // ----------------------------------------------------------------------------- |
200 // ----------------------------------------------------------------------------- |
177 // CGPSWatcher::CheckModules |
201 // CGPSWatcher::CheckModules |
178 // Check what modules are present and act accordingly |
202 // Check what modules are present and act accordingly |
179 // ----------------------------------------------------------------------------- |
203 // ----------------------------------------------------------------------------- |
180 // |
204 // |
181 void CGPSWatcher::CheckModules() |
205 TInt CGPSWatcher::CheckModules() |
182 { |
206 { |
183 // Get number of modules |
207 TUint numModules = 0; |
184 TUint numModules; |
208 TPositionModuleInfo* moduleInfo = NULL; |
185 if(iPosServer.GetNumModules(numModules)!=KErrNone || !numModules) |
209 TInt error = KErrNone; |
186 return; |
210 RPositionServer posServer; |
187 |
211 |
188 // Collect all active and satellite capable modules |
212 // Destroy the old list: |
189 TFullName moduleName; |
213 iActiveSatelliteModules.ResetAndDestroy(); |
190 RPointerArray<TPositionModuleInfo> satelliteModules; |
214 |
191 |
215 // open connection to the positioning server: |
192 TPositionModuleInfo *moduleInfo(0); |
216 error = posServer.Connect(); |
193 |
217 if( error ) |
194 for(TUint i=0; i<numModules; i++) |
218 { |
|
219 return error; |
|
220 } |
|
221 |
|
222 error = posServer.GetNumModules( numModules ); |
|
223 |
|
224 if(error || !numModules) |
|
225 { |
|
226 DRMLOG2(_L("CheckModules: modules available (%d)"), numModules); |
|
227 DRMLOG2(_L("CheckModules: error code (%d)"), error); |
|
228 |
|
229 return KErrNotFound; |
|
230 } |
|
231 |
|
232 for( TUint i = 0; i < numModules; i++) |
195 { |
233 { |
196 if(!moduleInfo) |
234 if(!moduleInfo) |
197 { |
235 { |
198 moduleInfo = new TPositionModuleInfo; |
236 moduleInfo = new TPositionModuleInfo; |
199 if(!moduleInfo) |
237 if( !moduleInfo ) |
200 { |
238 { |
201 continue; |
239 // in practice OOM situation |
202 } |
240 posServer.Close(); |
|
241 return KErrNoMemory; |
|
242 } |
203 } |
243 } |
204 |
244 |
205 // Get module info from the server |
245 // Get module info from the server |
206 if(iPosServer.GetModuleInfoByIndex(i, *moduleInfo) != KErrNone) |
246 if(posServer.GetModuleInfoByIndex(i, *moduleInfo) != KErrNone) |
207 { |
247 { |
208 continue; |
248 continue; |
209 } |
249 } |
210 |
250 |
|
251 DRMLOG(_L("CheckModules: Checking for internal & satellite capable")); |
|
252 |
211 // Check if the module is internal and satellite capable |
253 // Check if the module is internal and satellite capable |
212 if(! (moduleInfo->DeviceLocation() & TPositionModuleInfo::EDeviceInternal) || |
254 if(! (moduleInfo->DeviceLocation() & TPositionModuleInfo::EDeviceInternal) || |
213 ! (moduleInfo->Capabilities() & TPositionModuleInfo::ECapabilitySatellite) ) |
255 ! (moduleInfo->Capabilities() & TPositionModuleInfo::ECapabilitySatellite) ) |
214 { |
256 { |
215 // Not internal or satellite capable |
257 // Not internal or satellite capable |
216 continue; |
258 continue; |
217 } |
259 } |
218 |
260 |
219 // Get module status |
261 // Get module status and check if the module is actually active: |
|
262 |
|
263 |
|
264 DRMLOG(_L("CheckModules: Checking module status")); |
|
265 |
220 TPositionModuleStatus moduleStatus; |
266 TPositionModuleStatus moduleStatus; |
221 if(iPosServer.GetModuleStatus(moduleStatus, moduleInfo->ModuleId()) != KErrNone) |
267 |
|
268 if(posServer.GetModuleStatus(moduleStatus, moduleInfo->ModuleId()) != KErrNone) |
222 { |
269 { |
223 continue; |
270 continue; |
224 } |
271 } |
225 // Check if the module is active |
272 |
226 if(moduleStatus.DeviceStatus() != TPositionModuleStatus::EDeviceActive) |
273 // Check if the module is active or ready as all might not use the active state: |
|
274 if(!(moduleStatus.DeviceStatus() == TPositionModuleStatus::EDeviceActive || |
|
275 moduleStatus.DeviceStatus() == TPositionModuleStatus::EDeviceReady) ) |
227 { |
276 { |
228 continue; |
277 continue; |
229 } |
278 } |
230 |
279 |
231 moduleInfo->GetModuleName(moduleName); |
280 |
232 |
281 DRMLOG(_L("CheckModules: Module is ready or active")); |
233 DRMLOG6( _L("Module %d: id=0x%08X, name = %S, cap=0x%08X, status=%d"), i, moduleInfo->ModuleId().iUid, &moduleName, moduleInfo->Capabilities(), moduleStatus.DeviceStatus()); |
|
234 |
282 |
235 // Active internal satellite device, try to append in the array |
283 // Active internal satellite device, try to append in the array |
236 if(satelliteModules.Append(moduleInfo) == KErrNone) |
284 if(iActiveSatelliteModules.Append(moduleInfo) == KErrNone) |
237 { |
285 { |
|
286 // Set this to 0 so that on the next round a new one will be created |
|
287 // old one will be in the list: |
|
288 DRMLOG2(_L("CheckModules: Appended modules to list available (%d) active now available"), iActiveSatelliteModules.Count()); |
238 moduleInfo = 0; |
289 moduleInfo = 0; |
239 } |
290 } |
240 } |
291 } |
241 |
292 |
242 delete moduleInfo; |
293 // There is a module created which was not added, delete it. |
243 |
294 if( moduleInfo ) |
244 if(satelliteModules.Count()) |
295 { |
245 { |
296 delete moduleInfo; |
246 DRMLOG( _L("Active satellite module available") ); |
297 moduleInfo = NULL; |
247 // We have an active satellite module available |
298 } |
248 TPositionModuleId moduleId = satelliteModules[0]->ModuleId(); |
299 |
249 |
300 // close connection to the positioning server: |
250 // Just allocating/deleting the time updater will do the trick |
301 posServer.Close(); |
251 iTimeUpdater = CGPSTimeUpdater::New(iPosServer, moduleId, iClock); |
302 return KErrNone; |
252 } |
303 } |
253 else |
304 |
254 { |
305 |
255 DRMLOG( _L("No active satellite modules available") ); |
306 // ----------------------------------------------------------------------------- |
256 // Delete time updater since no active GPS anymore |
307 // CGPSWatcher::CheckSatellites() |
257 delete iTimeUpdater; iTimeUpdater = 0; |
308 // Check what modules are present and act accordingly |
258 } |
309 // ----------------------------------------------------------------------------- |
259 |
310 // |
260 satelliteModules.ResetAndDestroy(); |
311 void CGPSWatcher::CheckSatellites() |
261 satelliteModules.Close(); |
312 { |
262 } |
313 CGPSTimeUpdater* updater = NULL; |
|
314 |
|
315 iTimeUpdaters.ResetAndDestroy(); |
|
316 |
|
317 // Start as many updaters as needed: |
|
318 for( TInt i = 0; i < iActiveSatelliteModules.Count(); i++ ) |
|
319 { |
|
320 updater = CGPSTimeUpdater::New( iActiveSatelliteModules[i]->ModuleId(), iClock ); |
|
321 if( updater ) |
|
322 { |
|
323 if( iTimeUpdaters.Append(updater) ) |
|
324 { |
|
325 delete updater; |
|
326 updater = NULL; |
|
327 } |
|
328 } |
|
329 } |
|
330 } |
|
331 |
|
332 // End of File |