|
1 /* |
|
2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * State machine for message receiving |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 #ifndef MMSRECEIVEMESSAGE_H |
|
22 #define MMSRECEIVEMESSAGE_H |
|
23 |
|
24 // INCLUDES |
|
25 #include <mentact.h> |
|
26 #include <mtsr.h> |
|
27 #include <s32mem.h> |
|
28 #include <es_sock.h> |
|
29 #include <etel.h> |
|
30 #include <etelmm.h> |
|
31 |
|
32 //#include "mmsoperation.h" |
|
33 #include "mmsbaseoperation.h" |
|
34 |
|
35 // CONSTANTS |
|
36 enum TMmsSettingsFetchMode |
|
37 { |
|
38 // Modes that send acknowledgements to MMSC |
|
39 |
|
40 // Fetch everything that fits criteria, discard rest |
|
41 // (too big messages, advertisements etc.) |
|
42 // Fetching is tried until message expires. |
|
43 // Retry interval may be lengthened in some cases. |
|
44 EMmsMinimumFetchingMode = 1, |
|
45 EMmsFetchingOn = EMmsMinimumFetchingMode, |
|
46 |
|
47 // Send a reject response to everything |
|
48 EMmsFetchingOff = EMmsFetchingOn + 1, |
|
49 |
|
50 // Send a deferred response to everything until the |
|
51 // user switches fetching mode on again. |
|
52 // At that point fetch everything that has not expired |
|
53 EMmsFetchingDeferred = EMmsFetchingOff + 1, |
|
54 |
|
55 // change this is modes added |
|
56 EMmsMaximumFetchingMode = EMmsFetchingDeferred |
|
57 }; |
|
58 |
|
59 // MACROS |
|
60 |
|
61 // DATA TYPES |
|
62 |
|
63 // FUNCTION PROTOTYPES |
|
64 |
|
65 // FORWARD DECLARATIONS |
|
66 class CMmsHeaders; |
|
67 class CMmsDecode; |
|
68 class CMmsEncode; |
|
69 class CMmsPhoneClient; |
|
70 |
|
71 // CLASS DECLARATION |
|
72 |
|
73 /** |
|
74 * State machine for handling message fetching. |
|
75 * Calls CMmsTransaction and CMmsDecode to do the dirty work |
|
76 */ |
|
77 //class CMmsReceiveMessage :public CMsgActive |
|
78 class CMmsReceiveMessage :public CMmsBaseOperation |
|
79 { |
|
80 public: // Constructors and destructor |
|
81 |
|
82 /** |
|
83 * C++ default constructor is private |
|
84 */ |
|
85 |
|
86 /** |
|
87 * Two-phased constructor. |
|
88 */ |
|
89 static CMmsReceiveMessage* NewL( RFs& aFs, CMmsSettings* aMmsSettings ); |
|
90 |
|
91 /** |
|
92 * Destructor. |
|
93 */ |
|
94 virtual ~CMmsReceiveMessage(); |
|
95 |
|
96 public: // New functions |
|
97 |
|
98 /** |
|
99 * Start the state machine. |
|
100 * @param aSelection list of notification ids referring to |
|
101 * messages to be fetched. <br> |
|
102 * If the code decides that a message will not be fetched, |
|
103 * it will send a "Reject" or "Deferred" response to MMSC |
|
104 * @param aServerEntry CMsvServerEntry pointer from CMmsServer |
|
105 * @param aSettings MMSC settings (entry points) |
|
106 * @param aService current MMS service id |
|
107 * @param aStatus TRequestStatus of the calling active object |
|
108 */ |
|
109 void StartL( |
|
110 CMsvEntrySelection& aSelection, |
|
111 CMsvServerEntry& aServerEntry, |
|
112 TMsvId aService, |
|
113 TRequestStatus& aStatus ); |
|
114 |
|
115 /** |
|
116 * Get list of successfully received messages. |
|
117 * Actually this is a list of notifications corresponding to successful message |
|
118 */ |
|
119 inline CMsvEntrySelection& Received() const; |
|
120 |
|
121 /** |
|
122 * Get list of failed messages |
|
123 */ |
|
124 inline CMsvEntrySelection& Failed() const; |
|
125 |
|
126 /** |
|
127 * Get list of bad notifications |
|
128 * These should be deleted. The scheduling information should |
|
129 * be removed first. After the scheduling has been finalized, |
|
130 * this function may disappear, if it turns out that we can |
|
131 * just delete these entries, and the schedules disappear |
|
132 * automatically. |
|
133 */ |
|
134 inline CMsvEntrySelection& BadNotifications() const; |
|
135 |
|
136 // Tells if we in home network or in foreign. |
|
137 inline TBool InForeignNetwork() const; |
|
138 |
|
139 public: // Functions from base classes |
|
140 |
|
141 protected: // New functions |
|
142 |
|
143 protected: // Functions from base classes |
|
144 |
|
145 private: |
|
146 |
|
147 /** |
|
148 * Default constructor |
|
149 */ |
|
150 CMmsReceiveMessage( RFs& aFs ); |
|
151 |
|
152 /** |
|
153 * By default Symbian OS constructor is private. |
|
154 */ |
|
155 void ConstructL( CMmsSettings* aMmsSettings ); |
|
156 |
|
157 // By default, prohibit copy constructor |
|
158 CMmsReceiveMessage( const CMmsReceiveMessage& ); |
|
159 // Prohibit assignment operator |
|
160 CMmsReceiveMessage& operator= ( const CMmsReceiveMessage& ); |
|
161 |
|
162 /** |
|
163 * From CMsgActive: Complete current operation. |
|
164 * Do whatever cleanup is possible. (Delete incomplete entry etc.) |
|
165 * @param aError Error code received by RunL |
|
166 */ |
|
167 void DoComplete(TInt& aStatus); |
|
168 |
|
169 /** |
|
170 * Decode one message |
|
171 */ |
|
172 void DecodeResponseL(); |
|
173 |
|
174 /** |
|
175 * Connect to Internet Access Point before connecting to WAP Gateway |
|
176 */ |
|
177 void ConnectToIAPL(); |
|
178 |
|
179 /** |
|
180 * Connect to MMSC |
|
181 */ |
|
182 void InitializeSessionL(); |
|
183 |
|
184 /** |
|
185 * Receive one message from MMSC |
|
186 */ |
|
187 void SubmitTransactionL(); |
|
188 |
|
189 /** |
|
190 * Check if we connection was successful for the next transaction. |
|
191 * @return |
|
192 * - ETrue if successfully connected and can continue |
|
193 * - EFalse if not connected (should terminate state machine) |
|
194 */ |
|
195 TBool IsConnected(); |
|
196 |
|
197 /** |
|
198 * Load the notification entry and clear old status if needed |
|
199 * @param aEntry Index entry of the notification (filled with data) |
|
200 * @return |
|
201 * - ETrue if processing can continue with this notification |
|
202 * - EFalse if processing should end. |
|
203 * If processing is discontinued, caller must return. |
|
204 * Depending on error the state machine goes to next state (if set active) |
|
205 * or terminates (not set active) |
|
206 */ |
|
207 TBool LoadNotificationL( TMsvEntry& aEntry ); |
|
208 |
|
209 /** |
|
210 * Check if the message has expired or if it can be fetched |
|
211 * In manual mode the fetch will continue even if the message |
|
212 * has expired. It is up to the user if he wants to try to fetch |
|
213 * expired messages. |
|
214 * @return |
|
215 * - ETrue continue operation with this notification |
|
216 * - EFalse message has expired and no response will be sent |
|
217 * The function has changed state and the caller should just return. |
|
218 */ |
|
219 TBool CheckExpirationL(); |
|
220 |
|
221 /** |
|
222 * Checks notification sanity. |
|
223 * If MMS major version number or message type is incorrect, |
|
224 * notification status will be set to "Unrecognized" |
|
225 * @return |
|
226 * - ETrue notification is insane |
|
227 * - EFalse notification is sane, and further checks can be made |
|
228 */ |
|
229 TBool IsNotificationInsaneL(); |
|
230 |
|
231 /** |
|
232 * Check is the message is not fetched |
|
233 * Response should be sent anyway´ |
|
234 * @param aEntry notification index entry |
|
235 * @return |
|
236 * - ETrue if the message will be fetched |
|
237 * - EFalse if the message is fetched, only response sent |
|
238 * The function will change state as needed, caller must return |
|
239 */ |
|
240 TBool WantToFetchThisL( TMsvEntry& aEntry ); |
|
241 |
|
242 /** |
|
243 * Create entry into inbox to receive the new message. |
|
244 * Called in chunked mode. |
|
245 * Does not complete the caller. |
|
246 */ |
|
247 void DoCreateEntryL(); |
|
248 |
|
249 /** |
|
250 * Finalize the new entry |
|
251 */ |
|
252 void StoreResponseL(); |
|
253 |
|
254 /** |
|
255 * Send notify response or acknowledge indication |
|
256 */ |
|
257 void SendAckL(); |
|
258 |
|
259 /** |
|
260 * Check if we sent the response successfully. |
|
261 * If not successful, we may need to requeue the notification. |
|
262 * Move entry to inbox if needed. |
|
263 */ |
|
264 void UpdateEntryStatusL(); |
|
265 |
|
266 /** |
|
267 * Encode a notify response |
|
268 */ |
|
269 void EncodeNotifyResponseL(); |
|
270 |
|
271 /** |
|
272 * Encode Acknowledge Indication |
|
273 */ |
|
274 void EncodeAcknowledgeIndicationL(); |
|
275 |
|
276 |
|
277 // start of ROAMING CHECK handling |
|
278 /** |
|
279 * Start the roaming check, will complete asynchronously |
|
280 */ |
|
281 void RoamingCheck(); |
|
282 |
|
283 /** |
|
284 * Check result of roaming state query |
|
285 */ |
|
286 void GetRoamingState(); |
|
287 // end of ROAMING CHECK handling |
|
288 |
|
289 /** |
|
290 * Handle messages that are type multipart alternative. |
|
291 * If text/plain part is found, it is retained, others are deleted. |
|
292 */ |
|
293 void HandleMultipartAlternativeL(); |
|
294 |
|
295 /** |
|
296 * Check the fate of the notification. |
|
297 * As Receive message has no PDU to send, we check the fate of the |
|
298 * notification in this state. If the state indicates that the |
|
299 * entry must not be fetched, we clean up this entry and loop |
|
300 * to the next. |
|
301 */ |
|
302 void EncodePDUL(); |
|
303 |
|
304 /** |
|
305 * Gets a folder entry id with 'aFolderName' name under a parent folder. |
|
306 * @param aParentFolder a folder, under where the folder is searched |
|
307 * @param aFolderName the name of the searched folder entry |
|
308 * @param aFolderId the entry id of the searched folder |
|
309 * @return KErrNone if successful |
|
310 */ |
|
311 TInt FolderEntryL( TMsvId aParent, const TDesC& aFolderName, TMsvId& aFolderId ); |
|
312 |
|
313 /** |
|
314 * Creates a folder entry id with 'aFolderName' name under a parent folder. |
|
315 * If the folder already exists, its folder id is returned. |
|
316 * @param aParentFolder a folder, under where the folder will be created |
|
317 * @param aFolderName the name of the folder entry to be created |
|
318 * @param aFolderId the entry id of the created folder |
|
319 * @return KErrNone if successful |
|
320 */ |
|
321 TInt CreateFolderEntryL( TMsvId aParentFolder, const TDesC& aFolderName, TMsvId& aFolderId ); |
|
322 |
|
323 /** |
|
324 * Find duplicate notification |
|
325 * @param aParent entry id, under where the duplicate is searched |
|
326 * @param aHeaders the original mms headers, whose duplicate is searched |
|
327 * @param aDuplicate entry id of the found duplicate |
|
328 */ |
|
329 TInt FindDuplicateNotificationL( TMsvId aParent, |
|
330 CMmsHeaders& aHeaders, TMsvId& aDuplicate ); |
|
331 |
|
332 /** |
|
333 * Get the message from a file in local mode |
|
334 */ |
|
335 void LocalModeFetchL(); |
|
336 |
|
337 /** |
|
338 * Dump the incoming message into a file if there has been an error. |
|
339 * Dumping can be done only when logging is enabled. |
|
340 */ |
|
341 void DumpIfNeededL(); |
|
342 |
|
343 /** |
|
344 * Close the message file used in local mode |
|
345 * aDeleteFile |
|
346 */ |
|
347 void CloseLocalFileL( TBool aDeleteFile ); |
|
348 |
|
349 /** |
|
350 * If the message contains an application id which is registered, move the |
|
351 * message to the corresponding folder. The corresponding folder is under |
|
352 * application folder. There may be several folders under application folder. |
|
353 * @param aEntry index entry of the message to be handled |
|
354 * @return status code that tells if the message was intended |
|
355 * for an unregistered applicatio or successfully moved to an |
|
356 * application folder. |
|
357 * Return value 0 denotes normal message. |
|
358 */ |
|
359 TInt MoveToApplicationFolderIfNeededL( TMsvEntry& aEntry ); |
|
360 |
|
361 /** |
|
362 * Skip inaccessible notification. |
|
363 * The notification remains in failed list. |
|
364 * The state machine winds back to start |
|
365 */ |
|
366 void SkipEntryL(); |
|
367 |
|
368 /** |
|
369 * Entry has been handled. Loop to next entry or finalize the whole loop |
|
370 */ |
|
371 void LoopToNextEntryL(); |
|
372 |
|
373 /** |
|
374 * The state of duplicate notification is cleared in case of fatal failure. |
|
375 * iServerEntry must point to the notification in question. |
|
376 * |
|
377 */ |
|
378 void ClearDuplicateEntryOperationL(); |
|
379 |
|
380 /** |
|
381 * Marks info inton notification and clear duplicate |
|
382 * @param aApplicationMessageStatus status that tells if the message |
|
383 * was addressed to an application. |
|
384 */ |
|
385 void ClearOperationL( TInt aApplicationMessageStatus ); |
|
386 |
|
387 /** |
|
388 * Copy missing info from notification to message. |
|
389 * If we have received a message that contains only status code |
|
390 * we copy fields like sender and subject from notification |
|
391 * to the message to retain some relevant information. |
|
392 */ |
|
393 void CopyDataFromNotificationToMessageL(); |
|
394 |
|
395 /** |
|
396 * Copy status code and application id from message to notification. |
|
397 * If we get a message with transient error, we copy the status data |
|
398 * to the notification before retry (to inform user about the cause |
|
399 * of the problem). |
|
400 * We also copy the application id in case the notification does not |
|
401 * already contain it. This may inform the user why the message went |
|
402 * to some application instead of appearing in the inbox (manual mode) |
|
403 */ |
|
404 void CopyDataFromMessageToNotificationL(); |
|
405 |
|
406 /** |
|
407 * Map the error status received from MMSC into an internal error code |
|
408 * @param aErrorStatus status from MMS headers |
|
409 * @return ETrue if the error is permanent, EFalse if the error is transient |
|
410 */ |
|
411 TBool MapErrorStatus( const TInt32 aErrorStatus ); |
|
412 |
|
413 /** |
|
414 * Set the bits to index entry to complete a received message |
|
415 * @param aEntry the index entry of the received message |
|
416 */ |
|
417 void SetIndexEntryBitsForReceivedMessage( TMsvEntry& aEntry ); |
|
418 |
|
419 /** |
|
420 * Try to free space by deleting older messages for the current application. |
|
421 * If memory can be freed iError is changed from KErrNoDisk to |
|
422 * KMmsErrorApplicationDiskFull. The operation will be rescheduled in |
|
423 * automatic mode. In manual mode the user must restart the fetch. |
|
424 */ |
|
425 void DeleteApplicationMessagesL(); |
|
426 |
|
427 |
|
428 public: // Data |
|
429 |
|
430 protected: // Data |
|
431 |
|
432 private: // Data |
|
433 RFile iFile; // local mode message |
|
434 |
|
435 CMmsHeaders* iMmsHeaders; // Headers from incoming message |
|
436 CMmsHeaders* iNotification; // Headers forming the notification |
|
437 TBool iAlreadyDeferred; // deferred response has already been sent |
|
438 CMsvEntrySelection* iBad; // bad notifications |
|
439 |
|
440 TMsvId iEntryUnderConstruction; |
|
441 TMsvId iNotificationParent; |
|
442 |
|
443 // Buffer for the incoming message. |
|
444 TInt iMessageDrive; // messages are on C: drive by default, |
|
445 TBool iFileOpen; // if file is not open, do not close |
|
446 |
|
447 TMmsReceivingMode iReceivingMode; // set to correct mode depending on network |
|
448 // tells if an application id has been registered or not |
|
449 TBool iRegistered; |
|
450 |
|
451 public: // Friend classes |
|
452 protected: // Friend classes |
|
453 private: // Friend classes |
|
454 |
|
455 }; |
|
456 |
|
457 #include "mmsreceivemessage.inl" |
|
458 |
|
459 #endif // MMSRECEIVEMESSAGE_H |
|
460 |
|
461 // End of File |