|
1 /* |
|
2 * Copyright (c) 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 "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: Active Object operation for serving server logic requests |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <e32cmn.h> |
|
22 #include <lbttriggerentry.h> |
|
23 #include <lbtgeoareabase.h> |
|
24 #include <lbtgeocircle.h> |
|
25 #include <lbtgeoareabase.h> |
|
26 #include <lbttriggerconditionbase.h> |
|
27 #include <lbttriggerconditionarea.h> |
|
28 #include <lbttriggerdynamicinfo.h> |
|
29 #include <s32mem.h> |
|
30 #include <lbtsessiontrigger.h> |
|
31 #include <lbtstartuptrigger.h> |
|
32 #include <lbterrors.h> |
|
33 #include "lbtcreatetriggeraooperation.h" |
|
34 #include "lbtaoobserver.h" |
|
35 #include "lbtserverconsts.h" |
|
36 #include "lbtglobal.h" |
|
37 #include "lbtcontainertriggerentry.h" |
|
38 #include "lbtcontainer.h" |
|
39 #include "lbtcontainerextendedtriggerinfo.h" |
|
40 #include "lbtsettingsmanager.h" |
|
41 #include "lbtlogger.h" |
|
42 |
|
43 // CONSTANTS |
|
44 const TInt KCircleRadiusCutoff(500); |
|
45 const TReal KMinHysteresisArea(20); |
|
46 |
|
47 |
|
48 // ===================== MEMBER FUNCTIONS ===================== |
|
49 |
|
50 // --------------------------------------------------------------------------- |
|
51 // CLbtCreateTriggerAOOperation::NewL |
|
52 // Symbian Two - phase constructor |
|
53 // --------------------------------------------------------------------------- |
|
54 // |
|
55 CLbtCreateTriggerAOOperation* CLbtCreateTriggerAOOperation::NewL(MLbtAOObserver& aObserver, |
|
56 const RMessage2& aMessage, |
|
57 CLbtContainer& aContainer, |
|
58 TInt aClientType, |
|
59 CLbtSettingsManager& aSettingsManager ) |
|
60 { |
|
61 FUNC_ENTER("CLbtCreateTriggerAOOperation::NewL"); |
|
62 CLbtCreateTriggerAOOperation* self = new (ELeave) CLbtCreateTriggerAOOperation(aObserver, |
|
63 aMessage, |
|
64 aContainer, |
|
65 aClientType, |
|
66 aSettingsManager); |
|
67 CleanupStack::PushL(self); |
|
68 self->ConstructL(); |
|
69 CleanupStack::Pop(); // self |
|
70 return self; |
|
71 } |
|
72 |
|
73 // --------------------------------------------------------------------------- |
|
74 // CLbtCreateTriggerAOOperation::~CLbtCreateTriggerAOOperation |
|
75 // Destructor |
|
76 // --------------------------------------------------------------------------- |
|
77 // |
|
78 CLbtCreateTriggerAOOperation::~CLbtCreateTriggerAOOperation() |
|
79 { |
|
80 FUNC_ENTER("CLbtCreateTriggerAOOperation::~CLbtCreateTriggerAOOperation"); |
|
81 iContainer.RemoveObserver(this); |
|
82 // Call cancel operation |
|
83 if( IsActive() ) |
|
84 { |
|
85 Cancel(); |
|
86 } |
|
87 delete iContainerTriggerEntry; |
|
88 } |
|
89 |
|
90 // --------------------------------------------------------------------------- |
|
91 // CLbtCreateTriggerAOOperation::CLbtCreateTriggerAOOperation |
|
92 // C++ Default constructor |
|
93 // --------------------------------------------------------------------------- |
|
94 // |
|
95 CLbtCreateTriggerAOOperation::CLbtCreateTriggerAOOperation(MLbtAOObserver& aObserver, |
|
96 const RMessage2& aMessage, |
|
97 CLbtContainer& aContainer, |
|
98 TInt aClientType, |
|
99 CLbtSettingsManager& aSettingsManager) |
|
100 : CLbtAOOperationBase(aObserver, aMessage, aContainer, aClientType), |
|
101 iSettingsManager(aSettingsManager) |
|
102 { |
|
103 FUNC_ENTER("CLbtCreateTriggerAOOperation::CLbtCreateTriggerAOOperation"); |
|
104 } |
|
105 |
|
106 // --------------------------------------------------------------------------- |
|
107 // CLbtCreateTriggerAOOperation::ConstructL |
|
108 // --------------------------------------------------------------------------- |
|
109 // |
|
110 void CLbtCreateTriggerAOOperation::ConstructL() |
|
111 { |
|
112 FUNC_ENTER("CLbtCreateTriggerAOOperation::ConstructL"); |
|
113 CActiveScheduler::Add(this); |
|
114 } |
|
115 |
|
116 // --------------------------------------------------------------------------- |
|
117 // CLbtCreateTriggerAOOperation::RunL |
|
118 // --------------------------------------------------------------------------- |
|
119 // |
|
120 void CLbtCreateTriggerAOOperation::RunL() |
|
121 { |
|
122 FUNC_ENTER("CLbtCreateTriggerAOOperation::RunL"); |
|
123 switch(iFunction) |
|
124 { |
|
125 case ELbtCreateTrigger: |
|
126 { |
|
127 if(iStatus.Int() == KErrNone) |
|
128 { |
|
129 LOGSTRING("Trigger created: \"%S\" ", &(iContainerTriggerEntry->TriggerEntry()->Name())); |
|
130 LOG1("Trigger Id:%d",iContainerTriggerEntry->TriggerEntry()->Id()); |
|
131 LOG1("Trigger state:%d",iContainerTriggerEntry->TriggerEntry()->State()); |
|
132 // For create trigger server has to write the trigger id back to the client |
|
133 TPckg<TUint32> triggerId(iContainerTriggerEntry->TriggerEntry()->Id()); |
|
134 LbtGlobal::Write(iMessage, KParamTriggerId,triggerId); |
|
135 } |
|
136 LbtGlobal::RequestComplete(iMessage, iStatus.Int()); |
|
137 break; |
|
138 } |
|
139 default: |
|
140 { |
|
141 // Handle the completion of request. Ideally this should not execute |
|
142 LbtGlobal::RequestComplete(iMessage, iStatus.Int()); |
|
143 break; |
|
144 } |
|
145 } |
|
146 |
|
147 iObserver.HandleOperationClosureL(this, iStatus.Int()); |
|
148 } |
|
149 |
|
150 // --------------------------------------------------------------------------- |
|
151 // CLbtCreateTriggerAOOperation::DoCancel |
|
152 // --------------------------------------------------------------------------- |
|
153 // |
|
154 void CLbtCreateTriggerAOOperation::DoCancel() |
|
155 { |
|
156 FUNC_ENTER("CLbtCreateTriggerAOOperation::DoCancel"); |
|
157 // Cancel container notifications |
|
158 iContainer.CancelAsyncOperation(iAOIdentificationNum); |
|
159 iMessage.Complete( iStatus.Int() ); |
|
160 } |
|
161 |
|
162 // --------------------------------------------------------------------------- |
|
163 // CLbtCreateTriggerAOOperation::StartOperationL |
|
164 // --------------------------------------------------------------------------- |
|
165 // |
|
166 void CLbtCreateTriggerAOOperation::StartOperationL() |
|
167 { |
|
168 FUNC_ENTER("CLbtCreateTriggerAOOperation::StartOperationL"); |
|
169 switch(iFunction) |
|
170 { |
|
171 case ELbtCreateTrigger: |
|
172 { |
|
173 if( CheckTriggerCap() ) |
|
174 { |
|
175 CreateTriggerL(); |
|
176 } |
|
177 else |
|
178 { |
|
179 LbtGlobal::RequestComplete(iMessage, KLbtErrMaxEnabledValidTriggersLimitExceeded ); |
|
180 iObserver.HandleOperationClosureL(this, KLbtErrMaxEnabledValidTriggersLimitExceeded ); |
|
181 } |
|
182 break; |
|
183 } |
|
184 default: |
|
185 { |
|
186 break; |
|
187 } |
|
188 } |
|
189 } |
|
190 |
|
191 // --------------------------------------------------------------------------- |
|
192 // CLbtCreateTriggerAOOperation::CheckTriggerCap() |
|
193 // --------------------------------------------------------------------------- |
|
194 // |
|
195 TBool CLbtCreateTriggerAOOperation::CheckTriggerCap() |
|
196 { |
|
197 TUint enabledValidTriggerCount = iContainer.GetCountOfEnabledAndValidTriggers(); |
|
198 |
|
199 if( iSettingsManager.EnabledValidTriggerCount() > enabledValidTriggerCount ) |
|
200 { |
|
201 // More triggers can be created. Return true |
|
202 return ETrue; |
|
203 } |
|
204 return EFalse; |
|
205 } |
|
206 |
|
207 // --------------------------------------------------------------------------- |
|
208 // CLbtCreateTriggerAOOperation::CreateTriggerL() |
|
209 // --------------------------------------------------------------------------- |
|
210 // |
|
211 void CLbtCreateTriggerAOOperation::CreateTriggerL() |
|
212 { |
|
213 FUNC_ENTER("CLbtCreateTriggerAOOperation::CreateTriggerL"); |
|
214 // Copy the trigger entry object descriptor from the client IPC message |
|
215 HBufC8* triggerEntryBuffer = LbtGlobal::CopyClientBuffer8LC(iMessage, KParamTriggerEntry); |
|
216 |
|
217 if( triggerEntryBuffer == NULL ) |
|
218 { |
|
219 iObserver.HandleOperationClosureL(this, KErrBadDescriptor); |
|
220 return; |
|
221 } |
|
222 |
|
223 TLbtTriggerCreationInfo triggerCreationInfo; |
|
224 |
|
225 TPckg<TLbtTriggerCreationInfo> des(triggerCreationInfo); |
|
226 LbtGlobal::Read(iMessage,2,des); |
|
227 |
|
228 |
|
229 // Read the buffer into a stream |
|
230 RDesReadStream stream(*triggerEntryBuffer); |
|
231 CleanupClosePushL(stream); |
|
232 |
|
233 // Create the trigger entry object based on the type of trigger |
|
234 CLbtTriggerEntry* trigger; |
|
235 if( triggerCreationInfo.iTriggerType== CLbtTriggerEntry::ETypeStartup) |
|
236 { |
|
237 trigger = CLbtStartupTrigger::NewLC(); |
|
238 } |
|
239 else |
|
240 { |
|
241 trigger = CLbtSessionTrigger::NewLC(); |
|
242 } |
|
243 |
|
244 // Internalize the trigger entry class since it is a "C" class |
|
245 trigger->InternalizeL(stream); |
|
246 |
|
247 // Fill the extended trigger info required by Stratergy |
|
248 CLbtExtendedTriggerInfo::TLbtTriggerRectArea area; |
|
249 |
|
250 if(trigger->GetCondition()->Type() == CLbtTriggerConditionBase::ETriggerConditionArea) |
|
251 { |
|
252 // Get the condition area base |
|
253 CLbtTriggerConditionArea* conditionArea = |
|
254 static_cast<CLbtTriggerConditionArea*>(trigger->GetCondition()); |
|
255 |
|
256 // Check if the area is a circle |
|
257 if(conditionArea->TriggerArea()->Type() == CLbtGeoAreaBase::ECircle) |
|
258 { |
|
259 CLbtGeoCircle* circle = static_cast<CLbtGeoCircle*>(conditionArea->TriggerArea()); |
|
260 |
|
261 // If the triggering area specified is less than the minimum triggering area |
|
262 // the return KErrTriggerAreaTooSmall |
|
263 |
|
264 if(circle->Radius() < iSettingsManager.MinimumTriggeringArea()) |
|
265 { |
|
266 CleanupStack::PopAndDestroy( 3 ); // trigger,stream,triggerEntry |
|
267 LbtGlobal::RequestComplete(iMessage, KErrTriggerAreaTooSmall); |
|
268 iObserver.HandleOperationClosureL(this, KErrTriggerAreaTooSmall); |
|
269 return; |
|
270 } |
|
271 |
|
272 CalculateRectangularArea(area, circle); |
|
273 } |
|
274 } |
|
275 |
|
276 // Create the extended trigger info |
|
277 CLbtExtendedTriggerInfo* extendedTriggerInfo = |
|
278 CLbtExtendedTriggerInfo::NewL(area, |
|
279 CalculateHysteresisAreaForTrigger(*trigger), |
|
280 EFalse, |
|
281 KNullDesC8, |
|
282 iMessage.SecureId(), |
|
283 triggerCreationInfo.iFireOnCreation); |
|
284 CleanupStack::PushL(extendedTriggerInfo); |
|
285 |
|
286 TLbtTriggerDynamicInfo* dynInfo = new (ELeave) TLbtTriggerDynamicInfo; |
|
287 CleanupStack::PushL(dynInfo); |
|
288 dynInfo->iValidity = TLbtTriggerDynamicInfo::EValid; |
|
289 |
|
290 |
|
291 |
|
292 // Create trigger class of Container. Container takes ownership of trigger and all info sent to it |
|
293 iContainerTriggerEntry = CLbtContainerTriggerEntry::NewL(trigger, dynInfo, extendedTriggerInfo); |
|
294 |
|
295 // Register for container change event observer |
|
296 TLbtTriggerEventMask eventMask = 0; |
|
297 eventMask|= CLbtContainer::ELbtConTriggerCreated; |
|
298 |
|
299 iContainer.SetChangeObserver( this ,eventMask ); |
|
300 |
|
301 // Creates the trigger in the container |
|
302 iContainer.CreateTrigger(*iContainerTriggerEntry,iAOIdentificationNum,iStatus); |
|
303 SetActive(); |
|
304 |
|
305 CleanupStack::Pop(5); //trigger, stream, triggerEntryBuffer, dynInfo and extendedTriggerInfo |
|
306 stream.Close(); |
|
307 delete triggerEntryBuffer; |
|
308 } |
|
309 |
|
310 // --------------------------------------------------------------------------- |
|
311 // CLbtCreateTriggerAOOperation::CancelCreateTrigger |
|
312 // --------------------------------------------------------------------------- |
|
313 // |
|
314 void CLbtCreateTriggerAOOperation::CancelCreateTrigger() |
|
315 { |
|
316 FUNC_ENTER("CLbtCreateTriggerAOOperation::CancelCreateTrigger"); |
|
317 Cancel(); |
|
318 } |
|
319 |
|
320 // --------------------------------------------------------------------------- |
|
321 // CLbtCreateTriggerAOOperation::GetTriggerId |
|
322 // --------------------------------------------------------------------------- |
|
323 // |
|
324 TLbtTriggerId CLbtCreateTriggerAOOperation::GetTriggerId() |
|
325 { |
|
326 FUNC_ENTER("CLbtCreateTriggerAOOperation::GetTriggerId"); |
|
327 return iContainerTriggerEntry->TriggerEntry()->Id(); |
|
328 } |
|
329 |
|
330 // --------------------------------------------------------------------------- |
|
331 // CLbtCreateTriggerAOOperation::CalculateHysteresisAreaForTrigger |
|
332 // --------------------------------------------------------------------------- |
|
333 // |
|
334 TInt CLbtCreateTriggerAOOperation::CalculateHysteresisAreaForTrigger( |
|
335 CLbtTriggerEntry& aTrigger) |
|
336 { |
|
337 FUNC_ENTER("CLbtCreateTriggerAOOperation::CalculateHysteresisAreaForTrigger"); |
|
338 // The Hysteresis for trigger is calculated as per this formula |
|
339 // If radius <= 500 |
|
340 // hysteresis = radius / 4. |
|
341 // Else |
|
342 // hysteresis = radius / Ln(radius/10) ( Log to the base e) |
|
343 // After the formula |
|
344 // if hysteresis < MinimumHysteresisRadius |
|
345 // hysteresis is taken to be the minimumHysteresis radius. |
|
346 |
|
347 // The constant values have to be store in cenrep and read |
|
348 // from there. |
|
349 |
|
350 TReal hysteresis = 0; |
|
351 CLbtTriggerConditionBase* conditionBase = aTrigger.GetCondition(); |
|
352 TReal radius = 0.0; |
|
353 |
|
354 // Fist find the type of the trigger |
|
355 if(conditionBase->Type() == |
|
356 CLbtTriggerConditionBase::ETriggerConditionArea) |
|
357 { |
|
358 CLbtTriggerConditionArea* basicCondition = |
|
359 static_cast<CLbtTriggerConditionArea*>(conditionBase); |
|
360 if(basicCondition->TriggerArea()->Type() == CLbtGeoAreaBase::ECircle) |
|
361 { |
|
362 // The trigger area is circular. Apply hysteresis formula for a circular area |
|
363 CLbtGeoCircle* circle = |
|
364 static_cast<CLbtGeoCircle*>(basicCondition->TriggerArea()); |
|
365 |
|
366 radius = circle->Radius(); |
|
367 |
|
368 if(radius > KCircleRadiusCutoff) |
|
369 { |
|
370 TReal logRadius; |
|
371 Math::Ln(logRadius, radius / 10 ); |
|
372 hysteresis = radius / logRadius; |
|
373 } |
|
374 else |
|
375 { |
|
376 hysteresis = radius / 4; |
|
377 } |
|
378 } |
|
379 } |
|
380 |
|
381 if(hysteresis < KMinHysteresisArea) |
|
382 { |
|
383 hysteresis = KMinHysteresisArea; |
|
384 } |
|
385 |
|
386 return (hysteresis + radius); |
|
387 } |
|
388 |
|
389 |
|
390 // --------------------------------------------------------------------------- |
|
391 // CLbtCreateTriggerAOOperation::CalculateRectangularArea |
|
392 // --------------------------------------------------------------------------- |
|
393 // |
|
394 void CLbtCreateTriggerAOOperation::CalculateRectangularArea( |
|
395 CLbtExtendedTriggerInfo::TLbtTriggerRectArea& aArea, |
|
396 CLbtGeoCircle* aCircle) |
|
397 { |
|
398 FUNC_ENTER("CLbtCreateTriggerAOOperation::CalculateRectangularArea"); |
|
399 TCoordinate center = aCircle->Center(); |
|
400 TCoordinate tmp = center; |
|
401 // Get the North Latitude of the ractangular area by moving north |
|
402 // (by using a bearing of 0). |
|
403 tmp.Move(0, aCircle->Radius()); |
|
404 aArea.iTrigAreaNorthLat = tmp.Latitude(); |
|
405 |
|
406 // From the previous point, Move west(by using a bearing of 270). |
|
407 // This gives the West Longitude. |
|
408 tmp.Move(270,aCircle->Radius()); |
|
409 aArea.iTrigAreaWestLong = tmp.Longitude(); |
|
410 |
|
411 |
|
412 // Reset tmp to the center |
|
413 tmp = center; |
|
414 |
|
415 // Get the South Latitude by moving south |
|
416 // (by using a bearing of 180). |
|
417 tmp.Move(180, aCircle->Radius()); |
|
418 aArea.iTrigAreaSouthLat = tmp.Latitude(); |
|
419 |
|
420 // From the previous point, Move east(by using a bearing of 90). |
|
421 // This gives the Eest Longitude. |
|
422 tmp.Move(90,aCircle->Radius()); |
|
423 aArea.iTrigAreaEastLong = tmp.Longitude(); |
|
424 |
|
425 return; |
|
426 } |
|
427 // end of file |