upload tizen1.0 source
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Messaging / MailSync.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  * @author          Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
19  */
20 #include <utility>
21 #include <email-types.h>
22 #include <email-api.h>
23 #include <email-api-network.h>
24 #include <email-api-init.h>
25 #include <email-api-account.h>
26
27 #include <dpl/log/log.h>
28 #include <dpl/assert.h>
29 #include <Commons/Exception.h>
30 #include <Commons/ThreadPool.h>
31 #include <API/Messaging/ReqReceiverMessage.h>
32 #include <API/Messaging/EventMessagingService.h>
33 #include <API/Messaging/IAttachment.h>
34
35 #include "MailSync.h"
36 #include "SyncNetworkStatus.h"
37 #include <API/Messaging/IMessage.h>
38 //for vconf
39 #include <vconf.h>
40 #include <vconf-keys.h>
41
42 namespace {
43 const char* DBUS_FILTER_NETWORK_STATUS =
44     "type='signal',interface='User.Email.NetworkStatus'";
45 //const char* DBUS_FILTER_EMAIL_RECEIVED =
46 //    "type='signal',interface='User.Email.StorageChange'";
47 }
48
49 namespace TizenApis {
50 namespace Platform {
51 namespace Messaging {
52
53 using namespace WrtDeviceApis::Commons;
54 using namespace WrtDeviceApis::CommonsJavaScript;
55
56 MailSync& MailSync::getInstance()
57 {
58     static MailSync instance;
59     return instance;
60 }
61
62 MailSync::MailSync() :
63     m_dbusThread(new DPL::Thread()),
64     m_dbus(new DBus::Connection())
65 {
66     m_dbusThread->Run();
67
68     m_dbus->setWorkerThread(m_dbusThread.Get());
69     m_dbus->AddListener(this);
70     m_dbus->SwitchAllListenersToThread(
71         ThreadPool::getInstance().getThreadRef(ThreadEnum::MESSAGING_THREAD)
72         );
73     m_dbus->addFilter(DBUS_FILTER_NETWORK_STATUS);
74     m_dbus->open(DBUS_BUS_SYSTEM);
75
76     //start email service
77         if (EMF_ERROR_NONE == email_service_begin()) {
78             LogDebug("Email service Begin\n");
79             if (EMF_ERROR_NONE == email_open_db()) {
80                     LogDebug("Email open DB success\n");
81             }
82             else{
83                     LogDebug("Email open DB failed\n");
84         }
85         }
86         else{
87             LogDebug("Email service not started\n");
88         }
89
90         //get retriving count
91         int slot_size = -1;
92         vconf_get_int("db/email/slot_size", &(slot_size));
93         if ( slot_size > 0 )
94                 m_default_slot_size = slot_size;
95
96         LogDebug( "Slot Size : " << m_default_slot_size );
97         
98 }
99
100 MailSync::~MailSync()
101 {
102     m_dbus->RemoveListener(this);
103     m_dbus->close();
104
105     m_dbusThread->Quit();
106
107     //close email service
108         if (EMF_ERROR_NONE == email_close_db()) {
109                 LogDebug("Email Close DB Success\n");
110                 if (EMF_ERROR_NONE == email_service_end())
111                 {
112                 LogDebug("Email service close Success\n");
113                 }
114                 else
115                 {
116                 LogDebug("Email service end failed\n");
117         }
118         }
119         else{
120                 LogDebug("Email Close DB failed\n");
121 }
122 }
123
124 int MailSync::downloadBody( const Api::Messaging::IEmailPtr& mail )
125 {       
126         if ( mail )
127         {       
128                 int mailId = mail->convertId(mail->getIdRef());         // get mail id
129                 LogDebug("start attachment, mail Id : " << mail->getIdRef());
130                 SyncRequestIterator it;
131                 for( it = m_SyncRequests.begin(); it != m_SyncRequests.end(); ++it)
132                 {
133                         const Api::Messaging::IEmailPtr& email = it->second.mail;
134                         LogDebug ( "Requests mail ID:" <<  mail->convertId(email->getIdRef()) );
135                         if ( mailId == mail->convertId(email->getIdRef()))
136                         {
137                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
138                                         "download Body: " << mailId << " already requested to be download Body.");
139                         }
140                 }               
141         }
142         
143         return downloadBodyInternal(mail, mail->getAccountID());
144         
145 }
146
147 void MailSync::cancelDownloadBody(int handle)
148 {
149         Assert(handle > -1);
150
151         SyncRequestIterator it = m_SyncRequests.find(handle);
152         if ( m_SyncRequests.end() != it)
153         {
154                 if (  it->second.messagingService )
155                         cancelEmailJobInternal( it->second.messagingService->getAccountID() , it->second.handle);
156                 //cancelDownloadBodyInternal(it->second.mail, it->second.handle );
157         }
158         else
159         {
160                 LogDebug("Don't find cancel DownloadBody handle : " << handle);
161                 //ThrowMsg(WrtDeviceApis::Commons::NotFoundException, "Email: " << mailId << " not found.");
162         }
163         
164 }
165
166 void MailSync::cancelDownloadAttachment(int handle)
167 {
168         Assert(handle > -1);
169
170         SyncRequestIterator it = m_SyncRequests.find(handle);
171         if ( m_SyncRequests.end() != it)
172         {
173                 if (  it->second.messagingService )
174                         cancelEmailJobInternal( it->second.messagingService->getAccountID() , it->second.handle);
175                 //cancelDownloadBodyInternal(it->second.mail, it->second.handle );
176         }
177         else
178         {
179                 LogDebug("Don't find cancel DownloadAttachment handle : " << handle);
180         }
181         
182 }
183
184 int MailSync::downloadAttachment(const Api::Messaging::IEmailPtr& mail, const Api::Messaging::IAttachmentPtr& attachment)
185 {       
186         if ( mail && attachment )
187         {       
188                 //int mailId = mail->convertId(mail->getIdRef());               // get mail id
189                 LogDebug("start attachment, mail Id : " << mail->getIdRef());
190                 SyncRequestIterator it;
191                 for( it = m_SyncRequests.begin(); it != m_SyncRequests.end(); ++it)
192                 {
193                         const Api::Messaging::IAttachmentPtr& iattachment = it->second.attachment;
194                         LogDebug ( "Requests Attachment ID:" <<  iattachment->getAttachmentID() << " Input Attachment ID: "  << attachment->getAttachmentID());
195                         if (iattachment->getAttachmentID() == attachment->getAttachmentID())
196                         {
197                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
198                                         "Attachment: " << attachment->getAttachmentID() << " already requested to be download Attachment.");
199                         }
200                 }
201         }
202
203         return downloadAttachmentInternal(mail, mail->getAccountID(), attachment);
204
205 }
206
207 int MailSync::syncAccount(const Api::Messaging::IMessagingServicePtr& messagingService, const int limit)
208 {
209         LogDebug("syncAccount : " << limit);
210         if (messagingService)
211         {
212                 int accountId = messagingService->getAccountID();
213                 LogDebug("start sync, account Id : " << accountId);
214                 SyncRequestIterator it;
215                 for( it = m_SyncRequests.begin(); it != m_SyncRequests.end(); ++it)
216                 {
217                         const Api::Messaging::IMessagingServicePtr& messagingService = it->second.messagingService;
218                         if (messagingService && messagingService->getAccountID() == accountId)
219                         {
220                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
221                           "Sync: " << accountId << " already requested to be Sync Account.");
222                         }
223                 }
224                 return syncAccountInternal(messagingService, limit);
225         }
226         else
227         {
228                 LogDebug("messagingService is NULL");
229         }
230
231         LogDebug("end sync" );
232         return -1;
233 }       
234
235 int MailSync::syncAccountInternal( const Api::Messaging::IMessagingServicePtr& messagingService, const int limit)
236 {
237         LogDebug("syncAccountInternal limit: " << limit);
238         
239         int account_id = messagingService->getAccountID();
240         int err = 0;
241         emf_mailbox_t mailbox ;
242         unsigned emf_handle = 0;
243         
244         memset(&mailbox, 0, sizeof(emf_mailbox_t));
245         mailbox.name = NULL;                            /* all folders. */
246         mailbox.account_id = account_id; //set account id.
247         int slot_size;
248         
249         if ( limit < 0 )
250                 slot_size = m_default_slot_size;
251         else
252                 slot_size = limit;
253         
254         email_set_mail_slot_size(0, NULL, slot_size);
255                         
256         LogDebug("mailbox.account_id " << mailbox.account_id );
257         err = email_sync_header(&mailbox, &emf_handle);
258         LogDebug("emf_handle " << emf_handle);
259
260         if (err != EMF_ERROR_NONE) {
261                 LogDebug("fail to sync all folders - err : " << err);
262         }
263         else
264         {
265                 LogDebug("Insert sync request");
266                 SyncRequestData data = SyncRequestData(emf_handle,      MESSAGING_SERVICE_SYNC_TYPE_SYNC, messagingService);
267                 m_SyncRequests.insert(std::make_pair(emf_handle, data));
268         }
269
270         return emf_handle;
271 }
272
273 void MailSync::syncAccountCancel(const int handle)
274 {
275         LogDebug("sync cancel");
276         Assert(handle > -1);
277
278         SyncRequestIterator it = m_SyncRequests.find(handle);
279         if ( m_SyncRequests.end() != it)
280         {
281                 if (  it->second.messagingService )
282                         cancelEmailJobInternal( it->second.messagingService->getAccountID() , it->second.handle);
283         }
284         else
285         {
286                 LogDebug("Don't find cancel Sync handle : " << handle);
287                 //ThrowMsg(WrtDeviceApis::Commons::NotFoundException, "Email: " << mailId << " not found.");
288         }       
289 }
290
291 int MailSync::syncFolder(const Api::Messaging::IMessagingServicePtr& messagingService, const std::string& folderName, const int limit)
292 {
293         LogDebug("sync folder : " << folderName << " limit : " << limit);
294         
295         if (messagingService)
296         {
297                 int accountId = messagingService->getAccountID();
298                 LogDebug("start sync, account Id : " << accountId);
299                 SyncRequestIterator it;
300                 for( it = m_SyncRequests.begin(); it != m_SyncRequests.end(); ++it)
301                 {
302                         const Api::Messaging::IMessagingServicePtr& messagingService = it->second.messagingService;
303                         if (messagingService && messagingService->getAccountID() == accountId 
304                                 && it->second.folderName == folderName)
305                         {
306                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
307                                           "Sync: " << accountId << " already requested to be Sync Account.");
308                         }
309                 }
310                 
311                 return syncFolderInternal(messagingService, folderName, limit);
312         }
313         else
314         {
315                 LogDebug("messagingService is NULL");
316         }
317
318         return -1;
319                 
320 }
321
322 void MailSync::syncFolderCancel(const int handle)
323 {
324         LogDebug("sync Folder Cancel");
325         Assert(handle > -1);
326
327         SyncRequestIterator it = m_SyncRequests.find(handle);
328         if ( m_SyncRequests.end() != it)
329         {
330                 if (  it->second.messagingService )
331                         cancelEmailJobInternal( it->second.messagingService->getAccountID() , it->second.handle);
332         }
333         else
334         {
335                 LogDebug("Don't find cancel Sync Folder handle : " << handle);
336                 //ThrowMsg(WrtDeviceApis::Commons::NotFoundException, "Email: " << mailId << " not found.");
337         }
338 }
339
340 int MailSync::syncFolderInternal(const Api::Messaging::IMessagingServicePtr& messagingService, const std::string& folderName, const int limit)
341 {
342         LogDebug("Folder Name=" << folderName << " limit : " << limit);
343
344         int account_id = messagingService->getAccountID();
345
346         unsigned emf_handle = 0;        
347         int err = 0;
348         int slot_size = 0;
349         emf_mailbox_t* mailbox;
350         char* mailbox_name = strdup(folderName.c_str());
351         
352         err = email_get_mailbox_by_name(account_id, mailbox_name, &mailbox );
353         if (EMF_ERROR_NONE != err) {
354                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
355                         "Couldn't add message to mailbox. [" << err << "]");
356         }       
357         
358         if ( limit < 0 )
359                 slot_size = m_default_slot_size;
360         else
361                 slot_size = limit;
362         
363         err = email_set_mail_slot_size(0, mailbox_name, slot_size);
364         if (EMF_ERROR_NONE != err) {
365                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
366                         "Couldn't set mail solt size. [" << err << "]");
367         }
368         
369         err = email_sync_header(mailbox, &emf_handle);
370         if (err != EMF_ERROR_NONE) {
371                 LogDebug("fail to sync folders - err : " << err);
372         }
373         else
374         {
375                 LogDebug("Insert sync request");
376
377                 SyncRequestData data = SyncRequestData(emf_handle,      MESSAGING_SERVICE_SYNC_TYPE_SYNC_FOLDER, messagingService, folderName);
378                 m_SyncRequests.insert(std::make_pair(emf_handle, data));
379         }
380
381         if (mailbox_name)
382                 free(mailbox_name);
383
384         if ( mailbox )
385                 if  (  EMF_ERROR_NONE != email_free_mailbox( &mailbox , 1) )
386                         LogDebug("fail to email_free_mailbox - err ");
387         
388         return emf_handle;
389 }
390         
391
392 // TODO Copied from former solution, refactor it.
393 void MailSync::OnEventReceived(const DBus::MessageEvent& event)
394 {
395     LogDebug("OnEventReceived");
396     SyncNetworkStatusPtr syncNetworkStatus(new SyncNetworkStatus(event.GetArg0()));
397     int mailId = syncNetworkStatus->getMailId();        //if email body download mode.
398     int status = syncNetworkStatus->getStatus();
399     int handle = syncNetworkStatus->getHandle();
400
401         // if Attachment Load
402         if ( status == NOTI_DOWNLOAD_ATTACH_FINISH ||
403         status == NOTI_DOWNLOAD_ATTACH_FAIL )
404         {       
405                 int nth = handle;
406                 LogDebug(" Debus mailID = " <<  mailId <<  " , Nth = " << nth );
407                 
408                 SyncRequestIterator it = m_SyncRequests.begin();
409                 for ( ; it != m_SyncRequests.end(); it++ )
410                 {
411                         const Api::Messaging::IEmailPtr& mail = it->second.mail;
412                         
413                         LogDebug(" request mailID = " <<  mail->getUID() <<  " , Nth = " << (it->second.attachment)->getNth() );
414                         if ( mail->getUID() == mailId && nth == (it->second.attachment)->getNth())
415                         {       
416                                 Api::Messaging::EventMessagingServiceReqReceiver* requestReceiver = mail->getRequestReceiver();
417                                 if ( mail && requestReceiver )
418                                 {
419                                         Api::Messaging::EventMessagingServicePtr event = mail->getMessagingServiceEvent();
420                                 
421                                         if (status == NOTI_DOWNLOAD_ATTACH_FINISH)
422                                         {
423                                                 LogDebug(" Attachment Finish " );
424                                                 int acountId = mail->getAccountID();
425                                                 const Api::Messaging::IAttachmentPtr& attachment = it->second.attachment;
426                                                 if (attachment)
427                                                 {
428                                                         emf_mailbox_t mailbox ;
429                                                         emf_attachment_info_t *attach_info = NULL;
430                                                         memset(&mailbox, 0, sizeof(emf_mailbox_t));
431                                                         mailbox.account_id = acountId; //set account id.
432                                                         //int attachmentId = attachment->getAttachmentID();
433                                                         std::stringstream stream;
434                                                         stream << attachment->getAttachmentID();
435                                                         LogDebug("Attachment ID = " << stream.str());
436                                                         
437                                                         int err = email_get_attachment_info( &mailbox,  mail->getUID(), stream.str().c_str() , &attach_info );
438                                                         if (err == EMF_ERROR_NONE) {
439                                                                 LogDebug("attachment Name : " << attach_info->name);
440                                                                 LogDebug("attachment ID : " << attach_info->attachment_id);
441                                                                 attachment->init(attach_info->savename, false);
442                                                         }
443                                                         else
444                                                         {
445                                                                 LogDebug("fail to email_get_attachment_info - err : " << err);
446                                                         }
447                                                         
448                                                 }
449                                                 
450                                         }
451                                         else 
452                                         {       
453                                                 event->setExceptionCode( WrtDeviceApis::Commons::ExceptionCodes::UnknownException);
454                                                 LogDebug(" Attachment Failed " );
455                                         }
456
457                                         requestReceiver->ManualAnswer(event);
458                                         m_SyncRequests.erase( handle );         
459                                 
460                                 }
461
462                         break;
463                         }
464                 } 
465         }
466         else if ( status == NOTI_DOWNLOAD_ATTACH_START ) 
467         {
468                 LogDebug("DownLoading... attachment : size = " << syncNetworkStatus->getErrorCode());
469                 return;
470         }
471
472     SyncRequestIterator it = m_SyncRequests.find(handle);
473     if ( m_SyncRequests.end() != it)
474     {   
475                 int syncType = it->second.syncType;
476                 LogDebug(" Sync ... handle : " << handle << " status : " << status << " SyncType: " << syncType);
477
478                 switch(syncType)
479                 {
480                         case MESSAGING_SERVICE_SYNC_TYPE_SYNC:
481                         {       
482                                 LogDebug(" Sync Account");
483                                 const Api::Messaging::IMessagingServicePtr& messagingService = it->second.messagingService;
484                                 Api::Messaging::EventMessagingServiceReqReceiver* requestReceiver = messagingService->getRequestReceiver();
485                                 
486                                 if ( messagingService && requestReceiver)
487                                 {       
488                                         Api::Messaging::EventMessagingServicePtr event = messagingService->getMessagingServiceEvent();
489                                         if ( status == NOTI_DOWNLOAD_FINISH )
490                                         {       
491                                                 LogDebug("Sync Success");
492                                                 requestReceiver->ManualAnswer(event);
493                                                 m_SyncRequests.erase( handle );                                                         
494                                         }
495                                         else if ( status == NOTI_DOWNLOAD_FAIL )
496                                         {       
497                                                 LogDebug("Sync Fail");
498                                         event->setExceptionCode( WrtDeviceApis::Commons::ExceptionCodes::UnknownException );
499                                                 requestReceiver->ManualAnswer(event);
500                                                 m_SyncRequests.erase( handle );
501                                         }       
502                                 }
503                                 else
504                                 {
505                                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "request Receiver is NULL. ");
506                                 }
507                                 
508                                 break;
509                         }
510                         case MESSAGING_SERVICE_SYNC_TYPE_SYNC_FOLDER:
511                         {       
512                                 LogDebug("Sync Folder");
513                                 const Api::Messaging::IMessagingServicePtr& messagingService = it->second.messagingService;
514                                 Api::Messaging::EventMessagingServiceReqReceiver* requestReceiver = messagingService->getRequestReceiver();
515                                 
516                                 if ( messagingService && requestReceiver)
517                                 {       
518                                         Api::Messaging::EventMessagingServicePtr event = messagingService->getMessagingServiceEvent();
519                                         if ( status == NOTI_DOWNLOAD_FINISH )
520                                         {       
521                                                 LogDebug("Sync Success");
522                                                 requestReceiver->ManualAnswer(event);
523                                                 m_SyncRequests.erase( handle );                                                         
524                                         }
525                                         else if ( status == NOTI_DOWNLOAD_FAIL )
526                                         {       
527                                                 LogDebug("Sync Fail");
528                                         event->setExceptionCode( WrtDeviceApis::Commons::ExceptionCodes::UnknownException );
529                                                 requestReceiver->ManualAnswer(event);
530                                                 m_SyncRequests.erase( handle );
531                                         }
532                                 }
533                                 else
534                                 {
535                                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "request Receiver is NULL. ");
536                                 }
537                                 break;
538                         }
539                         case MESSAGING_SERVICE_SYNC_TYPE_DOWNLOAD_BODY:
540                         {       
541                                 LogDebug(" DownLoad Body");
542                                 const Api::Messaging::IEmailPtr& mail = it->second.mail;        // IEmailPtr
543                                 Api::Messaging::EventMessagingServiceReqReceiver* requestReceiver = mail->getRequestReceiver();
544                                 if (mail && requestReceiver) {
545                                         Api::Messaging::EventMessagingServicePtr event = mail->getMessagingServiceEvent();
546                                         if ( status == NOTI_DOWNLOAD_BODY_FINISH )
547                                         {
548                                                 requestReceiver->ManualAnswer(event);
549                                                 m_SyncRequests.erase( handle );
550                                         }
551                                         else if ( status == NOTI_DOWNLOAD_BODY_FAIL )
552                                         {
553                                                 event->setExceptionCode( WrtDeviceApis::Commons::ExceptionCodes::UnknownException);
554                                                 requestReceiver->ManualAnswer(event);
555                                                 m_SyncRequests.erase( handle );
556                                         }              
557                         }
558                                 else
559                                 {
560                                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "request Receiver is NULL. ");
561                                 }
562                                 
563                                 break;
564                         }
565                         
566                 }
567
568                 
569         }
570                                 
571 }
572
573 int MailSync::downloadBodyInternal( const Api::Messaging::IEmailPtr& mail, int account_id)
574 {
575         
576         LogDebug("downloadInternal");
577
578         int err = 0;
579         int mailId = mail->convertId(mail->getIdRef());
580         unsigned int emf_handle = 0;
581         
582         LogDebug("folder type = " << mail->getCurrentFolder());
583
584         char *mailbox_name =NULL;
585         err = email_get_mailbox_name_by_mail_id(mailId, &mailbox_name);
586         if (EMF_ERROR_NONE != err) {
587                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
588                         "Couldn't add message to mailbox. [" << err << "]");
589         }
590         LogDebug("mail ID :" << mailId );
591         LogDebug("mailbox name : " << mailbox_name );   
592
593         emf_mailbox_t* mailbox;
594         err = email_get_mailbox_by_name(mail->getAccountID(), mailbox_name, &mailbox );
595         if (EMF_ERROR_NONE != err) {
596                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
597                         "Couldn't add message to mailbox. [" << err << "]");
598         }
599         
600         err = email_download_body(mailbox, mailId, 0, &emf_handle);
601         if (err != EMF_ERROR_NONE) {
602                 LogDebug("fail to downloadBody - err : " << err);
603                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Failed to initialize downloadBody request. [" << err << "]");
604         }
605         else
606         {
607                 LogDebug("Insert downloadBody request");
608                 LogDebug("handle : " << emf_handle);
609                 SyncRequestData data = SyncRequestData(emf_handle,      MESSAGING_SERVICE_SYNC_TYPE_DOWNLOAD_BODY, mail);
610                 m_SyncRequests.insert(std::make_pair(emf_handle, data));
611         }
612
613         if ( mailbox )
614                 if  (  EMF_ERROR_NONE != email_free_mailbox( &mailbox , 1) )
615                         LogDebug("fail to email_free_mailbox - err ");
616
617         return emf_handle;
618
619 }
620
621 int MailSync::downloadAttachmentInternal(const Api::Messaging::IEmailPtr& mail, int account_id, const Api::Messaging::IAttachmentPtr& attachment)
622 {
623         LogDebug("downloadAttachmentInternal");
624         Assert(mail);
625         
626         int err = 0;
627         int nth = 0;
628         int mailId = mail->convertId(mail->getIdRef());
629         unsigned emf_handle = 0;
630         
631         char *mailbox_name =NULL;
632         err = email_get_mailbox_name_by_mail_id(mailId, &mailbox_name);
633         if (EMF_ERROR_NONE != err) {
634                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
635                         "Couldn't add message to mailbox. [" << err << "]");
636         }
637         LogDebug("mail ID :" << mailId );
638         LogDebug("mailbox name : " << mailbox_name );   
639
640         emf_mailbox_t* mailbox;
641         err = email_get_mailbox_by_name(mail->getAccountID(), mailbox_name, &mailbox );
642         if (EMF_ERROR_NONE != err) {
643                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
644                         "Couldn't add message to mailbox. [" << err << "]");
645         }
646         
647         LogDebug("Attachment ID :" << attachment->getAttachmentID());   
648         std::stringstream stream;
649         
650         if (stream.fail()) {
651                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
652                                  "Couldn't convert e-mail attachment id");
653         }
654
655         //get nth 
656         std::vector<Api::Messaging::IAttachmentPtr> attachments = mail->getAttachments();
657         for ( unsigned int i = 0 ; i < attachments.size() ; i ++)
658         {
659                 LogDebug( "attachment ID is = " << attachments[i]->getAttachmentID());
660                 if (attachments[i]->getAttachmentID() == attachment->getAttachmentID())
661                 {
662                         nth = i;
663                         break;
664                 }
665         }
666         
667         stream << nth+1;
668         LogDebug("nth = " << stream.str());
669         LogDebug("attachment Order Index = " << stream.str());
670         err = email_download_attachment(mailbox, mailId, stream.str().c_str() , &emf_handle);
671         if (err != EMF_ERROR_NONE) {
672                 LogDebug("fail to downloadAttachment - err : " << err);
673                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Failed to initialize downloadAttachment request. [" << err << "]");
674         }
675         else
676         {
677                 LogDebug("Insert downloadAttachment request");
678                 LogDebug("handle : " << emf_handle);
679                 SyncRequestData data = SyncRequestData( emf_handle,     
680                         MESSAGING_SERVICE_SYNC_TYPE_DOWNLOAD_ATTACHMENT, mail, attachment );
681                 m_SyncRequests.insert(std::make_pair(emf_handle, data));                
682         }
683
684         if ( mailbox )
685                 if  (  EMF_ERROR_NONE != email_free_mailbox( &mailbox , 1) )
686                         LogDebug("fail to email_free_mailbox - err ");
687         
688         return emf_handle;
689 }
690
691 void MailSync::cancelEmailJobInternal(int accountId, int handle)
692 {
693         LogDebug("cancel Email Job, account : " <<accountId << " handle : " << handle);
694
695         int error = email_cancel_job(accountId, handle);
696         if (EMF_ERROR_NONE != error) {
697                 LogDebug("error code : " << error );
698                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
699                  "Couldn't cancel email job handle: " << handle);
700         }
701
702         m_SyncRequests.erase(handle);
703 }
704
705
706 }
707 }
708 }