24
|
1 |
// Copyright (c) 1999-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 |
|
|
21 |
#include "smspproc.h"
|
|
22 |
#include "smspmondsk.h"
|
|
23 |
#include "smspfacadestor.h"
|
|
24 |
#include "smsuset.h"
|
|
25 |
#include "smsulog.h"
|
|
26 |
#include "smspmain.h"
|
|
27 |
|
|
28 |
#include <gsmusar.h>
|
|
29 |
#include <exterror.h>
|
|
30 |
#include "gsmubuf.h"
|
|
31 |
#include "Gsmumsg.h"
|
|
32 |
#include "smspcdb.h"
|
|
33 |
#include "smspread.h"
|
|
34 |
|
|
35 |
|
|
36 |
/**
|
|
37 |
* Creates new CSmsPDUProcess instance
|
|
38 |
*
|
|
39 |
* @return a new CSmsPDUProcess object.
|
|
40 |
*/
|
|
41 |
CSmsPDUProcessor* CSmsPDUProcessor::NewL(MSmsComm& aSmsComm, const TSmsSettings& aSmsSettings,
|
|
42 |
CFacadeSmsReassemblyStore& aReassemblyStore,
|
|
43 |
CSmsSegmentationStore& aSegmentationStore,
|
|
44 |
CSmsMonitorDiskSpace& aSmsMonitorDiskSpace)
|
|
45 |
{
|
|
46 |
LOGSMSPROT1("CSmsPDUProcessor::NewL()");
|
|
47 |
|
|
48 |
CSmsPDUProcessor* smsPDUProcessor = new (ELeave) CSmsPDUProcessor(aSmsComm,
|
|
49 |
aSmsSettings,
|
|
50 |
aReassemblyStore,
|
|
51 |
aSegmentationStore,
|
|
52 |
aSmsMonitorDiskSpace);
|
|
53 |
|
|
54 |
CleanupStack::PushL(smsPDUProcessor);
|
|
55 |
smsPDUProcessor->ConstructL();
|
|
56 |
CleanupStack::Pop(smsPDUProcessor);
|
|
57 |
|
|
58 |
return smsPDUProcessor;
|
|
59 |
} // CSmsPDUProcessor::NewL
|
|
60 |
|
|
61 |
|
|
62 |
CSmsPDUProcessor::~CSmsPDUProcessor()
|
|
63 |
{
|
|
64 |
delete iSmsMessage;
|
|
65 |
delete iOriginalSmsMessage;
|
|
66 |
iStatusArray.Close();
|
|
67 |
} // CSmsPDUProcessor::~CSmsPDUProcessor
|
|
68 |
|
|
69 |
|
|
70 |
CSmsPDUProcessor::CSmsPDUProcessor(MSmsComm& aSmsComm,
|
|
71 |
const TSmsSettings& aSmsSettings,
|
|
72 |
CFacadeSmsReassemblyStore& aReassemblyStore,
|
|
73 |
CSmsSegmentationStore& aSegmentationStore,
|
|
74 |
CSmsMonitorDiskSpace& aSmsMonitorDiskSpace)
|
|
75 |
:iSmsComm(aSmsComm),
|
|
76 |
iSmsSettings(aSmsSettings),
|
|
77 |
iReassemblyStore(aReassemblyStore),
|
|
78 |
iSegmentationStore(aSegmentationStore),
|
|
79 |
iSmsMonitorDiskSpace(aSmsMonitorDiskSpace)
|
|
80 |
{
|
|
81 |
// NOP
|
|
82 |
} // CSmsPDUProcessor::CSmsPDUProcess
|
|
83 |
|
|
84 |
|
|
85 |
/**
|
|
86 |
* Second phase constructor.
|
|
87 |
*/
|
|
88 |
void CSmsPDUProcessor::ConstructL()
|
|
89 |
{
|
|
90 |
LOGSMSPROT1("CSmsPDUProcessor::ConstructL()");
|
|
91 |
} // CSmsPDUProcessor::ConstructL
|
|
92 |
|
|
93 |
|
|
94 |
void CSmsPDUProcessor::DecodeAndProcessPDUL(TGsmSmsSlot& aSlot, TBool aIsEnumeration)
|
|
95 |
{
|
|
96 |
LOGSMSPROT2("CSmsPDUProcessor::DecodeAndProcessPDUL(): aIsEnumeration=%d",
|
|
97 |
aIsEnumeration);
|
|
98 |
|
|
99 |
//
|
|
100 |
// Store the slot...
|
|
101 |
//
|
|
102 |
iSlot = aSlot;
|
|
103 |
|
|
104 |
//
|
|
105 |
// We need to know if this message is MT or MO before decoding...
|
|
106 |
//
|
|
107 |
if (iSlot.iMsgStatus == RMobileSmsStore::EStoredMessageUnread ||
|
|
108 |
iSlot.iMsgStatus == RMobileSmsStore::EStoredMessageRead)
|
|
109 |
{
|
|
110 |
iIsMobileTerminated = ETrue;
|
|
111 |
}
|
|
112 |
|
|
113 |
LOGSMSPROT2("CSmsStoreRead::DecodeAndProcessPDUL(): iIsMobileTerminated=%d",
|
|
114 |
iIsMobileTerminated);
|
|
115 |
|
|
116 |
//
|
|
117 |
// Put the PDU and Service Center Address in the TGsmSms structure...
|
|
118 |
//
|
|
119 |
TGsmSmsTelNumber sca;
|
|
120 |
|
|
121 |
sca.iTelNumber = iSlot.iServiceCentre.iTelNumber;
|
|
122 |
sca.iTypeOfAddress.SetFromETelMM(static_cast<NMobilePhone::TMobileTON>(iSlot.iServiceCentre.iTypeOfNumber),
|
|
123 |
static_cast<NMobilePhone::TMobileNPI>(iSlot.iServiceCentre.iNumberPlan));
|
|
124 |
iGsmSms.SetPdu(iSlot.iMsgData);
|
|
125 |
iGsmSms.SetSca(sca);
|
|
126 |
|
|
127 |
//
|
|
128 |
// Allocate a CSmsBuffer for use during the decoding of the PDU and
|
|
129 |
// create the CSmsMessage object - this will actaully decode the PDU. Note
|
|
130 |
// that the CSmsBuffer ownership is transfered during NewL()!!!
|
|
131 |
//
|
|
132 |
CSmsBuffer* smsBuffer = CSmsBuffer::NewL();
|
|
133 |
iSmsMessage = CSmsMessage::NewL(iReassemblyStore.FileSession(), iGsmSms,
|
|
134 |
smsBuffer, EFalse, iIsMobileTerminated);
|
|
135 |
|
|
136 |
//
|
|
137 |
// Store the enumeration type and calculate other basic info...
|
|
138 |
//
|
|
139 |
iIsEnumeration = aIsEnumeration;
|
|
140 |
|
|
141 |
AnalysePDUCharacteristics();
|
|
142 |
|
|
143 |
//
|
|
144 |
// If the store information is supplied, then check if the PDU will
|
|
145 |
// be deleted from the store.
|
|
146 |
//
|
|
147 |
// When enumerating, only messages which are on the SIM or in the
|
|
148 |
// Combined Store are forwarded to the client. If the message on the
|
|
149 |
// SIM is marked for automatic deletion or a type 0, then it may
|
|
150 |
// have its storage set to CSmsMessage::ESmsNoStorage in this routine.
|
|
151 |
// However the method CSmsProtocol::ExternalizeEnumeratedMessagesL()
|
|
152 |
// still needs to know that the message was originally on the SIM or
|
|
153 |
// the combined store.
|
|
154 |
//
|
|
155 |
if (iSlot.iStore.Length() > 0)
|
|
156 |
{
|
|
157 |
iSmsMessage->SetStatus(static_cast<NMobileSmsStore::TMobileSmsStoreStatus>(iSlot.iMsgStatus));
|
|
158 |
if (iSlot.iStore == KETelCombinedSmsStore)
|
|
159 |
{
|
|
160 |
if (iSmsSettings.DeletePDUsFromCombinedStores() == EFalse)
|
|
161 |
{
|
|
162 |
iSmsMessage->SetStorage(CSmsMessage::ESmsCombinedStorage);
|
|
163 |
}
|
|
164 |
|
|
165 |
iSmsMessage->SetDecodedOnSIM(ETrue);
|
|
166 |
}
|
|
167 |
else if (iSlot.iStore == KETelIccSmsStore)
|
|
168 |
{
|
|
169 |
if (iSmsSettings.DeletePDUsFromSIM() == EFalse)
|
|
170 |
{
|
|
171 |
iSmsMessage->SetStorage(CSmsMessage::ESmsSIMStorage);
|
|
172 |
}
|
|
173 |
|
|
174 |
iSmsMessage->SetDecodedOnSIM(ETrue);
|
|
175 |
}
|
|
176 |
else if (iSmsSettings.DeletePDUsFromPhoneStores() == EFalse)
|
|
177 |
{
|
|
178 |
iSmsMessage->SetStorage(CSmsMessage::ESmsPhoneStorage);
|
|
179 |
}
|
|
180 |
}
|
|
181 |
|
|
182 |
//
|
|
183 |
// If the PDU will be deleted, then assume it has no storage...
|
|
184 |
//
|
|
185 |
if (iIsPDUToBeDeleted)
|
|
186 |
{
|
|
187 |
iSmsMessage->SetStorage(CSmsMessage::ESmsNoStorage);
|
|
188 |
}
|
|
189 |
|
|
190 |
//
|
|
191 |
// Is this a MOSES message?
|
|
192 |
//
|
|
193 |
if (iSmsMessage->ToFromAddress().CompareF(KNETWORK) == 0)
|
|
194 |
{
|
|
195 |
LOGSMSPROT1("CSmsPDUProcessor::DecodeAndProcessPDUL(): MOSES OTE message!");
|
|
196 |
if (iSmsComm.NetworkInfoAvailable())
|
|
197 |
{
|
|
198 |
iSmsMessage->SetToFromAddressL(iSmsComm.NetworkInfo().iDisplayTag);
|
|
199 |
}
|
|
200 |
}
|
|
201 |
|
|
202 |
//
|
|
203 |
// Call the processing function for this time of message. Enumerations of
|
|
204 |
// a PDU can be SUBMIT, DELIVER or STATUS-REPORT. Receiving of a PDU can
|
|
205 |
// be SUBMIT or STATUS-REPORT...
|
|
206 |
//
|
|
207 |
if ((iIsEnumeration && iSmsMessage->Type() == CSmsPDU::ESmsSubmit) ||
|
|
208 |
iSmsMessage->Type() == CSmsPDU::ESmsDeliver)
|
|
209 |
{
|
|
210 |
if (iIsForwardMessageToClient)
|
|
211 |
{
|
|
212 |
//
|
|
213 |
// Record that this SMS should be forwarded to the client...
|
|
214 |
//
|
|
215 |
iSmsMessage->SetForwardToClient(ETrue);
|
|
216 |
|
|
217 |
//
|
|
218 |
// Check that there is disk space to process this PDU. This may signal to
|
|
219 |
// the network to stop SMS reception until further notice, and it may go
|
|
220 |
// active to monitor the disk space.
|
|
221 |
//
|
|
222 |
/*
|
|
223 |
The below logic is quite complicated. This logic is written to support backward compatibility.
|
|
224 |
Previously SMS stack was sending -ve ack for class 0 messages before implementation of REQ6523.
|
|
225 |
Even after implementation of REQ6523, there will be provision so that the customer who does
|
|
226 |
not want this feature, then can go back to previous implementation.
|
|
227 |
With REQ6523, there is another requiremnt REQ7012 which states that class 0 WAP messages
|
|
228 |
will be handled like other non-class 0 messages. That means in out-of-disk condition it will
|
|
229 |
send -ve ack to network. WAP class 0 messages will be stored in non-class 0 re-assembly store.
|
|
230 |
|
|
231 |
If SMS stack is configured for handling class 0 messages in out-of-disk condition,
|
|
232 |
Class 0 messages will be stored in reserved space (Pre-allocated file) internally.
|
|
233 |
But if this function is called at the time of enumeration and disk is full then -ve ack
|
|
234 |
will be sent to client for disk full. The behaviour is different for class 0 messages
|
|
235 |
at the time of enumeration & normal read from network.
|
|
236 |
*/
|
|
237 |
TInt ret=KErrNone;
|
|
238 |
iIsWapSms = iReassemblyStore.IsWapSMS(*iSmsMessage);
|
|
239 |
if (iIsClass0Message && iIsWapSms)
|
|
240 |
{
|
|
241 |
//Wap class 0 sms message will be stored in non-class 0 reassembly store.
|
|
242 |
TRAP(ret, iSmsMonitorDiskSpace.CheckDiskSpaceForPDUL(EFalse));
|
|
243 |
}
|
|
244 |
else
|
|
245 |
{
|
|
246 |
TRAP(ret, iSmsMonitorDiskSpace.CheckDiskSpaceForPDUL(iIsClass0Message));
|
|
247 |
}
|
|
248 |
|
|
249 |
if ((iIsClass0Message && !iIsWapSms) && iReassemblyStore.IsSeparateClass0StoreSupported() && (!aIsEnumeration))
|
|
250 |
{
|
|
251 |
if (ret == KErrDiskFull)
|
|
252 |
{
|
|
253 |
iReassemblyStore.SetDiskSpaceState(ESmsDiskSpaceFull);
|
|
254 |
ret = KErrNone;
|
|
255 |
}
|
|
256 |
else if (ret == KErrNone)
|
|
257 |
{
|
|
258 |
iReassemblyStore.SetDiskSpaceState(ESmsDiskSpaceAvailable);
|
|
259 |
}
|
|
260 |
}
|
|
261 |
|
|
262 |
if (ret!=KErrNone)
|
|
263 |
{
|
|
264 |
User::Leave(ret);
|
|
265 |
}
|
|
266 |
|
|
267 |
AddSlotToSmsMessageIfRequiredL();
|
|
268 |
AddSegmentOfMessageToReassemblyStoreIfRequiredL();
|
|
269 |
}
|
|
270 |
}
|
|
271 |
else if (iSmsMessage->Type() == CSmsPDU::ESmsStatusReport)
|
|
272 |
{
|
|
273 |
FindOriginalMessageAndProcessStatusReportL();
|
|
274 |
|
|
275 |
if (iIsForwardMessageToClient && iIsMessageGoingToBeStored)
|
|
276 |
{
|
|
277 |
//
|
|
278 |
// Record that this SMS should be forwarded to the client...
|
|
279 |
//
|
|
280 |
iSmsMessage->SetForwardToClient(ETrue);
|
|
281 |
|
|
282 |
AddSlotToSmsMessageIfRequiredL();
|
|
283 |
AddSegmentOfMessageToReassemblyStoreIfRequiredL();
|
|
284 |
}
|
|
285 |
|
|
286 |
//
|
|
287 |
// If the message to which this report refers is complete (and
|
|
288 |
// logically most will be as unless it refers to a SMS-SUBMIT
|
|
289 |
// message we no longer have), then update the received time and
|
|
290 |
// the
|
|
291 |
//
|
|
292 |
if (iIsComplete)
|
|
293 |
{
|
|
294 |
UpdateStatusReportL();
|
|
295 |
}
|
|
296 |
}
|
|
297 |
else
|
|
298 |
{
|
|
299 |
User::Leave(KErrCorrupt);
|
|
300 |
}
|
|
301 |
|
|
302 |
//
|
|
303 |
// Should we delete the PDU?
|
|
304 |
//
|
|
305 |
if ((iIsEnumeration && iSlot.iStore == KETelMeSmsStore) ||
|
|
306 |
(iIsEnumeration == EFalse && iSmsMessage->Storage() != CSmsMessage::ESmsSIMStorage) ||
|
|
307 |
iIsPDUToBeDeleted)
|
|
308 |
{
|
|
309 |
DeletePDUL();
|
|
310 |
}
|
|
311 |
} // CSmsPDUProcessor::DecodeAndProcessPDUL
|
|
312 |
|
|
313 |
|
|
314 |
void CSmsPDUProcessor::AnalysePDUCharacteristics()
|
|
315 |
{
|
|
316 |
LOGSMSPROT1("CSmsPDUProcessor::AnalysePDUCharacteristics()");
|
|
317 |
|
|
318 |
CSmsPDU& pdu = iSmsMessage->SmsPDU();
|
|
319 |
|
|
320 |
//
|
|
321 |
// Check store the message class...
|
|
322 |
//
|
|
323 |
TSmsDataCodingScheme::TSmsClass msgClass;
|
|
324 |
|
|
325 |
if (pdu.DataCodingSchemePresent() && pdu.Class(msgClass))
|
|
326 |
{
|
|
327 |
if (msgClass == TSmsDataCodingScheme::ESmsClass0)
|
|
328 |
{
|
|
329 |
LOGSMSPROT1("CSmsPDUProcessor::AnalysePDUCharacteristics(): Class 0");
|
|
330 |
iIsClass0Message = ETrue;
|
|
331 |
}
|
|
332 |
else if (msgClass == TSmsDataCodingScheme::ESmsClass1)
|
|
333 |
{
|
|
334 |
LOGSMSPROT1("CSmsPDUProcessor::AnalysePDUCharacteristics(): Class 1");
|
|
335 |
iIsClass1Message = ETrue;
|
|
336 |
}
|
|
337 |
else if (msgClass == TSmsDataCodingScheme::ESmsClass2)
|
|
338 |
{
|
|
339 |
LOGSMSPROT1("CSmsPDUProcessor::AnalysePDUCharacteristics(): Class 2");
|
|
340 |
iIsClass2Message = ETrue;
|
|
341 |
}
|
|
342 |
else if (msgClass == TSmsDataCodingScheme::ESmsClass3)
|
|
343 |
{
|
|
344 |
LOGSMSPROT1("CSmsPDUProcessor::AnalysePDUCharacteristics(): Class 3");
|
|
345 |
iIsClass3Message = ETrue;
|
|
346 |
}
|
|
347 |
else
|
|
348 |
{
|
|
349 |
LOGSMSPROT1("CSmsPDUProcessor::AnalysePDUCharacteristics(): Class Unknown!");
|
|
350 |
}
|
|
351 |
}
|
|
352 |
else
|
|
353 |
{
|
|
354 |
LOGSMSPROT1("CSmsPDUProcessor::AnalysePDUCharacteristics(): Class-less");
|
|
355 |
}
|
|
356 |
|
|
357 |
//
|
|
358 |
// Is this PDU PID Type 0?
|
|
359 |
//
|
|
360 |
if (pdu.ProtocolIdentifierPresent() &&
|
|
361 |
pdu.PIDType() == TSmsProtocolIdentifier::ESmsPIDShortMessageType &&
|
|
362 |
pdu.ShortMessageType() == TSmsProtocolIdentifier::ESmsShortMessageType0)
|
|
363 |
{
|
|
364 |
iIsPIDType0 = ETrue;
|
|
365 |
}
|
|
366 |
|
|
367 |
LOGSMSPROT2("CSmsPDUProcessor::AnalysePDUCharacteristics(): iIsPIDType0=%d",
|
|
368 |
iIsPIDType0);
|
|
369 |
|
|
370 |
//
|
|
371 |
// Should this message be forwarded to the client?
|
|
372 |
//
|
|
373 |
if (!(iIsPIDType0 &&
|
|
374 |
((iIsClass0Message && iOptionDiscardType0Class0) ||
|
|
375 |
(iIsClass2Message && iOptionDiscardType0Class2) ||
|
|
376 |
(iIsClass0Message == EFalse && iIsClass2Message == EFalse))))
|
|
377 |
{
|
|
378 |
iIsForwardMessageToClient = ETrue;
|
|
379 |
}
|
|
380 |
|
|
381 |
LOGSMSPROT2("CSmsPDUProcessor::AnalysePDUCharacteristics(): iIsForwardMessageToClient=%d",
|
|
382 |
iIsForwardMessageToClient);
|
|
383 |
|
|
384 |
//
|
|
385 |
// Is it flaged for auto-delete?
|
|
386 |
//
|
|
387 |
if (pdu.DataCodingSchemePresent())
|
|
388 |
{
|
|
389 |
TInt autoDelete = pdu.Bits7To4() & TSmsDataCodingScheme::ESmsDCSAutomaticDeletionMask;
|
|
390 |
|
|
391 |
if (autoDelete == TSmsDataCodingScheme::ESmsDCSAutomaticDeletion)
|
|
392 |
{
|
|
393 |
iIsMarkedForAutoDelete = ETrue;
|
|
394 |
}
|
|
395 |
}
|
|
396 |
|
|
397 |
LOGSMSPROT2("CSmsPDUProcessor::AnalysePDUCharacteristics(): iIsMarkedForAutoDelete=%d",
|
|
398 |
iIsMarkedForAutoDelete);
|
|
399 |
|
|
400 |
//
|
|
401 |
// Should this PDU be deleted after processing?
|
|
402 |
//
|
|
403 |
if (iIsMarkedForAutoDelete &&
|
|
404 |
(iIsClass2Message == EFalse || iOptionApplyAutoDeletionToClass2))
|
|
405 |
{
|
|
406 |
iIsPDUToBeDeleted = ETrue;
|
|
407 |
}
|
|
408 |
else if (iIsPIDType0 &&
|
|
409 |
(iIsClass2Message == EFalse || iOptionDiscardType0Class2))
|
|
410 |
{
|
|
411 |
iIsPDUToBeDeleted = ETrue;
|
|
412 |
}
|
|
413 |
|
|
414 |
LOGSMSPROT2("CSmsPDUProcessor::AnalysePDUCharacteristics(): iIsPDUToBeDeleted=%d",
|
|
415 |
iIsPDUToBeDeleted);
|
|
416 |
|
|
417 |
//
|
|
418 |
// Does the message need to be stored???
|
|
419 |
//
|
|
420 |
// Don't store class 2 SMSs with index 0 on SIM. Not sure why, but
|
|
421 |
// it appears to be delibrate and no one has ever complained!
|
|
422 |
//
|
|
423 |
// Don't store messages already stored somewhere other than the
|
|
424 |
// phone store.
|
|
425 |
//
|
|
426 |
if (iIsPDUToBeDeleted == EFalse &&
|
|
427 |
((iIsEnumeration && iSlot.iIndex != 0 && iSlot.iStore != KETelMeSmsStore) ||
|
|
428 |
(iSlot.iStore != KETelMeSmsStore && iSlot.iStore.Length() > 0)))
|
|
429 |
{
|
|
430 |
iIsMessageGoingToBeStored = ETrue;
|
|
431 |
}
|
|
432 |
|
|
433 |
LOGSMSPROT2("CSmsPDUProcessor::AnalysePDUCharacteristics(): iIsMessageGoingToBeStored=%d",
|
|
434 |
iIsMessageGoingToBeStored);
|
|
435 |
|
|
436 |
//
|
|
437 |
// Is the message complete? This value may change later, when the segmentation and
|
|
438 |
// reassembley stores are examined.
|
|
439 |
//
|
|
440 |
iIsComplete = iSmsMessage->IsComplete();
|
|
441 |
|
|
442 |
LOGSMSPROT2("CSmsPDUProcessor::AnalysePDUCharacteristics(): iIsComplete=%d",
|
|
443 |
iIsComplete);
|
|
444 |
|
|
445 |
//
|
|
446 |
// Store PDU Data. These values may be updated later.
|
|
447 |
//
|
|
448 |
iSmsPDUData.iType = iSmsMessage->Type();
|
|
449 |
iSmsPDUData.iTotal = 1;
|
|
450 |
iSmsPDUData.iReceived = 1;
|
|
451 |
} // CSmsPDUProcessor::AnalysePDUCharacteristics
|
|
452 |
|
|
453 |
|
|
454 |
void CSmsPDUProcessor::FindOriginalMessageAndProcessStatusReportL()
|
|
455 |
{
|
|
456 |
__ASSERT_DEBUG(iSmsMessage->Type() == CSmsPDU::ESmsStatusReport,
|
|
457 |
SmspPanic(KSmspPanicNotStatusReport));
|
|
458 |
|
|
459 |
//
|
|
460 |
// Find the original message in the segmentation store and update its status
|
|
461 |
// to that contained in the status report.
|
|
462 |
//
|
|
463 |
TBool found = iSegmentationStore.AddStatusReportL(iIndex, iIsComplete, *iSmsMessage);
|
|
464 |
|
|
465 |
LOGSMSPROT2("CSmsPDUReadProcess::FindOriginalMessageAndProcessStatusReportL(): found=%d",found);
|
|
466 |
|
|
467 |
if (found)
|
|
468 |
{
|
|
469 |
//
|
|
470 |
// The status report refers to a known message. Update the this status message
|
|
471 |
// with the correct Log Server ID and it's related info.
|
|
472 |
//
|
|
473 |
const TSmsSegmentationEntry& entry = (const TSmsSegmentationEntry&)
|
|
474 |
iSegmentationStore.Entries()[iIndex];
|
|
475 |
|
|
476 |
iSmsMessage->SetLogServerId(entry.LogServerId());
|
|
477 |
|
|
478 |
iSmsPDUData.iType = entry.PduType();
|
|
479 |
iSmsPDUData.iTotal = entry.Total();
|
|
480 |
iSmsPDUData.iSent = entry.Count();
|
|
481 |
iSmsPDUData.iDelivered = entry.Delivered();
|
|
482 |
iSmsPDUData.iFailed = entry.Failed();
|
|
483 |
|
|
484 |
//
|
|
485 |
// Load the original SUBMIT message into memory for further processing later...
|
|
486 |
// Note that smsBuffer's ownership transfers straight away!!!
|
|
487 |
//
|
|
488 |
CSmsBuffer* smsBuffer = CSmsBuffer::NewL();
|
|
489 |
|
|
490 |
iOriginalSmsMessage = CSmsMessage::NewL(iReassemblyStore.FileSession(),
|
|
491 |
CSmsPDU::ESmsSubmit,
|
|
492 |
smsBuffer);
|
|
493 |
iSegmentationStore.GetMessageL(iIndex, iSmsAddr, *iOriginalSmsMessage,
|
|
494 |
iStatusArray);
|
|
495 |
}
|
|
496 |
} // CSmsPDUProcessor::FindOriginalMessageAndProcessStatusReportL
|
|
497 |
|
|
498 |
|
|
499 |
void CSmsPDUProcessor::UpdateStatusReportL()
|
|
500 |
{
|
|
501 |
LOGSMSPROT1("CSmsPDUProcessor::UpdateStatusReportL()");
|
|
502 |
|
|
503 |
//
|
|
504 |
// Update the receive time of the status report...
|
|
505 |
//
|
|
506 |
TTime currTime;
|
|
507 |
currTime.UniversalTime();
|
|
508 |
|
|
509 |
iSmsMessage->SetTime(currTime);
|
|
510 |
iSmsMessage->SetUTCOffset(User::UTCOffset());
|
|
511 |
iSmsMessage->SetToFromAddressL(iOriginalSmsMessage->ToFromAddress());
|
|
512 |
|
|
513 |
//
|
|
514 |
// Set the status report to the last status received by the SME...
|
|
515 |
//
|
|
516 |
CSmsStatusReport& statusReport = (CSmsStatusReport&) iSmsMessage->SmsPDU();
|
|
517 |
TInt count = iStatusArray.Count();
|
|
518 |
|
|
519 |
for (TInt index = 0; index < count; index++)
|
|
520 |
{
|
|
521 |
TInt status = iStatusArray[index].Status();
|
|
522 |
|
|
523 |
statusReport.SetStatus((TSmsStatus::TSmsStatusValue) status);
|
|
524 |
if (status != TSmsStatus::ESmsShortMessageReceivedBySME)
|
|
525 |
{
|
|
526 |
break;
|
|
527 |
}
|
|
528 |
}
|
|
529 |
} // CSmsPDUProcessor::UpdateStatusReportL
|
|
530 |
|
|
531 |
|
|
532 |
void CSmsPDUProcessor::AddSlotToSmsMessageIfRequiredL()
|
|
533 |
{
|
|
534 |
LOGSMSPROT1("CSmsPDUProcessor::AddSlotToSmsMessageIfRequiredL()");
|
|
535 |
|
|
536 |
//
|
|
537 |
// Add the slot to the message (if it is not going to be deleted and
|
|
538 |
// the client needs to know it's location e.g. to store it)...
|
|
539 |
//
|
|
540 |
if (iIsMessageGoingToBeStored)
|
|
541 |
{
|
|
542 |
TGsmSmsSlotEntry smsSlotEntry;
|
|
543 |
|
|
544 |
smsSlotEntry.iIndex = iSlot.iIndex;
|
|
545 |
smsSlotEntry.iStore = iSlot.iStore;
|
|
546 |
|
|
547 |
iSmsMessage->AddSlotL(smsSlotEntry);
|
|
548 |
}
|
|
549 |
} // CSmsPDUProcessor::AddSlotToSmsMessageIfRequiredL
|
|
550 |
|
|
551 |
|
|
552 |
/**
|
|
553 |
* Add the message segment to the reassembly store. There are 5 possiblities:
|
|
554 |
*
|
|
555 |
* 1) This is the complete message (e.g. a single-segment message).
|
|
556 |
* We therefore have all the segments.
|
|
557 |
* 2) This is a duplicate message segment.
|
|
558 |
* We will ignore it.
|
|
559 |
* 3) This is the last segment in the message required to complete it.
|
|
560 |
* The other segments are already stored.
|
|
561 |
* 4) This is another PDU to an existing message in the store, but it is
|
|
562 |
* not yet complete.
|
|
563 |
* 5) This is the first PDU in the message, and therefore the message is
|
|
564 |
* not yet complete and no segments are stored.
|
|
565 |
*
|
|
566 |
* @note Only SUBMIT or DELIVER PDUs can be added to the reassembly store.
|
|
567 |
*/
|
|
568 |
void CSmsPDUProcessor::AddSegmentOfMessageToReassemblyStoreIfRequiredL()
|
|
569 |
{
|
|
570 |
LOGSMSPROT2("CSmsPDUReadProcess::AddSegmentOfMessageToReassemblyStoreIfRequiredL(): iIsComplete=%d",
|
|
571 |
iIsComplete);
|
|
572 |
|
|
573 |
iReassemblyStore.AddSegmentToReassemblyStoreL(*iSmsMessage, iGsmSms, iIndex, iIsComplete, iIsEnumeration, iSmsPDUData.iReceived, iSmsPDUData.iTotal);
|
|
574 |
} // CSmsPDUProcessor::AddSegmentOfMessageToReassemblyStoreIfRequiredL
|
|
575 |
|
|
576 |
|
|
577 |
void CSmsPDUProcessor::UpdateLogServerIdL()
|
|
578 |
{
|
|
579 |
LOGSMSPROT1("CSmsPDUProcessor::UpdateLogServerIdL()");
|
|
580 |
|
|
581 |
//
|
|
582 |
// If this is a SUBMIT or DELIVER PDU,
|
|
583 |
// then search for it in the Reassembly store.
|
|
584 |
//
|
|
585 |
if (iSmsMessage != NULL && iIndex != KErrNotFound &&
|
|
586 |
(iSmsMessage->Type() == CSmsPDU::ESmsSubmit ||
|
|
587 |
iSmsMessage->Type() == CSmsPDU::ESmsDeliver))
|
|
588 |
{
|
|
589 |
iReassemblyStore.UpdateLogServerIdL(*iSmsMessage, iIndex);
|
|
590 |
}
|
|
591 |
} // CSmsPDUProcessor::UpdateLogServerIdL
|
|
592 |
|
|
593 |
void CSmsPDUProcessor::ProcessMessageIfCompleteL()
|
|
594 |
{
|
|
595 |
LOGSMSPROT1("CSmsPDUProcessor::ProcessMessageIfCompleteL()");
|
|
596 |
|
|
597 |
if ((iIsClass0Message && !iIsWapSms) && iReassemblyStore.IsSeparateClass0StoreSupported())
|
|
598 |
{
|
|
599 |
//Note: Process Class 0 Message which is not wap message & return.
|
|
600 |
if (iIsComplete)
|
|
601 |
{
|
|
602 |
//
|
|
603 |
// Process the message...
|
|
604 |
//
|
|
605 |
if (iOriginalSmsMessage == NULL)
|
|
606 |
{
|
|
607 |
iReassemblyStore.ForwardCompleteClass0SmsMessagesL(iSmsComm, *iSmsMessage, NULL, iOriginalSmsMessage, iDeliverReportBuffer);
|
|
608 |
}
|
|
609 |
else
|
|
610 |
{
|
|
611 |
iReassemblyStore.ForwardCompleteClass0SmsMessagesL(iSmsComm, *iSmsMessage, &iSmsAddr, iOriginalSmsMessage, iDeliverReportBuffer);
|
|
612 |
}
|
|
613 |
}
|
|
614 |
else
|
|
615 |
{
|
|
616 |
iReassemblyStore.ProcessMessageIfExceedLimitationL(iSmsComm);
|
|
617 |
}
|
|
618 |
return;
|
|
619 |
}
|
|
620 |
|
|
621 |
if (iIsComplete)
|
|
622 |
{
|
|
623 |
//
|
|
624 |
// Process the message...
|
|
625 |
//
|
|
626 |
TInt ret(KErrUnknown);
|
|
627 |
|
|
628 |
if (iOriginalSmsMessage == NULL)
|
|
629 |
{
|
|
630 |
ret = iSmsComm.ProcessMessageL(*iSmsMessage, NULL,
|
|
631 |
iOriginalSmsMessage,
|
|
632 |
iDeliverReportBuffer);
|
|
633 |
}
|
|
634 |
else
|
|
635 |
{
|
|
636 |
ret = iSmsComm.ProcessMessageL(*iSmsMessage, &iSmsAddr,
|
|
637 |
iOriginalSmsMessage,
|
|
638 |
iDeliverReportBuffer);
|
|
639 |
}
|
|
640 |
|
|
641 |
//
|
|
642 |
// If successful, mark the entry as delivered to the msgc...
|
|
643 |
//
|
|
644 |
if(ret == KErrNone)
|
|
645 |
{
|
|
646 |
iReassemblyStore.SetMessagePassedToClientL(*iSmsMessage);
|
|
647 |
}
|
|
648 |
}
|
|
649 |
} // CSmsPDUProcessor::ProcessMessageIfCompleteL
|
|
650 |
|
|
651 |
void CSmsPDUProcessor::DeletePDUL()
|
|
652 |
{
|
|
653 |
LOGSMSPROT1("CSmsPDUProcessor::DeletePDUL()");
|
|
654 |
|
|
655 |
//
|
|
656 |
// If the slot number has an index and store assigned, then we can delete
|
|
657 |
// it.
|
|
658 |
//
|
|
659 |
if (iSlot.iIndex >= 0 && iSlot.iStore.Length() > 0)
|
|
660 |
{
|
|
661 |
CArrayFixFlat<TGsmSmsSlotEntry>* smsSlotEntryArray = new (ELeave) CArrayFixFlat<TGsmSmsSlotEntry>(1);
|
|
662 |
CleanupStack::PushL(smsSlotEntryArray);
|
|
663 |
|
|
664 |
TGsmSmsSlotEntry smsSlotEntry;
|
|
665 |
|
|
666 |
smsSlotEntry.iIndex = iSlot.iIndex;
|
|
667 |
smsSlotEntry.iStore = iSlot.iStore;
|
|
668 |
smsSlotEntryArray->AppendL(smsSlotEntry);
|
|
669 |
|
|
670 |
iSmsComm.DeletePDUs(*smsSlotEntryArray, NULL);
|
|
671 |
|
|
672 |
CleanupStack::PopAndDestroy(smsSlotEntryArray);
|
|
673 |
}
|
|
674 |
} // CSmsPDUProcessor::DeletePDUL
|
|
675 |
|