|
1 // Copyright (c) 2003-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 #include <e32base.h> |
|
17 #include <f32file.h> |
|
18 #include "smsprot.h" |
|
19 #include "WAPDGRM.H" |
|
20 #include "wappstor.h" |
|
21 #include "ws_main.h" |
|
22 #include "es_wsms.h" |
|
23 #include "ws_obsvr.h" |
|
24 #include "SmsuBackup.h" |
|
25 |
|
26 // |
|
27 // Sets the values used for the local wap ports |
|
28 // Limits the number of simultaneously open SAPs to 254 |
|
29 // |
|
30 const TInt KMaxWapPortNumber = 255; |
|
31 const TInt KMinWapPortNumber = 1; |
|
32 |
|
33 const TInt KMax8BitPortNumber = 255; |
|
34 const TInt KMax16BitPortNumber = 65535; |
|
35 |
|
36 |
|
37 /** |
|
38 * Constructor |
|
39 */ |
|
40 CWapSmsProtocol::CWapSmsProtocol() |
|
41 { |
|
42 iSAPList.SetOffset(CWapSmsProvider::LinkOffset()); |
|
43 } // CWapSmsProtocol::CWapSmsProtocol |
|
44 |
|
45 |
|
46 // |
|
47 // Factory |
|
48 // |
|
49 CWapSmsProtocol* CWapSmsProtocol::NewL() |
|
50 { |
|
51 LOGWAPPROT1("CWapSmsProtocol::NewL()"); |
|
52 |
|
53 CWapSmsProtocol* p=new(ELeave) CWapSmsProtocol; |
|
54 CleanupStack::PushL(p); |
|
55 User::LeaveIfError(p->iFs.Connect()); |
|
56 p->iObserver[0]=CWapProtocolObserver::NewL(p); |
|
57 p->iObserver[1]=CWapProtocolObserver::NewL(p); |
|
58 p->iObserver[2]=CWapProtocolObserver::NewL(p); |
|
59 p->iWapStore=CWapReassemblyStore::NewL(p->iFs); |
|
60 |
|
61 p->iBackupRestoreSession=CBackupAndRestore::NewL(*p); |
|
62 CleanupStack::Pop(); |
|
63 return p; |
|
64 } // CWapSmsProtocol::NewL |
|
65 |
|
66 |
|
67 void CWapSmsProtocol::HandleBackupOrRestoreStartingL() |
|
68 { |
|
69 LOGWAPPROT1("CWapSmsProtocol::HandleBackupOrRestoreStartingL"); |
|
70 iWapStore->Close(); |
|
71 } // CWapSmsProtocol::HandleBackupOrRestoreStartingL |
|
72 |
|
73 |
|
74 void CWapSmsProtocol::HandleBackupOrRestoreCompleteL() |
|
75 { |
|
76 LOGWAPPROT1("CWapSmsProtocol::HandleBackupOrRestoreCompleteL "); |
|
77 iWapStore->DoOpenL(); |
|
78 } // CWapSmsProtocol::HandleBackupOrRestoreCompleteL |
|
79 |
|
80 |
|
81 /** |
|
82 * Destructor |
|
83 */ |
|
84 CWapSmsProtocol::~CWapSmsProtocol() |
|
85 { |
|
86 delete iBackupRestoreSession; |
|
87 |
|
88 RemoveObserversFromSmsProtocol(); |
|
89 delete iObserver[0]; |
|
90 delete iObserver[1]; |
|
91 delete iObserver[2]; |
|
92 delete iWapStore; |
|
93 |
|
94 if (iSmsProtocol) |
|
95 { |
|
96 iSmsProtocol->Close(); |
|
97 } |
|
98 |
|
99 iFs.Close(); |
|
100 } // CWapSmsProtocol::~CWapSmsProtocol |
|
101 |
|
102 |
|
103 // |
|
104 // Socket server asking for a new sap |
|
105 // |
|
106 CServProviderBase *CWapSmsProtocol::NewSAPL(TUint aSocketType) |
|
107 { |
|
108 LOGWAPPROT1("*CWapSmsProtocol::NewSAPL"); |
|
109 |
|
110 if (aSocketType!=KSockDatagram) |
|
111 User::Leave(KErrNotSupported); |
|
112 CWapSmsProvider *pSAP = CWapSmsProvider::NewL(this); |
|
113 AddSAP(pSAP, aSocketType); |
|
114 return pSAP; |
|
115 } // CWapSmsProtocol::NewSAPL |
|
116 |
|
117 |
|
118 // |
|
119 // InitL call from socket server. |
|
120 // |
|
121 void CWapSmsProtocol::InitL(TDesC& /*aTag*/) |
|
122 { |
|
123 } |
|
124 |
|
125 |
|
126 // |
|
127 // Called by another protocol that runs on top of WAP |
|
128 // |
|
129 void CWapSmsProtocol::BindL(CProtocolBase* /*aProtocol*/, TUint /*aId*/) |
|
130 { |
|
131 // Ignore in code coverage - not intended to be used |
|
132 BULLSEYE_OFF |
|
133 LOGWAPPROT1("CWapSmsProtocol::BindL"); |
|
134 Panic(EWapSmsCantBind); |
|
135 BULLSEYE_RESTORE |
|
136 } |
|
137 |
|
138 // |
|
139 // StartL call from socket server. |
|
140 // Open lower layers |
|
141 // |
|
142 void CWapSmsProtocol::StartL() |
|
143 { |
|
144 } |
|
145 |
|
146 |
|
147 // |
|
148 // Identify request from SOCKET server |
|
149 // |
|
150 void CWapSmsProtocol::Identify(TServerProtocolDesc *aDes) const |
|
151 { |
|
152 LOGWAPPROT1("CWapSmsProtocol::Identify"); |
|
153 |
|
154 aDes->iName=KWAPSMSProtocolId; |
|
155 aDes->iAddrFamily=KWAPSMSAddrFamily; |
|
156 aDes->iSockType=KSockDatagram; |
|
157 aDes->iProtocol=KWAPSMSDatagramProtocol; |
|
158 |
|
159 aDes->iVersion=TVersion(KWapSmsMajorVersionNumber,KWapSmsMinorVersionNumber,KWapSmsBuildVersionNumber); |
|
160 aDes->iByteOrder=ELittleEndian; |
|
161 aDes->iServiceInfo=KWAPSMSDatagramServiceInfo; |
|
162 aDes->iNamingServices=0; |
|
163 aDes->iSecurity=KSocketNoSecurity; |
|
164 aDes->iMessageSize=KWAPSMSMaxDatagramSize; |
|
165 aDes->iServiceTypeInfo=0; |
|
166 aDes->iNumSockets=KWAPSMSNumberSockets; |
|
167 } // CWapSmsProtocol::Identify |
|
168 |
|
169 |
|
170 // |
|
171 // Called by socket server to initiate bind to SMS protocol |
|
172 // |
|
173 void CWapSmsProtocol::BindToL(CProtocolBase* aProtocol) |
|
174 { |
|
175 LOGWAPPROT1("CWapSmsProtocol::BindToL"); |
|
176 |
|
177 TServerProtocolDesc info; |
|
178 aProtocol->Identify(&info); |
|
179 TUint theirId = info.iProtocol; |
|
180 Identify(&info); |
|
181 TUint ourId = info.iProtocol; |
|
182 |
|
183 if (theirId==ourId) |
|
184 User::Leave(KErrGeneral); // Nutter! |
|
185 |
|
186 if (theirId!=KSMSDatagramProtocol) |
|
187 User::Leave(KErrGeneral); |
|
188 |
|
189 iSmsProtocol = (CSmsProtocol*)aProtocol; |
|
190 iSmsProtocol->Open(); |
|
191 iSmsProtocol->StartL(); |
|
192 BindObserversToSmsL(); |
|
193 } // CWapSmsProtocol::BindToL |
|
194 |
|
195 |
|
196 // |
|
197 // Register the observers with sms.prt |
|
198 // |
|
199 void CWapSmsProtocol::BindObserversToSmsL() |
|
200 { |
|
201 LOGWAPPROT1("CWapSmsProtocol::BindObserversToSmsL"); |
|
202 |
|
203 iNextSapPort=KMinWapPortNumber; |
|
204 TSmsAddr addr0; |
|
205 TSmsAddr addr1; |
|
206 TSmsAddr addr2; |
|
207 |
|
208 addr0.SetSmsAddrFamily(ESmsAddrMatchIEI); |
|
209 addr0.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing8Bit); |
|
210 addr1.SetSmsAddrFamily(ESmsAddrMatchIEI); |
|
211 addr1.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing16Bit); |
|
212 addr2.SetSmsAddrFamily(ESmsAddrMatchText); |
|
213 addr2.SetTextMatch(_L8("//SCK")); |
|
214 |
|
215 iSmsProtocol->AddSmsMessageObserverL(*iObserver[0]); |
|
216 TInt ret=iSmsProtocol->BindSmsMessageObserver(*iObserver[0],addr0); |
|
217 User::LeaveIfError(ret); |
|
218 |
|
219 iSmsProtocol->AddSmsMessageObserverL(*iObserver[1]); |
|
220 ret=iSmsProtocol->BindSmsMessageObserver(*iObserver[1],addr1); |
|
221 User::LeaveIfError(ret); |
|
222 |
|
223 iSmsProtocol->AddSmsMessageObserverL(*iObserver[2]); |
|
224 ret=iSmsProtocol->BindSmsMessageObserver(*iObserver[2],addr2); |
|
225 User::LeaveIfError(ret); |
|
226 } // CWapSmsProtocol::BindObserversToSmsL |
|
227 |
|
228 |
|
229 // |
|
230 // Deregister the observers |
|
231 // |
|
232 void CWapSmsProtocol::RemoveObserversFromSmsProtocol() |
|
233 { |
|
234 LOGWAPPROT1("CWapSmsProtocol::RemoveObserversFromSmsProtocol"); |
|
235 |
|
236 if (iSmsProtocol==NULL) |
|
237 return; |
|
238 iSmsProtocol->RemoveSmsMessageObserver(*iObserver[0]); |
|
239 iSmsProtocol->RemoveSmsMessageObserver(*iObserver[1]); |
|
240 iSmsProtocol->RemoveSmsMessageObserver(*iObserver[2]); |
|
241 } // CWapSmsProtocol::RemoveObserversFromSmsProtocol |
|
242 |
|
243 |
|
244 // |
|
245 // Send a datagram originating from a higher protocol |
|
246 // Can never be called as we don't implement BindL |
|
247 // |
|
248 // |
|
249 TInt CWapSmsProtocol::Send(TDes8 &, TSockAddr* /*to*/,TSockAddr* /*from*/,CProtocolBase* /*aSourceProtocol*/) |
|
250 { |
|
251 // Ignore in code coverage - not intended to be used |
|
252 BULLSEYE_OFF |
|
253 LOGWAPPROT1("CWapSmsProtocol::Send"); |
|
254 Panic(EWapSmsSendCallCantBind); |
|
255 return KErrNone; |
|
256 BULLSEYE_RESTORE |
|
257 } |
|
258 |
|
259 // |
|
260 // Receive an SMS |
|
261 // |
|
262 void CWapSmsProtocol::ProcessSmsL(const CSmsMessage& aSmsMessage) |
|
263 { |
|
264 LOGWAPPROT1("CWapSmsProtocol::ProcessSmsL"); |
|
265 TInt index=0; |
|
266 TBool storeDatagramComplete = EFalse; |
|
267 TBool isNewStyleClient = EFalse; |
|
268 |
|
269 __ASSERT_DEBUG(aSmsMessage.IsComplete(),Panic(EWapSmsIncompleteSms)); |
|
270 |
|
271 CWapDatagram* wapDatagram = CWapDatagram::NewL(aSmsMessage); |
|
272 |
|
273 CleanupStack::PushL(wapDatagram); |
|
274 TBool isCompleteDatagram = wapDatagram->IsComplete(); |
|
275 if (!isCompleteDatagram) |
|
276 { |
|
277 |
|
278 storeDatagramComplete = iWapStore->AddMessageL(index,*wapDatagram); |
|
279 if (!storeDatagramComplete) |
|
280 { |
|
281 CleanupStack::PopAndDestroy(wapDatagram); |
|
282 return; |
|
283 } |
|
284 iWapStore->GetDatagramL(index,*wapDatagram); |
|
285 } |
|
286 |
|
287 CWapSmsProvider* wapsmsProvider = LookupSAP(wapDatagram); |
|
288 |
|
289 if (wapsmsProvider) |
|
290 { |
|
291 isNewStyleClient= wapsmsProvider->IsNewStyleClient(); |
|
292 if(isCompleteDatagram && isNewStyleClient)//8 bit datagram or complete messages, Need to store it for new clients |
|
293 { |
|
294 storeDatagramComplete = iWapStore->AddMessageL(index,*wapDatagram); |
|
295 if (!storeDatagramComplete) |
|
296 { |
|
297 CleanupStack::PopAndDestroy(wapDatagram); |
|
298 return; |
|
299 } |
|
300 } |
|
301 if(!isNewStyleClient && !isCompleteDatagram) |
|
302 { |
|
303 iWapStore->BeginTransactionLC(); |
|
304 iWapStore->DeleteEntryL(index); |
|
305 iWapStore->CommitTransactionL(); |
|
306 } |
|
307 CleanupStack::Pop(wapDatagram); |
|
308 wapsmsProvider->AddToQueue(wapDatagram); |
|
309 return; |
|
310 } |
|
311 else if(!isCompleteDatagram) |
|
312 { |
|
313 iWapStore->BeginTransactionLC(); |
|
314 iWapStore->DeleteEntryL(index); |
|
315 iWapStore->CommitTransactionL(); |
|
316 } |
|
317 |
|
318 CleanupStack::PopAndDestroy(wapDatagram); |
|
319 User::Leave(KErrNotFound); |
|
320 } // CWapSmsProtocol::ProcessSmsL |
|
321 |
|
322 |
|
323 // |
|
324 // Get Wap Protocol options |
|
325 // If none match the level/name pass the query on to SMS |
|
326 // |
|
327 TInt CWapSmsProtocol::GetOption(TUint aLevel, TUint aName, TDes8& aOption, CProtocolBase* /*aSourceProtocol*/) |
|
328 { |
|
329 LOGWAPPROT1("CWapSmsProtocol::GetOption"); |
|
330 |
|
331 TInt ret = iSmsProtocol->GetOption(aLevel, aName, aOption,this); |
|
332 return ret; |
|
333 } // CWapSmsProtocol::GetOption |
|
334 |
|
335 |
|
336 // |
|
337 // Set Wap Protocol options |
|
338 // If none match the level/name pass the query on to SMS |
|
339 // |
|
340 TInt CWapSmsProtocol::SetOption(TUint aLevel, TUint aName, const TDesC8& aOption, CProtocolBase* /*aSourceProtocol*/) |
|
341 { |
|
342 LOGWAPPROT1("CWapSmsProtocol::SetOption"); |
|
343 |
|
344 TInt ret= iSmsProtocol->SetOption(aLevel,aName,aOption,this); |
|
345 return ret; |
|
346 } // CWapSmsProtocol::SetOption |
|
347 |
|
348 |
|
349 // |
|
350 // Inform all SAPs of error. |
|
351 // |
|
352 void CWapSmsProtocol::Error(TInt aError, CProtocolBase* /*aSourceProtocol*/) |
|
353 { |
|
354 LOGWAPPROT1("CWapSmsProtocol::Error"); |
|
355 |
|
356 TDblQueIter<CWapSmsProvider> iter(iSAPList); |
|
357 CWapSmsProvider* sap; |
|
358 while (sap = iter++, sap!=NULL) |
|
359 sap->Error(aError,MSocketNotify::EErrorAllOperations); |
|
360 } |
|
361 |
|
362 // |
|
363 // Socket server asking for a host resolver |
|
364 // |
|
365 CHostResolvProvdBase *CWapSmsProtocol::NewHostResolverL() |
|
366 { |
|
367 // Ignore in code coverage - not intended to be used |
|
368 BULLSEYE_OFF |
|
369 LOGWAPPROT1("*CWapSmsProtocol::NewHostResolverL"); |
|
370 Panic(EWapSmsCantCreateHostResolver); |
|
371 return NULL; |
|
372 BULLSEYE_RESTORE |
|
373 } |
|
374 |
|
375 // |
|
376 // Socket server asking for a service resolver |
|
377 // |
|
378 CServiceResolvProvdBase *CWapSmsProtocol::NewServiceResolverL() |
|
379 { |
|
380 // Ignore in code coverage - not intended to be used |
|
381 BULLSEYE_OFF |
|
382 LOGWAPPROT1("*CWapSmsProtocol::NewServiceResolverL"); |
|
383 Panic(EWapSmsCantCreateServiceResolver); |
|
384 return NULL; |
|
385 BULLSEYE_RESTORE |
|
386 } |
|
387 |
|
388 // |
|
389 // Socket server asking for a net data base |
|
390 // |
|
391 CNetDBProvdBase* CWapSmsProtocol::NewNetDatabaseL() |
|
392 { |
|
393 // Ignore in code coverage - not intended to be used |
|
394 BULLSEYE_OFF |
|
395 LOGWAPPROT1("CWapSmsProtocol::NewNetDatabaseL"); |
|
396 Panic(EWapSmsCantCreateNetDatabase); |
|
397 return NULL; |
|
398 BULLSEYE_RESTORE |
|
399 } |
|
400 |
|
401 // |
|
402 // Add a SAP to the SAP list and checks the SAR store for this SAP's entries |
|
403 // |
|
404 void CWapSmsProtocol::AddSAP(CWapSmsProvider* aSAP, TUint /*aSockType*/) |
|
405 { |
|
406 LOGWAPPROT1("CWapSmsProtocol::AddSAP"); |
|
407 |
|
408 iSAPList.AddLast(*aSAP); |
|
409 } // CWapSmsProtocol::AddSAP |
|
410 |
|
411 |
|
412 // |
|
413 // Set the sap port number |
|
414 // |
|
415 TBool CWapSmsProtocol::AllocateLocalAddress(TWapAddr& aAddr) |
|
416 { |
|
417 LOGWAPPROT1("CWapSmsProtocol::AllocateLocalAddressL"); |
|
418 // |
|
419 TBool found=EFalse; |
|
420 TUint count=0,attempts=0; |
|
421 count =KMaxWapPortNumber-KMinWapPortNumber+1; |
|
422 |
|
423 TSmsAddr addr8; |
|
424 addr8.SetSmsAddrFamily(ESmsAddrApplication8BitPort); |
|
425 |
|
426 for(;!found && attempts < count;attempts++) |
|
427 { |
|
428 addr8.SetPort(iNextSapPort++); |
|
429 if(iNextSapPort > KMaxWapPortNumber)iNextSapPort=KMinWapPortNumber; |
|
430 if(!iSmsProtocol->SmsAddrIsAlreadyUsed(NULL,addr8))found=ETrue; |
|
431 } |
|
432 if(found) |
|
433 aAddr.SetWapPort(static_cast<TWapPortNumber>(addr8.Port())); |
|
434 |
|
435 return found; |
|
436 } // CWapSmsProtocol::AllocateLocalAddress |
|
437 |
|
438 |
|
439 // |
|
440 // Find the provider who wants the message |
|
441 // |
|
442 CWapSmsProvider* CWapSmsProtocol::LookupSAP(CWapDatagram* aMsg) |
|
443 { |
|
444 LOGWAPPROT1("CWapSmsProtocol::LookupSAP"); |
|
445 |
|
446 TBuf8<KMaxSockAddrSize> addrBuf; |
|
447 addrBuf.Copy(aMsg->FromAddress()); |
|
448 TInt toPort=0; |
|
449 TInt fromPort=0; |
|
450 TInt Is16BitPorts = ETrue; |
|
451 aMsg->Ports(fromPort,toPort,&Is16BitPorts); |
|
452 |
|
453 // Modification to relax port checking to allow 16 bit port number < KMax8BitPortNumber |
|
454 if(toPort < 0 || (!Is16BitPorts && toPort > KMax8BitPortNumber) || (Is16BitPorts && toPort > KMax16BitPortNumber) ) |
|
455 { |
|
456 return NULL; |
|
457 } |
|
458 |
|
459 TWapAddr addr; |
|
460 addr.SetWapAddress(addrBuf); |
|
461 addr.SetWapPort(static_cast<TWapPortNumber>(toPort)); |
|
462 |
|
463 TDblQueIter<CWapSmsProvider> iter(iSAPList); |
|
464 CWapSmsProvider* sap; |
|
465 while (sap = iter++, sap!=NULL) |
|
466 { |
|
467 if (sap->MatchesLocalAddress(addr)) |
|
468 return sap; |
|
469 } |
|
470 |
|
471 return NULL; |
|
472 } // CWapSmsProtocol::LookupSAP |
|
473 |
|
474 |
|
475 // |
|
476 // Check for duplicate address |
|
477 // |
|
478 TInt CWapSmsProtocol::AddrAlreadyUsedByWAP(const TWapAddr &aAddr, const CWapSmsProvider* aSap) |
|
479 { |
|
480 LOGWAPPROT1("CWapSmsProtocol::AddrAlreadyUsedByWAP"); |
|
481 |
|
482 TDblQueIter<CWapSmsProvider> iter(iSAPList); |
|
483 CWapSmsProvider* sap; |
|
484 |
|
485 while ((sap = iter++)!=NULL) |
|
486 { |
|
487 if (sap->MatchesLocalAddress(aAddr)) |
|
488 { |
|
489 if(sap==aSap) |
|
490 return KErrAlreadyExists; |
|
491 else |
|
492 return KErrInUse; |
|
493 } |
|
494 } |
|
495 LOGWAPPROT1("CWapSmsProtocol::AddrAlreadyUsedByWAP not used by WAP"); |
|
496 return KErrNone; |
|
497 } // CWapSmsProtocol::AddrAlreadyUsedByWAP |
|
498 |
|
499 |
|
500 // |
|
501 // Return a pointer to the sms protocol |
|
502 // |
|
503 CSmsProtocol* CWapSmsProtocol::SmsProtocol() |
|
504 { |
|
505 LOGWAPPROT1("CWapSmsProtocol::SmsProtocol()"); |
|
506 |
|
507 return iSmsProtocol; |
|
508 } // CWapSmsProtocol::SmsProtocol |
|
509 |
|
510 |
|
511 // |
|
512 // Search the store for particular datagram, if found the entry is deleted |
|
513 // |
|
514 TBool CWapSmsProtocol::FindAndDeleteMsg(CWapDatagram& aDatagram) |
|
515 { |
|
516 LOGWAPPROT1("CWapSmsProtocol::FindAndDeleteMsg()"); |
|
517 |
|
518 TInt err; |
|
519 TInt ret = EFalse; |
|
520 TRAP(err,ret=iWapStore->FindAndDeleteDatagramL(aDatagram)); |
|
521 __ASSERT_DEBUG(!err,Panic(EWapSmsNotFoundInStore)); |
|
522 if(!err && ret) |
|
523 return ETrue; |
|
524 else |
|
525 return EFalse; |
|
526 } // CWapSmsProtocol::FindAndDeleteMsg |
|
527 |
|
528 |
|
529 // |
|
530 // Search for SAR for this SAP entries. If found any, adds it to message queue |
|
531 // Note: This retrieves stored but not acked messages for this SAP |
|
532 // Is called when client's socket binds to address |
|
533 // |
|
534 TInt CWapSmsProtocol::CheckSarL(const TWapAddr& aAddr,CWapSmsProvider* aSap) |
|
535 { |
|
536 LOGWAPPROT1("CWapSmsProtocol::CheckSarL()"); |
|
537 |
|
538 TInt count=0; |
|
539 TInt err = KErrNone; |
|
540 count = iWapStore->Entries().Count(); |
|
541 TWapReassemblyEntry entry; |
|
542 |
|
543 |
|
544 TWapPortNumber portNumber = aAddr.WapPort() ; |
|
545 for(TInt index=0;index< count; index++) |
|
546 { |
|
547 entry = (TWapReassemblyEntry&)iWapStore->Entries()[index]; |
|
548 if(entry.ToPort()==portNumber) |
|
549 { |
|
550 CWapDatagram* wapDatagram = NULL; |
|
551 wapDatagram = CWapDatagram::NewL(KNullDesC8); |
|
552 CleanupStack::PushL(wapDatagram); |
|
553 TRAP(err,iWapStore->GetDatagramL( index,*wapDatagram)); |
|
554 __ASSERT_DEBUG(!err,Panic(EWapSmsBadGetDataCall)); |
|
555 CleanupStack::Pop(wapDatagram); |
|
556 aSap->AddToQueue(wapDatagram); |
|
557 } |
|
558 } |
|
559 return err; |
|
560 } // CWapSmsProtocol::CheckSarL |