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 <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>
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/EventSendMessage.h>
33 #include <API/Messaging/EventMessagingService.h>
34 #include <API/Messaging/EventOnSendingFailed.h>
35 #include "MailSender.h"
36 #include "NetworkStatus.h"
37 #include "Messaging.h"
40 const char* DBUS_FILTER_NETWORK_STATUS =
41 "type='signal',interface='User.Email.NetworkStatus'";
48 using namespace WrtDeviceApis::Commons;
49 using namespace WrtDeviceApis::CommonsJavaScript;
51 MailSender& MailSender::getInstance()
53 static MailSender instance;
57 int MailSender::send(const Api::Messaging::IEmailPtr& mail)
59 Assert(mail && "Mail must not be NULL.");
61 int mailId = mail->convertId(mail->getIdRef());
62 LogDebug("send mailId = " << mailId);
63 SendRequestsIterator it = m_requests.find(mailId);
64 if (m_requests.end() != it) {
65 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
66 "Email: " << mailId << " already requested to be send.");
69 return sendInternal(mail);
72 void MailSender::cancel(int handle)
74 SendRequestsIterator it = m_requests.find(handle);
75 if (m_requests.end() == it) {
76 //ThrowMsg(WrtDeviceApis::Commons::PlatformException,
77 // "Email handle : " << handle << " not found.");
78 LogDebug("Email handle" << handle << " not found!");
83 cancelInternal(it->second);
87 // TODO Copied from former solution, refactor it.
88 void MailSender::OnEventReceived(const DBus::MessageEvent& event)
91 NetworkStatusPtr msg(new NetworkStatus(event.GetArg0()));
92 int mailId = msg->getMailId();
93 LogDebug("status : " << msg->getStatus() << " mailId : " << mailId);
96 if ( msg->getStatus() == NOTI_SEND_FINISH || msg->getStatus() == NOTI_SEND_FAIL)
99 SendRequestsIterator it = m_requests.begin();
100 for (; it != m_requests.end() ; it++)
102 if ( it->second.mail->getUID() == mailId)
105 LogDebug("handle : " << handle);
110 if (msg->getStatus() == NOTI_SEND_FAIL)
112 LogDebug(" Error Code : " << msg->getErrorCode());
117 if ( msg->getStatus() == NOTI_SEND_START )
119 LogDebug("NOTI_SEND_START");
121 else if ( msg->getStatus() == NOTI_SEND_CANCEL )
123 LogDebug("NOTI_SEND_CANCEL");
129 LogDebug("handle : " << handle);
131 SendRequestsIterator it = m_requests.find(handle); //find reqeuset
132 if (m_requests.end() != it) {
133 switch (msg->getStatus()) {
134 case NOTI_SEND_START:
135 LogInfo("Start sending e-mail: " << mailId);
138 case NOTI_SEND_FINISH:
140 const Api::Messaging::IEmailPtr& mail = it->second.mail;
141 //Api::Messaging::EventSendMessageReqReceiver* requestReceiver = mail->getRequestReceiver();
142 Api::Messaging::EventMessagingServiceReqReceiver* requestReceiver = mail->getRequestReceiver();
144 if (requestReceiver) {
145 //Api::Messaging::EventSendMessagePtr event = mail->getSendMessageEvent();
146 Api::Messaging::EventMessagingServicePtr event = mail->getMessagingServiceEvent();
149 for (size_t i = 0; i < mail->getToRecipients().getRecipientSize(); ++i) {
150 event->m_successRecipients.push_back(mail->getToRecipients().getRecipient(i));
152 for (size_t i = 0; i < mail->getCcRecipients().getRecipientSize(); ++i) {
153 event->m_successRecipients.push_back(mail->getCcRecipients().getRecipient(i));
155 for (size_t i = 0; i < mail->getBccRecipients().getRecipientSize(); ++i) {
156 event->m_successRecipients.push_back(mail->getBccRecipients().getRecipient(i));
159 requestReceiver->ManualAnswer(event);
163 mail->setMessageStatus(Api::Messaging::MESSAGE_STATUS_SENT);
164 LogInfo("E-mail sent: " << mailId);
165 m_requests.erase(mailId);
171 const Api::Messaging::IEmailPtr& mail = it->second.mail;
172 Api::Messaging::EventOnSendingFailedEmitterPtr emitter = mail->getEmitter();
173 //Api::Messaging::EventSendMessageReqReceiver *requestReceiver = mail->getRequestReceiver();
174 Api::Messaging::EventMessagingServiceReqReceiver* requestReceiver = mail->getRequestReceiver();
176 Api::Messaging::EventOnSendingFailedPtr event(
177 new Api::Messaging::EventOnSendingFailed()
179 switch (msg->getErrorCode()) {
180 case EMAIL_ERROR_NO_SIM_INSERTED:
181 case EMAIL_ERROR_FLIGHT_MODE:
183 Api::Messaging::EventOnSendingFailed::NO_NETWORKING
187 case EMAIL_ERROR_SMTP_SEND_FAILURE:
188 case EMAIL_ERROR_NO_SUCH_HOST:
189 case EMAIL_ERROR_CONNECTION_FAILURE:
190 case EMAIL_ERROR_CONNECTION_BROKEN:
191 case EMAIL_ERROR_INVALID_SERVER:
192 case EMAIL_ERROR_NO_RESPONSE:
194 Api::Messaging::EventOnSendingFailed::NO_CONNECTION
199 event->setError(Api::Messaging::EventOnSendingFailed::UNKNOWN);
201 emitter->emit(event);
202 } else if (requestReceiver) {
203 //Api::Messaging::EventSendMessagePtr event = mail->getSendMessageEvent();
204 Api::Messaging::EventMessagingServicePtr event = mail->getMessagingServiceEvent();
205 event->setExceptionCode(
206 WrtDeviceApis::Commons::ExceptionCodes::UnknownException
208 requestReceiver->ManualAnswer(event);
210 mail->setMessageStatus(Api::Messaging::MESSAGE_STATUS_FAILED);
212 LogInfo("Sending e-mail: " << mailId <<
213 " failed with error: " << msg->getErrorCode());
214 m_requests.erase(mailId);
221 MailSender::MailSender() :
222 m_dbusThread(new DPL::Thread()),
223 m_dbus(new DBus::Connection())
227 m_dbus->setWorkerThread(m_dbusThread.Get());
228 m_dbus->AddListener(this);
229 m_dbus->SwitchAllListenersToThread(
230 ThreadPool::getInstance().getThreadRef(ThreadEnum::MESSAGING_THREAD)
232 m_dbus->addFilter(DBUS_FILTER_NETWORK_STATUS);
233 m_dbus->open(DBUS_BUS_SYSTEM);
235 //start email service
236 if (EMAIL_ERROR_NONE == email_service_begin()) {
237 LogDebug("Email service Begin\n");
238 if (EMAIL_ERROR_NONE == email_open_db()) {
239 LogDebug("Email open DB success\n");
242 LogDebug("Email open DB failed\n");
246 LogDebug("Email service not started\n");
251 MailSender::~MailSender()
253 m_dbus->RemoveListener(this);
256 m_dbusThread->Quit();
259 //close email service
260 if (EMAIL_ERROR_NONE == email_close_db()) {
261 LogDebug("Email Close DB Success\n");
262 if (EMAIL_ERROR_NONE == email_service_end()){
263 LogDebug("Email service close Success\n");
266 LogDebug("Email service end failed\n");
270 LogDebug("Email Close DB failed\n");
275 int MailSender::sendInternal(const Api::Messaging::IEmailPtr& mail)
277 int mailId = mail->convertId(mail->getIdRef());
279 email_option_t options = {};
280 options.keep_local_copy = 1;
281 unsigned int email_handle=0;
283 int error = email_send_mail(mailId,
287 if (EMAIL_ERROR_NONE != error) {
288 LogDebug("Send Fail error = " << error );
289 m_requests.erase(mailId);
290 mail->setMessageStatus(Api::Messaging::MESSAGE_STATUS_SENDING);
291 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
292 "Failed to initialize send request. [" << error << "]");
297 m_requests.insert(std::make_pair(email_handle, SendRequestData(email_handle, mail)));
300 LogDebug("emf Handle : " << email_handle
301 << "requests size :" << m_requests.size() );
306 void MailSender::cancelInternal(const SendRequestData& data)
308 int error = email_cancel_job(data.mail->getAccountID(), data.handle,EMAIL_CANCELED_BY_USER);
309 if (EMAIL_ERROR_NONE != error) {
310 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
311 "Couldn't cancel sending for email: " <<
312 data.mail->getIdRef());
315 m_requests.erase(data.handle);