tizen beta release
[platform/framework/web/wrt-plugins-common.git] / src / modules / tizen / Messaging / Messaging.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       Messaging.cpp
20  * @author     Pawel Misiak (p.misiak@samsung.com)
21  * @version    0.1
22  * @brief
23  */
24 #include <emf-types.h>
25 #include <Emf_Mapi.h>
26
27 #include <Commons/Exception.h>
28 #include <Commons/StringUtils.h>
29 #include <dpl/log/log.h>
30 #include <dpl/scoped_free.h>
31 #include "Messaging.h"
32 #include "Sms.h"
33 #include "Mms.h"
34 #include "BinarySms.h"
35 #include "Email.h"
36 #include "EmailConverter.h"
37 #include "EmailService.h"
38 #include "NetworkStatus.h"
39
40 extern "C" {
41 #include <MapiStorage.h>
42 #include <MapiControl.h>
43 #include <MsgMmsTypes.h>
44 #include <MapiTransport.h>
45 #include <MapiMessage.h>
46 }
47
48 #include <Commons/ThreadPool.h>
49
50 #define LOG_ENTER LogDebug("---> ENTER");
51 #define LOG_EXIT LogDebug("---> EXIT");
52
53 using namespace WrtDeviceApis::Messaging;
54 using namespace WrtDeviceApis::Messaging::Api;
55 using namespace std;
56
57 namespace {
58 const int MESSAGE_FIND_LIMIT = 100;
59 }
60
61 namespace WrtDeviceApis {
62 namespace Messaging {
63
64 int Messaging::m_currentEmailAccountId = 0;
65 DPL::Atomic Messaging::m_objCounter;
66
67 Messaging& Messaging::getInstance()
68 {
69     static Messaging instance;
70     return instance;
71 }
72
73 Messaging::Messaging() :
74     m_onMessageReceivedHandleMgr(NULL),
75     m_mailNotifier(new MailNotifier())
76 {
77     Try
78     {
79         const vector<Api::EmailAccountInfo> accounts = getEmailAccounts();
80         LogDebug("Number of emails account=" << accounts.size());
81         if (accounts.size() > 0) {
82             // set default email account - first from the list
83             setCurrentEmailAccount(accounts[0]);
84         } else {
85             LogError("no default email account set");
86         }
87     }
88
89     Catch(Commons::PlatformException) {
90         LogError("No email accounts available");
91     }
92
93     Catch(Commons::InvalidArgumentException) {
94         LogError("No email accounts available");
95         //current email not configured, skipped
96     }
97
98     Catch(Commons::UnknownException) {
99         LogError("unknown error");
100     }
101
102     // Begin service for email management ?? pmi question if it should be added before email actions
103     if (0 == m_objCounter) {
104         int error = email_service_begin();
105         if (EMF_ERROR_NONE != error) {
106             LogError("email_service_begin() returned error " << error);
107         } else {
108             LogInfo("email_service_begin() executed without error");
109         }
110     }
111     ++m_objCounter;
112
113     m_mailNotifier->AddListener(this);
114 }
115
116 Messaging::~Messaging()
117 {
118     m_mailNotifier->RemoveListener(this);
119
120     if (!--m_objCounter) {
121         int error = email_service_end();
122         if (EMF_ERROR_NONE != error) {
123             LogError("email_service_end() returned error " << error);
124         } else {
125             LogDebug("email_service_end() executed without error");
126         }
127     }
128 }
129
130 void Messaging::getNumberOfMessages(MessageType msgType,
131         FolderType folder,
132         int* readed,
133         int* unReaded)
134 {
135     if (NULL == readed ||
136         NULL == unReaded) {
137         LogError("output pointers are NULL");
138         Throw(Commons::InvalidArgumentException);
139     }
140     *readed = 0;
141     *unReaded = 0;
142     if (Api::SMS == msgType) {
143         getNumberOfSms(folder, readed, unReaded);
144     } else if (Api::MMS == msgType) {
145         getNumberOfMms(folder, readed, unReaded);
146     } else if (Api::EMAIL == msgType) {
147         getNumberOfEmails(folder, readed, unReaded);
148     } else {
149         LogError("wrong message type");
150         Throw(Commons::PlatformException);
151     }
152 }
153
154 vector<IMessagePtr> Messaging::findMessages(const vector<MessageType>& msgTypes,
155         const string &folder,
156         const MessageFilterPtr& filter)
157 {
158     LogDebug("enter");
159     vector<IMessagePtr> retVal;
160     back_insert_iterator< vector<IMessagePtr> > biit(retVal);
161     vector<MessageType>::const_iterator it = msgTypes.begin();
162     for (; it != msgTypes.end(); ++it) {
163         LogDebug("Finding messages (" << *it << ")  in folder: " << folder);
164         vector<IMessagePtr> result;
165
166         switch (*it) {
167         case SMS:
168         {
169             FolderType folderEnum = Sms::toFolder(folder);
170             result = findSms(folderEnum, filter);
171             break;
172         }
173         case MMS:
174         {
175             FolderType folderEnum = Mms::toFolder(folder);
176             result = findMms(folderEnum, filter);
177             break;
178         }
179         case EMAIL:
180         {
181             result = findEmail(folder, filter);
182             break;
183         }
184         default:
185             LogError("message type unknown");
186             Throw(Commons::PlatformException);
187         }
188         LogDebug("Found: " << result.size());
189         copy(result.begin(), result.end(), biit);
190     }
191
192     return retVal;
193 }
194
195 vector<IMessagePtr> Messaging::findMessages(const vector<MessageType>& msgTypes,
196         FolderType folder,
197         const Api::MessageFilterPtr& filter)
198 {
199     LogDebug("enter");
200     vector<IMessagePtr> retVal;
201     back_insert_iterator< vector<IMessagePtr> > biit(retVal);
202     vector<MessageType>::const_iterator it = msgTypes.begin();
203     for (; it != msgTypes.end(); ++it) {
204         LogDebug("Finding messages (" << *it << ")  in folder: " << folder);
205         vector<IMessagePtr>(Messaging::*findFnPtr)(Api::FolderType folder,
206                                                    const Api::MessageFilterPtr
207                                                    & filter) = NULL;
208
209         switch (*it) {
210         case SMS:
211         {
212             findFnPtr = &Messaging::findSms;
213             break;
214         }
215         case MMS:
216         {
217             findFnPtr = &Messaging::findMms;
218             break;
219         }
220         case EMAIL:
221         {
222             findFnPtr = &Messaging::findEmail;
223             break;
224         }
225         default:
226             LogError("message type unknown");
227             Throw(Commons::PlatformException);
228         }
229         vector<IMessagePtr> result = (this->*findFnPtr)(folder, filter);
230         LogDebug("Found: " << result.size());
231         copy(result.begin(), result.end(), biit);
232     }
233
234     return retVal;
235 }
236
237 vector<string> Messaging::getMessageIds(MessageType msgType,
238         FolderType folder)
239 {
240     switch (msgType) {
241     case SMS:
242         return getSmsIds(folder);
243     case MMS:
244         return getMmsIds(folder);
245     case EMAIL:
246         return getEmailIds(folder);
247     default:
248         LogError("not supported message type");
249         Throw(Commons::InvalidArgumentException);
250     }
251 }
252
253 vector<string> Messaging::getSmsIds(FolderType folder)
254 {
255     vector<string> retVal;
256     msg_message_t msg = msg_new_message();
257     MSG_LIST_S folder_list_view = { 0, NULL };
258
259     Try
260     {
261         const MSG_SORT_RULE_S sort_rules = { MSG_SORT_BY_DISPLAY_TIME, true };
262         MSG_ERROR_T res = MSG_ERR_UNKNOWN;
263         const MSG_FOLDER_ID_T platformFolder = convertFolderToPlatform(folder);
264         res = msg_get_folder_view_list(
265                 MsgGetCommonHandle(), platformFolder, &sort_rules,
266                 &folder_list_view);
267
268         if (MSG_SUCCESS != res) {
269             LogError("msg_Get_folder_view_list failed" << res);
270             Throw(Commons::PlatformException);
271         }
272
273         for (int i = 0; i < folder_list_view.nCount; i++) {
274             if (MSG_TYPE_SMS ==
275                 msg_get_message_type(folder_list_view.msgInfo[i])) {
276                 int l_msgId = msg_get_message_id(folder_list_view.msgInfo[i]);
277                 ostringstream stream;
278                 stream << l_msgId;
279                 retVal.push_back(stream.str());
280             }
281         }
282
283         msg_release_message_list(&folder_list_view);
284     }
285
286     Catch(Commons::PlatformException) {
287         LogError("Problem with message creation, cleaning");
288         if (folder_list_view.nCount) {
289             msg_release_message_list(&folder_list_view);
290         }
291         if (msg) {
292             msg_release_message(&msg);
293         }
294         throw;
295     }
296
297     return retVal;
298 }
299
300 vector<string> Messaging::getMmsIds(FolderType folder)
301 {
302     vector<string> retVal;
303     msg_message_t msg = msg_new_message();
304     MSG_LIST_S folder_list_view = { 0, NULL };
305
306     Try
307     {
308         const MSG_SORT_RULE_S sort_rules = { MSG_SORT_BY_DISPLAY_TIME, true };
309         MSG_ERROR_T res = MSG_ERR_UNKNOWN;
310         const MSG_FOLDER_ID_T platformFolder = convertFolderToPlatform(folder);
311         res = msg_get_folder_view_list(
312                 MsgGetCommonHandle(), platformFolder, &sort_rules,
313                 &folder_list_view);
314
315         if (MSG_SUCCESS != res) {
316             LogError("msg_Get_folder_view_list failed" << res);
317             Throw(Commons::PlatformException);
318         }
319
320         for (int i = 0; i < folder_list_view.nCount; i++) {
321             if (MSG_TYPE_MMS ==
322                 msg_get_message_type(folder_list_view.msgInfo[i])) {
323                 int l_msgId = msg_get_message_id(folder_list_view.msgInfo[i]);
324                 ostringstream stream;
325                 stream << l_msgId;
326                 retVal.push_back(stream.str());
327             }
328         }
329
330         msg_release_message_list(&folder_list_view);
331     }
332
333     Catch(Commons::PlatformException) {
334         LogError("Problem with message creation, cleaning");
335         if (folder_list_view.nCount) {
336             msg_release_message_list(&folder_list_view);
337         }
338         if (msg) {
339             msg_release_message(&msg);
340         }
341         throw;
342     }
343
344     return retVal;
345 }
346
347 vector<string> Messaging::getEmailIds(FolderType /*folder*/)
348 {
349     vector<string> retVal;
350
351     //TODO
352     LogError("TODO");
353     Throw(Commons::UnknownException);
354
355     return retVal;
356 }
357
358 vector<EmailAccountInfo> Messaging::getEmailAccounts() const
359 {
360     emf_account_t* accounts = NULL;
361     int count = 0;
362     Try {
363         if (!email_get_account_list(&accounts, &count)) {
364             ThrowMsg(Commons::PlatformException,
365                      "Couldn't get e-mail accounts.");
366         }
367
368         if (0 == count) {
369             ThrowMsg(Commons::PlatformException, "No e-mail account found.");
370         }
371
372         vector<Api::EmailAccountInfo> result;
373         for (int i = 0; i < count; ++i) {
374             Api::EmailAccountInfo account(accounts[i].account_id,
375                                           accounts[i].user_name,
376                                           accounts[i].email_addr);
377             result.push_back(account);
378         }
379
380         if (accounts != NULL) {
381             email_free_account(&accounts, count);
382         }
383
384         return result;
385     }
386     Catch(Commons::PlatformException) {
387         if (accounts != NULL) {
388             email_free_account(&accounts, count);
389         }
390         throw;
391     }
392 }
393
394 int Messaging::getEmailAccountId(const std::string& account)
395 {
396     int retVal = 0;
397     string tmpAccount = account;
398     emf_account_t *pAccountArray = NULL;
399     int iCount = 0;
400
401     Try
402     {
403         if (account.empty()) {
404             tmpAccount = getCurrentEmailAccount().getAddress();
405             if (tmpAccount.empty()) {
406                 LogError(
407                     "current email account is not set, possible that no account created");
408                 Throw(Commons::PlatformException);
409             }
410         }
411
412         if (!email_get_account_list(&pAccountArray, &iCount)) {
413             LogError("email_get_account_list error");
414             Throw(Commons::PlatformException);
415         }
416
417         if (0 == iCount) {
418             LogError("no email account exist");
419             Throw(Commons::PlatformException);
420         }
421
422         for (int i = 0; i < iCount; i++) {
423             string tmp = pAccountArray[i].email_addr;
424             if (tmp == tmpAccount) {
425                 m_currentEmailAccountId = pAccountArray[i].account_id;
426                 retVal = m_currentEmailAccountId;
427                 break;
428             }
429         }
430
431         if (0 == m_currentEmailAccountId) {
432             LogError("wrong email account ID");
433             Throw(Commons::PlatformException);
434         }
435
436         if (pAccountArray != NULL) {
437             LogDebug("free account, ptr=" << pAccountArray);
438             email_free_account(&pAccountArray, iCount);
439         }
440
441         if (0 == retVal) {
442             LogError("no email account created");
443             Throw(Commons::PlatformException);
444         }
445     }
446
447     Catch(Commons::PlatformException) {
448         LogError("exception catch, platform exception");
449         if (pAccountArray != NULL) {
450             email_free_account(&pAccountArray, iCount);
451         }
452         throw;
453     }
454
455     return retVal;
456 }
457
458 void Messaging::fetchEmailHeaders()
459 {
460     emf_mailbox_t *mailbox = NULL;
461     unsigned handle = 0;
462     mailbox = static_cast<emf_mailbox_t*>(calloc(sizeof (emf_mailbox_t), 1));
463     if (!mailbox) {
464         LogError("calloc failed");
465         return;
466     }
467     mailbox->account_id = m_currentEmailAccountId;
468     mailbox->name = strdup(EMF_INBOX_NAME);
469     if (EMF_ERROR_NONE != email_sync_header(mailbox, &handle)) {
470         LogError("email_sync_header failed");
471     }
472     email_free_mailbox(&mailbox, 1);
473 }
474
475 int Messaging::convertFolderToPlatform(const FolderType folder)
476 {
477     MSG_FOLDER_ID_T platfromFolderId;
478     switch (folder) {
479     case INBOX:
480         platfromFolderId = MSG_INBOX_ID;
481         break;
482     case DRAFTBOX:
483         platfromFolderId = MSG_DRAFT_ID;
484         break;
485     case OUTBOX:
486         platfromFolderId = MSG_OUTBOX_ID;
487         break;
488     case SENTBOX:
489         platfromFolderId = MSG_SENTBOX_ID;
490         break;
491     case SPAMBOX:
492     
493     default:
494         LogError("Invalid folder: " << folder);
495         Throw(Commons::PlatformException);
496     }
497
498     return platfromFolderId;
499 }
500
501 int Messaging::convertFolderToPlatform(const std::string &folder)
502 {
503     MSG_FOLDER_LIST_S folderList = { 0, NULL };
504     int result = 0;
505     Try
506     {
507         if (MSG_SUCCESS !=
508             msg_get_folder_list(MsgGetCommonHandle(), &folderList)) {
509             LogError("msg_get_folder_list error");
510             Throw(Commons::PlatformException);
511         }
512         for (int i = 0; i < folderList.nCount; ++i) {
513             if (MSG_FOLDER_TYPE_USER_DEF ==
514                 folderList.folderInfo[i].folderType &&
515                 NULL != folderList.folderInfo[i].folderName &&
516                 folder == folderList.folderInfo[i].folderName) {
517                 result = folderList.folderInfo[i].folderId;
518                 break;
519             }
520         }
521     }
522     Catch(Commons::PlatformException) {
523         if (folderList.nCount) {
524             msg_release_folder_list(&folderList);
525         }
526         throw;
527     }
528     if (folderList.nCount) {
529         msg_release_folder_list(&folderList);
530     }
531     return result;
532 }
533
534 void Messaging::addOnMessageReceived(
535         const Api::EmitterMessageReceivedPtr& emitter)
536 {
537     LogDebug("ENTER");
538     m_onMessageReceived.attach(emitter);
539     EmittersMessageReceived::LockType lock = m_onMessageReceived.getLock();
540     if (m_onMessageReceived.size() == 1) {
541         m_onMessageReceivedHandleMgr = MsgServiceHandleMgrPtr(
542                 new MsgServiceHandleMgr());
543         int err;
544
545         err = msg_reg_sms_message_callback(
546                 m_onMessageReceivedHandleMgr->getHandle(),
547                 onSmsReceived,
548                 0,
549                 this);
550         if (err != MSG_SUCCESS) {
551             LogError("Couldn't register on SMS received callback, err=" << err);
552         }
553         err = msg_reg_mms_conf_message_callback(
554                 m_onMessageReceivedHandleMgr->getHandle(),
555                 onMmsReceived,
556                 NULL,
557                 this);
558         if (err != MSG_SUCCESS) {
559             LogError("Couldn't register on MMS received callback, err=" << err);
560         }
561     }
562 }
563
564 void Messaging::removeOnMessageReceived(Api::EmitterMessageReceived::IdType id)
565 {
566     LogDebug("ENTER");
567     m_onMessageReceived.detach(id);
568     EmittersMessageReceived::LockType lock = m_onMessageReceived.getLock();
569     if (m_onMessageReceived.size() == 0) {
570         m_onMessageReceivedHandleMgr = MsgServiceHandleMgrPtr(NULL);
571     }
572 }
573
574 void Messaging::OnEventReceived(const EmailReceivedEvent& event)
575 {
576     LogDebug("Received email: " << event.GetArg0());
577     EventMessageReceivedPtr jsEvent(new EventMessageReceived());
578     IMessagePtr msg = MessageFactory::createMessage(EMAIL, event.GetArg0());
579
580     IEmailPtr email = MessageFactory::convertToEmail(msg);
581     jsEvent->setMessage(msg);
582     m_onMessageReceived.emitIf(jsEvent,
583                                MessageFilterMatcher<Api::IEmailPtr>(email));
584 }
585
586 void Messaging::onSmsReceived(MSG_HANDLE_T /*handle*/,
587                               msg_message_t msg,
588                               void* data)
589 {
590     LogDebug("ENTER");
591     Messaging* this_ = static_cast<Messaging*>(data);
592     if (this_) {
593         Try {
594             IMessagePtr message = MessageFactory::createMessage(
595                     SMS,
596                     msg_get_message_id(
597                         msg));
598             ISmsPtr sms = MessageFactory::convertToSms(message);
599             EventMessageReceivedPtr event(new EventMessageReceived());
600             event->setMessage(message);
601             this_->m_onMessageReceived.emitIf(event,
602                                               MessageFilterMatcher<Api::ISmsPtr>(
603                                                   sms));
604         }
605         Catch(Commons::ConversionException) {
606             LogError("Couldn't convert message to sms.");
607         }
608     }
609 }
610
611 void Messaging::onMmsReceived(MSG_HANDLE_T /*handle*/,
612                               msg_message_t msg,
613                               void* data)
614 {
615     LogDebug("ENTER");
616     Messaging* this_ = static_cast<Messaging*>(data);
617     if (this_) {
618         Try {
619             IMessagePtr message = MessageFactory::createMessage(
620                     MMS,
621                     msg_get_message_id(
622                         msg));
623             IMmsPtr mms = MessageFactory::convertToMms(message);
624             EventMessageReceivedPtr event(new EventMessageReceived());
625             event->setMessage(message);
626             this_->m_onMessageReceived.emitIf(event,
627                                               MessageFilterMatcher<Api::IMmsPtr>(
628                                                   mms));
629         }
630         Catch(Commons::ConversionException) {
631             LogError("Couldn't convert message to mms.");
632         }
633     }
634 }
635
636 void Messaging::getNumberOfEmails(Api::FolderType folder,
637         int* read,
638         int* unread)
639 {
640     LOG_ENTER
641
642     emf_mailbox_t mailbox;
643     memset(&mailbox, 0, sizeof(emf_mailbox_t));
644     mailbox.account_id = 0; // means for all accounts
645     mailbox.name = Commons::String::strdup(
646             EmailConverter::toMailboxName(folder)
647             );
648
649     int error = email_count_message(&mailbox, read, unread);
650     free(mailbox.name);
651
652     if (EMF_ERROR_NONE != error) {
653         ThrowMsg(Commons::PlatformException,
654                  "Couldn't get number of emails. [" << error << "]");
655     }
656
657     LOG_EXIT
658 }
659
660 void Messaging::getNumberOfSms(Api::FolderType folder,
661         int* read,
662         int* unread)
663 {
664     getNumberOfSmsMms(folder, read, unread, SMS);
665 }
666
667 void Messaging::getNumberOfMms(Api::FolderType folder,
668         int* read,
669         int* unread)
670 {
671     getNumberOfSmsMms(folder, read, unread, MMS);
672 }
673
674 void Messaging::getNumberOfSmsMms(Api::FolderType folder,
675         int* read,
676         int* unread,
677         Api::MessageType msgType)
678 {
679     MSG_LIST_S folderListView = { 0, NULL };
680
681     *read = 0;
682     *unread = 0;
683
684     Try
685     {
686         MSG_MESSAGE_TYPE_T msgTypePlatform;
687         if (SMS == msgType) {
688             msgTypePlatform = MSG_TYPE_SMS;
689         } else if (MMS == msgType) {
690             msgTypePlatform = MSG_TYPE_MMS;
691         } else {
692             LogError("no supported message type in this method");
693             Throw(Commons::PlatformException);
694         }
695
696         MSG_FOLDER_ID_T msgFolderId;
697         switch (folder) {
698         case INBOX:
699             msgFolderId = MSG_INBOX_ID;
700             break;
701         case OUTBOX:
702             msgFolderId = MSG_OUTBOX_ID;
703             break;
704         case SPAMBOX:
705             msgFolderId = MSG_SPAMBOX_ID;
706             break;
707         case SENTBOX:
708             msgFolderId = MSG_SENTBOX_ID;
709             break;
710         case DRAFTBOX:
711             msgFolderId = MSG_DRAFT_ID;
712             break;
713         default:
714             LogError("wrong folder type");
715             Throw(Commons::PlatformException);
716             break;
717         }
718
719         const MSG_SORT_RULE_S sort_rules = { MSG_SORT_BY_DISPLAY_TIME, true };
720         if (msg_get_folder_view_list(MsgGetCommonHandle(), msgFolderId,
721                                      &sort_rules,
722                                      &folderListView) != MSG_SUCCESS) {
723             LogDebug("msg_get_folder_view_list empty or failed, msgFolderId=" <<
724                 (int) msgFolderId);
725             Throw(Commons::PlatformException);
726         }
727         // go thtough all message to check type of message
728         LogDebug("msgCount=" << (int) folderListView.nCount);
729         for (int msg_cnt = 0; msg_cnt < folderListView.nCount; msg_cnt++) {
730             LogDebug("msgMainType=" <<
731                      msg_get_message_type(folderListView.msgInfo[msg_cnt]) <<
732                      ", searching for = " << (int) msgTypePlatform);
733             if (msgTypePlatform == msg_get_message_type(
734                     folderListView.msgInfo[msg_cnt])) {
735                 if (msg_is_read(folderListView.msgInfo[msg_cnt])) {
736                     (*read)++;
737                 } else {
738                     (*unread)++;
739                 }
740             }
741         }
742         msg_release_message_list(&folderListView);
743
744         LogDebug("readed=" << *read << ", unReaded=" << *unread);
745     }
746
747     Catch(Commons::PlatformException) {
748         if (folderListView.nCount) {
749             msg_release_message_list(&folderListView);
750         }
751         throw;
752     }
753 }
754
755 vector<Api::IMessagePtr> Messaging::findSms(Api::FolderType folder,
756         const Api::MessageFilterPtr& filter)
757 {
758     vector<Api::IMessagePtr> retVal;
759     msg_message_t msg = msg_new_message();
760     MSG_LIST_S folder_list_view = { 0, NULL };
761
762     Try
763     {
764         const MSG_SORT_RULE_S sort_rules = { MSG_SORT_BY_DISPLAY_TIME, true };
765         MSG_ERROR_T res = MSG_ERR_UNKNOWN;
766         const MSG_FOLDER_ID_T platformFolder = convertFolderToPlatform(folder);
767         res = msg_get_folder_view_list(
768                 MsgGetCommonHandle(), platformFolder, &sort_rules,
769                 &folder_list_view);
770
771         if (MSG_SUCCESS != res) {
772             LogError("msg_get_folder_view_list failed " << res);
773             Throw(Commons::PlatformException);
774         }
775
776         for (int i = 0; i < folder_list_view.nCount; i++) {
777             if (MSG_TYPE_SMS ==
778                 msg_get_message_type(folder_list_view.msgInfo[i])) {
779                 int l_msgId = msg_get_message_id(folder_list_view.msgInfo[i]);
780                 Api::IMessagePtr msg = MessageFactory::createMessage(SMS,
781                                                                      l_msgId);
782                 // invalid or null filter = empty filter
783                 if (!filter || !filter->isValid() ||
784                     filter->compare(MessageFactory::convertToSms(msg))) {
785                     retVal.push_back(msg);
786                 }
787             }
788         }
789
790         msg_release_message_list(&folder_list_view);
791     }
792
793     Catch(Commons::PlatformException) {
794         LogError("Problem with message creation, cleaning");
795         if (folder_list_view.nCount) {
796             msg_release_message_list(&folder_list_view);
797         }
798         if (msg) {
799             msg_release_message(&msg);
800         }
801         throw;
802     }
803
804     return retVal;
805 }
806
807 vector<Api::IMessagePtr> Messaging::findMms(Api::FolderType folder,
808         const Api::MessageFilterPtr& filter)
809 {
810     vector<Api::IMessagePtr> retVal;
811     msg_message_t msg = msg_new_message();
812     MSG_LIST_S folder_list_view = { 0, NULL };
813
814     Try
815     {
816         const MSG_SORT_RULE_S sort_rules = { MSG_SORT_BY_DISPLAY_TIME, true };
817         MSG_ERROR_T res = MSG_ERR_UNKNOWN;
818         const MSG_FOLDER_ID_T platformFolder = convertFolderToPlatform(folder);
819         res = msg_get_folder_view_list(
820                 MsgGetCommonHandle(), platformFolder, &sort_rules,
821                 &folder_list_view);
822
823         if (MSG_SUCCESS != res) {
824             LogError("msg_Get_folder_view_list failed" << res);
825             Throw(Commons::PlatformException);
826         }
827
828         for (int i = 0; i < folder_list_view.nCount; i++) {
829             if (MSG_TYPE_MMS ==
830                 msg_get_message_type(folder_list_view.msgInfo[i])) {
831                 int l_msgId = msg_get_message_id(folder_list_view.msgInfo[i]);
832                 Api::IMessagePtr msg =
833                     MessageFactory::createMessage(MMS, l_msgId);
834                 // invalid or null filter = empty filter
835                 if (!filter || !filter->isValid() ||
836                     filter->compare(MessageFactory::convertToMms(msg))) {
837                     retVal.push_back(msg);
838                 }
839             }
840         }
841
842         msg_release_message_list(&folder_list_view);
843     }
844
845     Catch(Commons::PlatformException) {
846         LogError("Problem with message creation, cleaning");
847         if (folder_list_view.nCount) {
848             msg_release_message_list(&folder_list_view);
849         }
850         if (msg) {
851             msg_release_message(&msg);
852         }
853         throw;
854     }
855
856     return retVal;
857 }
858
859 void Messaging::createFolder(MessageType msgType,
860         const string& userFolder)
861 {
862     switch (msgType) {
863     case Api::SMS:
864     case Api::MMS:
865         createMsgServiceFolder(userFolder);
866         break;
867     case Api::EMAIL:
868         createEmailFolder(userFolder);
869         break;
870     default:
871         LogError("msg not supported");
872         Throw(Commons::UnknownException);
873     }
874 }
875
876 void Messaging::createMsgServiceFolder(const std::string& userFolder)
877 {
878     if (userFolder.length() > MAX_FOLDER_NAME_SIZE) {
879         LogError("folder name to long");
880         Throw(Commons::PlatformException);
881     }
882
883     MSG_FOLDER_INFO_S folderInfo;
884
885     folderInfo.folderId = 0;
886     strncpy(folderInfo.folderName, userFolder.c_str(), userFolder.length());
887
888     folderInfo.folderType = MSG_FOLDER_TYPE_USER_DEF;
889
890     if (msg_add_folder(MsgGetCommonHandle(), &folderInfo) != MSG_SUCCESS) {
891         LogError("msg_add_folder failed");
892         Throw(Commons::PlatformException);
893     }
894 }
895
896 void Messaging::createEmailFolder(const std::string& /*userFolder*/)
897 {
898     //TODO
899     LogError("TODO");
900     Throw(Commons::UnknownException);
901 }
902
903 void Messaging::deleteFolder(MessageType msgType,
904                              const string& userFolder)
905 {
906     switch (msgType) {
907     case Api::SMS:
908     case Api::MMS:
909         deleteMsgServiceFolder(userFolder);
910         break;
911     case Api::EMAIL:
912         deleteEmailFolder(userFolder);
913         break;
914     default:
915         LogError("msg not supported");
916         Throw(Commons::UnknownException);
917     }
918 }
919
920 void Messaging::deleteMsgServiceFolder(const string& userFolder)
921 {
922     Try
923     {
924         int platformFolderId = convertFolderToPlatform(userFolder);
925         if (MSG_SUCCESS !=
926             msg_delete_folder(MsgGetCommonHandle(), platformFolderId)) {
927             LogError("msg_get_folder_list failed");
928             Throw(Commons::PlatformException);
929         }
930     }
931     Catch(Commons::PlatformException) {
932         throw;
933     }
934 }
935
936 void Messaging::deleteEmailFolder(const string& /*userFolder*/)
937 {
938     //TODO
939     LogError("TODO");
940     Throw(Commons::UnknownException);
941 }
942
943 vector<string> Messaging::getFolderNames(MessageType msgType)
944 {
945     switch (msgType) {
946     case Api::SMS:
947     case Api::MMS:
948         return getFolderNamesMsgService();
949     case Api::EMAIL:
950         return getFolderNamesEmail();
951     default:
952         LogError("msg not supported");
953         Throw(Commons::UnknownException);
954     }
955 }
956
957 vector<string> Messaging::getFolderNamesMsgService()
958 {
959     vector<string> retVal;
960     MSG_FOLDER_LIST_S msgFolderList = { 0, NULL }; // output data
961
962     Try
963     {
964         if (msg_get_folder_list(MsgGetCommonHandle(),
965                                 &msgFolderList) != MSG_SUCCESS) {
966             LogError("msg_get_folder_list failed");
967             Throw(Commons::PlatformException);
968         }
969
970         LogDebug("number of folder=" << msgFolderList.nCount);
971         for (int i = 0; i < msgFolderList.nCount; i++) {
972             LogDebug("folderName=" << msgFolderList.folderInfo[i].folderName);
973             LogDebug("folderId=" << (int) msgFolderList.folderInfo[i].folderId);
974             LogDebug(
975                 "folderType=" <<
976                 (int) msgFolderList.folderInfo[i].folderType);
977             retVal.push_back(msgFolderList.folderInfo[i].folderName);
978         }
979         (void) msg_release_folder_list(&msgFolderList);
980     }
981
982     Catch(Commons::PlatformException) {
983         if (msgFolderList.nCount) {
984             (void) msg_release_folder_list(&msgFolderList);
985         }
986         throw;
987     }
988     return retVal;
989 }
990
991 vector<string> Messaging::getFolderNamesEmail()
992 {
993     vector<string> retVal;
994
995     string tmpStr;
996     emf_mailbox_t* mailboxes = NULL;
997     int mailboxesCount;
998     string emailAccountName;
999     Api::EmailAccountInfo account = getCurrentEmailAccount();
1000
1001     Try
1002     {
1003         if (!email_get_mailbox_list(account.getIntId(), -1, &mailboxes,
1004                                     &mailboxesCount) || !mailboxes) {
1005             LogError("error during get mailboxes");
1006         }
1007         for (int i = 0; i < mailboxesCount; i++) {
1008             retVal.push_back(mailboxes->name);
1009             LogDebug("mailbox found, name=" << mailboxes->name);
1010             mailboxes++;
1011         }
1012     }
1013
1014     Catch(Commons::PlatformException) {
1015         // nothing to clean, re-throw exception
1016         throw;
1017     }
1018
1019     return retVal;
1020 }
1021
1022 vector<Api::IMessagePtr> Messaging::findEmail(const std::string &folder,
1023         const Api::MessageFilterPtr& filter)
1024 {
1025     vector<Api::IMessagePtr> retVal;
1026
1027     Api::EmailAccountInfo account = getCurrentEmailAccount();
1028     if (account.getId().empty()) {
1029         LogWarning("No valid email accounts. Skipping");
1030         return retVal;
1031     }
1032
1033     int accountId = account.getIntId();
1034
1035     // number of found emails
1036     int count = 0;
1037     // start index
1038     int startIndex = 0;
1039
1040     do {
1041         emf_mail_list_item_t* results = NULL;
1042         int err = email_get_mail_list_ex(accountId,
1043                                          folder.c_str(),
1044                                          EMF_LIST_TYPE_NORMAL,
1045                                          startIndex,
1046                                          MESSAGE_FIND_LIMIT,
1047                                          EMF_SORT_DATETIME_HIGH,
1048                                          &results,
1049                                          &count);
1050         DPL::ScopedFree<emf_mail_list_item_t> autoFree(results);
1051         (void)autoFree;
1052         if (EMF_ERROR_MAIL_NOT_FOUND == err || results == NULL) {
1053             LogWarning("No emails found in mailbox: " << folder);
1054             break;
1055         } else if (EMF_ERROR_NONE != err) {
1056             LogError(
1057                 "Unable to get mail list for mailbox: " << folder <<
1058                 ", Error: " << err);
1059             Throw(Commons::PlatformException);
1060         }
1061
1062         // apply filter
1063         for (int i = 0; i < count; ++i) {
1064             Api::IMessagePtr msg = MessageFactory::createMessage(
1065                     EMAIL,
1066                     results[i].
1067                         mail_id);
1068             if (!filter ||
1069                 filter->compare(MessageFactory::convertToEmail(msg))) {
1070                 retVal.push_back(msg);
1071             }
1072         }
1073
1074         startIndex += count;
1075     }
1076     while (count >= MESSAGE_FIND_LIMIT);
1077
1078     return retVal;
1079 }
1080
1081 vector<Api::IMessagePtr> Messaging::findEmail(Api::FolderType folder,
1082         const Api::MessageFilterPtr& filter)
1083 {
1084     vector<Api::IMessagePtr> result;
1085
1086     Api::EmailAccountInfo account = getCurrentEmailAccount();
1087     if (account.getId().empty()) {
1088         LogWarning("No valid email accounts.");
1089         return result;
1090     }
1091
1092     string name;
1093     try {
1094         name = EmailConverter::toMailboxName(folder);
1095     }
1096     catch (const Commons::PlatformException& ex) {
1097         LogWarning(ex.DumpToString());
1098         return result;
1099     }
1100
1101     int accountId = account.getIntId();
1102     int startIndex = 0;
1103     int count = 0;
1104     do {
1105         emf_mail_list_item_t* messages = NULL;
1106         int error = email_get_mail_list_ex(accountId,
1107                                            name.c_str(),
1108                                            EMF_LIST_TYPE_NORMAL,
1109                                            startIndex,
1110                                            MESSAGE_FIND_LIMIT,
1111                                            EMF_SORT_DATETIME_HIGH,
1112                                            &messages,
1113                                            &count);
1114         DPL::ScopedFree<emf_mail_list_item_t> freeGuard(messages);
1115         if ((EMF_ERROR_MAIL_NOT_FOUND == error) || (NULL == messages)) {
1116             LogWarning("No emails found in mailbox: " << name);
1117             break;
1118         } else if (EMF_ERROR_NONE != error) {
1119             ThrowMsg(Commons::PlatformException,
1120                      "Couldn't get mail list from mailbox: " << name <<
1121                      ". [" << error << "]");
1122         }
1123
1124         for (int i = 0; i < count; ++i) {
1125             Api::IMessagePtr msg =
1126                 MessageFactory::createMessage(EMAIL, messages[i].mail_id);
1127             if (!filter ||
1128                 filter->compare(MessageFactory::convertToEmail(msg))) {
1129                 result.push_back(msg);
1130             }
1131         }
1132
1133         startIndex += count;
1134     }
1135     while (count >= MESSAGE_FIND_LIMIT);
1136
1137     return result;
1138 }
1139 }
1140 }