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.
18 * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
21 #include <emf-types.h>
23 #include <Emf_Mapi_Network.h>
24 #include <Emf_Mapi_Init.h>
25 #include <Emf_Mapi_Account.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/EventSendMessage.h>
33 #include <API/Messaging/EventOnSendingFailed.h>
34 #include "MailSender.h"
35 #include "NetworkStatus.h"
36 #include "Messaging.h"
39 const char* DBUS_FILTER_NETWORK_STATUS =
40 "type='signal',interface='User.Email.NetworkStatus'";
47 using namespace WrtDeviceApis::Commons;
48 using namespace WrtDeviceApis::CommonsJavaScript;
50 MailSender& MailSender::getInstance()
52 static MailSender instance;
56 int MailSender::send(const Api::Messaging::IEmailPtr& mail)
58 Assert(mail && "Mail must not be NULL.");
60 int mailId = mail->convertId(mail->getIdRef());
61 LogDebug("send mailId = " << mailId);
62 SendRequestsIterator it = m_requests.find(mailId);
63 if (m_requests.end() != it) {
64 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
65 "Email: " << mailId << " already requested to be send.");
68 return sendInternal(mail);
71 void MailSender::cancel(int handle)
73 SendRequestsIterator it = m_requests.find(handle);
74 if (m_requests.end() == it) {
75 //ThrowMsg(WrtDeviceApis::Commons::PlatformException,
76 // "Email handle : " << handle << " not found.");
77 LogDebug("Email handle" << handle << " not found!");
82 cancelInternal(it->second);
86 // TODO Copied from former solution, refactor it.
87 void MailSender::OnEventReceived(const DBus::MessageEvent& event)
90 NetworkStatusPtr msg(new NetworkStatus(event.GetArg0()));
91 int mailId = msg->getMailId();
92 LogDebug("status : " << msg->getStatus() << " mailId : " << mailId);
95 if ( msg->getStatus() == NOTI_SEND_FINISH || msg->getStatus() == NOTI_SEND_FAIL)
98 SendRequestsIterator it = m_requests.begin();
99 for (; it != m_requests.end() ; it++)
101 if ( it->second.mail->getUID() == mailId)
104 LogDebug("handle : " << handle);
109 if (msg->getStatus() == NOTI_SEND_FAIL)
111 LogDebug(" Error Code : " << msg->getErrorCode());
116 if ( msg->getStatus() == NOTI_SEND_START )
118 LogDebug("NOTI_SEND_START");
120 else if ( msg->getStatus() == NOTI_SEND_CANCEL )
122 LogDebug("NOTI_SEND_CANCEL");
128 LogDebug("handle : " << handle);
130 SendRequestsIterator it = m_requests.find(handle); //find reqeuset
131 if (m_requests.end() != it) {
132 switch (msg->getStatus()) {
133 case NOTI_SEND_START:
134 LogInfo("Start sending e-mail: " << mailId);
137 case NOTI_SEND_FINISH:
139 const Api::Messaging::IEmailPtr& mail = it->second.mail;
140 Api::Messaging::EventSendMessageReqReceiver* requestReceiver =
141 mail->getRequestReceiver();
142 if (requestReceiver) {
143 Api::Messaging::EventSendMessagePtr event = mail->getSendMessageEvent();
146 for (size_t i = 0; i < mail->getToRecipients().getRecipientSize(); ++i) {
147 event->m_successRecipients.push_back(mail->getToRecipients().getRecipient(i));
149 for (size_t i = 0; i < mail->getCcRecipients().getRecipientSize(); ++i) {
150 event->m_successRecipients.push_back(mail->getCcRecipients().getRecipient(i));
152 for (size_t i = 0; i < mail->getBccRecipients().getRecipientSize(); ++i) {
153 event->m_successRecipients.push_back(mail->getBccRecipients().getRecipient(i));
156 requestReceiver->ManualAnswer(event);
160 mail->setMessageStatus(Api::Messaging::MESSAGE_STATUS_SENT);
161 LogInfo("E-mail sent: " << mailId);
162 m_requests.erase(mailId);
168 const Api::Messaging::IEmailPtr& mail = it->second.mail;
169 Api::Messaging::EventOnSendingFailedEmitterPtr emitter = mail->getEmitter();
170 Api::Messaging::EventSendMessageReqReceiver *requestReceiver =
171 mail->getRequestReceiver();
173 Api::Messaging::EventOnSendingFailedPtr event(
174 new Api::Messaging::EventOnSendingFailed()
176 switch (msg->getErrorCode()) {
177 case EMF_ERROR_NO_SIM_INSERTED:
178 case EMF_ERROR_FLIGHT_MODE:
180 Api::Messaging::EventOnSendingFailed::NO_NETWORKING
184 case EMF_ERROR_SMTP_SEND_FAILURE:
185 case EMF_ERROR_NO_SUCH_HOST:
186 case EMF_ERROR_CONNECTION_FAILURE:
187 case EMF_ERROR_CONNECTION_BROKEN:
188 case EMF_ERROR_INVALID_SERVER:
189 case EMF_ERROR_NO_RESPONSE:
191 Api::Messaging::EventOnSendingFailed::NO_CONNECTION
196 event->setError(Api::Messaging::EventOnSendingFailed::UNKNOWN);
198 emitter->emit(event);
199 } else if (requestReceiver) {
200 Api::Messaging::EventSendMessagePtr event = mail->getSendMessageEvent();
201 event->setExceptionCode(
202 WrtDeviceApis::Commons::ExceptionCodes::UnknownException
204 requestReceiver->ManualAnswer(event);
206 mail->setMessageStatus(Api::Messaging::MESSAGE_STATUS_FAILED);
208 LogInfo("Sending e-mail: " << mailId <<
209 " failed with error: " << msg->getErrorCode());
210 m_requests.erase(mailId);
217 MailSender::MailSender() :
218 m_dbusThread(new DPL::Thread()),
219 m_dbus(new DBus::Connection())
223 m_dbus->setWorkerThread(m_dbusThread.Get());
224 m_dbus->AddListener(this);
225 m_dbus->SwitchAllListenersToThread(
226 ThreadPool::getInstance().getThreadRef(ThreadEnum::MESSAGING_THREAD)
228 m_dbus->addFilter(DBUS_FILTER_NETWORK_STATUS);
229 m_dbus->open(DBUS_BUS_SYSTEM);
231 //start email service
232 if (EMF_ERROR_NONE == email_service_begin()) {
233 LogDebug("Email service Begin\n");
234 if (EMF_ERROR_NONE == email_open_db()) {
235 LogDebug("Email open DB success\n");
238 LogDebug("Email open DB failed\n");
242 LogDebug("Email service not started\n");
247 MailSender::~MailSender()
249 m_dbus->RemoveListener(this);
252 m_dbusThread->Quit();
255 //close email service
256 if (EMF_ERROR_NONE == email_close_db()) {
257 LogDebug("Email Close DB Success\n");
258 if (EMF_ERROR_NONE == email_service_end()){
259 LogDebug("Email service close Success\n");
262 LogDebug("Email service end failed\n");
266 LogDebug("Email Close DB failed\n");
271 int MailSender::sendInternal(const Api::Messaging::IEmailPtr& mail)
273 int mailId = mail->convertId(mail->getIdRef());
275 emf_mailbox_t mailbox = {};
277 Messaging::getInstance().getEmailAccountId(mail->getFromRef());
278 // TODO Causes warning during compilation, refactor it.
279 mailbox.name = (char*)EMF_SENTBOX_NAME;
281 emf_option_t options = {};
282 options.keep_local_copy = 1;
283 unsigned int emf_handle=0;
285 int error = email_send_mail(&mailbox,
290 if (EMF_ERROR_NONE != error) {
291 LogDebug("Send Fail error = " << error );
292 m_requests.erase(mailId);
293 mail->setMessageStatus(Api::Messaging::MESSAGE_STATUS_SENDING);
294 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
295 "Failed to initialize send request. [" << error << "]");
300 m_requests.insert(std::make_pair(emf_handle, SendRequestData(emf_handle, mail)));
303 LogDebug("emf Handle : " << emf_handle
304 << "requests size :" << m_requests.size() );
309 void MailSender::cancelInternal(const SendRequestData& data)
311 int error = email_cancel_job(data.mail->getAccountID(), data.handle);
312 if (EMF_ERROR_NONE != error) {
313 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
314 "Couldn't cancel sending for email: " <<
315 data.mail->getIdRef());
318 m_requests.erase(data.handle);