|
1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Implements the functionality required to provide clients with |
|
15 // signal strength information. |
|
16 // |
|
17 // |
|
18 |
|
19 /** |
|
20 @file |
|
21 */ |
|
22 |
|
23 #include <testconfigfileparser.h> |
|
24 #include "CSimSignalStrength.h" |
|
25 #include "CSimPhone.h" |
|
26 #include "Simlog.h" |
|
27 #include "simtsyglobalproperties.h" |
|
28 |
|
29 const TInt KSignalStrengthGranularity=5; // < Granularity for signal strength list array |
|
30 |
|
31 CSimSignalStrength* CSimSignalStrength::NewL(CSimPhone* aPhone) |
|
32 /** |
|
33 * Standard two-phase constructor. |
|
34 * @param aPhone The parent phone object. |
|
35 * @return CSimSignalStrength The new signal strength class. |
|
36 */ |
|
37 { |
|
38 CSimSignalStrength* self=new(ELeave) CSimSignalStrength(aPhone); |
|
39 CleanupStack::PushL(self); |
|
40 self->ConstructL(); |
|
41 CleanupStack::Pop(); |
|
42 return self; |
|
43 } |
|
44 |
|
45 CSimSignalStrength::CSimSignalStrength(CSimPhone* aPhone) |
|
46 : iPhone(aPhone) |
|
47 /** |
|
48 * Trivial first phase construction. |
|
49 * @param aPhone The parent phone object. |
|
50 */ |
|
51 { |
|
52 } |
|
53 |
|
54 void CSimSignalStrength::ConstructL() |
|
55 /** |
|
56 * Second phase construction. Create instances of the necessary heap-based |
|
57 * objects and read in the signal strength information from the configuration file. |
|
58 * Finally, if any signal strength tags have been read, the initial values |
|
59 * will be loaded and the timer started. |
|
60 * |
|
61 * Entries in the configuration file will take the following format: |
|
62 * "SignalStrengthLevel= <duration>, <dB Level>, <Bar Level>" |
|
63 * A number of these entries may be included to create a signal strength profile |
|
64 * for the duration of the test. |
|
65 */ |
|
66 { |
|
67 iTimer=CSimTimer::NewL(iPhone); |
|
68 iSignalStrengthInfo=new(ELeave) CArrayFixFlat<TSignalStrengthInfo>(KSignalStrengthGranularity); |
|
69 |
|
70 LOGSS1("Starting to parse Signal Strength config parameters..."); |
|
71 |
|
72 const CTestConfigItem* item=NULL; |
|
73 TInt ret=KErrNone; |
|
74 item=CfgFile()->Item(KSSNotifyCap); |
|
75 |
|
76 if (item != NULL) |
|
77 { |
|
78 TInt notifyCap; |
|
79 ret = CTestConfig::GetElement(item->Value(),KStdDelimiter,0,notifyCap); |
|
80 if(ret != KErrNone) |
|
81 { |
|
82 iNotifyCapability = 0; |
|
83 } |
|
84 else |
|
85 { |
|
86 iNotifyCapability = notifyCap; |
|
87 } |
|
88 } |
|
89 else |
|
90 { |
|
91 iNotifyCapability = 0; |
|
92 } |
|
93 |
|
94 TInt count=CfgFile()->ItemCount(KSSLevel); |
|
95 |
|
96 TInt i; |
|
97 for(i=0;i<count;i++) |
|
98 { |
|
99 item=CfgFile()->Item(KSSLevel,i); |
|
100 if(!item) |
|
101 break; |
|
102 |
|
103 TInt duration,ss,ssb,err; |
|
104 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,duration); |
|
105 if(ret!=KErrNone) |
|
106 { |
|
107 LOGPARSERR("duration",ret,0,&KSSLevel); |
|
108 continue; |
|
109 } |
|
110 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,ss); |
|
111 if(ret!=KErrNone) |
|
112 { |
|
113 LOGPARSERR("ss",ret,1,&KSSLevel); |
|
114 continue; |
|
115 } |
|
116 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,ssb); |
|
117 if(ret!=KErrNone) |
|
118 { |
|
119 LOGPARSERR("ssb",ret,2,&KSSLevel); |
|
120 continue; |
|
121 } |
|
122 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,err); |
|
123 if (ret == KErrNotFound) |
|
124 { |
|
125 err = KErrNone; |
|
126 } |
|
127 else |
|
128 { |
|
129 LOGPARSERRANGE("ssb",ret,3,&KSSLevel,"0 or -1"); |
|
130 } |
|
131 |
|
132 TSignalStrengthInfo ssInfo; |
|
133 ssInfo.iDuration=duration; |
|
134 ssInfo.iLevel=ss; |
|
135 ssInfo.iBar=(TInt8)ssb; |
|
136 ssInfo.iErr = err; |
|
137 iSignalStrengthInfo->AppendL(ssInfo); |
|
138 } |
|
139 |
|
140 LOGSS1("...Finished parsing Signal Strength config parameters..."); |
|
141 |
|
142 if(iSignalStrengthInfo->Count()!=0) |
|
143 { |
|
144 iSSIndex=0; |
|
145 iCurrentLevel=iSignalStrengthInfo->At(0).iLevel; |
|
146 iCurrentBar=iSignalStrengthInfo->At(0).iBar; |
|
147 iCurrentError = iSignalStrengthInfo->At(0).iErr; |
|
148 iTimer->Start(iSignalStrengthInfo->At(0).iDuration,this); |
|
149 } |
|
150 //still have to listen on deprecated P&S uids |
|
151 iSignalStrengthChange = CSimPubSubChange::NewL(this, CSimPubSub::TPubSubProperty(KUidSimtsyCategoryLocal, KSimtsySignalStrengthChange, KSimtsySignalStrengthChangeType)); |
|
152 iPSSignalStrengthChange = CSimPubSubChange::NewL(this, CSimPubSub::TPubSubProperty(KUidPSSimTsyCategory, KPSSimTsySignalStrengthChange, KPSSimTsySignalStrengthChangeKeyType)); |
|
153 } |
|
154 |
|
155 CSimSignalStrength::~CSimSignalStrength() |
|
156 /** |
|
157 * Standard destructor. Destroy the heap-based object owned by this object. |
|
158 */ |
|
159 { |
|
160 delete iTimer; |
|
161 delete iSignalStrengthInfo; |
|
162 delete iSignalStrengthChange; |
|
163 delete iPSSignalStrengthChange; |
|
164 } |
|
165 |
|
166 TInt CSimSignalStrength::GetSignalCaps(TTsyReqHandle aReqHandle,TDes8* aPckg1) |
|
167 /** |
|
168 * Retrieve signal strength capability information. This function completes the |
|
169 * client's request synchronously. If the configuration file contains any signal |
|
170 * strength profile information, then it indicates support for signal strength |
|
171 * requests, otherwise it does not. |
|
172 * |
|
173 * @param aReqHandle The request handle associated with this request. |
|
174 * @param aPckg1 The first parameter package. This will be populated with the |
|
175 * capability data to be returned. |
|
176 * @return TInt Standard error value. |
|
177 */ |
|
178 { |
|
179 TPckg<TUint32>* signalCapsPckg=(TPckg<TUint32>*)aPckg1; |
|
180 TUint32& signalCaps=(*signalCapsPckg)(); |
|
181 |
|
182 if (iNotifyCapability != 0) |
|
183 { |
|
184 signalCaps= RMobilePhone::KCapsGetSignalStrength | |
|
185 RMobilePhone::KCapsNotifySignalStrengthChange; |
|
186 } |
|
187 else if(iSignalStrengthInfo->Count()==0) |
|
188 { |
|
189 signalCaps=0; |
|
190 } |
|
191 else if((iSignalStrengthInfo->Count()-1)<=iSSIndex) |
|
192 { |
|
193 signalCaps= RMobilePhone::KCapsGetSignalStrength; |
|
194 } |
|
195 else |
|
196 { |
|
197 signalCaps= RMobilePhone::KCapsGetSignalStrength | |
|
198 RMobilePhone::KCapsNotifySignalStrengthChange; |
|
199 } |
|
200 |
|
201 iPhone->ReqCompleted(aReqHandle,KErrNone); |
|
202 return KErrNone; |
|
203 } |
|
204 |
|
205 TInt CSimSignalStrength::GetSignalStrength(TTsyReqHandle aReqHandle,TDes8* aPckg1, TDes8* aPckg2) |
|
206 /** |
|
207 * Return the current signal strength information. This function completes synchronously. |
|
208 * If the configuration file contains any signal strength profile information, the |
|
209 * request completes successfully, otherwise it completes with KErrNotSupported. |
|
210 * |
|
211 * @param aReqHandle The request handle associated with this request. |
|
212 * @param aPckg1 The first parameter package. This is populated with the signal |
|
213 * strength dB level. |
|
214 * @param aPckg2 The second parameter package. This is populated with the signal |
|
215 * strength bar level. |
|
216 * @return TInt Standard error value. |
|
217 */ |
|
218 { |
|
219 LOGSS1(">>CSimSignalStrength::GetSignalStrength"); |
|
220 TPckg<TInt32>* ssPckg=(TPckg<TInt32>*)aPckg1; |
|
221 TInt32& ss=(*ssPckg)(); |
|
222 TPckg<TInt8>* ssbPckg=(TPckg<TInt8>*)aPckg2; |
|
223 TInt8& ssb=(*ssbPckg)(); |
|
224 |
|
225 if(iSignalStrengthInfo->Count()==0 && iNotifyCapability == 0) |
|
226 { |
|
227 iPhone->ReqCompleted(aReqHandle,KErrNotSupported); |
|
228 return KErrNone; |
|
229 } |
|
230 |
|
231 ss=iCurrentLevel; |
|
232 ssb=iCurrentBar; |
|
233 LOGSS3("<<CSimSignalStrength::GetSignalStrength with level=%d dB and bar=%d",iCurrentLevel,iCurrentBar); |
|
234 iPhone->ReqCompleted(aReqHandle,iCurrentError); |
|
235 return KErrNone; |
|
236 } |
|
237 |
|
238 TInt CSimSignalStrength::NotifySignalStrengthChange(TTsyReqHandle aReqHandle,TDes8* aPckg1, TDes8* aPckg2) |
|
239 /** |
|
240 * Register a client's interest in being notified when the signal strength changes. |
|
241 * This function records the request's parameters and awaits a change in signal |
|
242 * strength before completing. |
|
243 * |
|
244 * @param aPckg1 The first parameter package. This is populated with the signal |
|
245 * strength dB level. |
|
246 * @param aPckg2 The second parameter package. This is populated with the signal |
|
247 * strength bar level. |
|
248 * @return TInt Standard error value. |
|
249 */ |
|
250 { |
|
251 LOGSS1(">>CSimSignalStrength::NotifySignalStrengthChange"); |
|
252 TPckg<TInt32>* ssPckg=(TPckg<TInt32>*)aPckg1; |
|
253 TInt32& ss=(*ssPckg)(); |
|
254 TPckg<TInt8>* ssbPckg=(TPckg<TInt8>*)aPckg2; |
|
255 TInt8& ssb=(*ssbPckg)(); |
|
256 |
|
257 if(iSignalStrengthInfo->Count()==0 && iNotifyCapability == 0) |
|
258 { |
|
259 iPhone->ReqCompleted(aReqHandle,KErrNotSupported); |
|
260 return KErrNone; |
|
261 } |
|
262 |
|
263 __ASSERT_ALWAYS(!iSSChangeNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding)); |
|
264 iSSChangeNotificationPending=ETrue; |
|
265 iSSChangeNotificationReqHandle=aReqHandle; |
|
266 iSSChangeNotificationSSLevel=&ss; |
|
267 iSSChangeNotificationSSBarLevel=&ssb; |
|
268 return KErrNone; |
|
269 } |
|
270 |
|
271 void CSimSignalStrength::NotifySignalStrengthChangeCancel() |
|
272 /** |
|
273 * Cancel a previous request to be notified of a change in signal strength. |
|
274 */ |
|
275 { |
|
276 if(iSSChangeNotificationPending) |
|
277 { |
|
278 LOGSS1("CSimSignalStrength::NotifySignalStrengthChange has been cancelled"); |
|
279 iSSChangeNotificationPending=EFalse; |
|
280 iPhone->ReqCompleted(iSSChangeNotificationReqHandle,KErrCancel); |
|
281 } |
|
282 else |
|
283 LOGSS1("CSimSignalStrength::NotifySignalStrengthChange was not outstanding and hasn't been cancelled"); |
|
284 } |
|
285 |
|
286 void CSimSignalStrength::TimerCallBack(TInt /*aId*/) |
|
287 /** |
|
288 * The timer callback function. This function will be called when the timer |
|
289 * completes. It indicates a change in signal strength settings. So, the new |
|
290 * signal strength settings must be loaded into the member variables representing |
|
291 * the current settings and any pending signal strength notification requests must |
|
292 * be completed. Finally, the next timer is started. |
|
293 * |
|
294 * @param aId This parameter is unused. It is only required for CSimXxx classes |
|
295 * that have more than one timer instance and need to identify which |
|
296 * timer has expired. |
|
297 */ |
|
298 { |
|
299 iSSIndex++; |
|
300 if(iSignalStrengthInfo->Count()<=iSSIndex) |
|
301 return; |
|
302 |
|
303 iCurrentLevel=iSignalStrengthInfo->At(iSSIndex).iLevel; |
|
304 iCurrentBar=iSignalStrengthInfo->At(iSSIndex).iBar; |
|
305 iCurrentError = iSignalStrengthInfo->At(iSSIndex).iErr; |
|
306 if(iSSChangeNotificationPending) |
|
307 { |
|
308 iSSChangeNotificationPending=EFalse; |
|
309 *iSSChangeNotificationSSLevel=iCurrentLevel; |
|
310 *iSSChangeNotificationSSBarLevel=iCurrentBar; |
|
311 LOGSS3("<<CSimSignalStrength::NotifySignalStrengthChange with level=%d dB and bar=%d",iCurrentLevel,iCurrentBar); |
|
312 iPhone->ReqCompleted(iSSChangeNotificationReqHandle,iCurrentError); |
|
313 } |
|
314 iTimer->Start(iSignalStrengthInfo->At(iSSIndex).iDuration,this); |
|
315 } |
|
316 |
|
317 const CTestConfigSection* CSimSignalStrength::CfgFile() |
|
318 /** |
|
319 * Returns a pointer to the current configuration file section. |
|
320 * |
|
321 * @return CTestConfigSection A pointer to the current configuration file section. |
|
322 */ |
|
323 { |
|
324 return iPhone->CfgFile(); |
|
325 } |
|
326 |
|
327 /** |
|
328 * Called by CSimSignalStrengthChange when a signal strength request has been received. |
|
329 * |
|
330 * @param aNewVal The new signal strength value (number of bars) |
|
331 */ |
|
332 void CSimSignalStrength::PubSubCallback(TInt aNewVal) |
|
333 { |
|
334 LOGSS2("CSimSignalStrength::SignalStrengthChangeCallBack newVal=%d", aNewVal); |
|
335 if (iCurrentBar == aNewVal) |
|
336 { |
|
337 return; |
|
338 } |
|
339 iCurrentBar = (TInt8) aNewVal; |
|
340 if(iSSChangeNotificationPending) |
|
341 { |
|
342 iSSChangeNotificationPending=EFalse; |
|
343 *iSSChangeNotificationSSLevel=iCurrentLevel; |
|
344 *iSSChangeNotificationSSBarLevel=iCurrentBar; |
|
345 LOGSS3("<<CSimSignalStrength::NotifySignalStrengthChange with level=%d dB and bar=%d",iCurrentLevel,iCurrentBar); |
|
346 iPhone->ReqCompleted(iSSChangeNotificationReqHandle,iCurrentError); |
|
347 } |
|
348 } |