|
1 // Copyright (c) 1997-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 // Implementation for the CSmsuActiveBase based class CSmsMessageSend. |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 @internalAll |
|
21 */ |
|
22 |
|
23 #include "smspsend.h" |
|
24 #include "smspstor.h" |
|
25 #include "smspmain.h" |
|
26 #include "smsuset.h" |
|
27 #include "smsulog.h" |
|
28 #include "exterror.h" |
|
29 #include "gsmubuf.h" |
|
30 #include "SmsuTimer.h" |
|
31 #include <logwraplimits.h> |
|
32 |
|
33 |
|
34 /** |
|
35 * Static object constructor for CSmsMessageSend. |
|
36 * |
|
37 * @param aSegmentationStore Segmentation Store. |
|
38 * @param aSmsMessaging ETel SMS messaging subsession. |
|
39 * @param aSmsSettings The global SMS settings. |
|
40 * @param aMobileSmsCaps SMS messaging capabilities of TSY/phone. |
|
41 * @param aPriority Priority to use for the Active Object. |
|
42 * @param aSmspSetBearer Set bearer object. |
|
43 */ |
|
44 CSmsMessageSend* CSmsMessageSend::NewL(CSmsSegmentationStore& aSegmentationStore, |
|
45 const TSmsSettings& aSmsSettings, |
|
46 const RMobileSmsMessaging::TMobileSmsCapsV1& aMobileSmsCaps, |
|
47 RMobileSmsMessaging& aSmsMessaging, |
|
48 TInt aPriority, |
|
49 CSmspSetBearer& aSmspSetBearer) |
|
50 { |
|
51 LOGSMSPROT1("CSmsMessageSend::NewL()"); |
|
52 |
|
53 CSmsMessageSend* self = new (ELeave) CSmsMessageSend(aSegmentationStore, |
|
54 aSmsSettings, |
|
55 aMobileSmsCaps, |
|
56 aSmsMessaging, |
|
57 aPriority, |
|
58 aSmspSetBearer); |
|
59 CleanupStack::PushL(self); |
|
60 self->ConstructL(); |
|
61 CleanupStack::Pop(self); |
|
62 |
|
63 return self; |
|
64 } // CSmsMessageSend::NewL |
|
65 |
|
66 |
|
67 /** |
|
68 * 2nd Phase of construction. |
|
69 * |
|
70 * Creates CSmsTimeout object and the SMS event logger. |
|
71 */ |
|
72 void CSmsMessageSend::ConstructL() |
|
73 { |
|
74 LOGSMSPROT1("CSmsMessageSend::ConstructL()"); |
|
75 |
|
76 iSmsEventLogger = CSmsEventLogger::NewL(iSegmentationStore.FileSession(), |
|
77 Priority()); |
|
78 |
|
79 ConstructTimeoutL(); |
|
80 } // CSmsMessageSend::ConstructL |
|
81 |
|
82 |
|
83 /** |
|
84 * Default constructor. |
|
85 * |
|
86 * @param aSegmentationStore Segmentation Store. |
|
87 * @param aSmsSettings The global SMS settings. |
|
88 * @param aMobileSmsCaps SMS messaging capabilities of TSY/phone. |
|
89 * @param aSmsMessaging ETel SMS messaging subsession. |
|
90 * @param aPriority Priority to use for the Active Object. |
|
91 * @param aSmspSetBearer Set bearer object. |
|
92 */ |
|
93 CSmsMessageSend::CSmsMessageSend(CSmsSegmentationStore& aSegmentationStore, |
|
94 const TSmsSettings& aSmsSettings, |
|
95 const RMobileSmsMessaging::TMobileSmsCapsV1& aMobileSmsCaps, |
|
96 RMobileSmsMessaging& aSmsMessaging, |
|
97 TInt aPriority, |
|
98 CSmspSetBearer& aSmspSetBearer) |
|
99 : CSmsuActiveBase(aPriority), |
|
100 iState(ESmsMessageSendIdle), |
|
101 iSegmentationStore(aSegmentationStore), |
|
102 iSmspSetBearer(aSmspSetBearer), |
|
103 iSmsSettings(aSmsSettings), |
|
104 iMobileSmsCaps(aMobileSmsCaps), |
|
105 iSmsMessaging(aSmsMessaging), |
|
106 iMobileSmsSendAttributesV1Pckg(iMobileSmsSendAttributesV1), |
|
107 iSmsArray(8), |
|
108 iSegmentSequenceNumber(-1) |
|
109 { |
|
110 // NOP |
|
111 } // CSmsMessageSend::CSmsMessageSend |
|
112 |
|
113 |
|
114 /** |
|
115 * Standard destructor. |
|
116 */ |
|
117 CSmsMessageSend::~CSmsMessageSend() |
|
118 { |
|
119 Cancel(); |
|
120 delete iSmsEventLogger; |
|
121 } // CSmsMessageSend::~CSmsMessageSend |
|
122 |
|
123 |
|
124 void CSmsMessageSend::Start(CSmsMessage& aSmsMessage, TInt aOptions, |
|
125 const TSmsAddr& aSmsAddr, TRequestStatus& aStatus) |
|
126 { |
|
127 LOGSMSPROT1("CSmsMessageSend::Start()"); |
|
128 |
|
129 __ASSERT_DEBUG(iState == ESmsMessageSendIdle,SmspPanic(KSmspPanicUnexpectedState)); |
|
130 |
|
131 // |
|
132 // Store the request status that we will complete when finished... |
|
133 // |
|
134 Queue(aStatus); |
|
135 |
|
136 // |
|
137 // Initialise member data... |
|
138 // |
|
139 iSmsMessage=&aSmsMessage; |
|
140 iSmsMessage->ParsedToFromAddress(iToFromTelNumber); |
|
141 iOptions = aOptions; |
|
142 iSmsAddr = aSmsAddr; |
|
143 |
|
144 iSmsPDUData.iType = aSmsMessage.Type(); |
|
145 iSmsPDUData.iTotal = 0; |
|
146 iSmsPDUData.iSent = 0; |
|
147 iSmsPDUData.iDelivered = 0; |
|
148 |
|
149 iSendError = KErrNone; |
|
150 iSmsEventLogger->Event().SetId(KLogNullId); |
|
151 |
|
152 // |
|
153 // Begin by setting the bearer... |
|
154 // |
|
155 iState = ESmsMessageSendSetBearer; |
|
156 iSmspSetBearer.NotifyBearerSet(iStatus); |
|
157 SetActive(); |
|
158 } // CSmsMessageSend::Start |
|
159 |
|
160 |
|
161 void CSmsMessageSend::DoRunL() |
|
162 { |
|
163 LOGSMSPROT3("CSmsMessageSend::RunL(): iStatus=%d, iState=%d", iStatus.Int(), iState); |
|
164 |
|
165 switch (iState) |
|
166 { |
|
167 case ESmsMessageSendSetBearer: |
|
168 { |
|
169 // |
|
170 // If setting of bearer was successful then send the message. |
|
171 // |
|
172 // The TSY will complete with KErrNotSupported if it doesn't |
|
173 // support setting the send bearer. |
|
174 // |
|
175 if (iStatus.Int() == KErrNone || |
|
176 iStatus.Int() == KErrNotSupported) |
|
177 { |
|
178 if (iSmsEventLogger->ClientAvailable()) |
|
179 { |
|
180 CreateLogServerEvent(); |
|
181 } |
|
182 else |
|
183 { |
|
184 SegmentMessage(); |
|
185 } |
|
186 } |
|
187 } |
|
188 break; |
|
189 |
|
190 case ESmsMessageSendCreatingLogServerEvent: |
|
191 { |
|
192 // |
|
193 // If a log event was created ok, then store the id... |
|
194 // |
|
195 if (iStatus.Int() == KErrNone) |
|
196 { |
|
197 iSmsMessage->SetLogServerId(iSmsEventLogger->Event().Id()); |
|
198 } |
|
199 else |
|
200 { |
|
201 iSmsEventLogger->Event().SetId(KLogNullId); |
|
202 } |
|
203 |
|
204 // |
|
205 // Segment the message. This will send the first PDU as well... |
|
206 // |
|
207 SegmentMessage(); |
|
208 } |
|
209 break; |
|
210 |
|
211 case ESmsMessageSendSegmentingMessage: |
|
212 { |
|
213 // |
|
214 // If the previous PDU was sent ok, then send the next one... |
|
215 // |
|
216 if (iStatus.Int() == KErrNone) |
|
217 { |
|
218 SendNextPDU(); |
|
219 } |
|
220 else |
|
221 { |
|
222 // |
|
223 // An error occured. Save the error for later and either |
|
224 // update the log event, or drop to the end of RunL() so |
|
225 // that Complete() is called... |
|
226 // |
|
227 iSendError = iStatus.Int(); |
|
228 |
|
229 if (iSmsEventLogger->Event().Id() != KLogNullId) |
|
230 { |
|
231 UpdateLogServerEvent(); |
|
232 } |
|
233 } |
|
234 } |
|
235 break; |
|
236 |
|
237 case ESmsMessageSendPDU: |
|
238 { |
|
239 // |
|
240 // If the PDU is sent with an acknowledgement, then decode the |
|
241 // submit report... |
|
242 // |
|
243 if (iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsSendWithAck && |
|
244 iMobileSmsSendAttributesV1.iFlags & RMobileSmsMessaging::KGsmSubmitReport) |
|
245 { |
|
246 DecodeSubmitReportL(); |
|
247 } |
|
248 |
|
249 if (iStatus.Int() == KErrNone && !IsRPError()) |
|
250 { |
|
251 LOGSMSIF2("CSmsMessageSend::RunL(): Submit ACK'd MsgRef=%d", |
|
252 iMobileSmsSendAttributesV1.iMsgRef); |
|
253 } |
|
254 else if (IsRPError()) |
|
255 { |
|
256 LOGSMSIF2("CSmsMessageSend::RunL(): Submit N'ACK'D MsgRef=%d", |
|
257 iMobileSmsSendAttributesV1.iMsgRef); |
|
258 } |
|
259 else |
|
260 { |
|
261 LOGSMSIF2("CSmsMessageSend::RunL(): MsgRef=%d", |
|
262 iMobileSmsSendAttributesV1.iMsgRef); |
|
263 } |
|
264 |
|
265 // |
|
266 // If the PDU was sent okay, then update the segmentation store... |
|
267 // |
|
268 if (iStatus.Int() ==KErrNone) |
|
269 { |
|
270 iSegmentSequenceNumber++; |
|
271 UpdateSegmentationStore(); |
|
272 } |
|
273 else |
|
274 { |
|
275 // |
|
276 // An error occured. Save the error for later and either |
|
277 // update the log event, or drop to the end of RunL() so |
|
278 // that Complete() is called... |
|
279 // |
|
280 iSendError = iStatus.Int(); |
|
281 |
|
282 if (iSmsEventLogger->Event().Id() != KLogNullId) |
|
283 { |
|
284 UpdateLogServerEvent(); |
|
285 } |
|
286 } |
|
287 } |
|
288 break; |
|
289 |
|
290 case ESmsMessageSendUpdatingSegmentationStore: |
|
291 { |
|
292 if (iStatus.Int() == KErrNone) |
|
293 { |
|
294 // |
|
295 // The update has been successful, so update the log event or |
|
296 // send the next PDU. If the log event is updated, then it |
|
297 // will then send the next PDU... |
|
298 // |
|
299 if (iSmsEventLogger->Event().Id() != KLogNullId) |
|
300 { |
|
301 UpdateLogServerEvent(); |
|
302 } |
|
303 else |
|
304 { |
|
305 SendNextPDU(); |
|
306 } |
|
307 } |
|
308 else |
|
309 { |
|
310 // |
|
311 // An error occured. Save the error for later and either |
|
312 // update the log event, or drop to the end of RunL() so |
|
313 // that Complete() is called... |
|
314 // |
|
315 iSendError = iStatus.Int(); |
|
316 |
|
317 if (iSmsEventLogger->Event().Id() != KLogNullId) |
|
318 { |
|
319 UpdateLogServerEvent(); |
|
320 } |
|
321 } |
|
322 } |
|
323 break; |
|
324 |
|
325 case ESmsMessageSendUpdatingLogEvent: |
|
326 { |
|
327 // |
|
328 // Ignore log server error and continue with the next PDU if |
|
329 // the last send was okay, otherwise drop to the bottom of the |
|
330 // RunL() and Complete(). |
|
331 // |
|
332 if (iSendError == KErrNone) |
|
333 { |
|
334 SendNextPDU(); |
|
335 } |
|
336 } |
|
337 break; |
|
338 |
|
339 default: |
|
340 { |
|
341 SmspPanic(KSmspPanicUnexpectedState); |
|
342 } |
|
343 break; |
|
344 }; |
|
345 |
|
346 // |
|
347 // DoRunL() will now return to CSmsuActiveBase which if the object |
|
348 // is not active, will call Complete(). |
|
349 // |
|
350 } // CSmsMessageSend::DoRunL |
|
351 |
|
352 |
|
353 void CSmsMessageSend::DoCancel() |
|
354 { |
|
355 LOGSMSPROT2("CSmsMessageSend::DoCancel(): iState=%d", iState); |
|
356 |
|
357 TimedSetActiveCancel(); |
|
358 |
|
359 switch (iState) |
|
360 { |
|
361 case ESmsMessageSendSetBearer: |
|
362 { |
|
363 iSmspSetBearer.Cancel(); |
|
364 } |
|
365 break; |
|
366 |
|
367 case ESmsMessageSendSegmentingMessage: |
|
368 { |
|
369 // NOP |
|
370 } |
|
371 break; |
|
372 |
|
373 case ESmsMessageSendCreatingLogServerEvent: |
|
374 case ESmsMessageSendUpdatingLogEvent: |
|
375 { |
|
376 iSmsEventLogger->Cancel(); |
|
377 } |
|
378 break; |
|
379 |
|
380 case ESmsMessageSendPDU: |
|
381 { |
|
382 iSmsMessaging.CancelAsyncRequest(EMobileSmsMessagingSendMessage); |
|
383 } |
|
384 break; |
|
385 |
|
386 case ESmsMessageSendUpdatingSegmentationStore: |
|
387 { |
|
388 // NOP |
|
389 } |
|
390 break; |
|
391 |
|
392 default: |
|
393 { |
|
394 SmspPanic(KSmspPanicUnexpectedState); |
|
395 } |
|
396 break; |
|
397 }; |
|
398 |
|
399 iSendError = KErrCancel; |
|
400 |
|
401 // |
|
402 // Handle completion of this Active Object. Note that the object |
|
403 // may well still be active at this point... |
|
404 // |
|
405 if (TimedOut()) |
|
406 { |
|
407 Complete(KErrTimedOut); |
|
408 } |
|
409 else |
|
410 { |
|
411 Complete(KErrCancel); |
|
412 } |
|
413 } // CSmsMessageSend::DoCancel |
|
414 |
|
415 |
|
416 /** |
|
417 * Decodes SMS-SUBMIT-REPORT PDU and checks if it is SMS-SUBMIT-REPORT for |
|
418 * RP-ERROR. |
|
419 * |
|
420 * @leave Leaves if CSmsBuffer::NewL or CSmsMessage::NewL leaves. |
|
421 * |
|
422 */ |
|
423 void CSmsMessageSend::DecodeSubmitReportL() |
|
424 { |
|
425 LOGSMSPROT1("CSmsMessageSend::DecodeSubmitReportL()"); |
|
426 |
|
427 // |
|
428 // Only try to decode the submit report if error is a RP-error, in which case there should be a valid PDU |
|
429 // |
|
430 if (IsRPError()) |
|
431 { |
|
432 TGsmSms sms; |
|
433 sms.SetPdu(iMobileSmsSendAttributesV1.iSubmitReport); |
|
434 CSmsBuffer* buffer=CSmsBuffer::NewL(); |
|
435 |
|
436 // try to create a sms message from the submit report PDU (smsMessage takes ownership of the buffer) |
|
437 CSmsMessage* smsMessage = CSmsMessage::NewL(iSegmentationStore.FileSession(), |
|
438 sms,buffer,IsRPError(),ETrue); |
|
439 CleanupStack::PushL(smsMessage); |
|
440 |
|
441 if (smsMessage->SmsPDU().Type() == CSmsPDU::ESmsSubmitReport) |
|
442 { |
|
443 CSmsSubmitReport& submitReport =(CSmsSubmitReport&) smsMessage->SmsPDU(); |
|
444 TInt failureCause = submitReport.FailureCause(); |
|
445 |
|
446 if (failureCause != TSmsFailureCause::ESmsErrorFree) |
|
447 { |
|
448 iStatus = FailureCauseToError(failureCause); |
|
449 } |
|
450 } |
|
451 else |
|
452 { |
|
453 LOGSMSPROT3("Invalid PDU Type = %d with iStatus = %d", smsMessage->SmsPDU().Type(), iStatus.Int() ); |
|
454 } |
|
455 |
|
456 CleanupStack::PopAndDestroy(smsMessage); |
|
457 } |
|
458 } // CSmsMessageSend::DecodeSubmitReportL |
|
459 |
|
460 |
|
461 /** |
|
462 * Checks if TSY completed send message request with RP-error. |
|
463 * |
|
464 * @return boolean. |
|
465 */ |
|
466 TBool CSmsMessageSend::IsRPError() const |
|
467 { |
|
468 LOGSMSPROT1("CSmsMessageSend::IsRPError()"); |
|
469 |
|
470 TBool isRPError = EFalse; |
|
471 |
|
472 switch (iStatus.Int()) |
|
473 { |
|
474 case KErrGsmSMSUnassignedNumber: |
|
475 case KErrGsmSMSOperatorDeterminedBarring: |
|
476 case KErrGsmSMSCallBarred: |
|
477 case KErrGsmSMSReserved: |
|
478 case KErrGsmSMSNetworkFailure: |
|
479 case KErrGsmSMSShortMessageTransferRejected: |
|
480 case KErrGsmSMSMemoryCapacityExceeded: |
|
481 case KErrGsmSMSDestinationOutOfOrder: |
|
482 case KErrGsmSMSUnidentifiedSubscriber: |
|
483 case KErrGsmSMSFacilityRejected: |
|
484 case KErrGsmSMSUnknownSubscriber: |
|
485 case KErrGsmSMSNetworkOutOfOrder: |
|
486 case KErrGsmSMSTemporaryFailure: |
|
487 case KErrGsmSMSCongestion: |
|
488 case KErrGsmSMSResourcesUnavailable: |
|
489 case KErrGsmSMSRequestedFacilityNotSubscribed: |
|
490 case KErrGsmSMSRequestedFacilityNotImplemented: |
|
491 case KErrGsmSMSInvalidShortMessageTransferReferenceValue: |
|
492 case KErrGsmSMSUnspecifiedInvalidMessage: |
|
493 case KErrGsmSMSInvalidMandatoryInformation: |
|
494 case KErrGsmSMSNonExistentMessageType: |
|
495 case KErrGsmSMSIncompatibleMessageWithSmsProtocolState: |
|
496 case KErrGsmSMSInformationElementNotImplemented: |
|
497 case KErrGsmSMSUnspecifiedProtocolError: |
|
498 case KErrGsmSMSUnspecifiedInterworkingError: |
|
499 { |
|
500 isRPError = ETrue; |
|
501 } |
|
502 break; |
|
503 |
|
504 default: |
|
505 { |
|
506 // NOP |
|
507 } |
|
508 break; |
|
509 } |
|
510 |
|
511 return isRPError; |
|
512 } // CSmsMessageSend::IsRPError |
|
513 |
|
514 |
|
515 void CSmsMessageSend::SegmentMessage() |
|
516 { |
|
517 LOGSMSPROT1("CSmsMessageSend::SegmentMessage()"); |
|
518 |
|
519 iState = ESmsMessageSendSegmentingMessage; |
|
520 |
|
521 TRAPD(ret,DoSegmentMessageL()); |
|
522 |
|
523 CompleteMyself(ret); |
|
524 } // CSmsMessageSend::SegmentMessage |
|
525 |
|
526 |
|
527 void CSmsMessageSend::DoSegmentMessageL() |
|
528 { |
|
529 LOGSMSPROT1("CSmsMessageSend::DoSegmentMessageL()"); |
|
530 |
|
531 TInt reference=0; |
|
532 if (iSmsMessage->Type()==CSmsPDU::ESmsCommand) |
|
533 { |
|
534 CSmsCommand& command=(CSmsCommand&) iSmsMessage->SmsPDU(); |
|
535 |
|
536 CSmsSegmentationStore::RSmsSegmentationStoreRefStatusArray referencearray; |
|
537 CleanupClosePushL(referencearray); |
|
538 |
|
539 if (!iSegmentationStore.AddCommandL(iSmsAddr,*iSmsMessage, referencearray)) |
|
540 { |
|
541 User::Leave(KErrNotFound); |
|
542 } |
|
543 |
|
544 const TInt count=referencearray.Count(); |
|
545 CArrayFix<TGsmSms>* smsarray=new(ELeave) CArrayFixFlat<TGsmSms>(8); |
|
546 CleanupStack::PushL(smsarray); |
|
547 |
|
548 for (TInt i=0; i<count; i++) |
|
549 { |
|
550 command.SetMessageNumber(referencearray[i].Reference()); |
|
551 //TODO should reference be set to referencearray[i].iReference here? |
|
552 iSmsMessage->EncodeMessagePDUsL(*smsarray, reference); |
|
553 iSmsArray.AppendL(smsarray->At(0)); |
|
554 smsarray->Reset(); |
|
555 } |
|
556 CleanupStack::PopAndDestroy(2); // smsarray, referencearray |
|
557 } |
|
558 else |
|
559 { |
|
560 TBool iSentBefore=EFalse; |
|
561 TBool is16bit = EFalse; |
|
562 TBool concatenationIEPresent= iSmsMessage->SmsPDU().TextConcatenated( &is16bit ); |
|
563 iSmsMessage->SmsPDU().SetTextConcatenatedL(EFalse,EFalse); |
|
564 |
|
565 // Fix for INC039985; |
|
566 // The cause was that resending a SMS message(single PDU, same LogId), |
|
567 // caused an assertion fault; This did not happen with an SMS with multiple PDUs. |
|
568 // The reason for that is that for the multiple PDU case the stack employes a caching mechanism |
|
569 // built in - it checks which PDUs from an SMS message have already been sent and |
|
570 // then sends only the ones which have not been sent. This is performed by using the LodId, |
|
571 // which is used to uniquely identify an SMS message and the PDUs it consists of. |
|
572 // If an SMS message consisting of multiple PDUs is resend by an application and it has been already |
|
573 // sent sucessfully, the stack deletes the previous entry corresponding to the old LogId |
|
574 // segmentation store and replaces it with the new one with a new logid. |
|
575 // This mechanism has been extended for SMS messages consisting of single PDU. |
|
576 if(!iSmsMessage->EncodeIntoSinglePDUL(iSmsArray)) |
|
577 { |
|
578 if (concatenationIEPresent && is16bit) |
|
579 { |
|
580 iSmsMessage->Set16BitConcatenation(ETrue); |
|
581 } |
|
582 |
|
583 if(iSegmentationStore.HasEntryWithLogIdL(iSmsMessage->LogServerId(),reference,iSmsPDUData.iSent)) |
|
584 { |
|
585 iSentBefore=ETrue; |
|
586 } |
|
587 else |
|
588 { |
|
589 reference=is16bit? iSegmentationStore.Next16BitReferenceL(): iSegmentationStore.Next8BitReferenceL(); |
|
590 } |
|
591 iSmsMessage->EncodeMessagePDUsL(iSmsArray, reference); |
|
592 } |
|
593 else |
|
594 { |
|
595 if( iSegmentationStore.HasEntryWithLogIdL(iSmsMessage->LogServerId(),reference,iSmsPDUData.iSent)) |
|
596 { |
|
597 iSentBefore=ETrue; |
|
598 } |
|
599 } |
|
600 |
|
601 LOGSMSPROT3("CSmsMesageSend::DoSegmentMessageL [LogServerId=%d][iSentBefore=%d]",iSmsMessage->LogServerId(),iSentBefore); |
|
602 LOGSMSPROT3("CSmsMesageSend::DoSegmentMessageL [referenceNo=%d] [iCountOfSentBefore=%d ]",reference,iSmsPDUData.iSent); |
|
603 if(!iSentBefore) |
|
604 { |
|
605 iSegmentationStore.AddSubmitL(iSmsAddr,*iSmsMessage); |
|
606 } |
|
607 } |
|
608 } // CSmsMessageSend::DoSegmentMessageL |
|
609 |
|
610 |
|
611 void CSmsMessageSend::CreateLogServerEvent() |
|
612 { |
|
613 LOGSMSPROT1("CSmsMessageSend::CreateLogServerEvent()"); |
|
614 |
|
615 iState=ESmsMessageSendCreatingLogServerEvent; |
|
616 TLogId logid=(TLogId) iSmsMessage->LogServerId(); |
|
617 |
|
618 if (logid == KLogNullId) |
|
619 { |
|
620 iSmsPDUData.iTotal=iSmsArray.Count(); |
|
621 iSmsEventLogger->AddEvent(iStatus,*iSmsMessage,iSmsPDUData); |
|
622 } |
|
623 else |
|
624 { |
|
625 iSmsEventLogger->GetEvent(iStatus,logid); |
|
626 } |
|
627 SetActive(); |
|
628 } // CSmsMessageSend::CreateLogServerEvent |
|
629 |
|
630 |
|
631 void CSmsMessageSend::SendNextPDU() |
|
632 { |
|
633 LOGSMSPROT3("CSmsMessageSend::SendNextPDU [sending pdu %d of count=%d]",iSmsPDUData.iSent, iSmsArray.Count() ); |
|
634 |
|
635 if (iSmsPDUData.iSent<iSmsArray.Count()) |
|
636 { |
|
637 NMobilePhone::TMobileTON ton; |
|
638 NMobilePhone::TMobileNPI npi; |
|
639 |
|
640 TGsmSmsTelNumber parsedAddress(iSmsArray[iSmsPDUData.iSent].Sca()); |
|
641 |
|
642 iMobileSmsSendAttributesV1.iFlags = RMobileSmsMessaging::KGsmServiceCentre | |
|
643 RMobileSmsMessaging::KRemotePartyInfo | |
|
644 RMobileSmsMessaging::KSmsDataFormat | |
|
645 RMobileSmsMessaging::KMoreToSend; |
|
646 |
|
647 // |
|
648 // Set service centre address... |
|
649 // |
|
650 parsedAddress.iTypeOfAddress.ConvertToETelMM(ton, npi); |
|
651 iMobileSmsSendAttributesV1.iGsmServiceCentre.iTelNumber = parsedAddress.iTelNumber; |
|
652 iMobileSmsSendAttributesV1.iGsmServiceCentre.iTypeOfNumber = static_cast<RMobilePhone::TMobileTON>(static_cast<TInt>(ton)); |
|
653 iMobileSmsSendAttributesV1.iGsmServiceCentre.iNumberPlan = static_cast<RMobilePhone::TMobileNPI>(static_cast<TInt>(npi)); |
|
654 |
|
655 // |
|
656 // Set destination address... |
|
657 // |
|
658 iToFromTelNumber.iTypeOfAddress.ConvertToETelMM(ton, npi); |
|
659 iMobileSmsSendAttributesV1.iDestination.iTelNumber = iToFromTelNumber.iTelNumber; |
|
660 iMobileSmsSendAttributesV1.iDestination.iTypeOfNumber = static_cast<RMobilePhone::TMobileTON>(static_cast<TInt>(ton)); |
|
661 iMobileSmsSendAttributesV1.iDestination.iNumberPlan = static_cast<RMobilePhone::TMobileNPI>(static_cast<TInt>(npi)); |
|
662 |
|
663 iMobileSmsSendAttributesV1.iDataFormat = RMobileSmsMessaging::EFormatGsmTpdu; |
|
664 |
|
665 if (iSmsPDUData.iSent < iSmsArray.Count() - 1) |
|
666 { |
|
667 iMobileSmsSendAttributesV1.iMore = ETrue; |
|
668 } |
|
669 else |
|
670 { |
|
671 iMobileSmsSendAttributesV1.iMore = EFalse; |
|
672 } |
|
673 |
|
674 // |
|
675 // Debug logging of the PDU we are sending... |
|
676 // |
|
677 LOGSMSIFPDU(_L8("ETEL TX PDU: "), iSmsArray[iSmsPDUData.iSent].Pdu(), ETrue); |
|
678 LOGSMSIFSENDATTRIBUTES(_L8("SENDATTRIBS: "), iMobileSmsSendAttributesV1); |
|
679 LOGSMSIFTIMESTAMP(); |
|
680 |
|
681 // |
|
682 // Send the message and enter the correct state... |
|
683 // |
|
684 iState = ESmsMessageSendPDU; |
|
685 iSmsMessaging.SendMessage(iStatus, iSmsArray[iSmsPDUData.iSent].Pdu(), |
|
686 iMobileSmsSendAttributesV1Pckg); |
|
687 TimedSetActive(iSmsSettings.SendTryTimeout()); |
|
688 } |
|
689 } // CSmsMessageSend::SendNextPDU |
|
690 |
|
691 |
|
692 void CSmsMessageSend::UpdateSegmentationStore() |
|
693 { |
|
694 iState = ESmsMessageSendUpdatingSegmentationStore; |
|
695 |
|
696 TRAPD(ret,DoUpdateSegmentationStoreL()); |
|
697 |
|
698 CompleteMyself(ret); |
|
699 } // CSmsMessageSend::UpdateSegmentationStore |
|
700 |
|
701 |
|
702 void CSmsMessageSend::DoUpdateSegmentationStoreL() |
|
703 { |
|
704 LOGSMSPROT1("CSmsMessageSend::DoUpdateSegmentationStoreL()"); |
|
705 |
|
706 iSmsPDUData.iSent++; // This is the end of the sequence for sending an SMS PDU |
|
707 |
|
708 if (iSmsMessage->Scheme() == EControlParametersScheme || |
|
709 iSmsMessage->Scheme() == ETPSRRScheme) |
|
710 { |
|
711 iSegmentationStore.AddReferenceStatusPairL(*iSmsMessage,(TInt) iMobileSmsSendAttributesV1.iMsgRef, iSegmentSequenceNumber); |
|
712 } |
|
713 else if (iSmsMessage->Scheme() == EDefaultScheme) |
|
714 { |
|
715 iSegmentationStore.AddReferenceL(*iSmsMessage,(TInt) iMobileSmsSendAttributesV1.iMsgRef); |
|
716 } |
|
717 else |
|
718 { |
|
719 User::Leave(KErrNotFound); |
|
720 } |
|
721 } // CSmsMessageSend::DoUpdateSegmentationStoreL |
|
722 |
|
723 |
|
724 void CSmsMessageSend::UpdateLogServerEvent() |
|
725 { |
|
726 LOGSMSPROT1("CSmsMessageSend::UpdateLogServerEvent()"); |
|
727 |
|
728 // |
|
729 // Fill in log event... |
|
730 // |
|
731 iState = ESmsMessageSendUpdatingLogEvent; |
|
732 iSmsPDUData.iTotal = iSmsArray.Count(); |
|
733 iSmsEventLogger->ChangeEvent(iStatus, *iSmsMessage, iSmsPDUData); |
|
734 SetActive(); |
|
735 } // CSmsMessageSend::UpdateLogServerEvent |
|
736 |
|
737 |
|
738 void CSmsMessageSend::Complete(TInt aStatus) |
|
739 { |
|
740 LOGSMSPROT3("CSmsMessageSend::Complete [iStatus=%d, iState=%d]", iStatus.Int(), iState ); |
|
741 |
|
742 // |
|
743 // For completion during log events, use the saved error code instead... |
|
744 // |
|
745 if (iState == ESmsMessageSendCreatingLogServerEvent || |
|
746 iState == ESmsMessageSendUpdatingLogEvent) |
|
747 { |
|
748 aStatus = iSendError; |
|
749 } |
|
750 |
|
751 // |
|
752 // Clear all PDU data that was sent... |
|
753 // |
|
754 for (TInt i=0; i < iSmsPDUData.iSent; i++) |
|
755 { |
|
756 iSmsArray.Delete(0); |
|
757 } |
|
758 |
|
759 iSmsArray.Reset(); |
|
760 |
|
761 iState = ESmsMessageSendIdle; |
|
762 |
|
763 // |
|
764 // Call the base function to perform the actual complete... |
|
765 // |
|
766 CSmsuActiveBase::Complete(aStatus); |
|
767 } // CSmsMessageSend::Complete |