2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
20 #include <emf-types.h>
21 #include <Emf_Mapi_Network.h>
22 #include <dpl/log/log.h>
23 #include <dpl/assert.h>
24 #include <Commons/Exception.h>
25 #include <Commons/ThreadPool.h>
26 #include <API/Messaging/ReqReceiverMessage.h>
27 #include <API/Messaging/EventSendMessage.h>
28 #include <API/Messaging/EventOnSendingFailed.h>
29 #include "MailSender.h"
30 #include "NetworkStatus.h"
31 #include "Messaging.h"
34 const char* DBUS_FILTER_NETWORK_STATUS =
35 "type='signal',interface='User.Email.NetworkStatus'";
38 namespace WrtDeviceApis {
40 MailSender& MailSender::getInstance()
42 static MailSender instance;
46 void MailSender::send(const Api::IEmailPtr& mail)
48 Assert(mail && "Mail must not be NULL.");
50 int mailId = mail->convertId(mail->getIdRef());
51 SendRequestsIterator it = m_requests.find(mailId);
52 if (m_requests.end() != it) {
53 ThrowMsg(Commons::PlatformException,
54 "Email: " << mailId << " already requested to be send.");
60 void MailSender::cancel(int mailId)
62 SendRequestsIterator it = m_requests.find(mailId);
63 if (m_requests.end() == it) {
64 ThrowMsg(Commons::PlatformException,
65 "Email: " << mailId << " not found.");
68 cancelInternal(it->second);
71 // TODO Copied from former solution, refactor it.
72 void MailSender::OnEventReceived(const DBus::MessageEvent& event)
75 NetworkStatusPtr msg(new NetworkStatus(event.GetArg0()));
76 int mailId = msg->getMailId();
78 SendRequestsIterator it = m_requests.find(mailId);
79 if (m_requests.end() != it) {
80 switch (msg->getStatus()) {
82 LogInfo("Start sending e-mail: " << mailId);
85 case NOTI_SEND_FINISH:
87 const Api::IEmailPtr& mail = it->second.mail;
88 Api::EventSendMessageReqReceiver* requestReceiver =
89 mail->getRequestReceiver();
92 Api::EventSendMessagePtr event = mail->getSendMessageEvent();
93 event->addRecipientsSendResult(
94 mail->getToRecipientsPtr()->getRecipientsRef(),
96 event->addRecipientsSendResult(
97 mail->getCcRecipientsPtr()->getRecipientsRef(),
99 event->addRecipientsSendResult(
100 mail->getBccRecipientsPtr()->getRecipientsRef(),
102 requestReceiver->ManualAnswer(event);
104 LogInfo("E-mail sent: " << mailId);
105 m_requests.erase(mailId);
111 const Api::IEmailPtr& mail = it->second.mail;
112 Api::EventOnSendingFailedEmitterPtr emitter = mail->getEmitter();
113 Api::EventSendMessageReqReceiver *requestReceiver =
114 mail->getRequestReceiver();
116 Api::EventOnSendingFailedPtr event(
117 new Api::EventOnSendingFailed()
119 switch (msg->getErrorCode()) {
120 case EMF_ERROR_NO_SIM_INSERTED:
121 case EMF_ERROR_FLIGHT_MODE:
123 Api::EventOnSendingFailed::NO_NETWORKING
127 case EMF_ERROR_SMTP_SEND_FAILURE:
128 case EMF_ERROR_NO_SUCH_HOST:
129 case EMF_ERROR_CONNECTION_FAILURE:
130 case EMF_ERROR_CONNECTION_BROKEN:
131 case EMF_ERROR_INVALID_SERVER:
132 case EMF_ERROR_NO_RESPONSE:
134 Api::EventOnSendingFailed::NO_CONNECTION
139 event->setError(Api::EventOnSendingFailed::UNKNOWN);
141 emitter->emit(event);
143 else if (requestReceiver)
145 Api::EventSendMessagePtr event = mail->getSendMessageEvent();
146 event->addRecipientsSendResult(
147 mail->getToRecipientsPtr()->getRecipientsRef(),
149 event->addRecipientsSendResult(
150 mail->getCcRecipientsPtr()->getRecipientsRef(),
152 event->addRecipientsSendResult(
153 mail->getBccRecipientsPtr()->getRecipientsRef(),
155 event->setExceptionCode(
156 Commons::ExceptionCodes::UnknownException
158 requestReceiver->ManualAnswer(event);
160 LogInfo("Sending e-mail: " << mailId <<
161 " failed with error: " << msg->getErrorCode());
162 m_requests.erase(mailId);
169 MailSender::MailSender() :
170 m_dbusThread(new DPL::Thread()),
171 m_dbus(new DBus::Connection())
175 m_dbus->setWorkerThread(m_dbusThread.Get());
176 m_dbus->AddListener(this);
177 m_dbus->SwitchAllListenersToThread(
178 Commons::ThreadPool::getInstance().getThreadRef(Commons::ThreadEnum::MESSAGING_THREAD)
180 m_dbus->addFilter(DBUS_FILTER_NETWORK_STATUS);
181 m_dbus->open(DBUS_BUS_SYSTEM);
184 MailSender::~MailSender()
186 m_dbus->RemoveListener(this);
189 m_dbusThread->Quit();
192 void MailSender::sendInternal(const Api::IEmailPtr& mail)
194 int mailId = mail->convertId(mail->getIdRef());
196 emf_mailbox_t mailbox;
197 memset(&mailbox, 0, sizeof(emf_mailbox_t));
199 Messaging::getInstance().getEmailAccountId(mail->getFromRef());
200 // TODO remove ugly casting.
201 mailbox.name = (char*)EMF_SENTBOX_NAME;
203 emf_option_t options;
204 memset(&options, 0, sizeof(emf_option_t));
205 options.keep_local_copy = 1;
207 m_requests.insert(std::make_pair(mailId, SendRequestData(mail)));
209 int error = email_send_mail(&mailbox,
212 &m_requests.at(mailId).handle);
213 if (EMF_ERROR_NONE != error) {
214 m_requests.erase(mailId);
215 ThrowMsg(Commons::PlatformException,
216 "Failed to initialize send request. [" << error << "]");
220 void MailSender::cancelInternal(const SendRequestData& data)
222 int mailId = data.mail->convertId(data.mail->getIdRef());
224 int error = email_cancel_job(data.mail->getAccountId(), data.handle);
225 if (EMF_ERROR_NONE != error) {
226 ThrowMsg(Commons::PlatformException,
227 "Couldn't cancel sending for email: " <<
228 data.mail->getIdRef());
231 m_requests.erase(mailId);