a39f078cee5e3aee13675b7bad30ed7476237618
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Messaging / Mms.cpp
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. 
15 */
16
17
18 /**
19  *
20  *
21  * @file       Mms.cpp
22  * @author     Pawel Misiak (p.misiak@samsung.com)
23  * @version    0.1
24  * @brief
25  */
26 #include "Mms.h"
27
28 #include <vector>
29 #include <dpl/log/log.h>
30 #include <Commons/Exception.h>
31 #include <API/Messaging/ReqReceiverMessage.h>
32 #include "Messaging.h"
33 #include "CallbackMgr.h"
34 #include "MsgServiceHandleMgr.h"
35
36 extern "C" {
37 #include <MapiControl.h>
38 #include <MapiMessage.h>
39 #include <MapiStorage.h>
40 }
41
42 namespace {
43 const char* TEXT_AREA = "Text";
44 const char* TEXT_FILE_EXTENSION = ".txt";
45 const int WHITE_COLOR = 0xffffff;
46 const int BLACK_COLOR = 0x000000;
47 const int ROOT_LAYOUT_WIDTH = 100;
48 const int ROOT_LAYOUT_HEIGHT = 100;
49 const char* EMPTY_ID = "0";
50 }
51
52 using namespace std;
53 using namespace TizenApis::Api::Messaging;
54
55 namespace TizenApis {
56 namespace Platform {
57 namespace Messaging {
58
59 Mms::Mms(const string& id) :
60     IMessage(MMS, id),
61     m_bodyFilePath(string(tmpnam(NULL)) + TEXT_FILE_EXTENSION),
62     m_messageData(NULL)
63 {
64     LogDebug("enter");
65     LogDebug("m_id=" << getIdRef());
66     LogDebug("m_msgType=" << getMessageType());
67     if (getIdRef().empty()) {
68         createNewMessage();
69     } else {
70         readExistingMessage();
71     }
72 }
73
74 Mms::~Mms()
75 {
76     LogDebug("enter");
77
78     if (m_messageData) {
79         // release platform message structure
80         msg_release_message(&m_messageData);
81     }
82
83     //remove tmp file
84     //trying to remove file, return value is skipped
85     if (!m_bodyFilePath.empty()) {
86         LogDebug("remove tmp file=" << m_bodyFilePath);
87         (void) ::remove(m_bodyFilePath.c_str());
88     }
89 }
90
91 void Mms::createNewMessage()
92 {
93     if (m_messageData) {
94         msg_release_message(&m_messageData);
95         m_messageData = NULL;
96     }
97     m_messageData = msg_new_message();
98
99     MSG_SENDINGOPT_S sendOpt = { 0 };
100     sendOpt.bSetting = false;
101
102     // initialize platform message structure
103     msg_set_message_id(m_messageData, 0); // It should be set 0
104     msg_set_folder_id(m_messageData, MSG_DRAFT_ID);
105     msg_set_message_type(m_messageData, MSG_TYPE_MMS);
106     msg_set_storage_id(m_messageData, MSG_STORAGE_PHONE);
107     msg_set_subject(m_messageData, "");
108     msg_set_read_status(m_messageData, false);
109     msg_set_network_status(m_messageData, MSG_NETWORK_NOT_SEND);
110     msg_set_direction_info(m_messageData, MSG_DIRECTION_TYPE_MO);
111     msg_set_priority_info(m_messageData, MSG_MESSAGE_PRIORITY_NORMAL);
112
113     tm dateT = getDateTime();
114     msg_set_time(m_messageData, mktime(&dateT));
115
116     setMmsType(MULTIPART_MIXED);
117     setReadStatus(false);
118     setMessageStatus(Api::Messaging::MESSAGE_STATUS_DRAFT);
119
120     LogDebug("Message created successfully, Id: " << getIdRef());
121 }
122
123 void Mms::readExistingMessage()
124 {
125     LogDebug("entered");
126
127     if (getIdRef().empty() || (EMPTY_ID == getIdRef())) {
128         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Empty id.");
129     }
130
131     Try {
132         MSG_SENDINGOPT_S option;
133         option.bSetting = false;
134
135         // release old data
136         msg_release_message(&m_messageData);
137         m_messageData = NULL;
138         // crate new structure
139         m_messageData = msg_new_message();
140
141         // trying to get message from platform
142         if (MSG_SUCCESS != msg_get_message(
143                 MsgGetCommonHandle(), convertId(getIdRef()), m_messageData,
144                 &option)) {
145             LogError("get message error");
146             Throw(WrtDeviceApis::Commons::PlatformException);
147         }
148         LogDebug("message found with msgId=" << getIdRef());
149
150         // read all mms dat to abstraction layer
151         readRecipientList(m_messageData);
152         readPriority(m_messageData);
153         readSubject(m_messageData);
154         readBodyAndAttachments(m_messageData);
155         readFolder(m_messageData);
156         readDateTime(m_messageData);
157         readReadStatus(m_messageData);
158     }
159     Catch(WrtDeviceApis::Commons::Exception) {
160         // nothing to do
161     }
162 }
163
164 void Mms::readDateTime(msg_message_t& messageData)
165 {
166     tm* time = localtime(msg_get_time(messageData));
167     if (!time) {
168         LogError("localtime failed");
169         Throw(WrtDeviceApis::Commons::PlatformException);
170     }
171     setDateTime(*time);
172 }
173
174 void Mms::readReadStatus(msg_message_t& messageData)
175 {
176     setReadStatus(msg_is_read(messageData));
177 }
178
179 void Mms::readFolder(msg_message_t& messageData)
180 {
181     switch (msg_get_folder_id(messageData)) {
182     case MSG_INBOX_ID:
183         setFolderType(Api::Messaging::INBOX);
184         break;
185     case MSG_OUTBOX_ID:
186         setFolderType(Api::Messaging::OUTBOX);
187         break;
188     case MSG_SENTBOX_ID:
189         setFolderType(Api::Messaging::SENTBOX);
190         break;
191     case MSG_DRAFT_ID:
192         setFolderType(Api::Messaging::DRAFTBOX);
193         break;
194     case MSG_SPAMBOX_ID:
195         setFolderType(Api::Messaging::SPAMBOX);
196         break;
197     default:
198         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Unsupported folder id.");
199     }
200 }
201
202 void Mms::readPriority(msg_message_t& messageData)
203 {
204     switch (msg_get_priority_info(messageData)) {
205     case MSG_MESSAGE_PRIORITY_LOW:
206         setPriority(MessagePriority::LOW);
207         break;
208     case MSG_MESSAGE_PRIORITY_NORMAL:
209         setPriority(MessagePriority::NORMAL);
210         break;
211     case MSG_MESSAGE_PRIORITY_HIGH:
212         setPriority(MessagePriority::HIGH);
213         break;
214     default:
215         LogError("Wrong priority type");
216         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Wrong priority type");
217     }
218 }
219
220 void Mms::readRecipientList(msg_message_t& messageData)
221 {
222     std::string phoneNumber;
223     int recipientCount = msg_get_address_count(messageData);
224     LogDebug("Recipient count " << recipientCount);
225     for (int i = 0; i < recipientCount; ++i) {
226         int type = msg_get_direction_info(messageData);
227
228         if (MSG_DIRECTION_TYPE_MT == type) {
229             phoneNumber = msg_get_ith_address(messageData, i);
230             if (validatePhoneNumber(phoneNumber)) {
231                 setSourceAddress(phoneNumber);
232                 setFrom(phoneNumber);
233             }
234             LogDebug("phone number: " << phoneNumber);
235         } else if (MSG_DIRECTION_TYPE_MO == type) {
236             switch (msg_get_ith_recipient_type(messageData, i)) {
237             case MSG_RECIPIENTS_TYPE_TO:
238                 appendToRecipients(msg_get_ith_address(messageData, i));
239                 break;
240             case MSG_RECIPIENTS_TYPE_CC:
241                 appendCcRecipients(msg_get_ith_address(messageData, i));
242                 break;
243             case MSG_RECIPIENTS_TYPE_BCC:
244                 appendBccRecipients(msg_get_ith_address(messageData, i));
245                 break;
246             default:
247                 LogError("Wrong type of recipient");
248                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Wrong type of recipient");
249             }
250         } else {
251             LogError("Wrong type of recipient");
252             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Wrong type of recipient");
253         }
254     }
255 }
256
257 void Mms::readSubject(msg_message_t& messageData)
258 {
259     setSubject(msg_get_subject(messageData));
260 }
261
262 void Mms::readBodyAndAttachments(msg_message_t& messageData)
263 {
264     //TODO
265     MMS_MESSAGE_DATA_S msgBody = {};
266     msg_mms_get_message_body(messageData, &msgBody);
267
268     //if any page then multipart is related type
269     if (msgBody.pageCnt > 0) {
270         setMmsType(MULTIPART_RELATED);
271     } else {
272         setMmsType(MULTIPART_MIXED);
273     }
274
275     LogDebug("page count: " << msgBody.pageCnt);
276
277     for (int p = 0; p < msgBody.pageCnt; ++p) {
278         LogDebug("page " << p);
279         MMS_PAGE_S *page = msg_mms_get_page(p);
280         if (!page) {
281             LogError("returned page is null, continue");
282             continue;
283         }
284         for (int m = 0; m < page->mediaCnt; ++m) {
285             LogDebug("media file " << m);
286             MMS_MEDIA_S* media = msg_mms_get_media(page, m);
287             if (!media) {
288                 LogError("returned media is null, continue");
289                 continue;
290             }
291             if (0 == p && MMS_SMIL_MEDIA_TEXT == media->mediatype) {
292                 //text value on first page goes to body attribute
293                 LogDebug("setting body from " << media->szFilePath);
294                 FILE* f = NULL;
295                 f = fopen(media->szFilePath, "r");
296                 if (!f) {
297                     LogError("cannot read file with body" << media->szFilePath);
298                     ThrowMsg(WrtDeviceApis::Commons::PlatformException,
299                              "Cannot read file with body");
300                 }
301                 fseek(f, 0, SEEK_END);
302                 long int size = ftell(f);
303                 fseek(f, 0, SEEK_SET);
304                 char* data = new (nothrow) char[size + 1];
305                 if (data) {
306                     memset(data, 0, size + 1);
307                     fread(data, 1, size, f);
308                     setBody(data);
309                     delete[] data;
310                 } else {
311                     LogError("body is not set");
312                 }
313                 LogDebug("message body: '" << getBody() << "'");
314                 fclose(f);
315             } else {
316                 LogDebug("adding attachment " << media->szFilePath);
317
318                 IAttachmentPtr attachment = appendAttachment(media->szFilePath,
319                                                              false);
320                      //attachment->setMessage(this);    //set IMessagePtr
321                 if (NULL != media->szFileName &&
322                     strnlen(media->szFileName, MSG_FILENAME_LEN_MAX) > 0) {
323                     LogDebug("renaming to " << media->szFileName);
324                     attachment->rename(media->szFileName);
325                 } else if (MMS_SMIL_MEDIA_TEXT == media->mediatype) {
326                     std::stringstream newName;
327                     newName << "body_page_" << p + 1 << ".txt";
328                     LogDebug("renaming to " << newName.str());
329                     attachment->rename(newName.str());
330                 }
331
332             }
333         }
334     }
335
336     LogDebug("attachment count: " << msgBody.attachCnt);
337     for (int a = 0; a < msgBody.attachCnt; ++a) {
338         MMS_ATTACH_S* attachment = msg_mms_get_attachment(a);
339         if (!attachment) {
340             LogError("attachment is null, continue");
341             continue;
342         }
343         IAttachmentPtr att = appendAttachment(attachment->szFilePath, false);
344         if (NULL != attachment->szFileName &&
345             strnlen(attachment->szFileName, MSG_FILENAME_LEN_MAX) > 0) {
346             LogDebug("renaming to " << attachment->szFileName);
347             att->rename(attachment->szFileName);
348         }
349     }
350
351 }
352
353
354 void Mms::update(bool draftsOnly)
355 {
356     LogDebug("updating m_id=" << getIdRef());
357
358     if (!m_messageData) {
359         //error if platform message not exists
360         LogError("message can not be updated");
361         Throw(WrtDeviceApis::Commons::PlatformException);
362     }
363
364     //update mms data from abstraction
365     if (!draftsOnly || getCurrentFolder() == Api::Messaging::DRAFTBOX) {
366         updateSubject();
367         updateBodyAndAttachments();
368         updateRecipientList();
369         updatePriority();
370     }
371     updateReadStatus();
372 }
373
374 void Mms::updatePriority()
375 {
376     if (isPriorityValid()) {
377         return;
378     }
379     int priority = -1;
380     LogInfo("MMS updating priority");
381
382     //set priority in platform
383     switch (getPriority()) {
384     case MessagePriority::LOW:
385         priority = MSG_MESSAGE_PRIORITY_LOW;
386         break;
387     case MessagePriority::NORMAL:
388         priority = MSG_MESSAGE_PRIORITY_NORMAL;
389         break;
390     case MessagePriority::HIGH:
391         priority = MSG_MESSAGE_PRIORITY_HIGH;
392         break;
393     default:
394         LogError("Wrong priority");
395         Throw(WrtDeviceApis::Commons::PlatformException);
396     }
397     if (MSG_SUCCESS !=
398         msg_set_priority_info(m_messageData, MSG_MESSAGE_PRIORITY_LOW)) {
399         LogError("Error during setting priority");
400         Throw(WrtDeviceApis::Commons::PlatformException);
401     }
402 }
403
404 void Mms::updateRecipientList()
405 {
406     // check if abstraction recipient value has been changed
407     if (getToRecipients().isValid() &&
408         getBccRecipients().isValid() &&
409         getCcRecipients().isValid()) {
410         return;
411     }
412
413     LogInfo("MMS updating platform recipients");
414
415     // reset addresses in platform structure
416     msg_reset_address(m_messageData);
417
418     vector<string> to = getToRecipients().getRecipients();
419     vector<string> cc = getCcRecipients().getRecipients();
420     vector<string> bcc = getBccRecipients().getRecipients();
421
422     // update addresses in platform structure
423     if (to.size()) {
424         LogInfo("updating to");
425         for (size_t i = 0; i < to.size(); i++) {
426             if (msg_get_address_count(m_messageData) >= MAX_TO_ADDRESS_CNT) {
427                 LogError("max number of recipient exceeded");
428                 break;
429             }
430             LogDebug("adding to[" << i << "]=" << to[i]);
431             if (msg_add_address(m_messageData, to[i].c_str(),
432                                 MSG_RECIPIENTS_TYPE_TO) != MSG_SUCCESS) {
433                 LogError("problem with adding to address");
434                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
435                          "Problem with adding to address");
436             }
437         }
438     }
439
440     if (cc.size()) {
441         LogInfo("updating cc");
442         for (size_t i = 0; i < cc.size(); i++) {
443             if (msg_get_address_count(m_messageData) >= MAX_TO_ADDRESS_CNT) {
444                 LogError("max number of recipient exceeded");
445                 break;
446             }
447             LogDebug("adding cc[" << i << "]=" << cc[i]);
448             if (msg_add_address(m_messageData, cc[i].c_str(),
449                                 MSG_RECIPIENTS_TYPE_CC) != MSG_SUCCESS) {
450                 LogError("problem with adding cc address");
451                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
452                          "Problem with adding cc address");
453             }
454         }
455     }
456
457     if (bcc.size()) {
458         LogInfo("updating bcc");
459         for (size_t i = 0; i < bcc.size(); i++) {
460             if (msg_get_address_count(m_messageData) >= MAX_TO_ADDRESS_CNT) {
461                 LogError("max number of recipient exceeded");
462                 break;
463             }
464             LogDebug("adding bcc[" << i << "]=" << bcc[i]);
465             if (msg_add_address(m_messageData, bcc[i].c_str(),
466                                 MSG_RECIPIENTS_TYPE_BCC) != MSG_SUCCESS) {
467                 LogError("problem with adding bcc address");
468                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
469                          "Problem with adding bcc address");
470             }
471         }
472     }
473
474     setToValidity(true);
475     setCcValidity(true);
476     setBccValidity(true);
477 }
478
479 void Mms::updateSubject()
480 {
481     // check if abstraction subject value has been changed
482     if (isSubjectValid()) {
483         return;
484     }
485     LogInfo("updating platform subject: " << getSubjectRef());
486     if (MSG_SUCCESS !=
487         msg_set_subject(m_messageData, getSubjectRef().c_str())) {
488         LogError("problem with setting subject");
489         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Problem with setting subject");
490     }
491     setSubjectValidity(true);
492 }
493
494 void Mms::updateBodyAndAttachments()
495 {
496
497     // check if attachment or body source address value has been changed
498     if (isAttachmentsValid() && isBodyValid()) {
499         return;
500     }
501
502     MMS_MESSAGE_DATA_S *mmsData = NULL;
503     LogInfo("updating platform body and attachment");
504
505     Try
506     {
507         if (getMessageType() != MMS) {
508             LogError("Wrong msg type");
509             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Wrong msg type");
510         }
511         mmsData = msg_mms_create_message();
512         if (!mmsData) {
513             LogError("create message body failed");
514             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "create message body failed");
515         }
516
517         //body
518         if (!getBodyRef().empty()) {
519             FILE* f = NULL;
520             f = fopen(m_bodyFilePath.c_str(), "w");
521             if (!f) {
522                 LogError("cannot create file with body" << m_bodyFilePath);
523                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
524                          "cannot create file with body");
525             }
526             LogDebug("body file: " << m_bodyFilePath);
527                  fwrite(getBodyRef().c_str(), strlen(getBodyRef().c_str()), 1, f);
528                  
529             fclose(f);
530             if (!msg_mms_set_rootlayout(mmsData, ROOT_LAYOUT_WIDTH,
531                                         ROOT_LAYOUT_HEIGHT, WHITE_COLOR)) {
532                 LogError("cannot create root layout");
533                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
534                          "cannot create root layout");
535             }
536             if (!msg_mms_add_region(mmsData, TEXT_AREA, 0, 0, ROOT_LAYOUT_WIDTH,
537                                     ROOT_LAYOUT_HEIGHT, WHITE_COLOR)) {
538                 LogError("cannot create region");
539                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "cannot create region");
540             }
541             MMS_PAGE_S* page = msg_mms_add_page(mmsData, 0);
542             if (!page) {
543                 LogError("cannot create page");
544                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "cannot create page");
545             }
546             MMS_MEDIA_S* media = msg_mms_add_media(page,
547                                                    MMS_SMIL_MEDIA_TEXT,
548                                                    TEXT_AREA,
549                                                    const_cast<char*>(
550                                                        m_bodyFilePath.c_str()));
551             if (!media) {
552                 LogError("cannot create media");
553                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "cannot create media");
554             }
555             media->sMedia.sText.nColor = BLACK_COLOR;
556             media->sMedia.sText.nSize = MMS_SMIL_FONT_SIZE_NORMAL;
557         }
558                 
559         //attachments
560         struct stat buffer;
561         int errnum = 0;
562         for (size_t i = 0; i < getAttachmentsRef().size(); ++i) {
563             Api::Messaging::IAttachmentPtr att = getAttachment(i);
564             if (!att) {
565                 continue;
566             }
567
568             LogDebug("Add attachment=" << att->getFullPath());
569             //checking file
570             errnum = stat(att->getFullPath().c_str(), &buffer);
571             if (errnum) {
572                 LogError("Opening file: " <<
573                          att->getFullPath().c_str() <<
574                          " " << strerror(errnum));
575                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
576                          "cannot open attachment file");
577             }
578
579             //this function should return valid pointer
580             if (!msg_mms_add_attachment(mmsData,
581                                         const_cast<char*>(att->getFullPath().
582                                                               c_str()))) {
583                 LogError("add attachment failed");
584                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "add attachment failed");
585             }
586             LogDebug("Attachment added");
587
588             //reset errno
589             errnum = 0;
590         }
591
592         if (MSG_SUCCESS != msg_mms_set_message_body(m_messageData, mmsData)) {
593                 LogError("set message body error");
594                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "set message body error");
595         }
596         
597         msg_mms_destroy_message(mmsData);
598
599         setAttachmentsValidity(true);
600         setBodyValidity(true);
601         
602     }
603     Catch(WrtDeviceApis::Commons::PlatformException) {
604         LogError("Platform error");
605         if (mmsData) {
606             msg_mms_destroy_message(mmsData);
607         }
608         throw;
609     }
610
611
612 }
613
614
615 void Mms::updateReadStatus()
616 {
617     if (isReadStatusValid()) {
618         return;
619     }
620
621     LogInfo("updating platform read status: " << isRead());
622     if (MSG_SUCCESS != msg_set_read_status(m_messageData, isRead())) {
623         LogError("problem with setting subject");
624         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Problem with setting subject");
625     }
626
627     setReadStatusValidity(true);
628 }
629
630 void Mms::updateIsRead()
631 {
632     LogDebug("updating m_id=" << getIdRef());
633
634     if (!m_messageData) {
635         //error if platform message not exists
636         LogError("message can not be updated");
637         Throw(WrtDeviceApis::Commons::PlatformException);
638     }
639         
640     // check if abstraction from m_isReadChange value has been changed
641     if (isReadChangeStatusValid()) {
642         // do not update if not changed
643         return;
644     }
645
646     Try
647     {
648         if (this->getIdRef().empty()) {
649             LogError("existing msgId is zero, remove msg not done");
650             ThrowMsg(WrtDeviceApis::Commons::PlatformException,
651                      "existing msgId is zero, remove msg not done");
652         }
653
654         if (MSG_SUCCESS !=
655             msg_update_read_status(MsgGetCommonHandle(), convertId(getIdRef()), isReadChangeStatus()))
656         {
657             LogError("Failed to update isRead");
658             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Failed to update isRead");
659         }
660     }
661     Catch(WrtDeviceApis::Commons::PlatformException) {
662         LogError("platform error occurs");
663     }
664     setisReadChangeStatusValidity(true);
665
666 }
667
668 void Mms::addMessageToDraft()
669 {
670     LogDebug("convert m_id= " << convertId(getIdRef()));        
671
672     //prepare for add sms to draft folder
673     if (!m_messageData) {
674         //error if platform message not exists
675         LogError("message can not be updated");
676         Throw(WrtDeviceApis::Commons::PlatformException);
677     }
678
679     //update all sms data
680     if (getCurrentFolder() == Api::Messaging::DRAFTBOX) {
681         updateSubject();
682         updateBodyAndAttachments();
683         updateRecipientList();
684         updatePriority();
685     }
686
687     Try
688     {
689         MSG_SENDINGOPT_S option = { false, false, false };
690         option.option.smsSendOpt.bReplyPath = true;
691         // trying to get message from platform
692
693         const MSG_FOLDER_ID_T platfromFolderId =
694         Messaging::convertFolderToPlatform(DRAFTBOX);
695
696         msg_set_message_id(m_messageData, 0);           
697         msg_set_folder_id(m_messageData, platfromFolderId);
698         msg_set_network_status(m_messageData, MSG_NETWORK_NOT_SEND);
699
700         // trying to add message
701         int ret = msg_add_message(MsgGetCommonHandle(), m_messageData, &option);
702         if (ret < MSG_SUCCESS) {
703             LogError("msg_add_message failed, error code=" << ret);
704             Throw(WrtDeviceApis::Commons::PlatformException);
705         }
706
707         //releasing platform message structure
708             msg_release_message(&m_messageData);
709     }
710     Catch(WrtDeviceApis::Commons::PlatformException) {
711         LogError("remove message error");
712         if (m_messageData) {
713             //releasing platform message structure
714             msg_release_message(&m_messageData);
715         }
716         throw;
717     }
718
719 }       
720
721 void Mms::readAllData()
722 {
723     readExistingMessage();
724 }
725
726 void Mms::moveToFolder(const FolderType newFolder)
727 {
728     update();
729
730     Try
731     {
732         MSG_FOLDER_ID_T platfromFolderId = Messaging::convertFolderToPlatform(
733                 newFolder);
734
735         if (msg_move_msg_to_folder(MsgGetCommonHandle(), convertId(getId()),
736                                    platfromFolderId) != MSG_SUCCESS) {
737             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Error during movinf message");
738         }
739     }
740
741     Catch(WrtDeviceApis::Commons::PlatformException) {
742         LogError("remove message error");
743         throw;
744     }
745 }
746
747 void Mms::moveToFolder(const string& newFolder)
748 {
749     update();
750
751     Try
752     {
753         MSG_FOLDER_ID_T platfromFolderId = Messaging::convertFolderToPlatform(
754                 newFolder);
755
756         if (msg_move_msg_to_folder(MsgGetCommonHandle(), convertId(getId()),
757                                    platfromFolderId) != MSG_SUCCESS) {
758             LogError("msg_move_msg_to_folder error");
759             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "msg_move_msg_to_folder error");
760         }
761     }
762
763     Catch(WrtDeviceApis::Commons::PlatformException) {
764         LogError("remove message error");
765         throw;
766     }
767 }
768
769 void Mms::copyToFolder(const FolderType newFolder)
770 {
771     update();
772
773     msg_message_t msg = msg_new_message();
774
775     Try
776     {
777         MSG_SENDINGOPT_S option = { false, false, false };
778         option.option.smsSendOpt.bReplyPath = true;
779         if (MSG_SUCCESS ==
780             msg_get_message(MsgGetCommonHandle(), convertId(getIdRef()), msg,
781                             &option)) {
782             const MSG_FOLDER_ID_T platfromFolderId =
783                 Messaging::convertFolderToPlatform(newFolder);
784             msg_set_message_id(msg, 0);
785             msg_set_folder_id(msg, platfromFolderId);
786
787             int error = msg_add_message(MsgGetCommonHandle(), msg, &option);
788             if (error != MSG_SUCCESS) {
789                 LogError("msg_add_message failed, error code=" << error);
790                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "msg_add_message failed");
791             }
792         }
793         if (msg) {
794             msg_release_message(&msg);
795         }
796     }
797
798     Catch(WrtDeviceApis::Commons::PlatformException) {
799         LogError("remove message error");
800         if (msg) {
801             msg_release_message(&msg);
802         }
803         throw;
804     }
805 }
806
807 void Mms::copyToFolder(const string& newFolder)
808 {
809     update();
810
811     msg_message_t msg = msg_new_message();
812
813     Try
814     {
815         MSG_SENDINGOPT_S option = { false, false, false };
816         option.option.smsSendOpt.bReplyPath = true;
817         if (MSG_SUCCESS ==
818             msg_get_message(MsgGetCommonHandle(), convertId(getIdRef()), msg,
819                             &option)) {
820             const MSG_FOLDER_ID_T platfromFolderId =
821                 Messaging::convertFolderToPlatform(newFolder);
822             msg_set_message_id(msg, 0);
823             msg_set_folder_id(msg, platfromFolderId);
824
825             int error = msg_add_message(MsgGetCommonHandle(), msg, &option);
826             if (error != MSG_SUCCESS) {
827                 LogError("msg_add_message failed, error code=" << error);
828                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "msg_add_message failed");
829             }
830         }
831         if (msg) {
832             msg_release_message(&msg);
833         }
834     }
835
836     Catch(WrtDeviceApis::Commons::PlatformException) {
837         LogError("remove message error");
838         if (msg) {
839             msg_release_message(&msg);
840         }
841         throw;
842     }
843 }
844
845 void Mms::remove()
846 {
847     LogDebug("delete m_id=" << getIdRef());
848
849     Try
850     {
851         if (this->getIdRef().empty()) {
852             LogError("existing msgId is zero, remove msg not done");
853             ThrowMsg(WrtDeviceApis::Commons::PlatformException,
854                      "existing msgId is zero, remove msg not done");
855         }
856
857         if (MSG_SUCCESS !=
858             msg_delete_message(MsgGetCommonHandle(),
859                                convertId(getIdRef()))) {
860             LogError("Failed to delete Message");
861             ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Failed to delete Message");
862         }
863     }
864
865     Catch(WrtDeviceApis::Commons::PlatformException) {
866         LogError("platform error occurs");
867     }
868 }
869
870 int Mms::send()
871 {
872     LogDebug("sending message, id=" << getIdRef());
873     Try
874     {
875         //prepare for sending sms/mms
876         update();
877
878         LogDebug("Start Sending Message...");
879         LogDebug("msgId=" << msg_get_message_id(m_messageData));
880         LogDebug("subject: " << msg_get_subject(m_messageData));
881         LogDebug("recipient count: " << msg_get_address_count(m_messageData));
882            LogDebug("body size : " <<  msg_get_message_body_size( m_messageData ));
883                 
884         for (int i = 0; i < msg_get_address_count(m_messageData); ++i) {
885             LogDebug("recipient[" << i << "]: " <<
886                      msg_get_ith_address(m_messageData, i));
887         }
888         
889         LogDebug("trying to send mms");
890         MSG_ERROR_T err = CallbackMgrSingleton::Instance().registerAndSend(
891                 msg_mms_send_message,
892                 m_messageData,
893                 this);
894           
895         if (err != MSG_SUCCESS) {
896             LogError("Sending Message (submit request) failed!!! err=" << err);
897                  setMessageStatus(MESSAGE_STATUS_FAILED);
898             goto ERROR;
899         }
900
901         setMessageStatus(MESSAGE_STATUS_SENDING);
902
903         LogDebug("Sending Message request is submitted!");
904     }
905     Catch(WrtDeviceApis::Commons::PlatformException) {
906         LogError("message is not send, manually run callback");
907            goto ERROR;
908     }
909
910     return 0;
911 ERROR:
912          ReqReceiverMessage *requestReceiver = getRequestReceiver();
913         if (requestReceiver) {
914             LogError("send Error");
915             EventSendMessagePtr event = getSendMessageEvent();
916             event->setExceptionCode(WrtDeviceApis::Commons::ExceptionCodes::UnknownException);
917                  requestReceiver->WrtDeviceApis::Commons::EventRequestReceiver< EventSendMessage >::ManualAnswer(event);
918         }
919
920 }
921
922 void Mms::sendingCallback(MSG_SENT_STATUS_S *sent_status)
923 {
924     LogInfo(
925         "sendingCallback callback received. Req id = " <<
926         sent_status->reqId << " Status = " << (int)sent_status->status);
927     if (MSG_NETWORK_SEND_SUCCESS == sent_status->status) {
928         LogDebug("sending ok");
929         setSendingStatusOk();
930         setMessageStatus(MESSAGE_STATUS_SENT);
931     } else {
932         LogError("sending failed: " <<
933                  static_cast<unsigned int>(sent_status->status));
934         setSendingStatusFailed();
935            setMessageStatus(MESSAGE_STATUS_FAILED);
936     }
937 }
938
939 void Mms::sendCancel(int handle)
940 {
941     LogDebug("sending message, id=" << getIdRef());
942     //#warning "TODO"
943     LogDebug("handle =" << handle);
944 }
945
946 void Mms::setSendingStatusOk()
947 {
948     //success callback should be executed here
949     ReqReceiverMessage *requestReceiver = getRequestReceiver();
950     if (requestReceiver) {
951         LogInfo("calling JS success callback");
952         EventSendMessagePtr event = getSendMessageEvent();
953         event->setExceptionCode(WrtDeviceApis::Commons::ExceptionCodes::None);
954
955           for ( int index=0; index < msg_get_address_count(m_messageData); index++)
956           {
957                 LogDebug( "Address :" << msg_get_ith_address(m_messageData, index));
958                 event->m_successRecipients.push_back(msg_get_ith_address(m_messageData, index));
959           }
960           
961         requestReceiver->WrtDeviceApis::Commons::EventRequestReceiver< EventSendMessage >::ManualAnswer(event);
962         
963     }
964 }
965
966 void Mms::setSendingStatusFailed()
967 {       
968     //error callback should be executed here
969     EventOnSendingFailedEmitterPtr emitter = getEmitter();
970     if (emitter) {
971         EventOnSendingFailedPtr event(new EventOnSendingFailed);
972         event->setError(EventOnSendingFailed::UNKNOWN); // TODO error codes
973         emitter->emit(event);
974     } else {
975         ReqReceiverMessage *requestReceiver = getRequestReceiver();
976         if (requestReceiver) {
977             LogError("calling JS error callback");
978             EventSendMessagePtr event = getSendMessageEvent();
979             event->setExceptionCode(WrtDeviceApis::Commons::ExceptionCodes::UnknownException);
980                 
981                  for ( int index=0; index < msg_get_address_count(m_messageData); index++)
982                  {
983                    LogDebug( "Address :" << msg_get_ith_address(m_messageData, index));
984                    event->m_failRecipients.push_back(msg_get_ith_address(m_messageData, index));
985                  }
986
987         }
988     }
989 }
990
991 Api::Messaging::FolderType Mms::toFolder(const std::string &folder)
992 {
993     if (folder == "INBOX") {
994         return INBOX;
995     } else if (folder == "OUTBOX") {
996         return OUTBOX;
997     } else if (folder == "SENTBOX") {
998         return SENTBOX;
999     } else if (folder == "DRAFTBOX") {
1000         return DRAFTBOX;
1001     }
1002     ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Invalid folder");
1003 }
1004 }
1005 }
1006 }