|
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 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 */ |
|
19 |
|
20 #include "csimsmsmess.h" |
|
21 #include <testconfigfileparser.h> |
|
22 #include "Simlog.h" |
|
23 #include <etelmm.h> |
|
24 #include "CSimTsyMode.h" |
|
25 |
|
26 //macro |
|
27 #define UNPACK_PCKG(target,source,datatype) datatype& target= (*(TPckg<datatype>*)(source))() |
|
28 |
|
29 const TInt KSmsSettingGranularity=5; // < Granularity of SMS parameter list arrays. |
|
30 const TInt KSmsStoreGranularity=2; // < Granularity of SMS store list array. |
|
31 const TInt KNoMessageReferenceInCofigurationFile=0;//the reference number returned to the client is 0 if |
|
32 //no value is found in the configuration file |
|
33 |
|
34 // |
|
35 // CSimSmsMessaging |
|
36 // |
|
37 |
|
38 void CSimSmsMessaging::CloseSmsObj(TAny* aObj) |
|
39 /** |
|
40 * A utility function for cleaning up the stack. |
|
41 */ |
|
42 { |
|
43 ((CObject*)aObj)->Close(); |
|
44 } |
|
45 |
|
46 CSimSmsMessaging* CSimSmsMessaging::NewL(CSimPhone* aPhone) |
|
47 /** |
|
48 * Standard two phase constructor. |
|
49 */ |
|
50 { |
|
51 CSimSmsMessaging* smsMess=new(ELeave) CSimSmsMessaging(aPhone); |
|
52 TCleanupItem newObjClose(CloseSmsObj,smsMess); |
|
53 CleanupStack::PushL(newObjClose); |
|
54 smsMess->ConstructL(); |
|
55 CleanupStack::Pop(); |
|
56 return smsMess; |
|
57 } |
|
58 |
|
59 CSimSmsMessaging::CSimSmsMessaging(CSimPhone* aPhone) |
|
60 : iPhone(aPhone), iSmspBusy(EFalse) |
|
61 {} |
|
62 |
|
63 void CSimSmsMessaging::ConstructL() |
|
64 /** |
|
65 * Retrieve the SMS-related tags from the configuration file. |
|
66 * |
|
67 * |
|
68 * If there are no constraints any SMS specified in the configuration file and the "incoming SMS event" timer will |
|
69 * be started. |
|
70 */ |
|
71 { |
|
72 LOGSMS1("Starting to Load and Parse Sms Messaging Config "); |
|
73 iRxTimer=CSimTimer::NewL(iPhone); |
|
74 iTxTimer=CSimTimer::NewL(iPhone); |
|
75 iSmspTimer=CSimTimer::NewL(iPhone); |
|
76 |
|
77 iSmsRxParameterListGsm=new(ELeave) CArrayFixFlat<TSmsRxParametersGsm>(KSmsSettingGranularity); |
|
78 |
|
79 |
|
80 FindAndCreateRxAttributesL(); |
|
81 |
|
82 iSmsTxParametersListGsm=new(ELeave) CArrayFixFlat<TSmsTxParametersGsm>(KSmsSettingGranularity); |
|
83 |
|
84 FindAndCreateTxAttributesL(); |
|
85 iSmsStores=new(ELeave) CArrayFixFlat<CSimSmsStore*>(KSmsStoreGranularity); |
|
86 FindAndCreateSmsStoresL(iPhone); |
|
87 FindAndCreateConstraints(); |
|
88 iSmspReadAll=new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(KSmsStoreGranularity); |
|
89 FindAndCreateSmsParamsL(); |
|
90 |
|
91 // NOTE - no need to start iRxTimer; this will be started once a EMobileSmsMessagingReceiveMessage |
|
92 // request is received and/or Send Sms contrainst satisfied (see CompleteTxPendingReq) |
|
93 |
|
94 LOGSMS1("Finished parsing SMS Messaging config parameters"); |
|
95 } |
|
96 |
|
97 |
|
98 CSimSmsMessaging::~CSimSmsMessaging() |
|
99 /** |
|
100 * Standard destructor. Any objects created by the ::ConstructL() function should be destroyed here. |
|
101 */ |
|
102 { |
|
103 if(iSmsRxParameterListGsm) |
|
104 { |
|
105 iSmsRxParameterListGsm->Delete(0,iSmsRxParameterListGsm->Count()); |
|
106 delete iSmsRxParameterListGsm; |
|
107 } |
|
108 |
|
109 if(iSmsTxParametersListGsm) |
|
110 { |
|
111 iSmsTxParametersListGsm->Delete(0,iSmsTxParametersListGsm->Count()); |
|
112 delete iSmsTxParametersListGsm; |
|
113 } |
|
114 |
|
115 delete iSmspEntries; |
|
116 |
|
117 if (iSmsStores) |
|
118 { |
|
119 TInt storeCount=iSmsStores->Count(); |
|
120 for(TInt i=0;i<storeCount;i++) |
|
121 { |
|
122 iSmsStores->At(i)->Close(); |
|
123 } |
|
124 delete iSmsStores; |
|
125 } |
|
126 |
|
127 if (iSmspReadAll) |
|
128 { |
|
129 iSmspReadAll->ResetAndDestroy(); |
|
130 delete iSmspReadAll; |
|
131 } |
|
132 |
|
133 iConstraints.Close(); |
|
134 if(iRxTimer) |
|
135 delete iRxTimer; |
|
136 if(iTxTimer) |
|
137 delete iTxTimer; |
|
138 if(iSmspTimer) |
|
139 delete iSmspTimer; |
|
140 } |
|
141 |
|
142 void CSimSmsMessaging::FindAndCreateRxAttributesL() |
|
143 /** |
|
144 * Extract values from the tags |
|
145 * SmsRx, SmsRxPeriod, SmsAckNackPause, SmsResumePause, SmsDeliveryReport |
|
146 * |
|
147 */ { |
|
148 TInt ret=KErrNone; |
|
149 TInt count=CfgFileSection()->ItemCount(KSmsRx); |
|
150 const CTestConfigItem* item=NULL; |
|
151 TInt i; |
|
152 TSmsRxParametersGsm smsRxParameterGsm; |
|
153 |
|
154 LOGSMS2("CSimSmsMessaging::FindAndCreateRxAttributesL IN [count=%d]", count); |
|
155 |
|
156 // Need to do this *before* entering the loop (so that we know |
|
157 // whether or not to read a delivery report pdu off the config file). |
|
158 iSmsControlCaps=RMobileSmsMessaging::TMobileSmsControlCaps(CfgFileSection()->ItemValue(KSmsControlCaps,KDefaultSmsControlCaps)); |
|
159 |
|
160 for(i=0;i<count;i++) |
|
161 { |
|
162 item=CfgFileSection()->Item(KSmsRx,i); |
|
163 if(!item) |
|
164 break; |
|
165 |
|
166 TPtrC8 smsPdu,sca; |
|
167 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,smsPdu); |
|
168 if(ret!=KErrNone) |
|
169 { |
|
170 LOGPARSERR("smsPdu",ret,0,&KSmsRx); |
|
171 continue; |
|
172 } |
|
173 else |
|
174 { |
|
175 smsRxParameterGsm.iPdu.Zero(); |
|
176 ConvertAsciiSms(smsPdu,smsRxParameterGsm.iPdu); |
|
177 } |
|
178 |
|
179 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,sca); |
|
180 if(ret!=KErrNone) |
|
181 { |
|
182 LOGPARSERR("sca",ret,1,&KSmsRx); |
|
183 continue; |
|
184 } |
|
185 else |
|
186 { |
|
187 smsRxParameterGsm.iSca=sca; |
|
188 } |
|
189 |
|
190 //get delivery report pdu |
|
191 smsRxParameterGsm.iDeliveryReport.Zero(); |
|
192 if (!(iSmsControlCaps & RMobileSmsMessaging::KCapsReceiveUnstoredClientAck)) |
|
193 { |
|
194 TPtrC8 deliveryReportPdu; |
|
195 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,deliveryReportPdu); |
|
196 if( (ret!=KErrNone) && (ret!=KErrGeneral) ) |
|
197 { |
|
198 LOGPARSERR("deliveryReportPdu",ret,2,&KSmsRx); |
|
199 } |
|
200 else |
|
201 { |
|
202 if (CSimTsyMode::GetMode() != CSimTsyMode::ECdmaV1) |
|
203 { |
|
204 ConvertAsciiSms(deliveryReportPdu,smsRxParameterGsm.iDeliveryReport); |
|
205 } |
|
206 |
|
207 } |
|
208 } |
|
209 |
|
210 // add to list of params |
|
211 iSmsRxParameterListGsm->AppendL(smsRxParameterGsm); |
|
212 |
|
213 }// for |
|
214 |
|
215 iSmsRxPeriod=CfgFileSection()->ItemValue(KSmsRxPeriod,KDefaultSmsRxPeriod); |
|
216 iAckNackCompletePause=CfgFileSection()->ItemValue(KSmsAckNackPause,KDefaultSmsAckNackPause); |
|
217 iResumeCompletePause=CfgFileSection()->ItemValue(KSmsResumePause,KDefaultSmsResumePause); |
|
218 |
|
219 if (iSmsControlCaps & RMobileSmsMessaging::KCapsReceiveUnstoredClientAck) |
|
220 iSmsReceiveMode=RMobileSmsMessaging::EReceiveUnstoredClientAck; |
|
221 else iSmsReceiveMode=RMobileSmsMessaging::EReceiveModeUnspecified; |
|
222 LOGSMS5("iSmsRxPeriod =%d, iAckNackCompletePause=%d, iResumeCompletePause=%d, iSmsControlCaps=%d",iSmsRxPeriod, iAckNackCompletePause, iResumeCompletePause, iSmsControlCaps); |
|
223 LOGSMS4("iSmsModeCaps =%d, iSmsRxStartDelay = %d, iSmsReceiveMode = %d",iSmsModeCaps , iSmsRxStartDelay, iSmsReceiveMode); |
|
224 LOGSMS2("CSimSmsMessaging::FindAndCreateRxAttributesL OUT [count=%d]", iSmsRxParameterListGsm->Count()); |
|
225 } |
|
226 |
|
227 void CSimSmsMessaging::FindAndCreateTxAttributesL() |
|
228 /** |
|
229 * Extract values from the tags |
|
230 * SmsTx, SmsTxPause |
|
231 * |
|
232 */ |
|
233 { |
|
234 TInt ret=KErrNone; |
|
235 TInt count=CfgFileSection()->ItemCount(KSmsTx); |
|
236 |
|
237 TSmsTxParametersGsm smsTxParametersGsm; |
|
238 |
|
239 const CTestConfigItem* item=NULL; |
|
240 for(TInt i=0;i<count;i++) |
|
241 { |
|
242 item=CfgFileSection()->Item(KSmsTx,i);//Tx |
|
243 if(!item) |
|
244 break; |
|
245 |
|
246 //get pdu |
|
247 TPtrC8 smsTx; |
|
248 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,smsTx); |
|
249 if(ret!=KErrNone) |
|
250 { |
|
251 LOGPARSERR("smsTx",ret,0,&KSmsTx); |
|
252 continue; |
|
253 } |
|
254 else |
|
255 { |
|
256 smsTxParametersGsm.iPdu.Zero(); |
|
257 ConvertAsciiSms(smsTx,smsTxParametersGsm.iPdu); |
|
258 } |
|
259 |
|
260 //get Sca |
|
261 TPtrC8 sca; |
|
262 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,sca); |
|
263 if (ret!=KErrNone) |
|
264 { |
|
265 LOGPARSERR("sca",ret,1,&KSmsTx); |
|
266 continue; |
|
267 } |
|
268 else |
|
269 { |
|
270 smsTxParametersGsm.iSca.Copy(sca); |
|
271 } |
|
272 |
|
273 //get reference |
|
274 TInt reference; |
|
275 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,reference); |
|
276 if(ret!=KErrNone) |
|
277 { |
|
278 LOGPARSERR("reference",ret,2,&KSmsTx); |
|
279 smsTxParametersGsm.iRef=KNoMessageReferenceInCofigurationFile; |
|
280 } |
|
281 else |
|
282 { |
|
283 smsTxParametersGsm.iRef=reference; |
|
284 } |
|
285 |
|
286 //get submit report pdu |
|
287 TPtrC8 submitReportPdu; |
|
288 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,submitReportPdu); |
|
289 if(ret!=KErrNone) |
|
290 { |
|
291 LOGPARSERR("submitReportPdu",ret,3,&KSmsTx); |
|
292 continue; |
|
293 } |
|
294 else |
|
295 { |
|
296 smsTxParametersGsm.iSubmitReport.Zero(); |
|
297 ConvertAsciiSms(submitReportPdu,smsTxParametersGsm.iSubmitReport); |
|
298 } |
|
299 |
|
300 //get expected error code |
|
301 TInt errorCode; |
|
302 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,errorCode); |
|
303 if(ret!=KErrNone) |
|
304 { |
|
305 LOGPARSERR("errorCode",ret,4,&KSmsTx); |
|
306 continue; |
|
307 } |
|
308 else |
|
309 { |
|
310 smsTxParametersGsm.iExpectedError=errorCode; |
|
311 } |
|
312 |
|
313 iSmsTxParametersListGsm->AppendL(smsTxParametersGsm); |
|
314 |
|
315 } //end for SmsTx Tag |
|
316 |
|
317 iSmsTxPause=CfgFileSection()->ItemValue(KSmsTxPause,KDefaultSmsTxPause); |
|
318 } |
|
319 |
|
320 void CSimSmsMessaging::FindAndCreateConstraints() |
|
321 /** |
|
322 * Extract values from the tags |
|
323 * SmsStartRxDelay |
|
324 * |
|
325 */ |
|
326 { |
|
327 TInt ret=KErrNone; |
|
328 TInt count=CfgFileSection()->ItemCount(KSmsStartRxDelay); |
|
329 const CTestConfigItem* item=NULL; |
|
330 TConstraintEntry constraint; |
|
331 for(TInt i=0;i<count;i++)//Rx delay |
|
332 { |
|
333 item=CfgFileSection()->Item(KSmsStartRxDelay,i); |
|
334 if(!item) |
|
335 break; |
|
336 |
|
337 TInt ipc,noBefore,noAfter; |
|
338 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,ipc);//only :SendMessage() is supported |
|
339 if(ret!=KErrNone || ipc!=4207) |
|
340 { |
|
341 LOGPARSERR("ipc",ret,0,&KSmsStartRxDelay); |
|
342 continue; |
|
343 } |
|
344 |
|
345 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,noBefore); |
|
346 if(ret==KErrNone) |
|
347 constraint.iIpcCnt=noBefore; |
|
348 else |
|
349 { |
|
350 LOGPARSERR("noBefore",ret,1,&KSmsStartRxDelay); |
|
351 continue; |
|
352 } |
|
353 |
|
354 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,noAfter); |
|
355 if(ret==KErrNone) |
|
356 constraint.iRxCnt=noAfter; |
|
357 else |
|
358 { |
|
359 LOGPARSERR("noAfter",ret,2,&KSmsStartRxDelay); |
|
360 continue; |
|
361 } |
|
362 |
|
363 __ASSERT_ALWAYS(iConstraints.Append(constraint) == KErrNone,SimPanic(EGeneral)); |
|
364 } |
|
365 } |
|
366 |
|
367 void CSimSmsMessaging::FindAndCreateSmsStoresL(CSimPhone* aPhone) |
|
368 /** |
|
369 * Creates sms stores as defined in the comfiguation files |
|
370 * Extract values from the tags |
|
371 * SmsStore, SmsStoreEntry, SmsStoreIndividualReqPause, SmsStoreBatchReqPause |
|
372 */ |
|
373 { |
|
374 TInt count=CfgFileSection()->ItemCount(KSmsStore); |
|
375 const CTestConfigItem* item=NULL; |
|
376 TInt ret=KErrNone; |
|
377 |
|
378 for(TInt i=0;i<count;i++) |
|
379 { |
|
380 item=CfgFileSection()->Item(KSmsStore,i); |
|
381 if(!item) |
|
382 break; |
|
383 |
|
384 TPtrC8 storeName; |
|
385 TInt maxNumSlots; |
|
386 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,storeName); |
|
387 if(ret!=KErrNone) |
|
388 { |
|
389 LOGPARSERR("storeName",ret,0,&KSmsStore); |
|
390 continue; |
|
391 } |
|
392 |
|
393 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,maxNumSlots); |
|
394 if(ret!=KErrNone) |
|
395 { |
|
396 LOGPARSERR("maxNumSlots",ret,1,&KSmsStore); |
|
397 continue; |
|
398 } |
|
399 |
|
400 CSimSmsStore* smsStore=CSimSmsStore::NewL(this,storeName,maxNumSlots,aPhone); |
|
401 TCleanupItem newObjClose(CloseSmsObj,smsStore); |
|
402 CleanupStack::PushL(newObjClose); |
|
403 iSmsStores->AppendL(smsStore); |
|
404 CleanupStack::Pop(); |
|
405 } |
|
406 |
|
407 for(TInt j=0;j<iSmsStores->Count();j++) |
|
408 { |
|
409 iSmsStores->At(j)->PopulateStoreFromConfigFile(); |
|
410 } |
|
411 } |
|
412 |
|
413 void CSimSmsMessaging::FindAndCreateSmsParamsL() |
|
414 /** |
|
415 *Populates the sms parameter List as defined in the configuration file |
|
416 *Extract values from the tags |
|
417 *SmsParamEntry, SmsParamEntry, SmsParamBatchReqPause, SmsParamMaxNumSlots |
|
418 */ |
|
419 { |
|
420 iSmspEntries= CMobilePhoneSmspList::NewL(); |
|
421 |
|
422 const TInt maxSlots = CfgFileSection()->ItemValue(KSmspMaxNumSlots ,KDefaultSmspMaxNumSlots); |
|
423 iSmspEntries->SetMaxNumberEntries(maxSlots); |
|
424 |
|
425 iSmspBatchPause = CfgFileSection()->ItemValue(KSmspBatchReqPause,KDefaultSmspBatchReqPause); |
|
426 |
|
427 const TInt numberOfSmspEntries = Min(CfgFileSection()->ItemCount(KSmsParamEntry), maxSlots); |
|
428 const CTestConfigItem* item=NULL; |
|
429 TInt ret=KErrNone; |
|
430 |
|
431 for(TInt i=0;i < numberOfSmspEntries;i++) |
|
432 { |
|
433 item=CfgFileSection()->Item(KSmsParamEntry,i); |
|
434 |
|
435 if(!item) |
|
436 break; |
|
437 |
|
438 RMobileSmsMessaging::TMobileSmspEntryV1 entry = RMobileSmsMessaging::TMobileSmspEntryV1(); |
|
439 |
|
440 TInt index, pid, dcs, validityPeriod; |
|
441 TPtrC8 destAddress, sca, smspName; |
|
442 |
|
443 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,index); |
|
444 if((ret==KErrNone)&&(index < maxSlots)) |
|
445 entry.iIndex=index; |
|
446 else |
|
447 { |
|
448 LOGPARSERR("index",ret,0,&KSmsParamEntry); |
|
449 continue; |
|
450 } |
|
451 |
|
452 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,smspName); |
|
453 if(ret==KErrNone) |
|
454 entry.iText.Copy(smspName); |
|
455 else |
|
456 { |
|
457 LOGPARSERR("smspName",ret,1,&KSmsParamEntry); |
|
458 continue; |
|
459 } |
|
460 |
|
461 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,pid); |
|
462 if(ret==KErrNone) |
|
463 { |
|
464 entry.iProtocolId=TUint8(pid); |
|
465 entry.iValidParams |= RMobileSmsMessaging::KProtocolIdIncluded; |
|
466 } |
|
467 else |
|
468 { |
|
469 LOGPARSERR("pid",ret,2,&KSmsParamEntry); |
|
470 continue; |
|
471 } |
|
472 |
|
473 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,dcs); |
|
474 if(ret==KErrNone) |
|
475 { |
|
476 entry.iDcs=TUint8(dcs); |
|
477 entry.iValidParams |= RMobileSmsMessaging::KDcsIncluded; |
|
478 } |
|
479 else |
|
480 { |
|
481 LOGPARSERR("dcs",ret,3,&KSmsParamEntry); |
|
482 continue; |
|
483 } |
|
484 |
|
485 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,validityPeriod); |
|
486 if(ret==KErrNone) |
|
487 { |
|
488 entry.iValidityPeriod=TUint8(validityPeriod); |
|
489 entry.iValidParams |= RMobileSmsMessaging::KValidityPeriodIncluded; |
|
490 } |
|
491 else |
|
492 { |
|
493 LOGPARSERR("validityPeriod",ret,4,&KSmsParamEntry); |
|
494 continue; |
|
495 } |
|
496 |
|
497 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,5,destAddress); |
|
498 if(ret==KErrNone) |
|
499 { |
|
500 RecordDestination(destAddress, entry); |
|
501 } |
|
502 else |
|
503 { |
|
504 LOGPARSERR("destAddress",ret,5,&KSmsParamEntry); |
|
505 continue; |
|
506 } |
|
507 |
|
508 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,6,sca); |
|
509 if(ret==KErrNone) |
|
510 { |
|
511 RecordSca(sca, entry); |
|
512 } |
|
513 else |
|
514 { |
|
515 LOGPARSERR("sca",ret,6,&KSmsParamEntry); |
|
516 continue; |
|
517 } |
|
518 |
|
519 iSmspEntries->AddEntryL(entry); |
|
520 } |
|
521 } |
|
522 |
|
523 void CSimSmsMessaging::RecordSca(const TDesC8& aAsciiAddr, RMobileSmsMessaging::TMobileSmspEntryV1& aEntry) |
|
524 /** |
|
525 * Used to set the sca number in the smsp |
|
526 * |
|
527 * @param aAsciiSca Ascii representation of a telephone number such as the one found in the configuration file |
|
528 * @param aEntry reference to the actual smspentry in which the sca is going to be recorded |
|
529 */ |
|
530 { |
|
531 if(aAsciiAddr.Length()>0)//only support for international numbers |
|
532 { |
|
533 aEntry.iServiceCentre.iNumberPlan=RMobilePhone::EIsdnNumberPlan; |
|
534 aEntry.iServiceCentre.iTypeOfNumber=RMobilePhone::EInternationalNumber; |
|
535 aEntry.iServiceCentre.iTelNumber.Copy(aAsciiAddr); |
|
536 aEntry.iValidParams |= RMobileSmsMessaging::KSCAIncluded; |
|
537 } |
|
538 } |
|
539 |
|
540 void CSimSmsMessaging::RecordDestination(const TDesC8& aAsciiAddr, RMobileSmsMessaging::TMobileSmspEntryV1& aEntry) |
|
541 /** |
|
542 * Used to set the destination number in the smsp |
|
543 * |
|
544 * @param aAsciiAddr Ascii representation of a telephone number such as the one found in the configuration file |
|
545 * @param aEntry reference to the actual smspentry in which the destination is going to be recorded |
|
546 */ |
|
547 { |
|
548 if(aAsciiAddr.Length()>0)//only support for international numbers |
|
549 { |
|
550 aEntry.iDestination.iNumberPlan=RMobilePhone::EIsdnNumberPlan; |
|
551 aEntry.iDestination.iTypeOfNumber=RMobilePhone::EInternationalNumber; |
|
552 aEntry.iDestination.iTelNumber.Copy(aAsciiAddr); |
|
553 aEntry.iValidParams |= RMobileSmsMessaging::KDestinationIncluded; |
|
554 } |
|
555 } |
|
556 |
|
557 #ifdef _DEBUG // to stop the UREL build warnings |
|
558 void CSimSmsMessaging::LogRequest(const TBool aEntering, TInt aIpc, TInt aError) |
|
559 #else |
|
560 void CSimSmsMessaging::LogRequest(const TBool aEntering, TInt aIpc, TInt /*aError*/) |
|
561 #endif |
|
562 /** |
|
563 * This method logs client requests to the t_reg.txt |
|
564 * @param aDirection Tells if the request is coming into simtsy tsy or completing |
|
565 * @param aIpc IPC number of request |
|
566 * @param aError Error code that the request has |
|
567 */ |
|
568 { |
|
569 TBuf8<64> ipcBuf; |
|
570 |
|
571 switch (aIpc) |
|
572 { |
|
573 case EEtelServerLoadPhoneModule: |
|
574 ipcBuf = _L8("ServerLoadPhoneModule"); |
|
575 break; |
|
576 |
|
577 case EEtelPhoneGetStatus: |
|
578 ipcBuf = _L8("PhoneGetStatus"); |
|
579 break; |
|
580 |
|
581 case EEtelPhoneNotifyModemDetected: |
|
582 ipcBuf = _L8("PhoneNotifyModemDetected"); |
|
583 break; |
|
584 case EEtelPhoneInitialise: |
|
585 ipcBuf = _L8("PhoneInitialise"); |
|
586 break; |
|
587 case EMobileSmsMessagingGetCaps: |
|
588 ipcBuf = _L8("GetCaps"); |
|
589 break; |
|
590 case EMobileSmsMessagingGetReceiveMode: |
|
591 ipcBuf = _L8("GetReceiveMode"); |
|
592 break; |
|
593 case EMobileSmsMessagingGetMoSmsBearer: |
|
594 ipcBuf = _L8("GetMoSmsBearer"); |
|
595 break; |
|
596 case EMobileSmsMessagingEnumerateMessageStores: |
|
597 ipcBuf = _L8("EnumerateMessageStores"); |
|
598 break; |
|
599 case EMobileSmsMessagingGetMessageStoreInfo: |
|
600 ipcBuf = _L8("GetMessageStoreInfo"); |
|
601 break; |
|
602 case EMobileSmsMessagingGetSmspListPhase2: |
|
603 ipcBuf = _L8("GetSmspListPhase2"); |
|
604 break; |
|
605 case EMobileSmsMessagingSetReceiveMode: |
|
606 ipcBuf = _L8("SetReceiveMode"); |
|
607 break; |
|
608 case EMobileSmsMessagingSetMoSmsBearer: |
|
609 ipcBuf = _L8("SetMoSmsBearer"); |
|
610 break; |
|
611 case EMobileSmsMessagingAckSmsStored: |
|
612 ipcBuf = _L8("AckSmsStored"); |
|
613 break; |
|
614 case EMobileSmsMessagingNackSmsStored: |
|
615 ipcBuf = _L8("NackSmsStored"); |
|
616 break; |
|
617 case EMobileSmsMessagingResumeSmsReception: |
|
618 ipcBuf = _L8("ResumeSmsReception"); |
|
619 break; |
|
620 case EMobileSmsMessagingSendMessage: |
|
621 ipcBuf = _L8("SendMessage"); |
|
622 break; |
|
623 case EMobileSmsMessagingGetSmspListPhase1: |
|
624 ipcBuf = _L8("GetSmspListPhase1"); |
|
625 break; |
|
626 case EMobileSmsMessagingStoreSmspList: |
|
627 ipcBuf = _L8("StoreSmspList"); |
|
628 break; |
|
629 case EMobileSmsMessagingReceiveMessage: |
|
630 ipcBuf = _L8("ReceiveMessage"); |
|
631 break; |
|
632 case EMobileSmsMessagingNotifyReceiveModeChange: |
|
633 ipcBuf = _L8("NotifyReceiveModeChange"); |
|
634 break; |
|
635 case EMobileSmsMessagingNotifyMoSmsBearerChange: |
|
636 ipcBuf = _L8("NotifyMoSmsBearerChange"); |
|
637 break; |
|
638 case EMobileSmsMessagingNotifySmspListChange: |
|
639 ipcBuf = _L8("NotifySmspListChange"); |
|
640 break; |
|
641 case EMobileSmsMessagingSetReceiveModeCancel: |
|
642 ipcBuf = _L8("SetReceiveModeCancel"); |
|
643 break; |
|
644 case EMobileSmsMessagingNotifyReceiveModeChangeCancel: |
|
645 ipcBuf = _L8("NotifyReceiveModeChangeCancel"); |
|
646 break; |
|
647 case EMobileSmsMessagingSetMoSmsBearerCancel: |
|
648 ipcBuf = _L8("SetMoSmsBearerCancel"); |
|
649 break; |
|
650 case EMobileSmsMessagingNotifyMoSmsBearerChangeCancel: |
|
651 ipcBuf = _L8("NotifyMoSmsBearerChangeCancel"); |
|
652 break; |
|
653 case EMobileSmsMessagingAckSmsStoredCancel: |
|
654 ipcBuf = _L8("AckSmsStoredCancel"); |
|
655 break; |
|
656 case EMobileSmsMessagingNackSmsStoredCancel: |
|
657 ipcBuf = _L8("NackSmsStoredCancel"); |
|
658 break; |
|
659 case EMobileSmsMessagingResumeSmsReceptionCancel: |
|
660 ipcBuf = _L8("ResumeSmsReceptionCancel"); |
|
661 break; |
|
662 case EMobileSmsMessagingSendMessageCancel: |
|
663 ipcBuf = _L8("SendMessageCancel"); |
|
664 break; |
|
665 case EMobileSmsMessagingReceiveMessageCancel: |
|
666 ipcBuf = _L8("ReceiveMessageCancel"); |
|
667 break; |
|
668 case EMobileSmsMessagingGetMessageStoreInfoCancel: |
|
669 ipcBuf = _L8("GetMessageStoreInfoCancel"); |
|
670 break; |
|
671 case EMobileSmsMessagingGetSmspListCancel: |
|
672 ipcBuf = _L8("GetSmspListCancel"); |
|
673 break; |
|
674 case EMobileSmsMessagingStoreSmspListCancel: |
|
675 ipcBuf = _L8("StoreSmspListCancel"); |
|
676 break; |
|
677 case EMobileSmsMessagingNotifySmspListChangeCancel: |
|
678 ipcBuf = _L8("NotifySmspListChangeCancel"); |
|
679 break; |
|
680 default: |
|
681 ipcBuf = _L8("OTHER"); |
|
682 break; |
|
683 } |
|
684 |
|
685 if (aEntering!=EFalse) |
|
686 { |
|
687 LOGSMS3(">>%d,CSimSmsMessaging::%S",aIpc, &ipcBuf ); |
|
688 } |
|
689 else |
|
690 { |
|
691 LOGSMS4("<<%d, CSimSmsMessaging::%S with error %d",aIpc, &ipcBuf, aError); |
|
692 } |
|
693 } |
|
694 |
|
695 |
|
696 TInt CSimSmsMessaging::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg) |
|
697 /** |
|
698 * Sms Read/Send Dispatch Function. |
|
699 * |
|
700 * If this method returns with an KErr code apart from KErrNone then Etel will |
|
701 * complete and destory the clients request for us. |
|
702 * |
|
703 * @param aTsyReqHandle The handle of the request which started the IPC |
|
704 * @param aIpc The IPC being requested |
|
705 * @param aPackage Package of parameters associated with the IPC |
|
706 * @return Standard KErr... codes |
|
707 */ { |
|
708 TInt ret=KErrNone;//error is only used with LogRequest when at the end of ExtFunc |
|
709 LogRequest(ETrue, aIpc, ret); |
|
710 |
|
711 switch(aIpc) |
|
712 { |
|
713 case EMobileSmsMessagingReceiveMessage://4211 |
|
714 { |
|
715 TRAPD(leaveCode, ret = ReceiveMessageL(aReqHandle,aPckg.Des1n(),aPckg.Des2n())); |
|
716 if (leaveCode != KErrNone) |
|
717 { |
|
718 ret = leaveCode; |
|
719 } |
|
720 } |
|
721 break; |
|
722 |
|
723 case EMobileSmsMessagingGetCaps: |
|
724 ret = GetCaps(aReqHandle,aPckg.Des1n()); |
|
725 break; |
|
726 |
|
727 case EMobileSmsMessagingEnumerateMessageStores: |
|
728 ret = EnumerateMessagingStores(aReqHandle,aPckg.Des1n()); |
|
729 break; |
|
730 |
|
731 case EMobileSmsMessagingGetMessageStoreInfo: |
|
732 ret = GetMessageStoreInfo(aReqHandle,aPckg.Des1n(),aPckg.Des2n()); |
|
733 break; |
|
734 |
|
735 case EMobileSmsMessagingGetReceiveMode: |
|
736 ret = GetReceiveMode(aReqHandle,aPckg.Des1n()); |
|
737 break; |
|
738 |
|
739 case EMobileSmsMessagingSetReceiveMode: |
|
740 ret = SetReceiveMode(aReqHandle,aPckg.Des1n());//4202 |
|
741 break; |
|
742 |
|
743 case EMobileSmsMessagingAckSmsStored: |
|
744 ret = AckSmsStored(aReqHandle,aPckg.Des1n(),aPckg.Des2n()); |
|
745 break; |
|
746 |
|
747 case EMobileSmsMessagingNackSmsStored: |
|
748 ret = NackSmsStored(aReqHandle,aPckg.Des1n(),aPckg.Des2n()); |
|
749 break; |
|
750 |
|
751 case EMobileSmsMessagingResumeSmsReception: |
|
752 ret = ResumeSmsReception(aReqHandle); |
|
753 break; |
|
754 |
|
755 case EMobileSmsMessagingGetSmspListPhase1: |
|
756 ret = GetSmspListPhase1(aReqHandle,aPckg.Des1n(), aPckg.Des2n()); |
|
757 break; |
|
758 |
|
759 case EMobileSmsMessagingGetSmspListPhase2: |
|
760 ret = GetSmspListPhase2(aReqHandle,aPckg.Des1n(), aPckg.Des2n()); |
|
761 break; |
|
762 |
|
763 case EMobileSmsMessagingStoreSmspList: |
|
764 ret = StoreSmspList(aReqHandle,aPckg.Des1n()); |
|
765 break; |
|
766 |
|
767 case EMobileSmsMessagingSendMessage://4207 |
|
768 { |
|
769 TRAPD(leaveCode, ret = SendMessageL(aReqHandle,aPckg.Des1n(),aPckg.Des2n())); |
|
770 if (leaveCode != KErrNone) |
|
771 { |
|
772 ret = leaveCode; |
|
773 } |
|
774 } |
|
775 break; |
|
776 |
|
777 //This is used to re-read the configuration without having to restart the TSY |
|
778 //For testing purposes |
|
779 case EMobileSmsMessagingGetMoSmsBearer: |
|
780 // FALLTHRU |
|
781 |
|
782 default: |
|
783 ret=KErrNotSupported; |
|
784 break; |
|
785 } |
|
786 LogRequest(EFalse, aIpc, ret); |
|
787 return ret; |
|
788 } |
|
789 |
|
790 TBool CSimSmsMessaging::ConstraintEllapsed() const |
|
791 /** |
|
792 * Check if the current contraint has ellapsed - i.e. check that that the number of received SMS |
|
793 * messages has reached the expected number for the current constraint. |
|
794 * @return ETrue if a constraint has ellapsed |
|
795 */ |
|
796 { |
|
797 TBool ellapsed = EFalse; |
|
798 if( iConstraints.Count()>0 ) |
|
799 { |
|
800 //check if the number of rx mess has been reached |
|
801 ellapsed=(iConstraintRxCnt==iConstraints[iCurrentConstraint].iRxCnt); |
|
802 } |
|
803 return ellapsed; |
|
804 } |
|
805 |
|
806 TBool CSimSmsMessaging::IpcMatch() |
|
807 /** |
|
808 * Check if the number of Sms sent matches a constraint i.e. the number of messages sent reaches the number |
|
809 * of sms to be sent to allow incoming messages to start being simulated. |
|
810 * @return ETrue if a match is found |
|
811 */ |
|
812 { |
|
813 TInt i; |
|
814 TBool constraintEllapsed=ConstraintEllapsed(); |
|
815 |
|
816 // NOTE - call ConstraintEllapsed() before doing loop below as iCurrentConstraint |
|
817 // is updated in the loop and so can result in ConstraintEllapsed() giving a |
|
818 // different result |
|
819 |
|
820 for(i=0;i<iConstraints.Count();i++) |
|
821 { |
|
822 if(iSmsTxCnt==(iConstraints[i].iIpcCnt)) |
|
823 { |
|
824 iCurrentConstraint=i; |
|
825 LOGSMS2("New Constraint : %d", iCurrentConstraint); |
|
826 if(i!=0) |
|
827 { |
|
828 if( !constraintEllapsed ) |
|
829 { |
|
830 LOGSMS1("Panic The constraints are overlapping...Compare test code and config file"); |
|
831 } |
|
832 __ASSERT_ALWAYS(constraintEllapsed!=EFalse,SimPanic(EConstraintsOverlapping)); |
|
833 } |
|
834 return ETrue; |
|
835 } |
|
836 } |
|
837 return EFalse; |
|
838 } |
|
839 |
|
840 CTelObject* CSimSmsMessaging::OpenNewObjectByNameL(const TDesC& aName) |
|
841 /** |
|
842 * |
|
843 */ |
|
844 { |
|
845 LOGSMS1(">>CSimSmsMessaging::OpenNewObjectByNameL"); |
|
846 TBuf8<KMaxName> name; |
|
847 name.Copy(aName); // Do simple 16 bit to 8 bit conversion |
|
848 for(TInt i=0;i<iSmsStores->Count();i++) |
|
849 { |
|
850 if(name.MatchF(iSmsStores->At(i)->Name())==0) |
|
851 { |
|
852 // Base class open |
|
853 (void)iSmsStores->At(i)->Open(); |
|
854 return iSmsStores->At(i); |
|
855 } |
|
856 } |
|
857 User::Leave(KErrNotFound); |
|
858 return NULL; |
|
859 } |
|
860 |
|
861 CTelObject* CSimSmsMessaging::OpenNewObjectL(TDes&) |
|
862 /** |
|
863 * |
|
864 */ |
|
865 { |
|
866 User::Leave(KErrNotSupported); |
|
867 return NULL; |
|
868 } |
|
869 |
|
870 CTelObject::TReqMode CSimSmsMessaging::ReqModeL(const TInt aIpc) |
|
871 /** |
|
872 * This function returns the Request Mode for the request with the passed IPC value. |
|
873 * The ETel Server provides a function for returning the standard request modes for |
|
874 * the Core API requests. |
|
875 */ |
|
876 { |
|
877 CTelObject::TReqMode ret=0; |
|
878 |
|
879 switch(aIpc) |
|
880 { |
|
881 case EMobileSmsMessagingReceiveMessage: |
|
882 ret=KReqModeRePostImmediately; |
|
883 break; |
|
884 |
|
885 case EMobileSmsMessagingGetCaps: |
|
886 case EMobileSmsMessagingSetReceiveMode: |
|
887 case EMobileSmsMessagingGetReceiveMode: |
|
888 case EMobileSmsMessagingAckSmsStored: |
|
889 case EMobileSmsMessagingNackSmsStored: |
|
890 case EMobileSmsMessagingResumeSmsReception: |
|
891 case EMobileSmsMessagingEnumerateMessageStores: |
|
892 case EMobileSmsMessagingGetMessageStoreInfo: |
|
893 case EMobileSmsMessagingSendMessage: |
|
894 case EMobileSmsMessagingGetSmspListPhase1: |
|
895 case EMobileSmsMessagingGetSmspListPhase2: |
|
896 case EMobileSmsMessagingStoreSmspList: |
|
897 ret=0; |
|
898 break; |
|
899 case EMobileSmsMessagingGetMoSmsBearer: |
|
900 // FALLTHRU |
|
901 default: |
|
902 User::Leave(KErrNotSupported); |
|
903 break; |
|
904 } |
|
905 |
|
906 return ret; |
|
907 } |
|
908 |
|
909 TInt CSimSmsMessaging::RegisterNotification(const TInt /*aIpc*/) |
|
910 /** |
|
911 The ETel Server calls this function when the first client makes a notification |
|
912 request. If supported by the underlying protocol controlling the |
|
913 signalling stack, this can be used to start requesting updates for the relevant |
|
914 service. |
|
915 */ |
|
916 { |
|
917 return KErrNone; |
|
918 } |
|
919 |
|
920 TInt CSimSmsMessaging::DeregisterNotification(const TInt /*aIpc*/) |
|
921 /** |
|
922 The ETel Server calls this function when the last client that had previously |
|
923 made a notification request closes its ETel Server handle. If supported by |
|
924 the underlying protocol controlling the signalling stack, this can be used |
|
925 to stop requesting updates for the relevant service. |
|
926 */ |
|
927 { |
|
928 return KErrNone; |
|
929 } |
|
930 |
|
931 TInt CSimSmsMessaging::NumberOfSlotsL(const TInt /*aIpc*/) |
|
932 /** |
|
933 * Return the number of slots that the ETel Server should allocate for buffering requests |
|
934 * of the given IPC number. |
|
935 */ |
|
936 { |
|
937 return KDefaultNumberOfSlots; |
|
938 } |
|
939 |
|
940 TInt CSimSmsMessaging::CancelService(const TInt aIpc,const TTsyReqHandle /*aTsyReqHandle*/) |
|
941 /** |
|
942 * Cancel an outstanding request. |
|
943 */ |
|
944 { |
|
945 switch(aIpc) |
|
946 { |
|
947 case EMobileSmsMessagingReceiveMessage: |
|
948 ReceiveMessageCancel(); |
|
949 break; |
|
950 case EMobileSmsMessagingSendMessage: |
|
951 SendMessageCancel(); |
|
952 break; |
|
953 case EMobileSmsMessagingGetSmspListPhase1: |
|
954 StoreSmspListCancel(); |
|
955 break; |
|
956 case EMobileSmsMessagingStoreSmspList: |
|
957 GetSmspListCancel(); |
|
958 break; |
|
959 case EMobileSmsMessagingAckSmsStored: |
|
960 case EMobileSmsMessagingNackSmsStored: |
|
961 AckNackCancel(); |
|
962 break; |
|
963 case EMobileSmsMessagingResumeSmsReception: |
|
964 ResumeSmsReceptionCancel(); |
|
965 break; |
|
966 // These are actually implemented in a synchronous manner, so there's no cancel to perform. |
|
967 case EMobileSmsMessagingSetReceiveMode: |
|
968 case EMobileSmsMessagingGetReceiveMode: |
|
969 break; |
|
970 default: |
|
971 break; |
|
972 } |
|
973 return KErrNone; |
|
974 } |
|
975 |
|
976 void CSimSmsMessaging::Init() |
|
977 /** |
|
978 This function can be used to perform any necessary synchronous initialisation. |
|
979 */ |
|
980 { |
|
981 } |
|
982 |
|
983 TBool CSimSmsMessaging::CanStartRxEvent() const |
|
984 /** Check to see if the Rx event can be started. Conditions are that there are no constraints |
|
985 * and Rx PDUs have been defined, OR SMS messages have been sent and current constraint has |
|
986 * not ellapsed |
|
987 * @return ETrue if the Rx event can be started |
|
988 */ |
|
989 { |
|
990 TBool canStart = EFalse; |
|
991 if( (iConstraints.Count()==0 && iSmsRxParameterListGsm->Count()>0) || |
|
992 (iConstraints.Count()>0 && (iSmsTxCnt == iConstraints[iCurrentConstraint].iIpcCnt) && !ConstraintEllapsed()) ) |
|
993 { |
|
994 // No Constraints listed OR current constraint has not ellapsed |
|
995 canStart = ETrue; |
|
996 } |
|
997 return canStart; |
|
998 } |
|
999 |
|
1000 TInt CSimSmsMessaging::ActionRxEventUnstoredClientAck(TSmsRxEvent aRxEvent) |
|
1001 /** |
|
1002 * This function, triggered by sms receive events, manages the stated machine of |
|
1003 * receiving Unstored clientacked sms messages |
|
1004 * |
|
1005 */ |
|
1006 { |
|
1007 LOGSMS3(">>CSimSmsMessaging::ActionRxEventUnstoredClientAck [iRxState=%d aRxEvent=%d]", iRxState, aRxEvent); |
|
1008 switch(iRxState) |
|
1009 { |
|
1010 case ESmsRxStateIdle: |
|
1011 { |
|
1012 if(aRxEvent==ESmsEventPostedRxReq) |
|
1013 { |
|
1014 iRxState=ESmsRxStateWaitingForSmsRx; |
|
1015 if( CanStartRxEvent() ) |
|
1016 { |
|
1017 // Start the Rx timer to simulate received SMS from network |
|
1018 StartSmsMtTimer(); |
|
1019 } |
|
1020 return KErrNone; |
|
1021 } |
|
1022 return KErrGeneral; |
|
1023 } |
|
1024 case ESmsRxStateWaitingForSmsRx: |
|
1025 { |
|
1026 if(aRxEvent==ESmsEventRxTimer ) |
|
1027 { |
|
1028 iRxState=ESmsRxStateWaitingForAckNack; |
|
1029 TInt ret = AttemptSmsRxComplete(); //If successful Etel will repost the request and the state machine may be re-entered |
|
1030 return ret; |
|
1031 } |
|
1032 return KErrGeneral; |
|
1033 } |
|
1034 case ESmsRxStateWaitingForAckNack: |
|
1035 { |
|
1036 __ASSERT_ALWAYS(aRxEvent!=ESmsEventRxTimer,SimPanic(EIllegalSmsRxEvent, __LINE__)); |
|
1037 if(aRxEvent==ESmsEventRxAckNack) |
|
1038 { |
|
1039 iRxState=ESmsRxStateWaitingForNetworkAckNackResponse; |
|
1040 if (!iRxTimer->IsActive() && !iRxTimer->Running()) |
|
1041 { |
|
1042 LOGSMS1(">>CSimSmsMessaging::ActionRxEventUnstoredClientAck Starting Rx Timer"); |
|
1043 iRxTimer->Start(iAckNackCompletePause,this, ETimerIdSmsMessRx); |
|
1044 } |
|
1045 |
|
1046 return KErrNone; |
|
1047 } |
|
1048 else if(aRxEvent==ESmsEventResume) |
|
1049 { |
|
1050 return KErrGeneral; |
|
1051 } |
|
1052 } break; |
|
1053 case ESmsRxStateWaitingForNetworkAckNackResponse: |
|
1054 if(aRxEvent==ESmsEventRxTimer) |
|
1055 { |
|
1056 if(iSmsStoreFull) |
|
1057 iRxState=ESmsRxStateSuspend; |
|
1058 else if(iSmsRxReqOutstanding) |
|
1059 { |
|
1060 iRxState=ESmsRxStateWaitingForSmsRx; |
|
1061 StartSmsMtTimer(); |
|
1062 } |
|
1063 else |
|
1064 { |
|
1065 iRxState=ESmsRxStateIdle; |
|
1066 StartSmsMtTimer(); |
|
1067 } |
|
1068 CompletePendingReq(); |
|
1069 return KErrNone; |
|
1070 } |
|
1071 if(aRxEvent==ESmsEventPostedRxReq) |
|
1072 return KErrNone; |
|
1073 return KErrGeneral; |
|
1074 case ESmsRxStateSuspend: |
|
1075 { |
|
1076 __ASSERT_ALWAYS(aRxEvent!=ESmsEventRxTimer,SimPanic(EIllegalSmsRxEvent, __LINE__)); |
|
1077 if(aRxEvent==ESmsEventResume) |
|
1078 { |
|
1079 iRxState=ESmsRxStateWaitingForNetworkResumeResponse; |
|
1080 iRxTimer->Start(iResumeCompletePause,this, ETimerIdSmsMessResumeReception); |
|
1081 return KErrNone; |
|
1082 } |
|
1083 return KErrGeneral; |
|
1084 } |
|
1085 case ESmsRxStateWaitingForNetworkResumeResponse: |
|
1086 { |
|
1087 if(aRxEvent==ESmsEventPostedRxReq) |
|
1088 return KErrNone; |
|
1089 return KErrGeneral; |
|
1090 } |
|
1091 default: |
|
1092 return KErrGeneral; |
|
1093 } |
|
1094 return KErrNone; |
|
1095 } |
|
1096 |
|
1097 TInt CSimSmsMessaging::ActionRxEventUnstoredPhoneAck(TSmsRxEvent aRxEvent) |
|
1098 /** |
|
1099 * This function, triggered by sms receive events, manages the stated machine of |
|
1100 * receiving Unstored Phone acked sms messages |
|
1101 * |
|
1102 */ |
|
1103 { |
|
1104 LOGSMS3(">> ActionRxEventUnstoredPhoneAck Enter function. Event=%d, State=%d",aRxEvent,iRxState); |
|
1105 |
|
1106 TInt ret = KErrGeneral; |
|
1107 |
|
1108 switch(iRxState) |
|
1109 { |
|
1110 case ESmsRxStateIdle: |
|
1111 { |
|
1112 if(aRxEvent==ESmsEventPostedRxReq) |
|
1113 { |
|
1114 iRxState=ESmsRxStateWaitingForSmsRx; |
|
1115 if( CanStartRxEvent() ) |
|
1116 { |
|
1117 // Start the Rx timer to simulate received SMS from network |
|
1118 StartSmsMtTimer(); |
|
1119 } |
|
1120 ret = KErrNone; |
|
1121 } |
|
1122 } break; |
|
1123 case ESmsRxStateWaitingForSmsRx: |
|
1124 { |
|
1125 if(aRxEvent==ESmsEventRxTimer ) |
|
1126 { |
|
1127 iRxState=ESmsRxStateIdle; |
|
1128 ret = AttemptSmsRxComplete(); //If successful Etel will repost the request and the state machine may be re-entered |
|
1129 } |
|
1130 } break; |
|
1131 default: |
|
1132 // Do nothing - return default value of KErrGeneral |
|
1133 break; |
|
1134 } |
|
1135 return ret; |
|
1136 } |
|
1137 |
|
1138 TInt CSimSmsMessaging::ActionRxEventStored(TSmsRxEvent aRxEvent) |
|
1139 /** |
|
1140 * This function, triggered by sms receive events, manages the stated machine of |
|
1141 * receiving stored Phone acked sms messages |
|
1142 * |
|
1143 */ |
|
1144 { |
|
1145 LOGSMS3(">> ActionRxEventStored Enter function. Event=%d, State=%d",aRxEvent,iRxState); |
|
1146 TInt ret = KErrGeneral; |
|
1147 |
|
1148 switch(iRxState) |
|
1149 { |
|
1150 case ESmsRxStateIdle: |
|
1151 { |
|
1152 if(aRxEvent==ESmsEventPostedRxReq) |
|
1153 { |
|
1154 iRxState=ESmsRxStateWaitingForSmsRx; |
|
1155 if( CanStartRxEvent() ) |
|
1156 { |
|
1157 // Start the Rx timer to simulate received SMS from network |
|
1158 StartSmsMtTimer(); |
|
1159 } |
|
1160 ret = KErrNone; |
|
1161 } |
|
1162 } break; |
|
1163 case ESmsRxStateWaitingForSmsRx: |
|
1164 { |
|
1165 if(aRxEvent==ESmsEventRxTimer ) |
|
1166 { |
|
1167 iRxState=ESmsRxStateIdle; |
|
1168 ret = AttemptSmsRxComplete(); //If successful Etel will repost the request and the state machine may be re-entered |
|
1169 if( ret != KErrNone ) |
|
1170 { |
|
1171 //the message wasn't stored ->ignore it and re-run the network event |
|
1172 iRxState=ESmsRxStateWaitingForSmsRx; |
|
1173 StartSmsMtTimer(); |
|
1174 } |
|
1175 ret = KErrNone; |
|
1176 } |
|
1177 } break; |
|
1178 default: |
|
1179 // Do nothing - return default value of KErrGeneral |
|
1180 break; |
|
1181 } |
|
1182 return ret; |
|
1183 } |
|
1184 |
|
1185 TInt CSimSmsMessaging::ReceiveMessageL(const TTsyReqHandle aReqHandle, TDes8* aSmsPdu, TDes8* aParam2) |
|
1186 /** |
|
1187 * Process a Receive Message request. This boils down to recording the parameters for later completion. |
|
1188 * The mode of operation where first an SMS receive request is made and then later an SMS |
|
1189 * receive event is simulated is supported. If an SMS receive event is simulated and there is |
|
1190 * no receive request outstanding, the simulated incoming SMS will be discarded. This assumption |
|
1191 * may need to be revisited later. |
|
1192 */ |
|
1193 { |
|
1194 if (iSmsRxReqOutstanding!=EFalse)//Check if another client posts the request |
|
1195 { |
|
1196 ReqCompleted(aReqHandle, KErrInUse); |
|
1197 return KErrNone; |
|
1198 } |
|
1199 iSmsRxReqHandle=aReqHandle; |
|
1200 iSmsRxPdu=aSmsPdu; |
|
1201 RMobileSmsMessaging::TMobileSmsReceiveAttributesV1Pckg* aAttribPckg=(RMobileSmsMessaging::TMobileSmsReceiveAttributesV1Pckg*)aParam2; |
|
1202 RMobileSmsMessaging::TMobileSmsReceiveAttributesV1& attrib=(*aAttribPckg)(); |
|
1203 |
|
1204 // Check that the data structure is supported by the simulated TSY version |
|
1205 TInt err = iPhone->CheckSimTsyVersion(attrib); |
|
1206 if(err != KErrNone) |
|
1207 { |
|
1208 iPhone->ReqCompleted(aReqHandle, err); |
|
1209 return KErrNone; |
|
1210 } |
|
1211 |
|
1212 iSmsRxAttrib=&attrib; |
|
1213 iSmsRxReqOutstanding=ETrue; |
|
1214 LOGSMS3(">>ReceiveMessageL. aSmsPdu&=%x, aParam2&=%x",aSmsPdu,iSmsRxAttrib); |
|
1215 |
|
1216 // Print received PDU to simTSY log. |
|
1217 __ASSERT_ALWAYS(iSmsReceiveMode!=RMobileSmsMessaging::EReceiveModeUnspecified,SimPanic(EMobileSmsMessagingPhoneNotSetToAReceiveMode)); |
|
1218 TInt ret=0; |
|
1219 switch (iSmsReceiveMode)//swich which state machine to enter |
|
1220 { |
|
1221 case RMobileSmsMessaging::EReceiveUnstoredClientAck: |
|
1222 ret=ActionRxEventUnstoredClientAck(ESmsEventPostedRxReq); |
|
1223 break; |
|
1224 case RMobileSmsMessaging::EReceiveUnstoredPhoneAck: |
|
1225 ret=ActionRxEventUnstoredPhoneAck(ESmsEventPostedRxReq); |
|
1226 break; |
|
1227 case RMobileSmsMessaging::EReceiveStored: |
|
1228 ret=ActionRxEventStored(ESmsEventPostedRxReq); |
|
1229 break; |
|
1230 default: |
|
1231 ret=KErrNotSupported; |
|
1232 }//end switch |
|
1233 |
|
1234 if(ret==KErrNone) |
|
1235 { |
|
1236 |
|
1237 } |
|
1238 else |
|
1239 ReqCompleted(aReqHandle,ret); |
|
1240 return KErrNone; |
|
1241 } |
|
1242 |
|
1243 void CSimSmsMessaging::ReceiveMessageCancel() |
|
1244 /* |
|
1245 * Cancel an outstanding Receive Message request. |
|
1246 */ |
|
1247 { |
|
1248 if(iSmsRxReqOutstanding) |
|
1249 { |
|
1250 iSmsRxReqOutstanding=EFalse; |
|
1251 iRxState=ESmsRxStateIdle; |
|
1252 ReqCompleted(iSmsRxReqHandle,KErrCancel); |
|
1253 } |
|
1254 } |
|
1255 |
|
1256 TInt CSimSmsMessaging::AckSmsStored(const TTsyReqHandle aReqHandle,TDes8* aMsg,TDes8* aFullFlagPckg) |
|
1257 /** |
|
1258 * In response to an incoming sms message the sms stack Acks/Nacks the message |
|
1259 * This function implements the Ack action. |
|
1260 * The flag aFullFlagPckg if set informs the SC that the client has no space to store this message |
|
1261 * and hence that it should retry once instructed by the ME |
|
1262 */ |
|
1263 { |
|
1264 TPckg<TBool>* fullFlagPckg=(TPckg<TBool>*)aFullFlagPckg; |
|
1265 TBool& fullFlag=(*fullFlagPckg)(); |
|
1266 |
|
1267 // SMS-DELIVER-REPORT TPDU check |
|
1268 _LIT8(emptyDesc,""); |
|
1269 if(aMsg->Compare(emptyDesc) != KErrNone) |
|
1270 { |
|
1271 RMobileSmsMessaging::TMobileSmsGsmTpdu reportPdu; |
|
1272 reportPdu.Zero(); |
|
1273 if (CSimTsyMode::GetMode() != CSimTsyMode::ECdmaV1) |
|
1274 { |
|
1275 reportPdu = iSmsRxParameterListGsm->At(iSmsRxCnt-1).iDeliveryReport; |
|
1276 } |
|
1277 |
|
1278 |
|
1279 if (reportPdu.Length() > 0) // check if SMS-DELIVER-REPORT TPDU in config file is present |
|
1280 { |
|
1281 if(aMsg->Match(reportPdu)!=0)//check if the transmitted pdu and the one in config file are not identical |
|
1282 { |
|
1283 ReqCompleted(aReqHandle,KErrCorrupt); |
|
1284 return KErrNone; |
|
1285 } |
|
1286 } |
|
1287 } |
|
1288 |
|
1289 iSmsStoreFull=fullFlag; // Record the "Store Full" status for future state transitions. |
|
1290 TInt ret=ActionRxEventUnstoredClientAck(ESmsEventRxAckNack); |
|
1291 |
|
1292 // Handle any state transition errors now. Simulated Ack/Nack failures are not supported yet... |
|
1293 if(ret!=KErrNone) |
|
1294 { |
|
1295 ReqCompleted(aReqHandle,ret); |
|
1296 return KErrNone; |
|
1297 } |
|
1298 iPendingReqHandle=aReqHandle; |
|
1299 return KErrNone; |
|
1300 } |
|
1301 |
|
1302 TInt CSimSmsMessaging::NackSmsStored(const TTsyReqHandle aReqHandle,TDes8* aMsg,TDes8* aRpCausePckg) |
|
1303 /** |
|
1304 * In response to an incoming sms message the sms stack Acks/Nacks the message |
|
1305 * This function implements the NAck action. |
|
1306 * aRpCausePckg must be filled in with the reason |
|
1307 */ |
|
1308 { |
|
1309 TPckg<TInt>* rpCausePckg=(TPckg<TInt>*)aRpCausePckg; |
|
1310 TInt& rpCause=(*rpCausePckg)(); |
|
1311 |
|
1312 // SMS-DELIVER-REPORT TPDU check |
|
1313 _LIT8(emptyDesc,""); |
|
1314 if(aMsg->Compare(emptyDesc) != KErrNone) |
|
1315 { |
|
1316 RMobileSmsMessaging::TMobileSmsGsmTpdu reportPdu; |
|
1317 reportPdu.Zero(); |
|
1318 if (CSimTsyMode::GetMode() != CSimTsyMode::ECdmaV1) |
|
1319 { |
|
1320 reportPdu = iSmsRxParameterListGsm->At(iSmsRxCnt-1).iDeliveryReport; |
|
1321 } |
|
1322 |
|
1323 |
|
1324 if (reportPdu.Length() > 0) // check if SMS-DELIVER-REPORT TPDU in config file is present |
|
1325 { |
|
1326 if(aMsg->Match(reportPdu)!=0)//check if the transmitted pdu and the one in config file are not identical |
|
1327 { |
|
1328 ReqCompleted(aReqHandle,KErrCorrupt); |
|
1329 return KErrNone; |
|
1330 } |
|
1331 } |
|
1332 } |
|
1333 |
|
1334 if(rpCause==KErrGsmSMSMemoryCapacityExceeded) |
|
1335 iSmsStoreFull=ETrue; |
|
1336 else |
|
1337 iSmsStoreFull=EFalse; |
|
1338 |
|
1339 TInt ret=ActionRxEventUnstoredClientAck(ESmsEventRxAckNack); |
|
1340 |
|
1341 // Handle any state transition errors now. Simulated Ack/Nack failures are not supported yet... |
|
1342 if(ret!=KErrNone) |
|
1343 { |
|
1344 ReqCompleted(aReqHandle,ret); |
|
1345 return KErrNone; |
|
1346 } |
|
1347 |
|
1348 iPendingReqHandle=aReqHandle; |
|
1349 return KErrNone; |
|
1350 } |
|
1351 |
|
1352 |
|
1353 void CSimSmsMessaging::AckNackCancel() |
|
1354 /* |
|
1355 * Cancel an outstanding Receive Message request. |
|
1356 */ |
|
1357 { |
|
1358 //This method does nothing,, a complex implementation would have to be used to simulate a real tsy |
|
1359 } |
|
1360 |
|
1361 |
|
1362 TInt CSimSmsMessaging::ResumeSmsReception(const TTsyReqHandle aReqHandle) |
|
1363 /** |
|
1364 * After the sms reception has been suspended(store full), if the client frees some space |
|
1365 * the ME will inform the SC that reception can resume |
|
1366 * |
|
1367 */ |
|
1368 { |
|
1369 TInt ret=ActionRxEventUnstoredClientAck(ESmsEventResume); |
|
1370 // In case of state transition error, return the error code. |
|
1371 // Resume failures cannot be simulated by the tsy yet... |
|
1372 if(ret!=KErrNone) |
|
1373 { |
|
1374 ReqCompleted(aReqHandle,ret); |
|
1375 return KErrNone; |
|
1376 } |
|
1377 iPendingReqHandle=aReqHandle; |
|
1378 return KErrNone; |
|
1379 } |
|
1380 |
|
1381 void CSimSmsMessaging::ResumeSmsReceptionCancel() |
|
1382 { |
|
1383 //Does nothing, a complex implementation would have to be used to simulate a real tsy |
|
1384 } |
|
1385 |
|
1386 //********************************************** |
|
1387 //send |
|
1388 //********************************************* |
|
1389 |
|
1390 |
|
1391 TInt CSimSmsMessaging::ActionTxEvent(TSmsTxEvent aTxEvent) |
|
1392 /** |
|
1393 * This function actions the sms message sending state machine. It is triggered by sms sending events |
|
1394 * |
|
1395 */ |
|
1396 { |
|
1397 LOGSMS1(">>ActionTxEvent "); |
|
1398 switch(iTxState) |
|
1399 { |
|
1400 case ESmsTxStateIdle: |
|
1401 __ASSERT_ALWAYS(aTxEvent!=ESmsEventSubmitReportReceived,SimPanic(EIllegalSmsTxEvent)); |
|
1402 if(aTxEvent==ESmsEventSendReq) |
|
1403 { |
|
1404 iTxState=ESmsTxStateWaitingForSubmitReport; |
|
1405 iTxTimer->Start(iSmsTxPause,this, ETimerIdSmsMessTx); |
|
1406 } |
|
1407 break; |
|
1408 case ESmsTxStateWaitingForSubmitReport: |
|
1409 __ASSERT_ALWAYS(aTxEvent!=ESmsEventSendReq,SimPanic(EIllegalSmsTxEvent)); |
|
1410 if(aTxEvent==ESmsEventSubmitReportReceived) |
|
1411 { |
|
1412 iTxState=ESmsTxStateIdle; |
|
1413 |
|
1414 PopulateSmsTxAttrib(iSmsTxAttrib); |
|
1415 CompleteTxPendingReq(KErrNone); |
|
1416 } |
|
1417 break; |
|
1418 } |
|
1419 return KErrNone; |
|
1420 } |
|
1421 |
|
1422 TInt CSimSmsMessaging::SendMessageL(const TTsyReqHandle aReqHandle,TDes8* aSmsPdu,TDes8* aParam2) |
|
1423 /** |
|
1424 * This function simulates the transmission of an sms from the ME to the SC. |
|
1425 * It returns directly if |
|
1426 * -The Sms message description(SmsTx)tag in the config file specifies that this sms message should return with this error |
|
1427 * -The Pdu is corrupted |
|
1428 * Otherwise it start the sms message sending state machine |
|
1429 * |
|
1430 */ |
|
1431 |
|
1432 { |
|
1433 iSmsTxReqHandle=aReqHandle; |
|
1434 RMobileSmsMessaging::TMobileSmsSendAttributesV1Pckg* aAttribPckg=(RMobileSmsMessaging::TMobileSmsSendAttributesV1Pckg*)aParam2; |
|
1435 RMobileSmsMessaging::TMobileSmsSendAttributesV1& attrib=(*aAttribPckg)(); |
|
1436 |
|
1437 // Check that the data structure is supported by the simulated TSY version |
|
1438 TInt err = iPhone->CheckSimTsyVersion(attrib); |
|
1439 if(err != KErrNone) |
|
1440 { |
|
1441 iPhone->ReqCompleted(aReqHandle, err); |
|
1442 return KErrNone; |
|
1443 } |
|
1444 |
|
1445 iSmsTxAttrib=&attrib; |
|
1446 #ifdef _DEBUG |
|
1447 LogTMobileSmsAttributesV1(*iSmsTxAttrib); |
|
1448 #endif // _DEBUG |
|
1449 |
|
1450 |
|
1451 //check if messages defined in cfg file |
|
1452 TInt count = 0; |
|
1453 count = iSmsTxParametersListGsm->Count(); |
|
1454 |
|
1455 if (count<=iSmsTxCnt) |
|
1456 return KErrTotalLossOfPrecision; |
|
1457 |
|
1458 //check if expected error |
|
1459 //TInt err = KErrNone; |
|
1460 err = KErrNone; |
|
1461 err = iSmsTxParametersListGsm->At(iSmsTxCnt).iExpectedError; |
|
1462 if (err!=KErrNone) |
|
1463 { |
|
1464 PopulateSmsTxAttrib(iSmsTxAttrib); |
|
1465 CompleteTxPendingReq(err); |
|
1466 return KErrNone; |
|
1467 } |
|
1468 |
|
1469 //check if a non null pdu is defined in the config file |
|
1470 RMobileSmsMessaging::TMobileSmsGsmTpdu octetPdu; |
|
1471 octetPdu = iSmsTxParametersListGsm->At(iSmsTxCnt).iPdu; |
|
1472 |
|
1473 RMobileSmsMessaging::TMobileSmsGsmTpdu pduWith0; |
|
1474 TUint8 zero=0; |
|
1475 pduWith0.Append(&zero, 1); |
|
1476 if(octetPdu!=pduWith0)//if the pdu in config file is 00, skip the pdu check |
|
1477 { |
|
1478 if(aSmsPdu->Match(octetPdu)!=0)//check if the transmitted pdu and the one in config file are identical |
|
1479 { |
|
1480 CompleteTxPendingReq(KErrCorrupt); |
|
1481 return KErrNone; |
|
1482 } |
|
1483 } |
|
1484 |
|
1485 ActionTxEvent(ESmsEventSendReq); |
|
1486 return KErrNone; |
|
1487 } |
|
1488 |
|
1489 |
|
1490 void CSimSmsMessaging::SendMessageCancel() |
|
1491 /* |
|
1492 * Cancel an outstanding send Message request. |
|
1493 */ |
|
1494 { |
|
1495 if(iTxState==ESmsTxStateWaitingForSubmitReport) |
|
1496 { |
|
1497 iTxTimer->Cancel(); |
|
1498 iTxState=ESmsTxStateIdle; |
|
1499 CompleteTxPendingReq(KErrCancel); |
|
1500 } |
|
1501 } |
|
1502 |
|
1503 void CSimSmsMessaging::CompletePendingReq() |
|
1504 { |
|
1505 ReqCompleted(iPendingReqHandle,KErrNone); |
|
1506 } |
|
1507 |
|
1508 TInt CSimSmsMessaging::AttemptSmsRxComplete() |
|
1509 /** |
|
1510 * Complete an outstanding SMS message receive request if one is outstanding. If there is |
|
1511 * no request outstanding, the message will be discared. |
|
1512 * update the constraint count |
|
1513 */ |
|
1514 { |
|
1515 LOGSMS1(">>AttemptSmsRxComplete "); |
|
1516 |
|
1517 if (CSimTsyMode::GetMode() != CSimTsyMode::ECdmaV1) |
|
1518 { |
|
1519 iConstraintRxCnt++; |
|
1520 } |
|
1521 |
|
1522 TInt ret=KErrNone; |
|
1523 if(iSmsRxReqOutstanding) |
|
1524 { |
|
1525 if (iSmsReceiveMode==RMobileSmsMessaging::EReceiveStored) |
|
1526 { |
|
1527 LOGSMS4(">>Populating SMS Structures. iSmsRxPdu&=%x, iSmsRxAttrib&=%x, iSmsRxCnt=%d.",iSmsRxPdu,iSmsRxAttrib,iSmsRxCnt); |
|
1528 RMobileSmsStore::TMobileGsmSmsEntryV1 sms; |
|
1529 |
|
1530 *iSmsRxPdu=iSmsRxParameterListGsm->At(iSmsRxCnt).iPdu; |
|
1531 |
|
1532 sms.iMsgData=RMobileSmsMessaging::TMobileSmsGsmTpdu(*iSmsRxPdu); |
|
1533 sms.iServiceCentre.iTelNumber.Copy(iSmsRxParameterListGsm->At(iSmsRxCnt).iSca); |
|
1534 |
|
1535 sms.iServiceCentre.iTypeOfNumber=RMobilePhone::EInternationalNumber;//SmsMessaging only deals with international numbers |
|
1536 sms.iServiceCentre.iNumberPlan=RMobilePhone::EIsdnNumberPlan; |
|
1537 sms.iMsgStatus=RMobileSmsStore::EStoredMessageUnread; |
|
1538 ret = iSmsStores->At(0)->StoreIncomingMessage(&sms);//todo if several stores find the right one |
|
1539 if (ret==KErrNone) |
|
1540 { |
|
1541 iSmsRxAttrib->iStore.Copy(iSmsStores->At(0)->Name()); |
|
1542 iSmsRxAttrib->iStoreIndex=sms.iIndex; |
|
1543 } |
|
1544 } |
|
1545 else |
|
1546 { |
|
1547 *iSmsRxPdu = iSmsRxParameterListGsm->At(iSmsRxCnt).iPdu; |
|
1548 } |
|
1549 |
|
1550 if (ret==KErrNone) |
|
1551 { |
|
1552 iSmsRxReqOutstanding=EFalse; |
|
1553 PopulateSmsRxAttrib(iSmsRxParameterListGsm->At(iSmsRxCnt).iSca,iSmsRxAttrib); |
|
1554 |
|
1555 ReqCompleted(iSmsRxReqHandle,ret); |
|
1556 iSmsRxCnt++; |
|
1557 } |
|
1558 } |
|
1559 return ret; |
|
1560 } |
|
1561 |
|
1562 void CSimSmsMessaging::CompleteTxPendingReq(TInt aError) |
|
1563 /** |
|
1564 * Complete a SmsTx request and increments the SmsTx counter |
|
1565 * |
|
1566 */ |
|
1567 { |
|
1568 LOGSMS1(">>CompleteTxPendingReq "); |
|
1569 iSmsTxCnt++; |
|
1570 if(IpcMatch()) |
|
1571 { |
|
1572 iConstraintRxCnt=0; |
|
1573 if( iSmsRxReqOutstanding ) |
|
1574 { |
|
1575 // Client has a pending receive request - safe to start Rx timer |
|
1576 // to simulate received SMS from network. |
|
1577 StartSmsMtTimer(); |
|
1578 } |
|
1579 else |
|
1580 { |
|
1581 // No pending client receive request - need to wait for it before |
|
1582 // simulating received SMS from network. |
|
1583 LOGSMS1(" - no pending receive req from client - do not start Rx timer"); |
|
1584 } |
|
1585 } |
|
1586 ReqCompleted(iSmsTxReqHandle, aError); |
|
1587 } |
|
1588 |
|
1589 void CSimSmsMessaging::StartSmsMtTimer() |
|
1590 { |
|
1591 LOGSMS1(">>StartSmsMtTimer "); |
|
1592 TInt count = 0; |
|
1593 count = iSmsRxCnt<iSmsRxParameterListGsm->Count(); |
|
1594 |
|
1595 if(count) // Check that there are more messages defined in the config file. |
|
1596 { |
|
1597 if((iConstraints.Count()==0) || (iConstraintRxCnt<iConstraints[iCurrentConstraint].iRxCnt)) // If there are no constraints, or there are constraints and they're not exhausted. |
|
1598 { |
|
1599 LOGSMS1(">>StartSmsMtTimer Starting"); |
|
1600 iRxTimer->Start(iSmsRxPeriod,this, ETimerIdSmsMessRx); |
|
1601 LOGSMS1(">>StartSmsMtTimer Started"); |
|
1602 } |
|
1603 } |
|
1604 } |
|
1605 |
|
1606 |
|
1607 void CSimSmsMessaging::PopulateSmsRxAttrib(const TDesC8& aAsciiScaAddr,RMobileSmsMessaging::TMobileSmsReceiveAttributesV1* aAttrib) |
|
1608 /** |
|
1609 * Populate the SMS Rx Attributes from an ASCII respresentation, such as that stored in the configuration file. |
|
1610 * This involves checking the address for a leading '+' character and setting the TON and NPI |
|
1611 * accordingly. The address can then be copied into the iTelNumber structure. |
|
1612 */ |
|
1613 { |
|
1614 LOGSMS1(">>PopulateSmsRxAttrib, "); |
|
1615 aAttrib->iOriginator.iTelNumber.SetLength(0); |
|
1616 |
|
1617 switch (iSmsReceiveMode) |
|
1618 { |
|
1619 case RMobileSmsMessaging::EReceiveUnstoredClientAck: |
|
1620 aAttrib->iStatus=RMobileSmsMessaging::EMtMessageUnstoredClientAck; |
|
1621 aAttrib->iStore.SetLength(0); |
|
1622 aAttrib->iStoreIndex=-1; |
|
1623 break; |
|
1624 case RMobileSmsMessaging::EReceiveUnstoredPhoneAck: |
|
1625 aAttrib->iStatus=RMobileSmsMessaging::EMtMessageUnstoredPhoneAck; |
|
1626 aAttrib->iStore.SetLength(0); |
|
1627 aAttrib->iStoreIndex=-1; |
|
1628 break; |
|
1629 case RMobileSmsMessaging::EReceiveStored: |
|
1630 aAttrib->iStatus=RMobileSmsMessaging::EMtMessageStored; |
|
1631 break; |
|
1632 |
|
1633 default: |
|
1634 break; |
|
1635 } |
|
1636 aAttrib->iFlags=RMobileSmsMessaging::KGsmServiceCentre | RMobileSmsMessaging::KSmsDataFormat | RMobileSmsMessaging::KIncomingStatus; |
|
1637 aAttrib->iDataFormat=RMobileSmsMessaging::EFormatGsmTpdu; |
|
1638 |
|
1639 if(aAsciiScaAddr.Length()>0) |
|
1640 { |
|
1641 aAttrib->iGsmServiceCentre.iNumberPlan=RMobilePhone::EIsdnNumberPlan; |
|
1642 aAttrib->iGsmServiceCentre.iTypeOfNumber=RMobilePhone::EInternationalNumber; |
|
1643 aAttrib->iGsmServiceCentre.iTelNumber.Copy(aAsciiScaAddr); |
|
1644 } |
|
1645 } |
|
1646 |
|
1647 |
|
1648 void CSimSmsMessaging::PopulateSmsTxAttrib(RMobileSmsMessaging::TMobileSmsAttributesV1* aAttrib) |
|
1649 /** |
|
1650 * Populate the SMS Tx Attributes for SMS from an ASCII respresentation, such as that stored in the configuration file. |
|
1651 * - Message Identifier |
|
1652 * - TL Ack |
|
1653 */ |
|
1654 { |
|
1655 if (iSmsModeCaps == RMobileSmsMessaging::KCapsGsmSms) |
|
1656 { |
|
1657 RMobileSmsMessaging::TMobileSmsSendAttributesV1* attrib = static_cast<RMobileSmsMessaging::TMobileSmsSendAttributesV1*>(aAttrib); |
|
1658 attrib->iMsgRef = TUint16(iSmsTxParametersListGsm->At(iSmsTxCnt).iRef); |
|
1659 |
|
1660 attrib->iFlags = RMobileSmsMessaging::KMessageReference; |
|
1661 |
|
1662 if (iSmsControlCaps & RMobileSmsMessaging::KCapsSendWithAck) |
|
1663 { |
|
1664 attrib->iSubmitReport=iSmsTxParametersListGsm->At(iSmsTxCnt).iSubmitReport; |
|
1665 attrib->iFlags |= RMobileSmsMessaging::KGsmSubmitReport; |
|
1666 } |
|
1667 } |
|
1668 } |
|
1669 |
|
1670 void CSimSmsMessaging::PopulateSmsTxAttrib(RMobileSmsMessaging::TMobileSmsSendAttributesV1* aAttrib) |
|
1671 /** |
|
1672 * Populate the SMS Tx Attributes from an ASCII respresentation, such as that stored in the configuration file. |
|
1673 * -Message Reference |
|
1674 * -SUBMIT_REPORT_TPDU |
|
1675 */ |
|
1676 { |
|
1677 aAttrib->iMsgRef = TUint16(iSmsTxParametersListGsm->At(iSmsTxCnt).iRef); |
|
1678 aAttrib->iFlags = RMobileSmsMessaging::KMessageReference; |
|
1679 |
|
1680 if (iSmsControlCaps & RMobileSmsMessaging::KCapsSendWithAck) |
|
1681 { |
|
1682 aAttrib->iSubmitReport=iSmsTxParametersListGsm->At(iSmsTxCnt).iSubmitReport; |
|
1683 aAttrib->iFlags |= RMobileSmsMessaging::KGsmSubmitReport; |
|
1684 } |
|
1685 } |
|
1686 |
|
1687 TInt CSimSmsMessaging::GetCaps(const TTsyReqHandle aReqHandle,TDes8* aPckg) |
|
1688 /** |
|
1689 * Process a request to retrieve the caps. Currently, only the KCapsReceiveUnstoredClientAck |
|
1690 * mode is supported. |
|
1691 */ |
|
1692 { |
|
1693 RMobileSmsMessaging::TMobileSmsCapsV1Pckg* capsPckg=(RMobileSmsMessaging::TMobileSmsCapsV1Pckg*)aPckg; |
|
1694 RMobileSmsMessaging::TMobileSmsCapsV1& caps=(*capsPckg)(); |
|
1695 |
|
1696 // Check that the data structure is supported by the simulated TSY version |
|
1697 TInt err = iPhone->CheckSimTsyVersion(caps); |
|
1698 if(err != KErrNone) |
|
1699 { |
|
1700 iPhone->ReqCompleted(aReqHandle, err); |
|
1701 return KErrNone; |
|
1702 } |
|
1703 |
|
1704 caps.iSmsMode = RMobileSmsMessaging::KCapsGsmSms; |
|
1705 |
|
1706 caps.iSmsControl=iSmsControlCaps; |
|
1707 ReqCompleted(aReqHandle,KErrNone); |
|
1708 return KErrNone; |
|
1709 } |
|
1710 |
|
1711 TInt CSimSmsMessaging::GetReceiveMode(const TTsyReqHandle aReqHandle,TDes8* aPckg) |
|
1712 /** |
|
1713 * Process a request to retrieve the current SMS receive mode. Only the |
|
1714 * KCapsReceiveUnstoredClientAck mode is supported. |
|
1715 */ |
|
1716 { |
|
1717 TPckg<RMobileSmsMessaging::TMobileSmsReceiveMode>* modePckg=(TPckg<RMobileSmsMessaging::TMobileSmsReceiveMode>*)aPckg; |
|
1718 RMobileSmsMessaging::TMobileSmsReceiveMode& mode=(*modePckg)(); |
|
1719 mode=iSmsReceiveMode; |
|
1720 ReqCompleted(aReqHandle,KErrNone); |
|
1721 return KErrNone; |
|
1722 } |
|
1723 |
|
1724 TInt CSimSmsMessaging::SetReceiveMode(const TTsyReqHandle aReqHandle,TDes8* aPckg) |
|
1725 /** |
|
1726 * Process a request to set the current SMS receive mode. Only the |
|
1727 * KCapsReceiveUnstoredClientAck mode is supported. |
|
1728 */ |
|
1729 { |
|
1730 TPckg<RMobileSmsMessaging::TMobileSmsReceiveMode>* modePckg=(TPckg<RMobileSmsMessaging::TMobileSmsReceiveMode>*)aPckg; |
|
1731 RMobileSmsMessaging:: TMobileSmsReceiveMode& mode=(*modePckg)(); |
|
1732 |
|
1733 TInt result(KErrNone); |
|
1734 |
|
1735 switch (mode) |
|
1736 { |
|
1737 case RMobileSmsMessaging::EReceiveUnstoredClientAck: |
|
1738 { |
|
1739 if(iSmsControlCaps & RMobileSmsMessaging::KCapsReceiveUnstoredClientAck) |
|
1740 { |
|
1741 if ((iRxState==ESmsRxStateIdle) || (iRxState==ESmsRxStateWaitingForSmsRx))//can only change mode in these states |
|
1742 { |
|
1743 iSmsReceiveMode=RMobileSmsMessaging::EReceiveUnstoredClientAck; |
|
1744 ReqCompleted(aReqHandle,KErrNone); |
|
1745 } |
|
1746 else |
|
1747 { |
|
1748 if(iSmsReceiveMode==RMobileSmsMessaging::EReceiveUnstoredClientAck)//already in this state |
|
1749 ReqCompleted(aReqHandle,KErrNone); |
|
1750 else |
|
1751 ReqCompleted(aReqHandle,KErrNotSupported); |
|
1752 } |
|
1753 } |
|
1754 else ReqCompleted(aReqHandle,KErrNotSupported); |
|
1755 break; |
|
1756 } |
|
1757 |
|
1758 case RMobileSmsMessaging::EReceiveUnstoredPhoneAck: |
|
1759 { |
|
1760 if(iSmsControlCaps & RMobileSmsMessaging:: KCapsReceiveUnstoredPhoneAck) |
|
1761 { |
|
1762 if ((iRxState==ESmsRxStateIdle) || (iRxState==ESmsRxStateWaitingForSmsRx))//can only change mode in these states |
|
1763 { |
|
1764 iSmsReceiveMode=RMobileSmsMessaging::EReceiveUnstoredPhoneAck; |
|
1765 ReqCompleted(aReqHandle,KErrNone); |
|
1766 } |
|
1767 else |
|
1768 { |
|
1769 if (iSmsReceiveMode==RMobileSmsMessaging::EReceiveUnstoredPhoneAck)//already in this state |
|
1770 ReqCompleted(aReqHandle,KErrNone); |
|
1771 else |
|
1772 ReqCompleted(aReqHandle,KErrNotSupported); |
|
1773 } |
|
1774 } |
|
1775 else |
|
1776 ReqCompleted(aReqHandle,KErrNotSupported); |
|
1777 break; |
|
1778 } |
|
1779 |
|
1780 case RMobileSmsMessaging::EReceiveStored: |
|
1781 { |
|
1782 if(iSmsControlCaps & RMobileSmsMessaging:: KCapsReceiveStored) |
|
1783 { |
|
1784 if ((iRxState==ESmsRxStateIdle) || (iRxState==ESmsRxStateWaitingForSmsRx))//can only change mode in these states |
|
1785 { |
|
1786 iSmsReceiveMode=RMobileSmsMessaging::EReceiveStored; |
|
1787 ReqCompleted(aReqHandle,KErrNone); |
|
1788 } |
|
1789 else |
|
1790 { |
|
1791 if((iSmsReceiveMode==RMobileSmsMessaging::EReceiveStored))//already in this state |
|
1792 ReqCompleted(aReqHandle,KErrNone); |
|
1793 else |
|
1794 ReqCompleted(aReqHandle,KErrNotSupported); |
|
1795 } |
|
1796 } |
|
1797 else ReqCompleted(aReqHandle,KErrNotSupported); |
|
1798 break; |
|
1799 } |
|
1800 default: |
|
1801 result = KErrNotSupported; |
|
1802 } |
|
1803 |
|
1804 return result; |
|
1805 } |
|
1806 |
|
1807 TInt CSimSmsMessaging::EnumerateMessagingStores(TTsyReqHandle aReqHandle,TDes8* aPckg) |
|
1808 /** |
|
1809 * Process a request to retrieve the number of message stores supported. |
|
1810 * @param aReqHandle The TSY request handle associated with this request. |
|
1811 * @param aPckg The parameter package containing the count variable to be populated and |
|
1812 * returned. |
|
1813 * @return TInt Standard error value. |
|
1814 */ |
|
1815 { |
|
1816 TPckg<TInt>* countPckg=(TPckg<TInt>*)aPckg; |
|
1817 TInt& count=(*countPckg)(); |
|
1818 count=iSmsStores->Count(); |
|
1819 ReqCompleted(aReqHandle,KErrNone); |
|
1820 return KErrNone; |
|
1821 } |
|
1822 |
|
1823 TInt CSimSmsMessaging::GetMessageStoreInfo(TTsyReqHandle aReqHandle,TDes8* aPckg1, TDes8* aPckg2) |
|
1824 /** |
|
1825 * Retrieve information about an indexed SMS Message Store. |
|
1826 * @param aReqHandle The TSY request handle associated with this request. |
|
1827 * @param aPckg1 The parameter package containing the index of the SMS Store for which |
|
1828 * information is going to be retrieved. |
|
1829 * @param aPckg2 The parameter package in which the retrieved SMS Store information will |
|
1830 * be passed back to the client. |
|
1831 * @return TInt Standard error value. |
|
1832 */ |
|
1833 { |
|
1834 TPckg<TInt>* indexPckg=(TPckg<TInt>*)aPckg1; |
|
1835 TInt& index=(*indexPckg)(); |
|
1836 TPckg<RMobilePhoneStore::TMobilePhoneStoreInfoV1>* infoPckg=(TPckg<RMobilePhoneStore::TMobilePhoneStoreInfoV1>*)aPckg2; |
|
1837 RMobilePhoneStore::TMobilePhoneStoreInfoV1& info=(*infoPckg)(); |
|
1838 |
|
1839 // Check that the data structure is supported by the simulated TSY version |
|
1840 TInt err = iPhone->CheckSimTsyVersion(info); |
|
1841 if(err != KErrNone) |
|
1842 { |
|
1843 iPhone->ReqCompleted(aReqHandle, err); |
|
1844 return KErrNone; |
|
1845 } |
|
1846 |
|
1847 if((index<0) || (index>=iSmsStores->Count())) |
|
1848 { |
|
1849 ReqCompleted(aReqHandle,KErrArgument); |
|
1850 return KErrNone; |
|
1851 } |
|
1852 |
|
1853 info.iType=RMobilePhoneStore::EShortMessageStore; |
|
1854 info.iTotalEntries=iSmsStores->At(index)->MaxSlots(); |
|
1855 info.iUsedEntries=iSmsStores->At(index)->UsedEntries(); |
|
1856 info.iCaps= iSmsStores->At(index)->StoreCaps(); |
|
1857 info.iName.Copy(iSmsStores->At(index)->Name()); |
|
1858 ReqCompleted(aReqHandle,KErrNone); |
|
1859 return KErrNone; |
|
1860 } |
|
1861 |
|
1862 TInt CSimSmsMessaging::GetSmspListPhase1(const TTsyReqHandle aTsyReqHandle, |
|
1863 TDes8* aParam1,TDes8* aParam2) |
|
1864 /** Get SMSP List Phase 1 |
|
1865 * |
|
1866 * If the GetSmspListPhase1L should leave this method takes care of that and |
|
1867 * makes a premature ReqCompleted to the client. |
|
1868 * |
|
1869 * @param aTsyReqHandle the request ID |
|
1870 * @param aClient The client sends down a handle that is saved together with the |
|
1871 * list so the list can be returned to the right client in phase 2. |
|
1872 * @param aBufSiz The size of the retrieved network list. The size is set in |
|
1873 * @return error code. |
|
1874 */ |
|
1875 { |
|
1876 if(iSmspBusy==EFalse) |
|
1877 { |
|
1878 iSmspBusy=ETrue; |
|
1879 UNPACK_PCKG(clientId,aParam1,RMobilePhone::TClientId); |
|
1880 UNPACK_PCKG(bufSize,aParam2,TInt); |
|
1881 TRAPD(leaveCode,GetSmspListPhase1L(aTsyReqHandle,clientId,bufSize)); |
|
1882 if (leaveCode) |
|
1883 return leaveCode; |
|
1884 return KErrNone; |
|
1885 } |
|
1886 else |
|
1887 return KErrInUse; |
|
1888 |
|
1889 } |
|
1890 |
|
1891 void CSimSmsMessaging::GetSmspListPhase1L(TTsyReqHandle aTsyReqHandle, |
|
1892 RMobilePhone::TClientId& aClientId, |
|
1893 TInt& aBufSize) |
|
1894 /** Get SMSP List Phase 1 |
|
1895 * |
|
1896 * @param aTsyReqHandle the request ID |
|
1897 * @param aClient The client sends down a handle that is saved together with the |
|
1898 * list so the list can be returned to the right client in phase 2. |
|
1899 * @param aBufSiz The size of the smsp list. The size is set in |
|
1900 * @return error code. |
|
1901 */ |
|
1902 { |
|
1903 // just check and remove if there are already existing entries from the |
|
1904 // same client |
|
1905 TInt numberOfLists = iSmspReadAll->Count(); |
|
1906 // Find the get smsplists attempts from this client, starting from end. |
|
1907 for (TInt i = numberOfLists-1; i >= 0; --i) |
|
1908 { |
|
1909 CListReadAllAttempt* readOld=iSmspReadAll->At(i); |
|
1910 if ((readOld->iClient.iSessionHandle==aClientId.iSessionHandle) && |
|
1911 (readOld->iClient.iSubSessionHandle==aClientId.iSubSessionHandle)) |
|
1912 { |
|
1913 iSmspReadAll->Delete(i); |
|
1914 } |
|
1915 } |
|
1916 // once we have cleaned all then we can proceed... |
|
1917 iSmspReqHandle=aTsyReqHandle; |
|
1918 // Store the streamed list and the client ID |
|
1919 |
|
1920 CListReadAllAttempt* read=CListReadAllAttempt::NewL(aClientId, aTsyReqHandle); |
|
1921 CleanupStack::PushL(read); |
|
1922 |
|
1923 read->iListBuf = iSmspEntries->StoreLC(); |
|
1924 CleanupStack::Pop(read->iListBuf); // pop the CBufFlat allocated by StoreLC |
|
1925 |
|
1926 iSmspReadAll->AppendL(read); |
|
1927 CleanupStack::Pop(read); // pop the CListReadAllAttempt |
|
1928 |
|
1929 // return the CBufFlat's size to client |
|
1930 aBufSize=(read->iListBuf)->Size(); |
|
1931 |
|
1932 // CleanupStack::PopAndDestroy(); // pop&destroy list |
|
1933 |
|
1934 iSmspTimer->Start(iSmspBatchPause,this, ETimerIdSmsMessSmsp); |
|
1935 } |
|
1936 |
|
1937 TInt CSimSmsMessaging::GetSmspListPhase2(const TTsyReqHandle aTsyReqHandle, |
|
1938 TDes8* aParam1,TDes8* aParam2) |
|
1939 /** Get SMSP List phase 2 |
|
1940 * |
|
1941 * In this metod the list which was retrieved during phase 1 is copied to |
|
1942 * the memory which the client has allocated for this purose. |
|
1943 * @param aTsyReqHandle Const pointer to the request ID |
|
1944 * @param aClient Handle to the client which list we are looking for. |
|
1945 * @param aBuf Pointer to the memory that the etelmm has allocated. |
|
1946 * @return error code. |
|
1947 */ |
|
1948 { |
|
1949 UNPACK_PCKG(clientId,aParam1,RMobilePhone::TClientId); |
|
1950 TInt numberOfLists = iSmspReadAll->Count(); |
|
1951 // Find the get smsplists attempts from this client |
|
1952 for (TInt i = 0; i < numberOfLists; ++i) |
|
1953 { |
|
1954 CListReadAllAttempt* read=iSmspReadAll->At(i); |
|
1955 if ((read->iClient.iSessionHandle==clientId.iSessionHandle) && |
|
1956 (read->iClient.iSubSessionHandle==clientId.iSubSessionHandle)) |
|
1957 { |
|
1958 TPtr8 bufPtr((read->iListBuf)->Ptr(0)); |
|
1959 aParam2->Copy(bufPtr); // Copy the streamed list to the client |
|
1960 delete read; |
|
1961 iSmspReadAll->Delete(i); |
|
1962 ReqCompleted(aTsyReqHandle,KErrNone); // Completes the retrieval of a network list succesfully. |
|
1963 return KErrNone; |
|
1964 } |
|
1965 } |
|
1966 return(KErrNotFound); |
|
1967 } |
|
1968 |
|
1969 TInt CSimSmsMessaging::StoreSmspList(const TTsyReqHandle aTsyReqHandle, TDes8* aBuffer) |
|
1970 /** |
|
1971 * This function stores a new smsp list |
|
1972 * warning the new smsp list will only exist at run time. If the tsy is reloaded the smsp list |
|
1973 * will go back to the one defined in the configuration file |
|
1974 * @param aBuffer Descriptor containing the new smsp list |
|
1975 */ |
|
1976 { |
|
1977 if (iSmspBusy==EFalse) |
|
1978 { |
|
1979 iSmspBusy=ETrue; |
|
1980 TRAPD(leaveCode,iSmspEntries->RestoreL(*aBuffer)); |
|
1981 if (leaveCode) |
|
1982 return leaveCode; |
|
1983 iSmspReqHandle=aTsyReqHandle; |
|
1984 iSmspTimer->Start(iSmspBatchPause,this, ETimerIdSmsMessSmsp); |
|
1985 LOGSMS1("<<StoreSmsList,Exit function"); |
|
1986 return KErrNone; |
|
1987 } |
|
1988 else |
|
1989 LOGSMS1("<<StoreSmsList,Exit function"); |
|
1990 return KErrInUse; |
|
1991 |
|
1992 } |
|
1993 |
|
1994 void CSimSmsMessaging::StoreSmspListCancel() |
|
1995 /* |
|
1996 * Cancel an outstanding store smspList request |
|
1997 * as iSmspBusy mutexes get and store, only 1 request handle wil exist at a time |
|
1998 */ |
|
1999 { |
|
2000 if(iSmspBusy != EFalse) |
|
2001 { |
|
2002 iSmspTimer->Cancel(); |
|
2003 iSmspBusy=EFalse; |
|
2004 ReqCompleted(iSmspReqHandle,KErrNone);//The timer is cancelled but data has already been stored |
|
2005 } |
|
2006 } |
|
2007 |
|
2008 void CSimSmsMessaging::GetSmspListCancel() |
|
2009 /* |
|
2010 * Cancel an outstanding get smspList request. |
|
2011 * as iSmspBusy mutexes get and store, only 1 request handle wil exist at a time |
|
2012 */ |
|
2013 { |
|
2014 if(iSmspBusy != EFalse) |
|
2015 { |
|
2016 iSmspTimer->Cancel(); |
|
2017 iSmspBusy=EFalse; |
|
2018 ReqCompleted(iSmspReqHandle,KErrCancel); |
|
2019 } |
|
2020 } |
|
2021 |
|
2022 void CSimSmsMessaging::TimerCallBack(TInt aId) |
|
2023 /** |
|
2024 * Process a timer call back event. |
|
2025 * @param aId Contains the Id of the timer that triggered the event |
|
2026 * |
|
2027 */ |
|
2028 { |
|
2029 LOGSMS3(">>CSimSmsMesaging::TimerCallBack IN [aId=%d iSmsReceiveMode=%d]", aId, iSmsReceiveMode); |
|
2030 switch(aId) |
|
2031 { |
|
2032 case ETimerIdSmsMessTx: |
|
2033 { |
|
2034 TInt ret=ActionTxEvent(ESmsEventSubmitReportReceived); |
|
2035 __ASSERT_ALWAYS(ret==KErrNone,SimPanic(EIllegalSmsTxEvent)); // There should be no error from this action, but to check... |
|
2036 break; |
|
2037 } |
|
2038 case ETimerIdSmsMessSmsp: |
|
2039 { |
|
2040 iSmspBusy=EFalse; |
|
2041 ReqCompleted(iSmspReqHandle, KErrNone); |
|
2042 break; |
|
2043 } |
|
2044 case ETimerIdSmsMessRx: |
|
2045 { |
|
2046 TInt ret=0; |
|
2047 |
|
2048 switch (iSmsReceiveMode)//swich which state machine to enter |
|
2049 { |
|
2050 case RMobileSmsMessaging::EReceiveUnstoredClientAck: |
|
2051 ret=ActionRxEventUnstoredClientAck(ESmsEventRxTimer); |
|
2052 break; |
|
2053 case RMobileSmsMessaging::EReceiveUnstoredPhoneAck: |
|
2054 ret=ActionRxEventUnstoredPhoneAck(ESmsEventRxTimer); |
|
2055 break; |
|
2056 case RMobileSmsMessaging::EReceiveStored: |
|
2057 LOGSMS1("Recieve Stored SMS Rx Event."); |
|
2058 ret=ActionRxEventStored(ESmsEventRxTimer); |
|
2059 break; |
|
2060 default://other receive modes cannot be set |
|
2061 break; |
|
2062 }//end switch |
|
2063 |
|
2064 if (ret != KErrNone) |
|
2065 { |
|
2066 LOGSMS2("ERROR: Unexpected ret code %d", ret); |
|
2067 __ASSERT_ALWAYS(ret==KErrNone,SimPanic(EIllegalSmsRxEvent, __LINE__)); // There should be no error from this action, but to check... |
|
2068 } |
|
2069 |
|
2070 break; |
|
2071 } |
|
2072 |
|
2073 case ETimerIdSmsMessResumeReception: |
|
2074 { |
|
2075 if (iSmsRxReqOutstanding) |
|
2076 { |
|
2077 iRxState = ESmsRxStateWaitingForSmsRx; |
|
2078 } |
|
2079 else |
|
2080 { |
|
2081 iRxState = ESmsRxStateIdle; |
|
2082 } |
|
2083 StartSmsMtTimer(); |
|
2084 CompletePendingReq(); |
|
2085 break; |
|
2086 } |
|
2087 |
|
2088 default: |
|
2089 break; |
|
2090 } |
|
2091 LOGSMS1(">>CSimSmsMesaging::TimerCallBack OUT"); |
|
2092 } |
|
2093 |
|
2094 const CTestConfigSection* CSimSmsMessaging::CfgFileSection() |
|
2095 /** |
|
2096 * Returns a pointer to the config file section |
|
2097 * |
|
2098 * @return CTestConfigSection a pointer to the configuration file data section |
|
2099 */ |
|
2100 { |
|
2101 LOGSMS1(">>CSimSmsMessaging::CfgFileSection"); |
|
2102 return iPhone->CfgFile(); |
|
2103 } |
|
2104 |
|
2105 |
|
2106 TInt CSimSmsMessaging::ReloadConfigL(const TTsyReqHandle aReqHandle) |
|
2107 /** |
|
2108 * This function reloads the Rx, Tx and constraint parameters from the config file |
|
2109 * @param aReqHandle Handle to notify when operation completed |
|
2110 * @return KErrNone |
|
2111 */ |
|
2112 { |
|
2113 LOGSMS1("Reloading configuration"); |
|
2114 //Tell SimPhone to reread the test number property |
|
2115 iPhone->ResetTestNumber(); |
|
2116 //Delete current configuration |
|
2117 iSmsRxParameterListGsm->Reset(); |
|
2118 iSmsTxParametersListGsm->Reset(); |
|
2119 |
|
2120 iSmsTxCnt = 0; |
|
2121 iSmsRxCnt = 0; |
|
2122 iConstraints.Reset(); |
|
2123 iCurrentConstraint = 0; |
|
2124 iConstraintRxCnt = 0; |
|
2125 //Reread the configuration |
|
2126 TInt err; |
|
2127 TRAP(err, FindAndCreateRxAttributesL()); |
|
2128 if (err != KErrNone) return err; |
|
2129 TRAP(err, FindAndCreateTxAttributesL()); |
|
2130 if (err != KErrNone) return err; |
|
2131 FindAndCreateConstraints(); |
|
2132 |
|
2133 TInt count; |
|
2134 count = iSmsRxParameterListGsm->Count(); |
|
2135 |
|
2136 if((count>0)&&(iConstraints.Count()==0)) // If there are messages to receive & no constraints, then |
|
2137 { |
|
2138 if (iRxTimer->Running()) |
|
2139 { |
|
2140 iRxTimer->Cancel(); |
|
2141 } |
|
2142 LOGSMS1("Starting Rx Timer"); |
|
2143 iRxStatePrevious = iRxState; |
|
2144 iRxState = ESmsRxStateWaitingToStart; |
|
2145 iRxTimer->Start(iSmsRxStartDelay,this, ETimerIdSmsMessRx); |
|
2146 } |
|
2147 else if (iRxTimer->Running()) |
|
2148 { |
|
2149 LOGSMS1("Stopping Rx Timer"); |
|
2150 iRxTimer->Cancel(); |
|
2151 } |
|
2152 |
|
2153 LOGSMS1("Finished reloading configuration"); |
|
2154 ReqCompleted(aReqHandle,KErrNone); |
|
2155 return KErrNone; |
|
2156 } |
|
2157 |
|
2158 HBufC8* CSimSmsMessaging::PduToAscii(TDesC8& aSmsPdu) |
|
2159 /** |
|
2160 * Converts the contents of a TDes8 to their Hex representation |
|
2161 * @param aSmsPdu Reference to the descriptor to convert |
|
2162 * @return A pointer to an HBufC8 containing the Hex representation of aSmsPdu. The caller is responsible for freeing the object. |
|
2163 * @return Null if the HBufC8 was not successfuly created. |
|
2164 */ |
|
2165 { |
|
2166 HBufC8* hexBuf = HBufC8::New(aSmsPdu.Length()*2+1); |
|
2167 if (hexBuf == NULL) return NULL; |
|
2168 TPtr8 des = hexBuf->Des(); |
|
2169 des.FillZ(); |
|
2170 des.Zero(); |
|
2171 if (hexBuf != NULL) |
|
2172 { |
|
2173 for (TInt i = 0; i < aSmsPdu.Length(); i++) |
|
2174 { |
|
2175 TInt left = (aSmsPdu[i] & 0xF0) >> 4; |
|
2176 TInt right = aSmsPdu[i] & 0x0F; |
|
2177 if (left < 10) |
|
2178 { |
|
2179 des.Append(0x30 + left); |
|
2180 } |
|
2181 else |
|
2182 { |
|
2183 des.Append(0x41 + (left - 10)); |
|
2184 } |
|
2185 if (right < 10) |
|
2186 { |
|
2187 des.Append(0x30 + right); |
|
2188 } |
|
2189 else |
|
2190 { |
|
2191 des.Append(0x41 + (right - 10)); |
|
2192 } |
|
2193 } |
|
2194 } |
|
2195 des.Append(0); |
|
2196 return hexBuf; |
|
2197 } |
|
2198 |
|
2199 #ifdef _DEBUG // to prevent UREL build warnings |
|
2200 void CSimSmsMessaging::DumpPdu(const TDesC8& aText, TDesC8& aSmsPdu, HBufC8* aPduInAscii) |
|
2201 #else |
|
2202 void CSimSmsMessaging::DumpPdu(const TDesC8& /*aText*/, TDesC8& aSmsPdu, HBufC8* aPduInAscii) |
|
2203 #endif |
|
2204 /** |
|
2205 Print PDU in a loop, 150 chars per line |
|
2206 @param aText - a header line about the PDU. |
|
2207 @param aSmsPdu - PDU to log. |
|
2208 @param aPduInAscii - aSmsPdu in ASCII format (default NULL). |
|
2209 */ |
|
2210 { |
|
2211 LOGSMS3("%S pdu length=%d", &aText, aSmsPdu.Length()); |
|
2212 |
|
2213 if( !aSmsPdu.Length() ) |
|
2214 return; |
|
2215 |
|
2216 // In sendPdu case, caller needs to call PduToAscii for comparison. |
|
2217 // Then aPduInAscii is non-zero. |
|
2218 HBufC8* hexBuf = (aPduInAscii) ? aPduInAscii : PduToAscii(aSmsPdu); |
|
2219 if (! hexBuf) |
|
2220 return; |
|
2221 |
|
2222 //Print the pdu in a loop because LOGTEXT can only print up to 150 characters |
|
2223 for (TInt i = 0; i < hexBuf->Length(); i+=100) |
|
2224 { |
|
2225 TInt len = Min(100, hexBuf->Mid(i).Length()); |
|
2226 TPtrC8 pduChunk(hexBuf->Mid(i).Left(len).Ptr(), len); |
|
2227 LOGSMS2("PDU Chunk: %S:", &pduChunk); |
|
2228 } |
|
2229 |
|
2230 if (0 == aPduInAscii) |
|
2231 delete hexBuf; |
|
2232 } |
|
2233 |
|
2234 #ifdef _DEBUG |
|
2235 |
|
2236 /** |
|
2237 Appends Type of number and Numbering plan identification to TBuf8 buffer. |
|
2238 |
|
2239 @param aBuffer Name of aTon will be appended to this buffer. |
|
2240 @param aTon TMobileTON whose name will be appended to aBuffer. |
|
2241 */ |
|
2242 void CSimSmsMessaging::AppendTonToBuffer(TDes8& aBuffer,const RMobilePhone::TMobileTON& aTon) |
|
2243 { |
|
2244 switch(aTon) |
|
2245 { |
|
2246 case (RMobilePhone::EUnknownNumber): |
|
2247 { |
|
2248 aBuffer.Append(_L("EUnknownNumber")); |
|
2249 break; |
|
2250 } |
|
2251 case (RMobilePhone::EInternationalNumber): |
|
2252 { |
|
2253 aBuffer.Append(_L("EInternationalNumber")); |
|
2254 break; |
|
2255 } |
|
2256 case (RMobilePhone::ENationalNumber): |
|
2257 { |
|
2258 aBuffer.Append(_L("ENationalNumber")); |
|
2259 break; |
|
2260 } |
|
2261 case (RMobilePhone::ENetworkSpecificNumber): |
|
2262 { |
|
2263 aBuffer.Append(_L("ENetworkSpecificNumber")); |
|
2264 break; |
|
2265 } |
|
2266 case (RMobilePhone::ESubscriberNumber): |
|
2267 { |
|
2268 aBuffer.Append(_L("ESubscriberNumber")); |
|
2269 break; |
|
2270 } |
|
2271 case (RMobilePhone::EAlphanumericNumber): |
|
2272 { |
|
2273 aBuffer.Append(_L("EAlphanumericNumber")); |
|
2274 break; |
|
2275 } |
|
2276 case (RMobilePhone::EAbbreviatedNumber): |
|
2277 { |
|
2278 aBuffer.Append(_L("EAbbreviatedNumber")); |
|
2279 break; |
|
2280 } |
|
2281 default: |
|
2282 aBuffer.Append(_L("Wrong Ton Type")); |
|
2283 } |
|
2284 } |
|
2285 |
|
2286 void CSimSmsMessaging::AppendNpiToBuffer(TDes8& aBuffer,const RMobilePhone::TMobileNPI& aNpi) |
|
2287 /** |
|
2288 * Appends Numbering plan identification to TBuf8 buffer. |
|
2289 */ |
|
2290 { |
|
2291 switch(aNpi) |
|
2292 { |
|
2293 case (RMobilePhone::EUnknownNumberingPlan): |
|
2294 { |
|
2295 aBuffer.Append(_L("EUnknownNumberingPlan")); |
|
2296 break; |
|
2297 } |
|
2298 case (RMobilePhone::EIsdnNumberPlan): |
|
2299 { |
|
2300 aBuffer.Append(_L("EIsdnNumberPlan")); |
|
2301 break; |
|
2302 } |
|
2303 case (RMobilePhone::EDataNumberPlan): |
|
2304 { |
|
2305 aBuffer.Append(_L("EDataNumberPlan")); |
|
2306 break; |
|
2307 } |
|
2308 case (RMobilePhone::ETelexNumberPlan): |
|
2309 { |
|
2310 aBuffer.Append(_L("ETelexNumberPlan")); |
|
2311 break; |
|
2312 } |
|
2313 case (RMobilePhone::EServiceCentreSpecificPlan1): |
|
2314 { |
|
2315 aBuffer.Append(_L("EServiceCentreSpecificPlan1")); |
|
2316 break; |
|
2317 } |
|
2318 case (RMobilePhone::EServiceCentreSpecificPlan2): |
|
2319 { |
|
2320 aBuffer.Append(_L("EServiceCentreSpecificPlan2")); |
|
2321 break; |
|
2322 } |
|
2323 case (RMobilePhone::ENationalNumberPlan): |
|
2324 { |
|
2325 aBuffer.Append(_L("ENationalNumberPlan")); |
|
2326 break; |
|
2327 } |
|
2328 case (RMobilePhone::EPrivateNumberPlan): |
|
2329 { |
|
2330 aBuffer.Append(_L("EPrivateNumberPlan")); |
|
2331 break; |
|
2332 } |
|
2333 case (RMobilePhone::EERMESNumberPlan): |
|
2334 { |
|
2335 aBuffer.Append(_L("EERMESNumberPlan")); |
|
2336 break; |
|
2337 } |
|
2338 default: |
|
2339 aBuffer.Append(_L("Wrong Npi Type")); |
|
2340 } |
|
2341 } |
|
2342 |
|
2343 void CSimSmsMessaging::LogTMobileSmsAttributesV1(const RMobileSmsMessaging::TMobileSmsAttributesV1& aSmsAttributesV1) |
|
2344 { |
|
2345 const TInt KTextWidth = 100; |
|
2346 _LIT8(KFLAGS, " iFlags: "); |
|
2347 _LIT8(KSCADDR, " SC Address: "); |
|
2348 _LIT8(KSCADDRTON, " SC Addr TON: "); |
|
2349 _LIT8(KSCADDRNPI, " SC Addr NPI: "); |
|
2350 _LIT8(KDATAFORMAT, " iDataFormat: "); |
|
2351 _LIT8(KDEADDR, " DE Address: "); |
|
2352 _LIT8(KDEADDRTON, " DE Addr TON: "); |
|
2353 _LIT8(KDEADDRNPI, " DE Addr NPI: "); |
|
2354 _LIT8(KMORETOSEND, " iMore: "); |
|
2355 _LIT8(KMSGREF, " iMsgRef: "); |
|
2356 _LIT8(KSUBMITREP, " iSubmitRep: "); |
|
2357 |
|
2358 TBuf8<KTextWidth> buffer; |
|
2359 |
|
2360 LOGSMS1("Send Sms Attributes:"); |
|
2361 |
|
2362 buffer.Zero(); |
|
2363 buffer.Copy(KFLAGS); |
|
2364 buffer.Append(_L8("0x")); |
|
2365 buffer.AppendFormat(_L8("%08X") , ((TInt)(aSmsAttributesV1.iFlags))); |
|
2366 LOGSMS2("Buffer: %S", &buffer); |
|
2367 |
|
2368 if(aSmsAttributesV1.iFlags & RMobileSmsMessaging::KGsmServiceCentre) |
|
2369 { |
|
2370 buffer.Zero(); |
|
2371 buffer.Copy(KSCADDR); |
|
2372 buffer.Append(aSmsAttributesV1.iGsmServiceCentre.iTelNumber); |
|
2373 LOGSMS2("buffer: %S", &buffer); |
|
2374 |
|
2375 buffer.Zero(); |
|
2376 buffer.Copy(KSCADDRTON); |
|
2377 AppendTonToBuffer(buffer,(aSmsAttributesV1.iGsmServiceCentre.iTypeOfNumber)); |
|
2378 LOGSMS2("buffer: %S", &buffer); |
|
2379 |
|
2380 buffer.Zero(); |
|
2381 buffer.Copy(KSCADDRNPI); |
|
2382 AppendNpiToBuffer(buffer,(aSmsAttributesV1.iGsmServiceCentre.iNumberPlan)); |
|
2383 LOGSMS2("buffer: %S", &buffer); |
|
2384 } |
|
2385 if(aSmsAttributesV1.iFlags & RMobileSmsMessaging::KSmsDataFormat) |
|
2386 { |
|
2387 buffer.Zero(); |
|
2388 buffer.Copy(KDATAFORMAT); |
|
2389 if(aSmsAttributesV1.iDataFormat == RMobileSmsMessaging::EFormatUnspecified) |
|
2390 { |
|
2391 buffer.Append(_L("EFormatUnspecified")); |
|
2392 } |
|
2393 else if(aSmsAttributesV1.iDataFormat == RMobileSmsMessaging::EFormatGsmTpdu) |
|
2394 { |
|
2395 buffer.Append(_L("EFormatGsmTpdu")); |
|
2396 } |
|
2397 LOGSMS2("buffer: %S", &buffer); |
|
2398 } |
|
2399 if(aSmsAttributesV1.iFlags & RMobileSmsMessaging::KRemotePartyInfo) |
|
2400 { |
|
2401 const RMobileSmsMessaging::TMobileSmsSendAttributesV1& smsSendAttributesV1 = static_cast<const RMobileSmsMessaging::TMobileSmsSendAttributesV1&> (aSmsAttributesV1); |
|
2402 |
|
2403 buffer.Zero(); |
|
2404 buffer.Copy(KDEADDR); |
|
2405 buffer.Append(smsSendAttributesV1.iDestination.iTelNumber); |
|
2406 LOGSMS2("buffer: %S", &buffer); |
|
2407 |
|
2408 buffer.Zero(); |
|
2409 buffer.Copy(KDEADDRTON); |
|
2410 AppendTonToBuffer(buffer,(smsSendAttributesV1.iDestination.iTypeOfNumber)); |
|
2411 LOGSMS2("buffer: %S", &buffer); |
|
2412 |
|
2413 buffer.Zero(); |
|
2414 buffer.Copy(KDEADDRNPI); |
|
2415 AppendNpiToBuffer(buffer,(smsSendAttributesV1.iDestination.iNumberPlan)); |
|
2416 LOGSMS2("buffer: %S", &buffer); |
|
2417 } |
|
2418 if(aSmsAttributesV1.iFlags & RMobileSmsMessaging::KMoreToSend) |
|
2419 { |
|
2420 const RMobileSmsMessaging::TMobileSmsSendAttributesV1& smsSendAttributesV1 = static_cast<const RMobileSmsMessaging::TMobileSmsSendAttributesV1&> (aSmsAttributesV1); |
|
2421 |
|
2422 buffer.Zero(); |
|
2423 buffer.Copy(KMORETOSEND); |
|
2424 |
|
2425 if(smsSendAttributesV1.iMore) |
|
2426 { |
|
2427 buffer.Append(_L8("ETrue")); |
|
2428 } |
|
2429 else |
|
2430 { |
|
2431 buffer.Append(_L8("EFalse")); |
|
2432 } |
|
2433 LOGSMS2("buffer: %S", &buffer); |
|
2434 } |
|
2435 if(aSmsAttributesV1.iFlags & RMobileSmsMessaging::KMessageReference) |
|
2436 { |
|
2437 const RMobileSmsMessaging::TMobileSmsSendAttributesV1& smsSendAttributesV1 = static_cast<const RMobileSmsMessaging::TMobileSmsSendAttributesV1&> (aSmsAttributesV1); |
|
2438 |
|
2439 buffer.Zero(); |
|
2440 buffer.Copy(KMSGREF); |
|
2441 buffer.Append(_L("0x")); |
|
2442 buffer.AppendFormat(_L8("%08X") , smsSendAttributesV1.iMsgRef); |
|
2443 LOGSMS2("buffer: %S", &buffer); |
|
2444 } |
|
2445 |
|
2446 if(aSmsAttributesV1.iFlags & RMobileSmsMessaging::KGsmSubmitReport) |
|
2447 { |
|
2448 const RMobileSmsMessaging::TMobileSmsSendAttributesV1& smsSendAttributesV1 = static_cast<const RMobileSmsMessaging::TMobileSmsSendAttributesV1&> (aSmsAttributesV1); |
|
2449 |
|
2450 buffer.Zero(); |
|
2451 buffer.Copy(KSUBMITREP); |
|
2452 |
|
2453 TInt i = buffer.Length(); |
|
2454 TInt j(0); |
|
2455 TInt k = (smsSendAttributesV1.iSubmitReport.Length() * 2) + buffer.Length(); |
|
2456 |
|
2457 TInt l = 0; |
|
2458 do |
|
2459 { |
|
2460 for(;i<=(KTextWidth-2);i+=2) |
|
2461 { |
|
2462 if(j==smsSendAttributesV1.iSubmitReport.Length()) |
|
2463 { |
|
2464 break; |
|
2465 } |
|
2466 buffer.AppendFormat(_L8("%X") , smsSendAttributesV1.iSubmitReport[j]); |
|
2467 j++; |
|
2468 } |
|
2469 LOGSMS2("buffer: %S", &buffer); |
|
2470 buffer.Zero(); |
|
2471 i=0; |
|
2472 l+=KTextWidth; |
|
2473 } |
|
2474 while(l < k); |
|
2475 } |
|
2476 } |
|
2477 |
|
2478 #endif // _DEBUG |