From f41432be2cab10f39c241ecfa80f0e25f5ee639c Mon Sep 17 00:00:00 2001 From: Kim Kibum Date: Sun, 29 Apr 2012 16:58:27 +0900 Subject: [PATCH] upload tizen1.0 source --- AUTHORS | 1 + CMakeLists.txt | 97 ++ LICENSE | 204 +++ capi-messaging-messages.pc.in | 14 + debian/README | 0 debian/capi-messaging-messages-dev.install | 4 + debian/capi-messaging-messages-dev.postinst | 1 + debian/capi-messaging-messages.install | 1 + debian/capi-messaging-messages.postinst | 1 + debian/changelog | 21 + debian/compat | 1 + debian/control | 21 + debian/rules | 69 + include/messages.h | 482 +++++++ include/messages_error.h | 55 + include/messages_private.h | 51 + include/messages_types.h | 147 ++ packaging/capi-messaging-messages.spec | 56 + src/messages.c | 1413 +++++++++++++++++++ test/.messages_search_test.c.swp | Bin 0 -> 12288 bytes test/CMakeLists.txt | 17 + test/messages_search_test.c | 46 + test/messages_send_mms_test.c | 57 + test/messages_send_sms_test.c | 54 + 24 files changed, 2813 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100755 LICENSE create mode 100644 capi-messaging-messages.pc.in create mode 100644 debian/README create mode 100644 debian/capi-messaging-messages-dev.install create mode 100644 debian/capi-messaging-messages-dev.postinst create mode 100644 debian/capi-messaging-messages.install create mode 100644 debian/capi-messaging-messages.postinst create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100755 debian/rules create mode 100644 include/messages.h create mode 100644 include/messages_error.h create mode 100644 include/messages_private.h create mode 100644 include/messages_types.h create mode 100644 packaging/capi-messaging-messages.spec create mode 100644 src/messages.c create mode 100644 test/.messages_search_test.c.swp create mode 100755 test/CMakeLists.txt create mode 100644 test/messages_search_test.c create mode 100644 test/messages_send_mms_test.c create mode 100644 test/messages_send_sms_test.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..b7b0832 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +WonYoung Choi diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..913d03f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,97 @@ + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_name "capi-messaging-messages") + +PROJECT(${fw_name}) + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +SET(INC_DIR include) +INCLUDE_DIRECTORIES(${INC_DIR}) + +SET(dependents "dlog glib-2.0 msg-service capi-base-common") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_name} REQUIRED ${dependents}) +FOREACH(flag ${${fw_name}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +IF("${ARCH}" STREQUAL "arm") + ADD_DEFINITIONS("-DTARGET") +ENDIF("${ARCH}" STREQUAL "arm") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DTIZEN_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +aux_source_directory(src SOURCES) +ADD_LIBRARY(${fw_name} SHARED ${SOURCES}) + +TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS}) + +SET_TARGET_PROPERTIES(${fw_name} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 +) + +INSTALL(TARGETS ${fw_name} DESTINATION lib) +INSTALL( + DIRECTORY ${INC_DIR}/ DESTINATION include/messaging + FILES_MATCHING + PATTERN "*_private.h" EXCLUDE + PATTERN "${INC_DIR}/*.h" +) + +SET(PC_NAME ${fw_name}) +SET(PC_REQUIRED ${dependents}) +SET(PC_LDFLAGS -l${fw_name}) +SET(PC_CFLAGS -I\${includedir}/messaging) + +CONFIGURE_FILE( + ${fw_name}.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc + @ONLY +) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig) + +ADD_SUBDIRECTORY(test) + +IF(UNIX) + +ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution) +ADD_CUSTOM_COMMAND( + DEPENDS clean + COMMENT "distribution clean" + COMMAND find + ARGS . + -not -name config.cmake -and \( + -name tester.c -or + -name Testing -or + -name CMakeFiles -or + -name cmake.depends -or + -name cmake.check_depends -or + -name CMakeCache.txt -or + -name cmake.check_cache -or + -name *.cmake -or + -name Makefile -or + -name core -or + -name core.* -or + -name gmon.out -or + -name install_manifest.txt -or + -name *.pc -or + -name *~ \) + | grep -v TC | xargs rm -rf + TARGET distclean + VERBATIM +) + +ENDIF(UNIX) + diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..9c13a9b --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/capi-messaging-messages.pc.in b/capi-messaging-messages.pc.in new file mode 100644 index 0000000..a771af9 --- /dev/null +++ b/capi-messaging-messages.pc.in @@ -0,0 +1,14 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=/usr/lib +includedir=/usr/include + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: -I${includedir} @PC_CFLAGS@ + diff --git a/debian/README b/debian/README new file mode 100644 index 0000000..e69de29 diff --git a/debian/capi-messaging-messages-dev.install b/debian/capi-messaging-messages-dev.install new file mode 100644 index 0000000..8e40cf3 --- /dev/null +++ b/debian/capi-messaging-messages-dev.install @@ -0,0 +1,4 @@ +/usr/include/* +/usr/include/*/* +/usr/lib/pkgconfig/*.pc +/usr/lib/lib*.so diff --git a/debian/capi-messaging-messages-dev.postinst b/debian/capi-messaging-messages-dev.postinst new file mode 100644 index 0000000..1a24852 --- /dev/null +++ b/debian/capi-messaging-messages-dev.postinst @@ -0,0 +1 @@ +#!/bin/sh diff --git a/debian/capi-messaging-messages.install b/debian/capi-messaging-messages.install new file mode 100644 index 0000000..eeaf559 --- /dev/null +++ b/debian/capi-messaging-messages.install @@ -0,0 +1 @@ +/usr/lib/lib*.so.* diff --git a/debian/capi-messaging-messages.postinst b/debian/capi-messaging-messages.postinst new file mode 100644 index 0000000..1a24852 --- /dev/null +++ b/debian/capi-messaging-messages.postinst @@ -0,0 +1 @@ +#!/bin/sh diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..932b411 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,21 @@ +capi-messaging-messages (0.1.0-3) unstable; urgency=low + + * fix messages_search_cb() callback. + * Git: slp/api/messages + * Tag: capi-messaging-messages_0.1.0-3 + + -- WonYoung Choi Thu, 05 Apr 2012 19:00:23 +0900 + +capi-messaging-messages (0.1.0-2) unstable; urgency=low + + * fix bugs, added DTS. + * Git: slp/api/messages + * Tag: capi-messaging-messages_0.1.0-2 + + -- WonYoung Choi Mon, 02 Apr 2012 17:17:52 +0900 + +capi-messaging-messages (0.1.0-1) unstable; urgency=low + + * Initial release. + + -- WonYoung Choi Thu, 08 Mar 2012 15:04:37 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..0cc178c --- /dev/null +++ b/debian/control @@ -0,0 +1,21 @@ +Source: capi-messaging-messages +Section: libs +Priority: extra +Maintainer: WonYoung Choi +Build-Depends: debhelper (>= 5), dlog-dev, libglib2.0-dev, libslp-msg-service-dev, capi-base-common-dev + +Package: capi-messaging-messages +Architecture: any +Depends: ${shilbs:Depends}, ${misc:Depends} +Description: A SMS/MMS library in Tizen Native API + +Package: capi-messaging-messages-dev +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, capi-messaging-messages (= ${Source-Version}), dlog-dev, libglib2.0-dev, libslp-msg-service-dev, capi-base-common-dev +Description: A SMS/MMS library in Tizen Native API (DEV) + +Package: capi-messaging-messages-dbg +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, capi-messaging-messages (= ${Source-Version}) +Description: A SMS/MMS library in Tizen Native API (DBG) + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..5d29f0d --- /dev/null +++ b/debian/rules @@ -0,0 +1,69 @@ +#!/usr/bin/make -f + +FULLVER ?= $(shell dpkg-parsechangelog | grep Version: | cut -d ' ' -f 2 | cut -d '-' -f 1) +MAJORVER ?= $(shell echo $(FULLVER) | cut -d '.' -f 1) + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif +CMAKE_ROOT_DIR ?= $(CURDIR) +CMAKE_BUILD_DIR ?= $(CURDIR)/cmake_build_tmp + +configure: configure-stamp +configure-stamp: + dh_testdir + mkdir -p $(CMAKE_BUILD_DIR) && cd $(CMAKE_BUILD_DIR) && cmake .. -DFULLVER=${FULLVER} -DMAJORVER=${MAJORVER} + + touch configure-stamp + + +build: build-stamp +build-stamp: configure-stamp + dh_testdir + cd $(CMAKE_BUILD_DIR) && $(MAKE) + touch $@ + +clean: + cd $(CMAKE_ROOT_DIR) + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + rm -f `find . -name *.pc` + rm -rf $(CMAKE_BUILD_DIR) + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + cd $(CMAKE_BUILD_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + +binary-indep: build install + +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_install --sourcedir=debian/tmp + dh_installman + dh_link + dh_strip --dbg-package=capi-messaging-messages-dbg + dh_fixperms + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure + diff --git a/include/messages.h b/include/messages.h new file mode 100644 index 0000000..6529dea --- /dev/null +++ b/include/messages.h @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TIZEN_MESSAGING_H__ +#define __TIZEN_MESSAGING_H__ + + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @addtogroup TIZEN_MESSAGING_MODULE + * @{ + */ + + +/** + * @brief Opens a handle for messaging service. + * + * @remark @a service must be released with messages_close_service() by you. + * + * @param[out] service The message service handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_SERVER_NOT_READY Server is not read + * @retval #MESSAGES_ERROR_COMMUNICATION_WITH_SERVER_FAILED Communication with server failed + * + * @see messages_close_service() + */ +int messages_open_service(messages_service_h *service); + + +/** + * @brief Closes a handle for messaging service. + * + * @param[in] service The message service handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_COMMUNICATION_WITH_SERVER_FAILED Communication with server failed + * + * @see messages_open_service() + */ +int messages_close_service(messages_service_h service); + + +/** + * @brief Creates a message handle. + * + * @remark @a msg must be released with messages_destroy_message() by you. + * + * @param[in] type A message type (MESSAGES_TYPE_SMS or MESSAGES_TYPE_MMS) \n + * If @a type is #MESSAGES_TYPE_UNKNOWN, #MESSAGES_ERROR_INVALID_PARAMETER occurs. + * @param[out] msg A message handle to be newly created if successful + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OUT_OF_MEMORY Out of memory + * + * @see messages_destroy_message() + */ +int messages_create_message(messages_message_type_e type, messages_message_h *msg); + + +/** + * @brief Destroys a message handle and release all its resources. + * + * @param[in] msg A message handle to destroy + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see messages_create_message() + */ +int messages_destroy_message(messages_message_h msg); + + +/** + * @brief Gets the type of the message. + * + * @param[in] msg The message handle + * @param[out] type The message type + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see messages_create_message() + */ +int messages_get_message_type(messages_message_h msg, messages_message_type_e *type); + + +/** + * @brief Adds an recipient's address(phone number) to the message. + * @details The maximum number of recipients per a message is 10. + * + * @param[in] msg The message handle + * @param[in] address The recipient's address to receive a message \n + * The maximum length of @a address is 254. + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see messages_get_address() + * @see messages_remove_all_addresses() + */ +int messages_add_address(messages_message_h msg, const char *address); + + +/** + * @brief Gets the total number of recipients in the message. + * + * @param[in] msg The message handle + * @param[out] count The total number of recipients + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see messages_add_address() + * @see messages_remove_all_addresses() + */ +int messages_get_address_count(messages_message_h msg, int *count); + + +/** + * @brief Gets a recipient's address with specified index. + * + * @remarks @a address must be released with @c free() by you. + * + * @param[in] msg The message handle + * @param[in] index The zero-based index of address to receive a message. + * @param[out] address The recipient's address with specified index + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OUT_OF_MEMORY Out of memory + * + * @see messages_add_address() + * @see messages_remove_all_addresses() + */ +int messages_get_address(messages_message_h msg, int index, char **address); + + +/** + * @brief Removes all recipients in the message. + * + * @param[in] msg The message handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see messages_add_address() + * @see messages_get_address() + */ +int messages_remove_all_addresses(messages_message_h msg); + + +/** + * @brief Sets the text of the message. + * + * @param[in] msg The message handle + * @param[in] text The text of the message \n + * The maximum length of @a text is 1530. + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OUT_OF_MEMORY Out of memory + * + * @see messages_get_text() + */ +int messages_set_text(messages_message_h msg, const char *text); + + +/** + * @brief Gets the text of the message. + * + * @remarks @a text must be released with @c free() by you. + * + * @param[in] msg The message handle + * @param[out] text The text of the message + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OUT_OF_MEMORY Out of memory + * + * @see messages_set_text() + */ +int messages_get_text(messages_message_h msg, char **text); + + +/** + * @brief Sends the message to all recipients. + * + * @remarks In order to check whether sending a message succeeds, + * you should register messages_sent_cb() using messages_set_message_sent_cb(). + * + * @param[in] service The message service handle + * @param[in] msg The message handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_SENDING_FAILED Sending a message failed + * @retval #MESSAGES_ERROR_OPERATION_FAILED Messaging operation failed + * + * @see messages_sent_cb() + */ +int messages_send_message(messages_service_h service, messages_message_h msg); + + +/** + * @brief Searches for messages. + * + * @param[in] service The message service handle + * @param[in] mbox The message box type + * @param[in] type The message type \n + * If @a type is #MESSAGES_TYPE_UNKNOWN, all sms and mms messages are searched. + * @param[in] keyword The keyword search in text and subject + * @param[in] address The recepient address + * @param[in] offset The start position (base 0) + * @param[in] limit The maximum amount of messages to get (In case of 0, this method passes to thecallback all searched messages.) + * @param[in] callback The callback function to get a message + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGES_ERROR_OPERATION_FAILED Messaging operation failed + * + * @post It invokes messages_search_cb(). + * @see messages_search_cb() + */ +int messages_foreach_message_from_db(messages_service_h service, + messages_message_box_e mbox, + messages_message_type_e type, + const char *keyword, const char *address, + int offset, int limit, + messages_search_cb callback, void *user_data); + +/** + * @brief Registers a callback to be invoked when a message is sent. + * + * @details You will be notified when sending a message finishes and check whether it succeeds using messages_sent_cb(). + * + * @param[in] service The message service handle + * @param[in] callback The callback function + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OPERATION_FAILED Messaging operation failed + * + * @post It will invoke messages_sent_cb(). + * + * @see messages_unset_message_sent_cb() + * @see messages_sent_cb() + */ +int messages_set_message_sent_cb(messages_service_h service, messages_sent_cb callback, void *user_data); + + +/** + * @brief Unregisters the callback function. + * + * @param[in] service The message service handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @post It will invoke messages_sent_cb(). + * + * @see messages_set_message_sent_cb() + * @see messages_sent_cb() + */ +int messages_unset_message_sent_cb(messages_service_h service); + + +/** + * @brief Registers a callback to be invoked when an incoming message is received. + * + * @param[in] service The message service handle + * @param[in] callback The callback function + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OPERATION_FAILED Messaging operation failed + * + * @post It will invoke messages_incoming_cb(). + * + * @see messages_unset_message_incoming_cb() + * @see messages_incoming_cb() + */ +int messages_set_message_incoming_cb(messages_service_h service, messages_incoming_cb callback, void *user_data); + + +/** + * @brief Unregisters the callback function. + * + * @param[in] service The message service handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see messages_set_message_incoming_cb() + * @see messages_incoming_cb() + */ +int messages_unset_message_incoming_cb(messages_service_h service); + + +/** + * @addtogroup TIZEN_MESSAGING_MMS_MODULE + * @{ + */ +/** + * @brief Sets the subject of the message. + * + * @param[in] msg The message handle + * @param[in] subject The subject of the message \n + * The maximum length of @a subject is 120. + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre @a msg is created as a #MESSAGES_TYPE_MMS. + * + * @see messages_mms_get_subject() + */ +int messages_mms_set_subject(messages_message_h msg, const char *subject); + + +/** + * @brief Gets the subject of the message. + * + * @remarks @a subject must be released with @c free() by you. + * + * @param[in] msg The message handle + * @param[out] subject The subject of the message + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OUT_OF_MEMORY Out of memory + * + * @pre @a msg is created as a #MESSAGES_TYPE_MMS. + * + * @see messages_mms_set_subject() + */ +int messages_mms_get_subject(messages_message_h msg, char **subject); + + +/** + * @brief Adds the attachment to the MMS message. + * + * @param[in] msg The message handle + * @param[in] type The attachment type + * @param[in] path The file path to attach \n + * The maximum length of @a path is 1024. + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OUT_OF_MEMORY Out of memory + * + * @pre @a msg is created as a #MESSAGES_TYPE_MMS. + * + * @see messages_mms_get_attachment() + * @see messages_mms_get_attachment_count() + * @see messages_mms_remove_all_attachments() + */ +int messages_mms_add_attachment(messages_message_h msg, messages_media_type_e type, const char *path); + + +/** + * @brief Gets the file path of the attachment with the specified index. + * + * @remark @a path must be released with @c free() by you. + * + * @param[in] msg The message handle + * @param[in] index The zero-based index of attachment + * @param[out] type The attachment type + * @param[out] path The file path to attach + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGES_ERROR_OUT_OF_MEMORY Out of memory + * + * @pre @a msg is created as a #MESSAGES_TYPE_MMS. + * + * @see messages_mms_add_attachment() + * @see messages_mms_get_attachment_count() + * @see messages_mms_remove_all_attachments() + */ +int messages_mms_get_attachment(messages_message_h msg, int index, messages_media_type_e *type, char **path); + + +/** + * @brief Gets the attachment with the specified index. + * + * @param[in] msg The message handle + * @param[out] count The total number of attachments + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre @a msg is created as a #MESSAGES_TYPE_MMS. + * + * @see messages_mms_add_attachment() + * @see messages_mms_get_attachment() + * @see messages_mms_remove_all_attachments() + */ +int messages_mms_get_attachment_count(messages_message_h msg, int *count); + + +/** + * @brief Removes all attachments to the MMS message. + * + * @param[in] msg The message handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGES_ERROR_NONE Successful + * @retval #MESSAGES_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre @a msg is created as a #MESSAGES_TYPE_MMS. + * + * @see messages_mms_add_attachment() + * @see messages_mms_get_attachment() + * @see messages_mms_get_attachment_count() + */ +int messages_mms_remove_all_attachments(messages_message_h msg); +/** + * @} + */ + +/** + * @} + */ + + + +#ifdef __cplusplus +} +#endif + + +#endif /* __TIZEN_MESSAGING_H__ */ diff --git a/include/messages_error.h b/include/messages_error.h new file mode 100644 index 0000000..c42781e --- /dev/null +++ b/include/messages_error.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TIZEN_MESSAGING_ERROR_H__ +#define __TIZEN_MESSAGING_ERROR_H__ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** + * @addtogroup TIZEN_MESSAGING_MODULE + * @{ + */ + + +/** + * @brief Enumerations of error code for Messaging. + */ +typedef enum { + MESSAGES_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + MESSAGES_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + MESSAGES_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + MESSAGES_ERROR_SERVER_NOT_READY = TIZEN_ERROR_MESSAGING_CLASS|0x501, /**< Server is not read */ + MESSAGES_ERROR_COMMUNICATION_WITH_SERVER_FAILED = TIZEN_ERROR_MESSAGING_CLASS|0x502, /**< Communication with server failed */ + MESSAGES_ERROR_SENDING_FAILED = TIZEN_ERROR_MESSAGING_CLASS|0x504, /**< Sending a message failed */ + MESSAGES_ERROR_OPERATION_FAILED = TIZEN_ERROR_MESSAGING_CLASS|0x505, /**< Messaging operation failed */ +} MESSAGES_error_e; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_MESSAGING_ERROR_H__ */ diff --git a/include/messages_private.h b/include/messages_private.h new file mode 100644 index 0000000..33759c9 --- /dev/null +++ b/include/messages_private.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TIZEN_MESSAGING_PRIVATE_H__ +#define __TIZEN_MESSAGING_PRIVATE_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct _messages_service_s { + MSG_HANDLE_T service_h; + void* sent_cb; + void* sent_cb_user_data; + bool sent_cb_enabled; + void* incoming_cb; + void* incoming_cb_user_data; + bool incoming_cb_enabled; +} messages_service_s; + +typedef struct _messages_message_s { + msg_message_t msg_h; + char *text; + GSList *attachment_list; +} messages_message_s; + +typedef struct _messages_attachment_s { + int media_type; + char filepath[MSG_FILEPATH_LEN_MAX]; +} messages_attachment_s; + + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_MESSAGING_PRIVATE_H__ */ diff --git a/include/messages_types.h b/include/messages_types.h new file mode 100644 index 0000000..a2efcba --- /dev/null +++ b/include/messages_types.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TIZEN_MESSAGING_TYPES_H__ +#define __TIZEN_MESSAGING_TYPES_H__ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @addtogroup TIZEN_MESSAGING_MODULE + * @{ + */ + +/** + * @brief The messaging service handle. + */ +typedef struct messages_service_s *messages_service_h; + + +/** + * @brief The message handle. + */ +typedef struct messages_message_s *messages_message_h; + + +/** + * @brief The message box type. + */ +typedef enum { + MESSAGES_MBOX_ALL = 0, /**< All message box type */ + MESSAGES_MBOX_INBOX = 1, /**< Inbox type */ + MESSAGES_MBOX_OUTBOX = 2, /**< Outbox type*/ + MESSAGES_MBOX_SENTBOX = 3, /**< Sentbox type */ + MESSAGES_MBOX_DRAFT = 4, /**< Draft type */ +} messages_message_box_e; + + +/** + * @brief The message type. + */ +typedef enum { + MESSAGES_TYPE_UNKNOWN = 0, /**< Unknown type */ + MESSAGES_TYPE_SMS = 1, /**< SMS type */ + MESSAGES_TYPE_MMS = 2, /**< MMS type */ +} messages_message_type_e; + + +/** + * @brief The attachment type for MMS messaging. + */ +typedef enum { + MESSAGES_MEDIA_UNKNOWN = 0, /**< Unknown */ + MESSAGES_MEDIA_IMAGE = 1, /**< The image */ + MESSAGES_MEDIA_AUDIO = 2, /**< The audio */ + MESSAGES_MEDIA_VIDEO = 3, /**< The video */ +} messages_media_type_e; + + +/** + * @brief The result of sending a message. + */ +typedef enum { + MESSAGES_SENDING_FAILED = -1, /**< Message sending is failed */ + MESSAGES_SENDING_SUCCEEDED = 0, /**< Message sending is succeeded */ +} messages_sending_result_e; + + + +/** + * @brief Called when the process of sending a message to all recipients finishes. + * + * @param[in] result The result of message sending. + * @param[in] user_data The user data passed from the callback registration function + * + * @pre messages_send_message() will invoke this callback if you register this callback using messages_set_message_sent_cb(). + * + * @see messages_set_message_sent_cb() + * @see messages_unset_message_sent_cb() + * @see messages_send_message() + */ +typedef void (* messages_sent_cb)(messages_sending_result_e result, void *user_data); + + +/** + * @brief Called when an incoming message is received. + * + * @param[in] incoming_msg An incoming message + * @param[in] user_data The user data passed from the callback registration function + * + * @pre You register this callback using messages_set_message_incoming_cb() for getting an incoming message. + * + * @see messages_set_message_incoming_cb() + * @see messages_unset_message_incoming_cb() + */ +typedef void (* messages_incoming_cb)(messages_message_h incoming_msg, void *user_data); + + +/** + * @brief Called when a message is retrieved from a search request. + * + * @remark You should not call messages_destroy_message() with @a msg. + * + * @param[in] msg The message handle (It can be NULL if nothing is found) + * @param[in] user_data The user data passed from the foreach function + * @param[in] index The index of a message from the messages that have been retrieved as a search result + * @param[in] result_count The count of the messages that have been retrieved as a result applying @a limit and @a offset.\n + * If the search has a @a limit, then this value is always equal or less than the limit. + * @param[in] total_count The count of the messages that have been retrieved as a result without applying @a limit and @a offset. \n + * The value can be used to calculate the total number of page views for the searched meessages.\n + * For example, if the count of message search is 50 and the limit is 20, then using this value, you can notice the total page is 3. + * + * @return @c true to continue with the next iteration of the loop or return @c false to break out of the loop. + * + * @pre messages_foreach_message_from_db() will invoke this callback function. + * + * @see messages_foreach_message_from_db() + */ +typedef bool (* messages_search_cb)(messages_message_h msg, int index, int result_count, int total_count, void *user_data); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_MESSAGING_TYPES_H__ */ diff --git a/packaging/capi-messaging-messages.spec b/packaging/capi-messaging-messages.spec new file mode 100644 index 0000000..1ee5ca0 --- /dev/null +++ b/packaging/capi-messaging-messages.spec @@ -0,0 +1,56 @@ +Name: capi-messaging-messages +Summary: A SMS/MMS library in Tizen Native API +Version: 0.1.0 +Release: 3 +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(msg-service) +BuildRequires: pkgconfig(capi-base-common) +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description + + +%package devel +Summary: A SMS/MMS library in Tizen Native API (Development) +Requires: %{name} = %{version}-%{release} +Requires: pkgconfig(msg-service) +Requires: pkgconfig(capi-base-common) + +%description devel + + + +%prep +%setup -q + + +%build +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} + + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + + +%files +%{_libdir}/libcapi-messaging-messages.so.* + +%files devel +%{_includedir}/messaging/*.h +%{_libdir}/pkgconfig/*.pc +%{_libdir}/libcapi-messaging-messages.so + + diff --git a/src/messages.c b/src/messages.c new file mode 100644 index 0000000..b46dbd8 --- /dev/null +++ b/src/messages.c @@ -0,0 +1,1413 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "CAPI_MESSAGING" +#define DBG_MODE (1) + +#define MAX_MESSAGES_TEXT_LEN 1530 + +/* Private Utility Functions */ +int _messages_error_converter(int err, const char *func, int line); +int _messages_get_media_type_from_filepath(const char *filepath); +int _messages_save_mms_data(messages_message_s *msg); +int _messages_load_mms_data(messages_message_s *msg, MSG_HANDLE_T handle); +int _messages_save_textfile(const char *text, char **filepath); +int _messages_load_textfile(const char *filepath, char **text); +MSG_FOLDER_ID_T _messages_convert_mbox_to_fw(messages_message_box_e mbox); +MSG_MESSAGE_TYPE_T _messages_convert_msgtype_to_fw(messages_message_type_e type); + + +#define ERROR_CONVERT(err) _messages_error_converter(err, __FUNCTION__, __LINE__); +#define CHECK_NULL(p) \ + if (NULL == p) { \ + LOGE("[%s] INVALID_PARAMETER(0x%08x) %s is null.", \ + __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER, #p); \ + return MESSAGES_ERROR_INVALID_PARAMETER; \ + } + + + + + +int messages_open_service(messages_service_h *svc) +{ + int ret; + messages_service_s *_svc; + + CHECK_NULL(svc); + + _svc = (messages_service_s*)calloc(1, sizeof(messages_service_s)); + if (NULL == svc) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create a 'svc'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + + _svc->sent_cb = NULL; + _svc->sent_cb_user_data = NULL; + _svc->sent_cb_enabled = false; + + ret = msg_open_msg_handle(&_svc->service_h); + + *svc = (messages_service_h)_svc; + + return ERROR_CONVERT(ret); +} + +int messages_close_service(messages_service_h svc) +{ + int ret; + + ret = msg_close_msg_handle(&((messages_service_s*)svc)->service_h); + + free(svc); + + return ERROR_CONVERT(ret); +} + +int messages_create_message(messages_message_type_e type, messages_message_h *msg) +{ + int ret; + messages_message_s *_msg = NULL; + + CHECK_NULL(msg); + + _msg = (messages_message_s*)calloc(1, sizeof(messages_message_s)); + if (NULL == _msg) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create '_msg'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + + _msg->msg_h = msg_new_message(); + if (NULL == _msg->msg_h) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create '_msg->msg_h'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + free(_msg); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + + _msg->text = NULL; + _msg->attachment_list = NULL; + + if (MESSAGES_TYPE_SMS == type) + { + ret = ERROR_CONVERT(msg_set_message_type(_msg->msg_h, MSG_TYPE_SMS)); + if (MESSAGES_ERROR_NONE != ret) + { + msg_release_message(&_msg->msg_h); + free(_msg); + return ret; + } + } + else if (MESSAGES_TYPE_MMS == type) + { + ret = ERROR_CONVERT(msg_set_message_type(_msg->msg_h, MSG_TYPE_MMS)); + if (MESSAGES_ERROR_NONE != ret) + { + msg_release_message(&_msg->msg_h); + free(_msg); + return ret; + } + } + else + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : the message type is unknown." + , __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER); + msg_release_message(&_msg->msg_h); + free(_msg); + return MESSAGES_ERROR_INVALID_PARAMETER; + } + + *msg = (messages_message_h)_msg; + + return MESSAGES_ERROR_NONE; +} + +int messages_destroy_message(messages_message_h msg) +{ + int ret; + + messages_message_s *_msg = (messages_message_s*)msg; + + CHECK_NULL(_msg); + + messages_mms_remove_all_attachments(msg); + if (_msg->text) + { + free(_msg->text); + _msg->text = NULL; + } + + ret = msg_release_message(&_msg->msg_h); + + free(msg); + + return ERROR_CONVERT(ret); +} + +int messages_get_message_type(messages_message_h msg, messages_message_type_e *type) +{ + int msgType; + + messages_message_s *_msg = (messages_message_s*)msg; + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(type); + + msgType = msg_get_message_type(_msg->msg_h); + + switch (msgType) + { + case MSG_TYPE_SMS: + case MSG_TYPE_SMS_CB: + case MSG_TYPE_SMS_JAVACB: + case MSG_TYPE_SMS_WAPPUSH: + case MSG_TYPE_SMS_MWI: + case MSG_TYPE_SMS_SYNCML: + case MSG_TYPE_SMS_REJECT: + *type = MESSAGES_TYPE_SMS; + break; + case MSG_TYPE_MMS: + case MSG_TYPE_MMS_NOTI: + case MSG_TYPE_MMS_JAVA: + *type = MESSAGES_TYPE_MMS; + break; + default: + *type = MESSAGES_TYPE_UNKNOWN; + break; + } + + return MESSAGES_ERROR_NONE; +} + +int messages_add_address(messages_message_h msg, const char *address) +{ + int ret; + + messages_message_s *_msg = (messages_message_s*)msg; + + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(address); + + ret = msg_add_address(_msg->msg_h, address, MSG_RECIPIENTS_TYPE_TO); + + return ERROR_CONVERT(ret); +} + +int messages_get_address_count(messages_message_h msg, int *count) +{ + messages_message_s *_msg = (messages_message_s*)msg; + + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(count); + + *count = msg_get_address_count(_msg->msg_h); + + return MESSAGES_ERROR_NONE; +} + +int messages_get_address(messages_message_h msg, int index, char **address) +{ + const char *_address; + + messages_message_s *_msg = (messages_message_s*)msg; + + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(address); + + _address = msg_get_ith_address(_msg->msg_h, index); + if (NULL == _address) + { + *address = NULL; + } + else + { + *address = strdup(_address); + if (NULL == *address) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create a '*address'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + } + + return MESSAGES_ERROR_NONE; +} + +int messages_remove_all_addresses(messages_message_h msg) +{ + int ret; + + messages_message_s *_msg = (messages_message_s*)msg; + + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + + ret = msg_reset_address(_msg->msg_h); + + return ERROR_CONVERT(ret); +} + +void _dump_message(messages_message_h msg) +{ + int ret; + //messages_message_s *_msg = (messages_message_s*)msg; + + messages_message_type_e msgType; + char *buf; + int i, count; + + + + LOGD("======================================================="); + // type + ret = messages_get_message_type(msg, &msgType); + if (MESSAGES_ERROR_NONE == ret) { + switch(msgType) { + case MESSAGES_TYPE_SMS: LOGD("Type: SMS"); break; + case MESSAGES_TYPE_MMS: LOGD("Type: MMS"); break; + default: LOGD("Type: Unknown (%d)", msgType); break; + } + } else { + LOGD("Type: Err (%d)", ret); + } + + // text + ret = messages_get_text(msg, &buf); + if (MESSAGES_ERROR_NONE == ret) { + LOGD("Text: %s", buf); + free(buf); + } else { + LOGD("Text: Err (%d)", ret); + } + + // address + ret = messages_get_address_count(msg, &count); + if (MESSAGES_ERROR_NONE == ret) { + LOGD("Address_Count: %d", count); + for (i=0; i < count; i++) { + ret = messages_get_address(msg, i, &buf); + if (MESSAGES_ERROR_NONE == ret) { + LOGD("Address[%d]: %s", i, buf); + free(buf); + } else { + LOGD("Address[%d]: Err (%d)", ret); + } + } + } else { + LOGD("Address Count: Err (%d)", ret); + } + +} + +int messages_send_message(messages_service_h svc, messages_message_h msg) +{ + int ret; + MSG_REQUEST_S req = {0}; + messages_message_type_e msgType; + + messages_service_s *_svc = (messages_service_s*)svc; + messages_message_s *_msg = (messages_message_s*)msg; + + CHECK_NULL(_svc); + CHECK_NULL(_svc->service_h); + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + + req.msg = (msg_message_t)_msg->msg_h; + + messages_get_message_type(msg, &msgType); + + if (MESSAGES_TYPE_SMS == msgType) + { + ret = msg_sms_send_message(_svc->service_h, &req); + } + else if (MESSAGES_TYPE_MMS == msgType) + { + ret = _messages_save_mms_data(_msg); + if (MESSAGES_ERROR_NONE == ret) + { + if (DBG_MODE) + { + _dump_message(msg); + } + ret = msg_mms_send_message(_svc->service_h, &req); + } + } + else + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : Invalid Message Type.", + __FUNCTION__, TIZEN_ERROR_INVALID_PARAMETER); + return TIZEN_ERROR_INVALID_PARAMETER; + } + + return ERROR_CONVERT(ret); +} + +int messages_foreach_message_from_db(messages_service_h svc, + messages_message_box_e mbox, + messages_message_type_e type, + const char *keyword, const char *address, + int offset, int limit, + messages_search_cb callback, void *user_data) +{ + int i; + int ret; + bool ret_cb; + + MSG_LIST_S msg_list; + MSG_SEARCH_CONDITION_S searchCon; + messages_message_type_e _msgType; + + messages_service_s *_svc = (messages_service_s*)svc; + messages_message_s *_msg = NULL; + + CHECK_NULL(_svc); + CHECK_NULL(callback); + + // Set Condition + searchCon.folderId = _messages_convert_mbox_to_fw(mbox); + searchCon.msgType = _messages_convert_msgtype_to_fw(type); + searchCon.pSearchVal = NULL == keyword ? NULL : strdup(keyword); + searchCon.pAddressVal = NULL == address ? NULL : strdup(address); + + ret = msg_search_message(_svc->service_h, &searchCon, offset, limit, &msg_list); + if (MSG_SUCCESS != ret) + { + return ERROR_CONVERT(ret); + } + + for (i=0; i < msg_list.nCount; i++) + { + _msg = (messages_message_s*)calloc(1, sizeof(messages_message_s)); + _msg->text = NULL; + _msg->attachment_list = NULL; + if (NULL == _msg) + { + LOGE("[%s:%d] OUT_OF_MEMORY(0x%08x) fail to create '_msg'." + , __FUNCTION__, __LINE__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + + _msg->msg_h = msg_list.msgInfo[i]; + + messages_get_message_type((messages_message_h)_msg, &_msgType); + + if (MESSAGES_TYPE_MMS == _msgType) + { + // TODO: Well... performance issue. + // Shoud I load mms data at here? + _messages_load_mms_data(_msg, _svc->service_h); + } + + // do callback + // TODO: total count is not supported yet. + ret_cb = callback((messages_message_h)_msg, i, msg_list.nCount, -1, user_data); + + messages_mms_remove_all_attachments((messages_message_h)_msg); + msg_release_message(&_msg->msg_h); + free(_msg); + + if (false == ret_cb) + { + break; + } + } + + return MESSAGES_ERROR_NONE; +} + +void _messages_sent_mediator_cb(MSG_HANDLE_T handle, MSG_SENT_STATUS_S *pStatus, void *user_param) +{ + messages_sending_result_e ret; + messages_service_s *_svc = (messages_service_s*)user_param; + + if (NULL == _svc) + { + return; + } + + if (_svc->sent_cb_enabled && _svc->sent_cb != NULL) + { + ret = (pStatus->status == MSG_NETWORK_SEND_SUCCESS) ? + MESSAGES_SENDING_SUCCEEDED : MESSAGES_SENDING_FAILED; + ((messages_sent_cb)_svc->sent_cb)(ret, _svc->sent_cb_user_data); + } +} + +int messages_set_message_sent_cb(messages_service_h svc, messages_sent_cb callback, void *user_data) +{ + int ret; + + messages_service_s *_svc = (messages_service_s*)svc; + + CHECK_NULL(_svc); + CHECK_NULL(callback); + + if (NULL == _svc->sent_cb) + { + ret = ERROR_CONVERT( + msg_reg_sent_status_callback(_svc->service_h, &_messages_sent_mediator_cb, (void*)_svc) + ); + if (MESSAGES_ERROR_NONE != ret) + { + return ret; + } + } + + _svc->sent_cb = (void*)callback; + _svc->sent_cb_user_data = (void*)user_data; + _svc->sent_cb_enabled = true; + + return MESSAGES_ERROR_NONE; +} + +int messages_unset_message_sent_cb(messages_service_h svc) +{ + messages_service_s *_svc = (messages_service_s*)svc; + + CHECK_NULL(_svc); + + _svc->sent_cb_enabled = false; + + return MESSAGES_ERROR_NONE; +} + +void _messages_incoming_mediator_cb(MSG_HANDLE_T handle, msg_message_t msg, void *user_param) +{ + messages_message_type_e msgType; + messages_message_s *_msg; + messages_service_s *_svc = (messages_service_s*)user_param; + + if (NULL == _svc) + { + return; + } + + if (_svc->incoming_cb_enabled && _svc->incoming_cb != NULL) + { + _msg = (messages_message_s*)calloc(1, sizeof(messages_message_s)); + if (NULL == _msg) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create '_msg'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return; + } + + _msg->msg_h = msg; + + messages_get_message_type((messages_message_h)_msg, &msgType); + + if (MESSAGES_TYPE_MMS == msgType) + { + _messages_load_mms_data(_msg, handle); + } + + ((messages_incoming_cb)_svc->incoming_cb)((messages_message_h)_msg, _svc->incoming_cb_user_data); + + free(_msg); + } +} + +int messages_set_message_incoming_cb(messages_service_h svc, messages_incoming_cb callback, void *user_data) +{ + int ret; + + messages_service_s *_svc = (messages_service_s*)svc; + + CHECK_NULL(_svc); + CHECK_NULL(callback); + + if (NULL == _svc->incoming_cb) + { + ret = ERROR_CONVERT( + msg_reg_sms_message_callback(_svc->service_h, &_messages_incoming_mediator_cb, 0, (void*)_svc) + ); + if (MESSAGES_ERROR_NONE != ret) + { + return ret; + } + + ret = ERROR_CONVERT( + msg_reg_mms_conf_message_callback(_svc->service_h, &_messages_incoming_mediator_cb, NULL, (void*)_svc) + ); + if (MESSAGES_ERROR_NONE != ret) + { + return ret; + } + } + + _svc->incoming_cb = (void*)callback; + _svc->incoming_cb_user_data = (void*)user_data; + _svc->incoming_cb_enabled = true; + + return MESSAGES_ERROR_NONE; +} + +int messages_unset_message_incoming_cb(messages_service_h svc) +{ + messages_service_s *_svc = (messages_service_s*)svc; + + CHECK_NULL(_svc); + + _svc->incoming_cb_enabled = false; + + return MESSAGES_ERROR_NONE; +} + +int messages_set_text(messages_message_h msg, const char *text) +{ + int ret; + int len; + messages_message_type_e type; + + messages_message_s *_msg = (messages_message_s*)msg; + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(text); + + ret = messages_get_message_type(msg, &type); + if (MESSAGES_ERROR_NONE != ret) { + return ret; + } + + if (MESSAGES_TYPE_SMS == type) + { + len = strlen(text); + if (len > MAX_MESSAGES_TEXT_LEN) + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : the length of body exceeded the max, 1530 ." + , __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER); + return MESSAGES_ERROR_INVALID_PARAMETER; + } + ret = ERROR_CONVERT( + msg_sms_set_message_body(_msg->msg_h, text, len) + ); + } + else if (MESSAGES_TYPE_MMS == type) + { + if (NULL != _msg->text) + { + free(_msg->text); + } + + _msg->text = strdup(text); + if (NULL == _msg->text) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create a '_msg->text'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + + ret = MESSAGES_ERROR_NONE; + } + else + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : unknown message type" + , __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER); + return MESSAGES_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +int messages_get_text(messages_message_h msg, char **text) +{ + int ret; + const char *_text; + messages_message_type_e type; + + messages_message_s *_msg = (messages_message_s*)msg; + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + + ret = messages_get_message_type(msg, &type); + if (MESSAGES_ERROR_NONE != ret) { + return ret; + } + + if (MESSAGES_TYPE_SMS == type) + { + _text = msg_sms_get_message_body(_msg->msg_h); + if (NULL == _text) + { + *text = NULL; + } + else + { + *text = strdup(_text); + if (NULL == *text) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create a '*text'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + } + } + else if (MESSAGES_TYPE_MMS == type) + { + if (NULL == _msg->text) + { + *text = NULL; + } + else + { + *text = strdup(_msg->text); + if (NULL == *text) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create a '*text'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + } + } + else + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : unknown message type" + , __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER); + return MESSAGES_ERROR_INVALID_PARAMETER; + } + + return MESSAGES_ERROR_NONE; +} + + + +// MMS ///////////////////////////////////////////////////////////////////// + +int messages_mms_set_subject(messages_message_h msg, const char *subject) +{ + int ret; + messages_message_type_e type; + + messages_message_s *_msg = (messages_message_s*)msg; + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(subject); + + ret = messages_get_message_type(msg, &type); + if (MESSAGES_ERROR_NONE != ret) { + return ret; + } + + if (MESSAGES_TYPE_MMS != type) + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : the message type should be MESSAGES_TYPE_MMS" + , __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER); + return MESSAGES_ERROR_INVALID_PARAMETER; + } + + ret = msg_set_subject(_msg->msg_h, subject); + + return ERROR_CONVERT(ret); +} + +int messages_mms_get_subject(messages_message_h msg, char **subject) +{ + int ret; + const char *_subject; + messages_message_type_e type; + + messages_message_s *_msg = (messages_message_s*)msg; + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(subject); + + ret = messages_get_message_type(msg, &type); + if (MESSAGES_ERROR_NONE != ret) { + return ret; + } + + if (MESSAGES_TYPE_MMS != type) + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : the message type should be MESSAGES_TYPE_MMS" + , __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER); + return MESSAGES_ERROR_INVALID_PARAMETER; + } + + _subject = msg_get_subject(_msg->msg_h); + if (NULL == _subject) + { + *subject = NULL; + } + else + { + *subject = strdup(_subject); + if (NULL == *subject) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create a '*subject'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + } + + return MESSAGES_ERROR_NONE; +} + + +int messages_mms_add_attachment(messages_message_h msg, messages_media_type_e type, const char *path) +{ + messages_message_type_e msg_type; + + messages_message_s *_msg = (messages_message_s*)msg; + messages_attachment_s *attach; + + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(path); + + // Check Message Type + messages_get_message_type(msg, &msg_type); + if (MESSAGES_TYPE_MMS != msg_type) + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : the message type should be MESSAGES_TYPE_MMS" + , __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER); + return MESSAGES_ERROR_INVALID_PARAMETER; + } + + // New Attach + attach = (messages_attachment_s *)calloc(1, sizeof(messages_attachment_s)); + if (NULL == attach) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create a 'attach'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + + attach->media_type = type; + strncpy(attach->filepath, path, strlen(path)); + + // Append + _msg->attachment_list = g_slist_append(_msg->attachment_list, attach); + + return MESSAGES_ERROR_NONE; +} + +int messages_mms_get_attachment_count(messages_message_h msg, int *count) +{ + messages_message_type_e type; + + messages_message_s *_msg = (messages_message_s*)msg; + + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(count); + + // Check Message Type + messages_get_message_type(msg, &type); + if (MESSAGES_TYPE_MMS != type) + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : the message type should be MESSAGES_TYPE_MMS" + , __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER); + return MESSAGES_ERROR_INVALID_PARAMETER; + } + + // Count + *count = g_slist_length(_msg->attachment_list); + + return MESSAGES_ERROR_NONE; +} + +int messages_mms_get_attachment(messages_message_h msg, int index, messages_media_type_e *type, char **path) +{ + messages_attachment_s *_attach; + messages_message_type_e msg_type; + + messages_message_s *_msg = (messages_message_s*)msg; + + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + CHECK_NULL(path); + + // Check Message Type + messages_get_message_type(msg, &msg_type); + if (MESSAGES_TYPE_MMS != msg_type) + { + LOGE("[%s] INVALID_PARAMETER(0x%08x) : the message type should be MESSAGES_TYPE_MMS" + , __FUNCTION__, MESSAGES_ERROR_INVALID_PARAMETER); + return MESSAGES_ERROR_INVALID_PARAMETER; + } + + _attach = (messages_attachment_s *)g_slist_nth_data(_msg->attachment_list, index); + if (NULL == _attach) + { + *type = MESSAGES_MEDIA_UNKNOWN; + *path = NULL; + } + else + { + *type = _attach->media_type; + *path = strdup(_attach->filepath); + if (NULL == *path) + { + LOGE("[%s] OUT_OF_MEMORY(0x%08x) fail to create a '*path'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + } + + return MESSAGES_ERROR_NONE; +} + +int messages_mms_remove_all_attachments(messages_message_h msg) +{ + messages_message_s *_msg = (messages_message_s*)msg; + + CHECK_NULL(_msg); + CHECK_NULL(_msg->msg_h); + + if (_msg->attachment_list) + { + g_slist_foreach(_msg->attachment_list, (GFunc)g_free, NULL); + g_slist_free(_msg->attachment_list); + _msg->attachment_list = NULL; + } + + return MESSAGES_ERROR_NONE; +} + +int _messages_save_mms_data(messages_message_s *msg) +{ + int i; + int ret; + + MMS_MESSAGE_DATA_S *mms_data; + MMS_SMIL_ROOTLAYOUT *layout; + MMS_PAGE_S *page; + MMS_MEDIA_S *media; + + messages_attachment_s *attach; + messages_attachment_s *image; + messages_attachment_s *audio; + + char *filepath = NULL; + + CHECK_NULL(msg); + + mms_data = msg_mms_create_message(); + if (NULL == mms_data) + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : msg_mms_create_message failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + // Check Attachments + image = NULL; + audio = NULL; + for (i=0; i < g_slist_length(msg->attachment_list); i++) + { + attach = g_slist_nth_data(msg->attachment_list, i); + if (MESSAGES_MEDIA_IMAGE == attach->media_type) + { + if (NULL == image) + { + image = attach; + } + } + else if (MESSAGES_MEDIA_VIDEO == attach->media_type) + { + if (NULL == image) + { + image = attach; + } + } + else if (MESSAGES_MEDIA_AUDIO == attach->media_type) + { + if (NULL == audio) + { + audio = attach; + } + } + } + + // Layout Setting + layout = msg_mms_set_rootlayout(mms_data, 100, 100, 0xffffff); + if (NULL == layout) + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : msg_mms_set_rootlayout failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + msg_mms_destroy_message(mms_data); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + if (NULL == image) + { + msg_mms_add_region(mms_data, "Text", 0, 0, 100, 100, 0xffffff); + } + else if (NULL == msg->text) + { + msg_mms_add_region(mms_data, "Image", 0, 0, 100, 100, 0xffffff); + } + else + { + msg_mms_add_region(mms_data, "Image", 0, 0, 100, 50, 0xffffff); + msg_mms_add_region(mms_data, "Text", 0, 50, 100, 50, 0xffffff); + } + + // Add Media + page = msg_mms_add_page(mms_data, 5440); + if (NULL == page) + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : msg_mms_add_page failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + msg_mms_destroy_message(mms_data); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + if (NULL != image) + { + if (MESSAGES_MEDIA_IMAGE == image->media_type) + { + media = msg_mms_add_media(page, MMS_SMIL_MEDIA_IMG, "Image", (char *)image->filepath); + if (NULL == media) + { + LOGW("msg_mms_add_media failed, filepath=%s", image->filepath); + } + } + else if (MESSAGES_MEDIA_VIDEO == image->media_type) + { + media = msg_mms_add_media(page, MMS_SMIL_MEDIA_VIDEO, "Image", (char *)image->filepath); + if (NULL == media) + { + LOGW("msg_mms_add_media failed, filepath=%s", image->filepath); + } + } + } + + if (NULL != audio) + { + media = msg_mms_add_media(page, MMS_SMIL_MEDIA_AUDIO, NULL, (char *)audio->filepath); + if (NULL == media) + { + LOGW("msg_mms_add_media failed, filepath=%s", audio->filepath); + } + } + + if (NULL != msg->text) + { + ret = _messages_save_textfile(msg->text, &filepath); + if (MESSAGES_ERROR_NONE == ret) + { + media = msg_mms_add_media(page, MMS_SMIL_MEDIA_TEXT, "Text", (char *)filepath); + if (NULL != media) + { + media->sMedia.sText.nColor = 0x000000; + media->sMedia.sText.nSize = MMS_SMIL_FONT_SIZE_NORMAL; + media->sMedia.sText.bBold = false; + } + else + { + LOGW("msg_mms_add_media failed, filepath=%s", audio->filepath); + } + } + + if (NULL != filepath) + { + free(filepath); + } + } + + // Add Attachment + for (i=0; i < g_slist_length(msg->attachment_list); i++) + { + attach = g_slist_nth_data(msg->attachment_list, i); + if (image != attach && audio != attach) + { + msg_mms_add_attachment(mms_data, (char *)attach->filepath); + } + } + + + ret = msg_mms_set_message_body(msg->msg_h, mms_data); + if (MSG_SUCCESS != ret) + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : msg_mms_add_page failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + msg_mms_destroy_message(mms_data); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + msg_mms_destroy_message(mms_data); + + return MESSAGES_ERROR_NONE; +} + +int _messages_load_mms_data(messages_message_s *msg, MSG_HANDLE_T handle) +{ + int i,j; + int ret; + int msg_id; + msg_message_t new_msg_h; + MSG_SENDINGOPT_S sendOpt = {0, }; + MMS_MESSAGE_DATA_S *mms_data; + MMS_PAGE_S *mms_page; + MMS_MEDIA_S *mms_media; + MMS_ATTACH_S *mms_attach; + messages_attachment_s *attach; + + CHECK_NULL(msg); + + // Get MessageId + msg_id = msg_get_message_id(msg->msg_h); + if (MSG_ERR_NULL_POINTER == msg_id) + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : msg_get_message_id failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + // Load MMS_MESSAGE_DATA_S + new_msg_h = msg_new_message(); + ret = msg_get_message(handle, msg_id, new_msg_h, &sendOpt); + if (MSG_SUCCESS != ret) + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : msg_get_message failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + mms_data = msg_mms_create_message(); + if (NULL == mms_data) + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : msg_mms_create_message failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + msg_release_message(&new_msg_h); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + ret = msg_mms_get_message_body(new_msg_h, mms_data); + if (MSG_SUCCESS != ret) + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : msg_mms_get_message_body failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + msg_mms_destroy_message(mms_data); + msg_release_message(&new_msg_h); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + msg_release_message(&new_msg_h); + + // Load Media, Text + for (i=0; i < mms_data->pageCnt; i++) + { + mms_page = msg_mms_get_page(mms_data, i); + if (NULL == mms_page) + { + continue; + } + for (j=0; j < mms_page->mediaCnt; j++) + { + mms_media = msg_mms_get_media(mms_page, j); + if (NULL == mms_media) + { + continue; + } + + attach = (messages_attachment_s *)calloc(1, sizeof(messages_attachment_s)); + if (NULL == attach) + { + LOGW("[%s] OUT_OF_MEMORY(0x%08x) fail to create a 'attach'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + break; + } + + if (MMS_SMIL_MEDIA_TEXT == mms_media->mediatype) + { + _messages_load_textfile(mms_media->szFilePath, &msg->text); + } + else + { + strncpy(attach->filepath, mms_media->szFilePath, MSG_FILEPATH_LEN_MAX); + switch (mms_media->mediatype) + { + case MMS_SMIL_MEDIA_IMG: + attach->media_type = MESSAGES_MEDIA_IMAGE; + break; + case MMS_SMIL_MEDIA_VIDEO: + attach->media_type = MESSAGES_MEDIA_VIDEO; + break; + case MMS_SMIL_MEDIA_AUDIO: + attach->media_type = MESSAGES_MEDIA_AUDIO; + break; + default: + attach->media_type = MESSAGES_MEDIA_UNKNOWN; + } + + msg->attachment_list = g_slist_append(msg->attachment_list, attach); + } + } + } + + // Load Attachments + for (i=0; i < mms_data->attachCnt; i++) + { + mms_attach = msg_mms_get_attachment(mms_data, i); + if (NULL == mms_attach) + { + continue; + } + + attach = (messages_attachment_s *)calloc(1, sizeof(messages_attachment_s)); + if (NULL == attach) + { + LOGW("[%s] OUT_OF_MEMORY(0x%08x) fail to create a 'attach'." + , __FUNCTION__, MESSAGES_ERROR_OUT_OF_MEMORY); + break; + } + + strncpy(attach->filepath, mms_attach->szFilePath, MSG_FILEPATH_LEN_MAX); + attach->media_type = _messages_get_media_type_from_filepath(attach->filepath); + } + + msg_mms_destroy_message(mms_data); + + return MESSAGES_ERROR_NONE; +} + +int _messages_save_textfile(const char *text, char **filepath) +{ + FILE* file = NULL; + + CHECK_NULL(text); + + *filepath = (char *)malloc(sizeof(char)*MSG_FILEPATH_LEN_MAX+1); + if (NULL == *filepath) + { + LOGE("[%s:%d] OUT_OF_MEMORY(0x%08x) fail to create a '*filepath'." + , __FUNCTION__, __LINE__, MESSAGES_ERROR_OUT_OF_MEMORY); + return MESSAGES_ERROR_OUT_OF_MEMORY; + } + + snprintf(*filepath, MSG_FILEPATH_LEN_MAX+1, "/tmp/.capi_messages_text_%d.txt", getpid()); + + file = fopen(*filepath, "w"); + if (file != NULL) + { + fputs(text, file); + fclose(file); + } + else + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : opening file for text of message failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + return MESSAGES_ERROR_NONE; +} + +int _messages_load_textfile(const char *filepath, char **text) +{ + FILE *file = NULL; + char buf[1024]; + struct stat st; + size_t nread, len; + char *pos; + + CHECK_NULL(filepath); + + file = fopen(filepath, "r"); + + if (NULL == file) + { + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : opening file for text of message failed.", + __FUNCTION__, __LINE__, MESSAGES_ERROR_OPERATION_FAILED); + return MESSAGES_ERROR_OPERATION_FAILED; + } + + fstat(fileno(file), &st); + + if (NULL == *text) + { + *text = (char*)calloc(1, st.st_size + 1); + pos = *text; + } + else + { + len = strlen(*text); + (*text)[len] = '\n'; + *text = (char*)realloc(*text, len + st.st_size + 1); + pos = *text + len; + } + + while(0 < (nread = fread(buf, 1, 1024, file))) + { + memcpy(pos, buf, nread); + pos += nread; + } + pos[0] = '\0'; + + return 0; +} + +int _messages_get_media_type_from_filepath(const char *filepath) +{ + int len; + int ret; + char *file_ext; + + if (NULL == filepath) + { + return MESSAGES_MEDIA_UNKNOWN; + } + // check the length of filepath + len = strlen(filepath); + if (len < 5) + { + return MESSAGES_MEDIA_UNKNOWN; + } + + // check extension of file + file_ext = (char *)&filepath[len - 4]; + + if(strncmp(file_ext,".jpg",4) !=0 && strncmp(file_ext,".gif",4) !=0 + && strncmp(file_ext,".bmp",4) !=0 && strncmp(file_ext,".png",4) !=0) + { + ret = MESSAGES_MEDIA_IMAGE; + } + else if(strncmp(file_ext,".mp4",4) !=0 && strncmp(file_ext,".3gp",4) !=0) + { + ret = MESSAGES_MEDIA_VIDEO; + } + else if(strncmp(file_ext,".mid",4) !=0 && strncmp(file_ext,".aac",4) !=0 && strncmp(file_ext,".amr",4) !=0) + { + ret = MESSAGES_MEDIA_AUDIO; + } + else + { + ret = MESSAGES_MEDIA_UNKNOWN; + } + + return ret; +} + +MSG_FOLDER_ID_T _messages_convert_mbox_to_fw(messages_message_box_e mbox) +{ + MSG_FOLDER_ID_T folderId; + switch(mbox) + { + case MESSAGES_MBOX_INBOX: + folderId = MSG_INBOX_ID; + break; + case MESSAGES_MBOX_OUTBOX: + folderId = MSG_OUTBOX_ID; + break; + case MESSAGES_MBOX_SENTBOX: + folderId = MSG_SENTBOX_ID; + break; + case MESSAGES_MBOX_DRAFT: + folderId = MSG_DRAFT_ID; + break; + default: + folderId = MSG_ALLBOX_ID; + break; + } + return folderId; +} + +MSG_MESSAGE_TYPE_T _messages_convert_msgtype_to_fw(messages_message_type_e type) +{ + MSG_MESSAGE_TYPE_T msgType; + switch (type) + { + case MESSAGES_TYPE_SMS: + msgType = MSG_TYPE_SMS; + break; + case MESSAGES_TYPE_MMS: + msgType = MSG_TYPE_MMS; + break; + default: + msgType = MSG_TYPE_INVALID; + break; + } + return msgType; +} + + +int _messages_error_converter(int err, const char *func, int line) +{ + switch(err) + { + case MSG_ERR_NULL_POINTER: + LOGE("[%s:%d] NULL_POINTER(0x%08x) : Error from internal Messaging F/W ret: %d.", + func, line, MESSAGES_ERROR_INVALID_PARAMETER, err); + return MESSAGES_ERROR_INVALID_PARAMETER; + + case MSG_ERR_INVALID_PARAMETER: + LOGE("[%s:%d] INVALID_PARAMETER(0x%08x) : Error from internal Messaging F/W ret: %d.", + func, line, MESSAGES_ERROR_INVALID_PARAMETER, err); + return MESSAGES_ERROR_INVALID_PARAMETER; + + case -EINVAL: + LOGE("[%s:%d] EINVAL(0x%08x) : Error from internal Messaging F/W ret: %d.", + func, line, MESSAGES_ERROR_INVALID_PARAMETER, err); + return MESSAGES_ERROR_INVALID_PARAMETER; + + case MSG_ERR_SERVER_NOT_READY: + LOGE("[%s:%d] SERVER_NOT_READY(0x%08x) : Error from internal Messaging F/W ret: %d.", + func, line, MESSAGES_ERROR_SERVER_NOT_READY, err); + return MESSAGES_ERROR_SERVER_NOT_READY; + + case MSG_ERR_COMMUNICATION_ERROR: + LOGE("[%s:%d] OMMUNICATION_ERROR(0x%08x) : Error from internal Messaging F/W ret: %d.", + func, line, MESSAGES_ERROR_COMMUNICATION_WITH_SERVER_FAILED, err); + return MESSAGES_ERROR_COMMUNICATION_WITH_SERVER_FAILED; + + case MSG_ERR_TRANSPORT_ERROR: + LOGE("[%s:%d] TRANSPORT_ERROR(0x%08x) : Error from internal Messaging F/W ret: %d.", + func, line, MESSAGES_ERROR_SENDING_FAILED, err); + return MESSAGES_ERROR_SENDING_FAILED; + + case MSG_SUCCESS: + return MESSAGES_ERROR_NONE; + + default: + LOGE("[%s:%d] OPERATION_FAILED(0x%08x) : Error from internal Messaging F/W ret: %d.", + func, line, MESSAGES_ERROR_OPERATION_FAILED, err); + return MESSAGES_ERROR_OPERATION_FAILED; + + } +} \ No newline at end of file diff --git a/test/.messages_search_test.c.swp b/test/.messages_search_test.c.swp new file mode 100644 index 0000000000000000000000000000000000000000..b224d246cab2e9d6f5a9b1b27486d55916b08445 GIT binary patch literal 12288 zcmeI2O-~a+7{>?Sl2uTn2jj`11hOTiEqKsSAwkm^650|9$csAJ?oQh^bQgEGm6z0; z@#fKkU%`)HFzN>|@uo+wCSLSvqW>xFQUy!nP4aB|3$xEYGyBYMrWZPeIY&KxygOiGetIRHP28HAolaDw?;9oQ zCj#jQ;hpfM;hANjf^qZkfhmIwkb%wyszGt&dLO$wHkurW^z(}s7CPtCQ!+pX$N(82 z17v^u0_MpJ07d$to4^@#L5*Bj@pv(KXFdeXpg=Vm|@J+~sP zf*$1)e9(%-IMz6d0qi2zGwFPO>UKIW(sOgUIg!m})4YG8k-@j|4lNnu__R(?n}rz9 zF3ilR?wS@+2dXiiip02zgu`WS=9a{i3WuTj<=M2zXYwi&6`+_yE5@!ucK0)P*QFC~ z$$yycA7%YE+)!hSGYxB^;=H-@QC&EVW=NDda`6Syus%vZ8G(T+*nsVrYgJ3~8?8?9@??A153Du2pn`j;h}o_R{Q}mp Bm`wlx literal 0 HcmV?d00001 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100755 index 0000000..7715cac --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,17 @@ +SET(fw_test "${fw_name}-test") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_test} REQUIRED glib-2.0) +FOREACH(flag ${${fw_test}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall") + +aux_source_directory(. sources) +FOREACH(src ${sources}) + GET_FILENAME_COMPONENT(src_name ${src} NAME_WE) + MESSAGE("${src_name}") + ADD_EXECUTABLE(${src_name} ${src}) + TARGET_LINK_LIBRARIES(${src_name} ${fw_name} ${${fw_test}_LDFLAGS}) +ENDFOREACH() diff --git a/test/messages_search_test.c b/test/messages_search_test.c new file mode 100644 index 0000000..30bb295 --- /dev/null +++ b/test/messages_search_test.c @@ -0,0 +1,46 @@ +#include +#include + +#include + + +bool _search_cb(messages_message_h msg, int index, int result_count, int total_count, void *user_data) +{ + char *text; + + messages_get_text(msg, &text); + + printf(">>%s\n", text); + + return true; +} + +int main(int argc, char *argv[]) +{ + int ret; + + messages_service_h svc; + + // open service + ret = messages_open_service(&svc); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_open_service() = %d", ret); + return 1; + } + + ret = messages_foreach_message_from_db(svc, + MESSAGES_MBOX_ALL, MESSAGES_TYPE_SMS, + "test", NULL, + 0, 0, _search_cb, NULL); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_foreach_message_from_db() = %d", ret); + return 1; + } + + + // destroy + messages_close_service(svc); + + + return 0; +} diff --git a/test/messages_send_mms_test.c b/test/messages_send_mms_test.c new file mode 100644 index 0000000..0eead72 --- /dev/null +++ b/test/messages_send_mms_test.c @@ -0,0 +1,57 @@ +#include +#include + +#include + +void _sent_cb(messages_sending_result_e result, void *user_data) +{ +} + +int main(int argc, char *argv[]) +{ + int ret; + + messages_service_h svc; + messages_message_h msg; + + // open service + ret = messages_open_service(&svc); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_open_service() = %d", ret); + return 1; + } + + // create message + ret = messages_create_message(MESSAGES_TYPE_MMS, &msg); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_create_message() = %d", ret); + return 1; + } + + messages_add_address(msg, "3488858734"); + messages_set_text(msg, "This is a multi-media message!"); + + messages_mms_set_subject(msg, "TEST!"); + messages_mms_add_attachment(msg, MESSAGES_MEDIA_VIDEO, "/opt/etc/msg-service/V091120_104905.3gp"); + messages_mms_add_attachment(msg, MESSAGES_MEDIA_IMAGE, "/opt/etc/msg-service/P091120_104633.jpg"); + + // send message + ret = messages_set_message_sent_cb(svc, _sent_cb, NULL); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_set_message_sent_cb() = %d", ret); + return 1; + } + + ret = messages_send_message(svc, msg); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_send_message() = %d", ret); + return 1; + } + + // destroy + messages_destroy_message(msg); + messages_close_service(svc); + + + return 0; +} diff --git a/test/messages_send_sms_test.c b/test/messages_send_sms_test.c new file mode 100644 index 0000000..b4b96e3 --- /dev/null +++ b/test/messages_send_sms_test.c @@ -0,0 +1,54 @@ +#include +#include + +#include + +void _sent_cb(messages_sending_result_e result, void *user_data) +{ +} + +int main(int argc, char *argv[]) +{ + int ret; + + messages_service_h svc; + messages_message_h msg; + + // open service + ret = messages_open_service(&svc); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_open_service() = %d", ret); + return 1; + } + + // create message + ret = messages_create_message(MESSAGES_TYPE_SMS, &msg); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_create_message() = %d", ret); + return 1; + } + + messages_add_address(msg, "3488858734"); + messages_set_text(msg, "This is simple message!"); + + + // send message + ret = messages_set_message_sent_cb(svc, _sent_cb, NULL); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_set_message_sent_cb() = %d", ret); + return 1; + } + + ret = messages_send_message(svc, msg); + if (MESSAGES_ERROR_NONE != ret) { + printf("error: messages_send_message() = %d", ret); + return 1; + } + + // destroy + messages_destroy_message(msg); + messages_close_service(svc); + + + return 0; +} -- 2.34.1