4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <stdarg.h> /* Needed for the definition of va_list */
31 #include "email-daemon.h"
32 #include "email-daemon-emn.h"
33 #include "email-debug-log.h"
34 #include "email-utilities.h"
35 #include "email-internal-types.h"
36 #include "email-storage.h"
38 #ifdef __FEATURE_OMA_EMN__
41 #include "msg_storage.h"
42 #include "msg_transport.h"
44 #include <wbxml/wbxml.h>
45 #include <wbxml/wbxml_handlers.h>
46 #include <wbxml/wbxml_parser.h>
47 #include <wbxml/wbxml_errors.h>
49 static void _cb_parser_start_document(void* ctx, WB_LONG charset, const WBXMLLangEntry* lang)
51 EM_DEBUG_FUNC_BEGIN();
52 EM_DEBUG_LOG("Root Element: %s", lang->publicID->xmlRootElt);
53 EM_DEBUG_LOG_SEC("Public ID: %s", lang->publicID->xmlPublicID);
54 EM_DEBUG_LOG("DTD: %s", lang->publicID->xmlDTD);
58 static void _cb_parser_end_document(void* ctx)
60 EM_DEBUG_FUNC_BEGIN();
64 static void _cb_parser_start_element(void* ctx, WBXMLTag* element, WBXMLAttribute** atts, WB_BOOL empty)
66 EM_DEBUG_FUNC_BEGIN();
67 WB_UTINY* p, **pp = ctx;
68 WB_ULONG j = 0, len = 0;
69 EM_DEBUG_LOG("parse_clb_start_element");
71 if (strcasecmp((char *)wbxml_tag_get_xml_name(element), "emn") != 0) {
72 EM_DEBUG_LOG("not email notification");
77 EM_DEBUG_LOG("no emn attributes");
81 len = EM_SAFE_STRLEN((char *)wbxml_tag_get_xml_name(element)) + 1;
82 while (atts[j] != NULL) {
83 len += (EM_SAFE_STRLEN((char *)wbxml_attribute_get_xml_name(atts[j])) + EM_SAFE_STRLEN((char *)wbxml_attribute_get_xml_value(atts[j])) + 7);
88 if (!(p = malloc(sizeof(WB_UTINY) * len + 1))) {
92 EM_DEBUG_LOG_SEC("<%s", (char *)wbxml_tag_get_xml_name(element));
93 sprintf((char *)p, "<%s", (char *)wbxml_tag_get_xml_name(element));
96 while (atts[j] != NULL) {
97 EM_DEBUG_LOG_SEC(" %s=\"%s\"", (char *)wbxml_attribute_get_xml_name(atts[j]), (char *)wbxml_attribute_get_xml_value(atts[j]));
98 strcat((char *)p, " ");
99 strcat((char *)p, (char *)wbxml_attribute_get_xml_name(atts[j]));
100 strcat((char *)p, "=");
101 strcat((char *)p, "\"");
102 strcat((char *)p, (char *)wbxml_attribute_get_xml_value(atts[j]));
103 strcat((char *)p, "\"");
108 EM_DEBUG_LOG_SEC("/>");
109 strcat((char *)p, "/>");
112 EM_DEBUG_LOG_SEC(">");
113 strcat((char *)p, ">");
120 static void _cb_parser_end_element(void* ctx, WBXMLTag* element, WB_BOOL empty)
122 EM_DEBUG_FUNC_BEGIN();
126 static void _cb_parser_characters(void* ctx, WB_UTINY* ch, WB_ULONG start, WB_ULONG length)
128 EM_DEBUG_FUNC_BEGIN();
132 static int _get_addr_from_element(unsigned char* elm,int* type, unsigned char** incoming_server_user_name, unsigned char** host_addr, unsigned char** mbox_name, unsigned char** auth_type)
134 EM_DEBUG_FUNC_BEGIN();
136 int err = EMAIL_ERROR_NONE;
137 unsigned char *p = NULL;
138 unsigned char *s = NULL;
139 unsigned char *user = NULL;
140 unsigned char *host = NULL;
141 unsigned char *mailbox = NULL;
142 unsigned char *auth = NULL;
144 if (!(p = (unsigned char*)strstr((char *)elm, "mailbox"))) {
145 EM_DEBUG_EXCEPTION("invalid notification data");
146 err = EMAIL_ERROR_XML_PARSER_FAILURE;
151 s = (unsigned char*)strchr((char *)p, '\"');
157 case 'm':/* mailat (RFC2234) */
160 if (!(s = (unsigned char*)strchr((char *)p, '@'))) return 0;
162 user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
164 host = (unsigned char*)EM_SAFE_STRDUP((char *)s);
169 case 'p':/* pop3 (RFC2384) */
172 if ((s = (unsigned char*)strchr((char *)p, ';'))) {
174 if (EM_SAFE_STRLEN((char *)p)) user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
177 if ((s = (unsigned char*)strchr((char *)p, '@'))) {
179 if (user || *(p - 3) == '/') {
180 if (strncmp((char *)p, "AUTH=", 5) == 0) auth = (unsigned char*)EM_SAFE_STRDUP((char *)p + 5);
183 user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
186 if ((s = (unsigned char*)strchr((char *)p, ':'))) {
189 EM_DEBUG_LOG("PORT:%s", s);
191 host = (unsigned char*)EM_SAFE_STRDUP((char *)p);
195 case 'i':/* imap (RFC2192) */
198 if ((s = (unsigned char*)strchr((char *)p, ';'))) {
200 if (EM_SAFE_STRLEN((char *)p)) user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
203 if ((s = (unsigned char*)strchr((char *)p, '@'))) {
205 if (user || *(p - 3) == '/') {
206 if (strncmp((char *)p, "AUTH=", 5) == 0) auth = (unsigned char*)EM_SAFE_STRDUP((char *)p + 5);
209 user = (unsigned char*)EM_SAFE_STRDUP((char *)p);
213 if ((s = (unsigned char *)strchr((char *)p, '/'))) { /*prevent 47327*/
215 host = (unsigned char *)EM_SAFE_STRDUP((char *)p);
219 if ((s = (unsigned char*)strchr((char *)p, '?')))
221 else if ((s = (unsigned char*)strchr((char *)p, ';')))
224 s = p + EM_SAFE_STRLEN((char *)p);
228 if (EM_SAFE_STRLEN((char *)p))
229 mailbox =(unsigned char*) EM_SAFE_STRDUP((char *)p);
232 case 'h': /* not supported */
233 EM_DEBUG_LOG("Http URI is not yet supported");
234 err = EMAIL_ERROR_XML_PARSER_FAILURE;
238 err = EMAIL_ERROR_XML_PARSER_FAILURE;
242 if (err == EMAIL_ERROR_NONE) {
243 *incoming_server_user_name = user;
245 *mbox_name = mailbox;
251 EM_DEBUG_FUNC_END("err [%d]", err);
255 static int _get_time_from_element(unsigned char* elm, unsigned char** time_stamp)
257 EM_DEBUG_FUNC_BEGIN("elm[%p] time_stamp[%p]", elm, time_stamp);
258 int err = EMAIL_ERROR_NONE;
259 unsigned char* p, *s, *stamp = NULL;
261 if (!(p = (unsigned char*)strstr((char *)elm, "timestamp"))) {
262 EM_DEBUG_EXCEPTION("invalid notification data");
263 err = EMAIL_ERROR_XML_PARSER_FAILURE;
268 s = (unsigned char*)strchr((char *)p, '\"');
275 EM_DEBUG_EXCEPTION("malloc failed");
276 err = EMAIL_ERROR_OUT_OF_MEMORY;
280 memcpy(stamp + 4, p + 5, 2);
281 memcpy(stamp + 6, p + 8, 2);
282 memcpy(stamp + 8, p + 11, 2);
283 memcpy(stamp + 10, p + 14, 2);
284 memcpy(stamp + 12, p + 17, 2);
291 EM_DEBUG_FUNC_END("err [%d]", err);
295 /* <emn mailbox="mailat:user@wapforum.org" timestamp="2002-04-16T06:40:00Z"/> */
296 static int _get_data_from_element(unsigned char* elm, int* type, unsigned char** incoming_server_user_name, unsigned char** host_addr, unsigned char** mbox_name, unsigned char** auth_type, unsigned char** time_stamp)
298 EM_DEBUG_FUNC_BEGIN();
299 int err = EMAIL_ERROR_NONE;
301 if ((err = _get_time_from_element(elm, time_stamp)) != EMAIL_ERROR_NONE) {
302 EM_DEBUG_EXCEPTION("EMAIL_ERROR_XML_PARSER_FAILURE");
306 /* must call get_addr_from_element after calling _get_time_from_element */
307 if (!_get_addr_from_element(elm, type, incoming_server_user_name, host_addr, mbox_name, auth_type)) {
308 EM_SAFE_FREE(*time_stamp);
309 err = EMAIL_ERROR_XML_PARSER_FAILURE;
310 EM_DEBUG_EXCEPTION("EMAIL_ERROR_XML_PARSER_FAILURE");
315 EM_DEBUG_FUNC_END("err[%d]", err);
320 * get account from OMA EMN data
323 * account_id: id of account to be retrieved from EMN data
324 * mailbox : if mail-box information exists in EMN data, mailbox holds the name of mailbox.
325 * err_code : hold error code
330 static int _get_emn_account(unsigned char *input_wbxml, int input_wbxml_length, email_account_t *account, char **mailbox)
332 EM_DEBUG_FUNC_BEGIN("input_wbxml[%p] input_wbxml_length[%d] account[%p] mailbox[%p]", input_wbxml, input_wbxml_length, account, mailbox);
333 WBXMLContentHandler parse_handler = {
334 (WBXMLStartDocumentHandler) _cb_parser_start_document,
335 (WBXMLEndDocumentHandler) _cb_parser_end_document,
336 (WBXMLStartElementHandler) _cb_parser_start_element,
337 (WBXMLEndElementHandler) _cb_parser_end_element,
338 (WBXMLCharactersHandler) _cb_parser_characters,
342 WBXMLParser* wbxml_parser = NULL;
343 WB_UTINY* wbxml = NULL;
344 WB_UTINY* elm = NULL;
345 WB_ULONG wbxml_len = 0;
346 WB_ULONG err_idx = 0;
347 WBXMLError ret = WBXML_OK;
348 email_account_t* accounts = NULL;
349 unsigned char* incoming_server_user_name = NULL;
350 unsigned char* host_addr = NULL;
351 unsigned char* mbox_name = NULL;
352 unsigned char* auth_type = NULL;
353 unsigned char* time_stamp = NULL;
354 unsigned char email_address[MAX_EMAIL_ADDRESS_LENGTH] = { 0, };
359 int err = EMAIL_ERROR_NONE;
361 if (!input_wbxml || !account) {
362 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
363 err = EMAIL_ERROR_INVALID_PARAM;
367 EM_DEBUG_LOG("wbxml_b64 [%s]", input_wbxml);
369 /* wbxml = g_base64_decode((const char*)wbxml_b64, (unsigned int*)&wbxml_len); */
372 wbxml_len = input_wbxml_length;
374 EM_DEBUG_LOG("wbxml [%s]", wbxml);
375 EM_DEBUG_LOG("wbxml_len [%d]", wbxml_len);
377 /* create wbxml parser */
378 if (!(wbxml_parser = wbxml_parser_create())) {
379 err = EMAIL_ERROR_OUT_OF_MEMORY;
383 /* initialize wbxml parser */
384 wbxml_parser_set_user_data(wbxml_parser, (void*)&elm);
385 wbxml_parser_set_content_handler(wbxml_parser, &parse_handler);
388 if ((ret = wbxml_parser_parse(wbxml_parser, wbxml, wbxml_len)) != WBXML_OK) {
389 err_idx = wbxml_parser_get_current_byte_index(wbxml_parser);
390 EM_DEBUG_EXCEPTION("Parsing failed at %u - Token %x - %s", err_idx, wbxml[err_idx], wbxml_errors_string(ret));
391 err = EMAIL_ERROR_XML_PARSER_FAILURE;
395 EM_DEBUG_LOG("Parsing OK !");
399 wbxml_parser_destroy(wbxml_parser);
409 EM_DEBUG_EXCEPTION("invalid elements");
410 err = EMAIL_ERROR_XML_PARSER_FAILURE;
414 EM_DEBUG_LOG("elements = [%s]", elm);
415 _get_data_from_element(elm, &type, &incoming_server_user_name, &host_addr, &mbox_name, &auth_type, &time_stamp);
419 EM_DEBUG_LOG("user_type = [%d]", type);
420 EM_DEBUG_LOG_SEC("incoming_server_user_name = [%s]", (char *)incoming_server_user_name ? (char*)incoming_server_user_name : "NIL");
421 EM_DEBUG_LOG("host_addr = [%s]", (char *)host_addr ? (char*)host_addr : "NIL");
422 EM_DEBUG_LOG_SEC("mbox_name = [%s]", (char *)mbox_name ? (char*)mbox_name : "NIL");
423 EM_DEBUG_LOG("auth_type = [%s]", (char *)auth_type ? (char*)auth_type : "NIL");
424 EM_DEBUG_LOG("time_stamp= [%s]", (char *)time_stamp? (char*)time_stamp: "NIL");
426 if(incoming_server_user_name && host_addr)
427 SNPRINTF((char*)email_address, MAX_EMAIL_ADDRESS_LENGTH, "%s@%s", incoming_server_user_name, host_addr);
429 if (!emdaemon_get_account_list(NULL, &accounts, &count, &err)) {
430 EM_DEBUG_EXCEPTION("EMAIL_ERROR_DB_FAILURE");
431 err = EMAIL_ERROR_DB_FAILURE;
435 for (i = 0; i < count; i++) {
436 char* temp_account_name = NULL;
438 /* EM_DEBUG_LOG(">>>> Account Information UserName [ %s ] Email Addr [ %s], Account ID [ %d] >>> ",accounts[i].incoming_server_user_name,accounts[i].user_email_address, accounts[i].account_id); */
439 temp_account_name =(char*) EM_SAFE_STRDUP((char *)accounts[i].incoming_server_user_name);
441 if ((s = (char*)strchr((char *)temp_account_name, '@'))) {
443 EM_SAFE_FREE(accounts[i].incoming_server_user_name);
444 accounts[i].incoming_server_user_name = (char*)EM_SAFE_STRDUP((char *)temp_account_name);
446 EM_SAFE_FREE(temp_account_name);
447 if (incoming_server_user_name && host_addr) {
448 if (strstr(accounts[i].user_email_address, (char*)email_address)) {
449 EM_DEBUG_LOG(">>>> Account Match >>> ");
451 (type == 2 && accounts[i].incoming_server_type == EMAIL_SERVER_TYPE_POP3) ||
452 (type == 3 && accounts[i].incoming_server_type == EMAIL_SERVER_TYPE_IMAP4)) {
453 /* accounts[i].flag2 = type; */
454 EM_DEBUG_LOG_SEC("found target account id[%d] name[%s]", accounts[i].account_id, accounts[i].incoming_server_user_name);
462 EM_DEBUG_EXCEPTION("EMAIL_ERROR_ACCOUNT_NOT_FOUND");
463 err = EMAIL_ERROR_ACCOUNT_NOT_FOUND;
468 account->account_id = accounts[i].account_id;
469 /* account->flag2 = accounts[i].flag2; */
473 *mailbox = mbox_name ? (char *)mbox_name : NULL;
476 emdaemon_free_account(&accounts, count, NULL);
488 wbxml_parser_destroy(wbxml_parser);
493 emdaemon_free_account(&accounts, count, NULL);
495 EM_SAFE_FREE(incoming_server_user_name);
496 EM_SAFE_FREE(mbox_name);
497 EM_SAFE_FREE(auth_type);
498 EM_SAFE_FREE(time_stamp);
500 EM_DEBUG_FUNC_END("err [%d]", err);
505 static int emdaemon_handle_emn_notification(unsigned char* wbxml_b64, int input_body_lenth)
507 EM_DEBUG_FUNC_BEGIN("wbxml_b64[%p] input_body_lenth[%d]", wbxml_b64, input_body_lenth);
509 int err = EMAIL_ERROR_NONE;
511 char* mailbox_name = NULL;
512 email_account_t account = { 0 };
513 emstorage_mailbox_tbl_t *mailbox_tbl = NULL;
516 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
517 err = EMAIL_ERROR_INVALID_PARAM;
521 if ((err = _get_emn_account(wbxml_b64, input_body_lenth, &account, &mailbox_name)) != EMAIL_ERROR_NONE) {
522 EM_DEBUG_EXCEPTION("_get_emn_account failed [%d]", err);
526 if (account.incoming_server_type == EMAIL_SERVER_TYPE_IMAP4 && mailbox_name) {
527 if (!emstorage_get_mailbox_by_name(multi_user_name, account.account_id, -1, mailbox_name, &mailbox_tbl, false, &err)) {
528 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_name failed [%d", err);
533 if (!emstorage_get_mailbox_by_mailbox_type(multi_user_name, account.account_id, EMAIL_MAILBOX_TYPE_INBOX, &mailbox_tbl, false, &err)) {
534 EM_DEBUG_EXCEPTION("emstorage_get_mailbox_by_mailbox_type failed [%d", err);
539 if (!emdaemon_sync_header(multi_user_name, mailbox_tbl->account_id, mailbox_tbl->mailbox_id, &handle, &err)) {
540 EM_DEBUG_EXCEPTION("emdaemon_sync_header failed [%d]", err);
548 emstorage_free_mailbox(&mailbox_tbl, 1, NULL);
550 EM_DEBUG_FUNC_END("err [%d]", err);
554 void oma_emn_push_cb(msg_handle_t input_handle, const char *input_push_header, const char *input_push_body, int input_push_body_lenth, void *input_user_param)
556 EM_DEBUG_FUNC_BEGIN("input_handle[%d] input_push_header[%p] input_push_body[%p] input_push_body_lenth[%d] input_user_param[%p]", input_handle, input_push_header, input_push_body, input_push_body_lenth, input_user_param);
557 int err = EMAIL_ERROR_NONE;
559 EM_DEBUG_LOG("input_push_header [%s]", input_push_header);
560 EM_DEBUG_LOG("input_push_body [%s]", input_push_body);
561 EM_DEBUG_LOG("input_push_body_lenth [%d]", input_push_body_lenth);
563 if((err = emdaemon_handle_emn_notification((unsigned char*)input_push_body, input_push_body_lenth)) != EMAIL_ERROR_NONE) {
564 EM_DEBUG_EXCEPTION("emdaemon_handle_emn_notification failed [%d]", err);
567 EM_DEBUG_FUNC_END("err [%d]", err);
570 static int emdaemon_register_wap_push_callback(msg_handle_t *input_msg_handle, char *input_app_id)
572 EM_DEBUG_FUNC_BEGIN("input_msg_handle [%p] input_app_id [%p]", input_msg_handle, input_app_id);
573 int err = EMAIL_ERROR_NONE;
574 msg_error_t msg_err = MSG_SUCCESS;
575 msg_struct_t msg_struct = NULL;
576 char *content_type = "application/vnd.wap.emn+wbxml";
577 char *pkg_name = "org.tizen.email";
578 bool bLaunch = false;
580 if(input_msg_handle == NULL || input_app_id == NULL) {
581 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
582 err = EMAIL_ERROR_INVALID_PARAM;
586 msg_struct = msg_create_struct(MSG_STRUCT_PUSH_CONFIG_INFO);
588 if(msg_struct == NULL) {
589 EM_DEBUG_EXCEPTION("msg_create_struct() failed [%d]", msg_err);
590 err = EMAIL_ERROR_INPROPER_RESPONSE_FROM_MSG_SERVICE;
594 msg_set_str_value(msg_struct, MSG_PUSH_CONFIG_CONTENT_TYPE_STR, content_type, MAX_WAPPUSH_CONTENT_TYPE_LEN);
595 msg_set_str_value(msg_struct, MSG_PUSH_CONFIG_APPLICATON_ID_STR, input_app_id, MAX_WAPPUSH_ID_LEN);
596 msg_set_str_value(msg_struct, MSG_PUSH_CONFIG_PACKAGE_NAME_STR, pkg_name, MSG_FILEPATH_LEN_MAX);
597 msg_set_bool_value(msg_struct, MSG_PUSH_CONFIG_LAUNCH_BOOL, bLaunch);
599 msg_add_push_event(*input_msg_handle, msg_struct);
601 if ((msg_err = msg_reg_push_message_callback(*input_msg_handle, &oma_emn_push_cb, input_app_id, NULL)) != MSG_SUCCESS) {
602 EM_DEBUG_EXCEPTION_SEC("msg_reg_push_message_callback() for %s failed [%d]", msg_err, input_app_id);
603 err = EMAIL_ERROR_INPROPER_RESPONSE_FROM_MSG_SERVICE;
610 msg_release_struct(&msg_struct);
612 EM_DEBUG_FUNC_END("err [%d]", err);
617 int emdaemon_initialize_emn(void)
619 EM_DEBUG_FUNC_BEGIN();
621 msg_error_t msg_err = MSG_SUCCESS;
622 msg_handle_t msg_handle = NULL;
623 int err = EMAIL_ERROR_NONE;
624 char *oma_docomo_app_id = "x-oma-docomo:xmd.mail.ua";
625 char *oma_emn_app_id = "x-wap-application:emn.ua";
627 if ((msg_err = msg_open_msg_handle(&msg_handle)) != MSG_SUCCESS) {
628 EM_DEBUG_EXCEPTION("msg_open_msg_handle() failed [%d]", msg_err);
629 err = EMAIL_ERROR_INPROPER_RESPONSE_FROM_MSG_SERVICE;
633 if ((err = emdaemon_register_wap_push_callback(&msg_handle, oma_docomo_app_id)) != EMAIL_ERROR_NONE) {
634 EM_DEBUG_EXCEPTION("emdaemon_register_wap_push_callback() failed [%d]", err);
638 if ((err = emdaemon_register_wap_push_callback(&msg_handle, oma_emn_app_id)) != EMAIL_ERROR_NONE) {
639 EM_DEBUG_EXCEPTION("emdaemon_register_wap_push_callback() failed [%d]", err);
646 EM_DEBUG_FUNC_END("err [%d]", err);
650 int emdaemon_finalize_emn(gboolean bExtDest)
652 EM_DEBUG_FUNC_BEGIN();
657 #endif /* __FEATURE_OMA_EMN__ */