|
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 // indicators information. |
|
16 // |
|
17 // |
|
18 |
|
19 /** |
|
20 @file |
|
21 */ |
|
22 |
|
23 #include <testconfigfileparser.h> |
|
24 #include "CSimIndicator.h" |
|
25 #include "CSimPhone.h" |
|
26 #include "Simlog.h" |
|
27 |
|
28 |
|
29 const TInt KIndicatorsGranularity=5; // < Granularity for indicators list array |
|
30 |
|
31 CSimIndicator* CSimIndicator::NewL(CSimPhone* aPhone) |
|
32 /** |
|
33 * Standard two-phase constructor. |
|
34 * @param aPhone The parent phone object. |
|
35 * @return CSimIndicator The new Ondicator class class. |
|
36 */ |
|
37 { |
|
38 CSimIndicator* self=new(ELeave) CSimIndicator(aPhone); |
|
39 CleanupStack::PushL(self); |
|
40 self->ConstructL(); |
|
41 CleanupStack::Pop(); |
|
42 return self; |
|
43 } |
|
44 |
|
45 CSimIndicator::CSimIndicator(CSimPhone* aPhone) |
|
46 : iPhone(aPhone),iNotificationNumber(0) |
|
47 /** |
|
48 * Trivial first phase construction. |
|
49 * @param aPhone The parent phone object. |
|
50 */ |
|
51 { |
|
52 } |
|
53 |
|
54 |
|
55 void CSimIndicator::ConstructL() |
|
56 /** |
|
57 * Second phase construction. Create instances of the necessary heap-based |
|
58 * objects and read in the indicators information from the configuration file. |
|
59 * Finally, if any indicators tags have been read, the initial values |
|
60 * will be loaded and the timer started. |
|
61 * |
|
62 * Entries in the configuration file will take the following format: |
|
63 * "Indicator= <duration>, <Flags>" |
|
64 * A number of these entries may be included to create an indicator profile |
|
65 * for the duration of the test. |
|
66 */ |
|
67 { |
|
68 iIndicatorsInfo=new(ELeave) CArrayFixFlat<TPhoneIndicatorsInfo>(KIndicatorsGranularity); |
|
69 |
|
70 LOGPHONE1("Starting to parse Indicators config parameters..."); |
|
71 TInt count=CfgFile()->ItemCount(KIndicators); |
|
72 const CTestConfigItem* item=NULL; |
|
73 TInt ret=KErrNone; |
|
74 |
|
75 TInt i; |
|
76 for(i=0;i<count;i++) |
|
77 { |
|
78 item=CfgFile()->Item(KIndicators,i); |
|
79 if(!item) |
|
80 break; |
|
81 |
|
82 TInt number; |
|
83 TInt error; |
|
84 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,number); |
|
85 if(ret!=KErrNone) |
|
86 { |
|
87 LOGPARSERR("number",ret,0,&KIndicators); |
|
88 continue; |
|
89 } |
|
90 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,error); |
|
91 if(ret!=KErrNone) |
|
92 { |
|
93 LOGPARSERR("error",ret,1,&KIndicators); |
|
94 continue; |
|
95 } |
|
96 TPhoneIndicatorsInfo indicInfo; |
|
97 indicInfo.iNotificationNumber=number; |
|
98 indicInfo.iError=error; |
|
99 iIndicatorsInfo->AppendL(indicInfo); |
|
100 } |
|
101 LOGPHONE2("Finished parsing Indicators config parameters...%d items found", count); |
|
102 |
|
103 iIndicatorCheckPeriod = 1; |
|
104 count = CfgFile()->ItemCount(KIndicatorCheckPeriod); |
|
105 if (count > 1) |
|
106 { |
|
107 LOGPHONE1("Warning: Error parsing IndicatorCheckPeriod in config file."); |
|
108 LOGPHONE1(" More than one value found, using default value."); |
|
109 } |
|
110 else |
|
111 { |
|
112 item=CfgFile()->Item(KIndicatorCheckPeriod); |
|
113 |
|
114 if (item != NULL) |
|
115 { |
|
116 TInt period; |
|
117 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,period); |
|
118 if(ret!=KErrNone) |
|
119 { |
|
120 LOGPHONE1("Warning: Error parsing IndicatorCheckPeriod in config file."); |
|
121 LOGPHONE1(" No value for IndicatorCheckPeriod found."); |
|
122 } |
|
123 else |
|
124 { |
|
125 iIndicatorCheckPeriod = period; |
|
126 } |
|
127 } |
|
128 } |
|
129 |
|
130 iCurrentIndicator=IndicatorState(); |
|
131 iTimer = CSimTimer::NewL(iPhone); |
|
132 } |
|
133 |
|
134 |
|
135 CSimIndicator::~CSimIndicator() |
|
136 /** |
|
137 * Standard destructor. Destroy the heap-based object owned by this object. |
|
138 */ |
|
139 { |
|
140 if (iIndicatorsInfo) |
|
141 { |
|
142 iIndicatorsInfo->Delete(0,iIndicatorsInfo->Count()); |
|
143 delete iIndicatorsInfo;//todo check ptr |
|
144 } |
|
145 delete iTimer; |
|
146 } |
|
147 |
|
148 |
|
149 TInt CSimIndicator::GetIndicatorCaps(TTsyReqHandle aReqHandle,TDes8* aPckg1, TDes8* aPckg2) |
|
150 /** |
|
151 * Retrieve Indicators capability information. This function completes the |
|
152 * client's request synchronously. If the configuration file contains any |
|
153 * indicator profile information, then it indicates support for indicator |
|
154 * requests, otherwise it does not. |
|
155 * |
|
156 * @param aReqHandle The request handle associated with this request. |
|
157 * @param aPckg1 The first parameter package. This will be populated with the action caps(methods supported) |
|
158 * . |
|
159 * @param aPckg2 the second parameter package. This will be populated with the Indicator caps(wich indicator(s) are supported) |
|
160 * @return TInt Standard error value. |
|
161 */ |
|
162 { |
|
163 TPckg<TUint32>* indicatorActionCapsPckg=(TPckg<TUint32>*)aPckg1; |
|
164 TUint32& indicatorActionCaps=(*indicatorActionCapsPckg)(); |
|
165 |
|
166 TPckg<TUint32>* indicatorIndCapsPckg=(TPckg<TUint32>*)aPckg2; |
|
167 TUint32& indicatorIndCaps=(*indicatorIndCapsPckg)(); |
|
168 |
|
169 indicatorActionCaps= RMobilePhone::KCapsGetIndicator | RMobilePhone::KCapsNotifyIndicatorChange; |
|
170 indicatorIndCaps= RMobilePhone::KIndChargerConnected | RMobilePhone::KIndNetworkAvailable | RMobilePhone::KIndCallInProgress; |
|
171 |
|
172 iPhone->ReqCompleted(aReqHandle,KErrNone); |
|
173 return KErrNone; |
|
174 } |
|
175 |
|
176 |
|
177 TInt CSimIndicator::GetIndicator(TTsyReqHandle aReqHandle,TDes8* aPckg1) |
|
178 /** |
|
179 * Return the current indicators information. This function completes synchronously. |
|
180 * If the configuration file contains any indicators profile information, the |
|
181 * request completes successfully, otherwise it completes with KErrNotSupported. |
|
182 * |
|
183 * @param aReqHandle The request handle associated with this request. |
|
184 * @param aPckg1 This is populated with the Indicators flags. |
|
185 * @return TInt Standard error value. |
|
186 */ |
|
187 { |
|
188 LOGPHONE2("CSimIndicator::GetIndicator request made: returning %d",iCurrentIndicator); |
|
189 TPckg<TUint32>* indicPckg=(TPckg<TUint32>*)aPckg1; |
|
190 TUint32& indic=(*indicPckg)(); |
|
191 |
|
192 indic=iCurrentIndicator; |
|
193 iPhone->ReqCompleted(aReqHandle,KErrNone); |
|
194 return KErrNone; |
|
195 } |
|
196 |
|
197 TInt CSimIndicator::NotifyIndicatorChange(TTsyReqHandle aReqHandle,TDes8* aPckg1) |
|
198 /** |
|
199 * Register a client's interest in being notified when the Indicators change. |
|
200 * This function records the request's parameters and awaits a change in |
|
201 * indicators before completing. |
|
202 * |
|
203 * @param aPckg1 The first parameter package. This is populated with the Indicators flags. |
|
204 * @return TInt Standard error value. |
|
205 */ |
|
206 { |
|
207 LOGPHONE1("CSimIndicator::NotifyIndicatorChange notification posted"); |
|
208 TPckg<TUint32>* indicPckg=(TPckg<TUint32>*)aPckg1; |
|
209 TUint32& indic=(*indicPckg)(); |
|
210 |
|
211 __ASSERT_ALWAYS(!iIndicatorsChangeNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding)); |
|
212 iIndicatorsChangeNotificationPending=ETrue; |
|
213 iIndicatorsChangeNotificationReqHandle=aReqHandle; |
|
214 iIndicatorsChangeNofificationValue=&indic; |
|
215 if (!(iTimer->Running())) |
|
216 iTimer->Start(iIndicatorCheckPeriod, this); |
|
217 return KErrNone; |
|
218 } |
|
219 |
|
220 void CSimIndicator::NotifyIndicatorChangeCancel() |
|
221 /** |
|
222 * Cancel a previous request to be notified of a change in indicators. |
|
223 */ |
|
224 { |
|
225 if(iIndicatorsChangeNotificationPending) |
|
226 { |
|
227 LOGPHONE1("CSimIndicator::NotifyIndicatorChange notification cancelled"); |
|
228 iIndicatorsChangeNotificationPending=EFalse; |
|
229 iPhone->ReqCompleted(iIndicatorsChangeNotificationReqHandle,KErrCancel); |
|
230 } |
|
231 } |
|
232 |
|
233 |
|
234 void CSimIndicator::CheckNotification() |
|
235 /** |
|
236 * The timer callback function. This function will be called when the timer |
|
237 * completes. It indicates a change in indicators. So, the new |
|
238 * indicators settings must be loaded into the member variables representing |
|
239 * the current settings and any pending indicators notification requests must |
|
240 * be completed. Finally, the next timer is started. |
|
241 * |
|
242 * @param aId This parameter is unused. It is only required for CSimXxx classes |
|
243 * that have more than one timer instance and need to identify which |
|
244 * timer has expired. |
|
245 */ |
|
246 { |
|
247 TUint32 newIndicator=IndicatorState(); |
|
248 if(newIndicator!=iCurrentIndicator) |
|
249 { |
|
250 iCurrentIndicator=newIndicator; |
|
251 if(iIndicatorsChangeNotificationPending) |
|
252 { |
|
253 // First see if this notification should be completed with an error... |
|
254 ++iNotificationNumber; |
|
255 TInt ret=KErrNone; |
|
256 for(TInt i=0;i<iIndicatorsInfo->Count();i++) |
|
257 { |
|
258 if (iIndicatorsInfo->At(i).iNotificationNumber==iNotificationNumber) |
|
259 ret=iIndicatorsInfo->At(i).iError; |
|
260 } |
|
261 |
|
262 // Trigger notification with appropriate data and result codes |
|
263 iIndicatorsChangeNotificationPending=EFalse; |
|
264 *iIndicatorsChangeNofificationValue=iCurrentIndicator; |
|
265 LOGPHONE2("CSimIndicator::NotifyIndicatorChange triggered: returned %d",iCurrentIndicator); |
|
266 iPhone->ReqCompleted(iIndicatorsChangeNotificationReqHandle,ret); |
|
267 } |
|
268 } |
|
269 } |
|
270 |
|
271 TUint32 CSimIndicator::IndicatorState() |
|
272 /** |
|
273 * Construct and return the current value for the indicator. |
|
274 * |
|
275 * @return TUint32 Current indicator value. |
|
276 */ |
|
277 { |
|
278 TUint indicator=0; |
|
279 |
|
280 RMobilePhone::TMobilePhoneBatteryStatus state = iPhone->BatteryStatus(); |
|
281 |
|
282 if (state == RMobilePhone::EBatteryConnectedButExternallyPowered) |
|
283 indicator |= RMobilePhone::KIndChargerConnected; |
|
284 |
|
285 RPhone::TMode mode = iPhone->Mode(); |
|
286 |
|
287 if((mode == RPhone::EModeEstablishingLink) || (mode == RPhone::EModeOnlineData) || |
|
288 (mode == RPhone::EModeOnlineCommand)) |
|
289 indicator |= RMobilePhone::KIndCallInProgress; |
|
290 |
|
291 RMobilePhone::TMobilePhoneRegistrationStatus nkStatus = iPhone->RegistrationStatus(); |
|
292 if ((nkStatus == RMobilePhone::ERegisteredOnHomeNetwork) || |
|
293 (nkStatus == RMobilePhone::ERegisteredRoaming) || |
|
294 (nkStatus == RMobilePhone::ERegisteredBusy)) |
|
295 indicator |= RMobilePhone::KIndNetworkAvailable; |
|
296 |
|
297 return indicator; |
|
298 } |
|
299 |
|
300 const CTestConfigSection* CSimIndicator::CfgFile() |
|
301 /** |
|
302 * Returns a pointer to the current configuration file section. |
|
303 * |
|
304 * @return CTestConfigSection A pointer to the current configuration file section. |
|
305 */ |
|
306 { |
|
307 return iPhone->CfgFile(); |
|
308 } |
|
309 |
|
310 void CSimIndicator::TimerCallBack(TInt /*aId*/) |
|
311 { |
|
312 CheckNotification(); |
|
313 } |