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