From 364b5f2203c15fc2cbc0e0b1e070828a5a2edcea Mon Sep 17 00:00:00 2001 From: Jinkun Jang Date: Sat, 16 Mar 2013 21:17:33 +0900 Subject: [PATCH] sync with master --- CMakeLists.txt | 85 +++++ LICENSE.APLv2 | 202 +++++++++++ NOTICE | 3 + include/message-port-data-types.h | 33 ++ include/message-port-messages.h | 38 +++ include/message-port-param-traits.h | 99 ++++++ include/message-port.h | 259 ++++++++++++++ message-port.manifest | 5 + message-port.pc.in | 15 + packaging/message-port.spec | 73 ++++ src/IIpcClientEventListener.h | 54 +++ src/IpcClient.cpp | 583 +++++++++++++++++++++++++++++++ src/IpcClient.h | 143 ++++++++ src/MessagePortProxy.cpp | 663 ++++++++++++++++++++++++++++++++++++ src/MessagePortProxy.h | 113 ++++++ src/message-port-log.h | 43 +++ src/message-port-messages.cpp | 24 ++ src/message-port.cpp | 184 ++++++++++ 18 files changed, 2619 insertions(+) create mode 100755 CMakeLists.txt create mode 100644 LICENSE.APLv2 create mode 100644 NOTICE create mode 100644 include/message-port-data-types.h create mode 100644 include/message-port-messages.h create mode 100644 include/message-port-param-traits.h create mode 100755 include/message-port.h create mode 100644 message-port.manifest create mode 100755 message-port.pc.in create mode 100755 packaging/message-port.spec create mode 100644 src/IIpcClientEventListener.h create mode 100644 src/IpcClient.cpp create mode 100644 src/IpcClient.h create mode 100644 src/MessagePortProxy.cpp create mode 100644 src/MessagePortProxy.h create mode 100644 src/message-port-log.h create mode 100644 src/message-port-messages.cpp create mode 100644 src/message-port.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..64adece --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,85 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(this_target "message-port") + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +## OUTPUT PATHS +SET(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/cmake_build_tmp/output) + +INCLUDE_DIRECTORIES ( + /usr/include + /usr/include/appfw + /usr/include/dlog + /usr/include/glib-2.0 + /usr/lib/glib-2.0/include + /usr/include/chromium + include + ) + +SET (${this_target}_SOURCE_FILES + src/IpcClient.cpp + src/message-port.cpp + src/message-port-messages.cpp + src/MessagePortProxy.cpp +) + +SET(requires "dlog bundle glib-2.0 chromium") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${this_target} REQUIRED ${requires}) +FOREACH(flag ${${this_target}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall" ) + +## SET C COMPILER FLAGS +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +## SET CPP COMPILER FLAGS +SET(CMAKE_CXX_FLAGS "${OSP_DEBUG_FLAGS} ${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}") + +IF("${ARCH}" STREQUAL "arm") + ADD_DEFINITIONS("-DTARGET") +ENDIF("${ARCH}" STREQUAL "arm") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DSLP_DEBUG") + +## Create Library +ADD_LIBRARY (${this_target} SHARED ${${this_target}_SOURCE_FILES}) + +## SET LINKER FLAGS +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +TARGET_LINK_LIBRARIES(${this_target} "-ldlog" ) +TARGET_LINK_LIBRARIES(${this_target} "-lbundle" ) +TARGET_LINK_LIBRARIES(${this_target} "-lglib-2.0" ) +TARGET_LINK_LIBRARIES(${this_target} "-lchromium" ) +TARGET_LINK_LIBRARIES(${this_target} "-lcapi-appfw-app-manager" ) +TARGET_LINK_LIBRARIES(${this_target} "-lcapi-appfw-package-manager" ) + +SET_TARGET_PROPERTIES(${this_target} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 + ) + + +# pkgconfig file +CONFIGURE_FILE(${this_target}.pc.in ${CMAKE_SOURCE_DIR}/${this_target}.pc @ONLY) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/${this_target}.pc DESTINATION lib/pkgconfig) + +INSTALL(TARGETS ${this_target} DESTINATION lib) + +INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/appfw FILES_MATCHING PATTERN "*.h") + +INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/ DESTINATION lib + FILES_MATCHING PATTERN "*.so*" + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,202 @@ + + 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/NOTICE b/NOTICE new file mode 100644 index 0000000..0e0f016 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License terms and conditions. diff --git a/include/message-port-data-types.h b/include/message-port-data-types.h new file mode 100644 index 0000000..dc5940e --- /dev/null +++ b/include/message-port-data-types.h @@ -0,0 +1,33 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file message-port-data-types.h + * @brief This is the header file for data types for IPC. + */ + +#ifndef _APPFW_MESSAGE_PORT_DATA_TYPES_H_ +#define _APPFW_MESSAGE_PORT_DATA_TYPES_H_ + +#include + +typedef struct +{ + bundle* b; +} BundleBuffer; + +#endif //_APPFW_MESSAGE_PORT_DATA_TYPES_H_ diff --git a/include/message-port-messages.h b/include/message-port-messages.h new file mode 100644 index 0000000..54d80e4 --- /dev/null +++ b/include/message-port-messages.h @@ -0,0 +1,38 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file message-port-messages.h + * @brief This is the header file for message types for IPC. + */ + +#ifndef _APPFW_MESSAGE_PORT_MESSAGES_H_ +#define _APPFW_MESSAGE_PORT_MESSAGES_H_ + +#include "ipc/ipc_message_macros.h" +#include "message-port-data-types.h" +#include "message-port-param-traits.h" + +#define MessagePortStart 0 +#define IPC_MESSAGE_START MessagePortStart + +IPC_SYNC_MESSAGE_CONTROL1_1(MessagePort_registerPort, BundleBuffer, int) +IPC_SYNC_MESSAGE_CONTROL1_1(MessagePort_checkRemotePort, BundleBuffer, int) +IPC_SYNC_MESSAGE_CONTROL1_1(MessagePort_sendMessage, BundleBuffer, int) +IPC_MESSAGE_CONTROL1(MessagePort_sendMessageAsync, BundleBuffer) + +#endif //_APPFW_MESSAGE_PORT_MESSAGES_H_ diff --git a/include/message-port-param-traits.h b/include/message-port-param-traits.h new file mode 100644 index 0000000..4142b8d --- /dev/null +++ b/include/message-port-param-traits.h @@ -0,0 +1,99 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file message-port-param-traits.h + * @brief This is the header file for message port param traits for IPC. + */ + +#ifndef _APPFW_MESSAGE_PORT_PARAM_TRAITS_H_ +#define _APPFW_MESSAGE_PORT_PARAM_TRAITS_H_ +#pragma once + +#include +#include + +#include + +#include "message-port-data-types.h" + +namespace IPC +{ + +template<> +struct ParamTraits +{ + typedef BundleBuffer param_type; + + static void Write(Message* m, const param_type& p) + { + int len = 0; + bundle_raw* raw = NULL; + bundle_encode(p.b, &raw, &len); + + + m->WriteInt(len); + m->WriteBytes((const void*) raw, len); + + m->WriteInt(len); + + bundle_free_encoded_rawdata(&raw); + } + + static bool Read(const Message* m, void** iter, param_type* r) + { + int len = 0; + const char* pBuffer = NULL; + + if (!m->ReadLength(iter, &len)) + { + return false; + } + + if (!m->ReadBytes(iter, &pBuffer, len)) + { + return false; + } + + if (!m->ReadLength(iter, &len)) + { + return false; + } + + if (pBuffer != NULL) + { + // Truncated + ((char*)pBuffer)[len] = '\0'; + } + else + { + return false; + } + + r->b = bundle_decode((const bundle_raw*)pBuffer, len); + + return true; + } + + static void Log(const param_type& p, std::string* l) + { + } +}; + +} + +#endif //_APPFW_MESSAGE_PORT_PARAM_TRAITS_H_ diff --git a/include/message-port.h b/include/message-port.h new file mode 100755 index 0000000..65aec02 --- /dev/null +++ b/include/message-port.h @@ -0,0 +1,259 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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 __APPFW_MESSAGE_PORT_H__ +#define __APPFW_MESSAGE_PORT_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumerations of error code for Application. + */ +typedef enum +{ + MESSAGEPORT_ERROR_NONE = 0, /**< Successful */ + MESSAGEPORT_ERROR_IO_ERROR = -1, /**< Internal I/O error */ + MESSAGEPORT_ERROR_OUT_OF_MEMORY = -2, /**< Out of memory */ + MESSAGEPORT_ERROR_INVALID_PARAMETER = -3, /**< Invalid parameter */ + MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND = -4, /**< The message port of the remote application is not found */ + MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH = -5, /**< The remote application is not signed with the same certificate */ + MESSAGEPORT_ERROR_MAX_EXCEEDED = -6, /**< The size of message has exceeded the maximum limit */ +} messageport_error_e; + + +/** + * @brief Called when a message is received from the remote application. + * + * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port() + * @param [in] remote_app_id The ID of the remote application which has sent this message + * @param [in] remote_port The name of the remote message port + * @param [in] trusted_message @c true if the trusted remote message port is ready to receive the response data + * @param [in] data the data passed from the remote application + * @remarks @a data must be released with bundle_free() by you + * @remark @a remote_app_id and @a remote_port will be set if the remote application sends a bidirectional message, otherwise they are NULL. + */ +typedef void (*messageport_message_cb)(int id, const char* remote_app_id, const char* remote_port, bool trusted_message, bundle* data); + + +/** + * @brief Registers the local message port. + * + * @param [in] local_port the name of the local message port + * @param [in] callback The callback function to be called when a message is received + * @return A message port id on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error + */ +int messageport_register_local_port(const char* local_port, messageport_message_cb callback); + +/** + * @brief Registers the trusted local message port. + * + * @param [in] local_port the name of the local message port + * @param [in] callback The callback function to be called when a message is received + * @return A message port id on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error + */ +int messageport_register_trusted_local_port(const char* local_port, messageport_message_cb callback); + + +/** + * @brief Unregisters the local message port. + * + * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port() + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + */ +int messageport_unregister_local_port(int id); + +/** + * @brief Checks if the message port of a remote application is registered. + * + * @param [in] remote_app_id The ID of the remote application + * @param [in] remote_port the name of the remote message port + * @param [out] exist @c true if the message port of the remote application exists, otherwise @c false + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error + */ +int messageport_check_remote_port(const char* remote_app_id, const char *remote_port, bool* exist); + +/** + * @brief Checks if the trusted message port of a remote application is registered. + * + * @param [in] remote_app_id The ID of the remote application + * @param [in] remote_port the name of the remote message port + * @param [out] exist @c true if the message port of the remote application exists, otherwise @c false + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH The remote application is not signed with the same certificate + * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error + */ +int messageport_check_trusted_remote_port(const char* remote_app_id, const char *remote_port, bool* exist); + +/** + * @brief Sends a message to the message port of a remote application. + * + * @param [in] remote_app_id The ID of the remote application + * @param [in] remote_port the name of the remote message port + * @param [in] message the message to be passed to the remote application + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND The message port of the remote application is not found + * @retval #MESSAGEPORT_ERROR_MAX_EXCEEDED The size of message has exceeded the maximum limit + * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error + * + * @code + * #include + * + * bundle *b = bundle_create(); + * bundle_add(b, "key1", "value1"); + * bundle_add(b, "key2", "value2"); + * + * int ret = messageport_send_message("0123456789.BasicApp", "BasicAppPort", b); + * + * bundle_free(b); + * @endcode + */ +int messageport_send_message(const char* remote_app_id, const char* remote_port, bundle* message); + +/** + * @brief Sends a trusted message to the message port of a remote application. + * + * @param [in] remote_app_id The ID of the remote application + * @param [in] remote_port the name of the remote message port + * @param [in] message the message to be passed to the remote application + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND The message port of the remote application is not found + * @retval #MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH The remote application is not signed with the same certificate + * @retval #MESSAGEPORT_ERROR_MAX_EXCEEDED The size of message has exceeded the maximum limit + * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error + */ +int messageport_send_trusted_message(const char* remote_app_id, const char* remote_port, bundle* message); + +/** + * @brief Sends a message to the message port of a remote application. This method is used for the bidirectional communication. + * + * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port() + * @param [in] remote_app_id The ID of the remote application + * @param [in] remote_port the name of the remote message port + * @param [in] message the message to be passed to the remote application + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND The message port of the remote application is not found + * @retval #MESSAGEPORT_ERROR_MAX_EXCEEDED The size of message has exceeded the maximum limit + * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error + * + * @code + * #include + * + * static void + * OnMessageReceived(int id, const char* remote_app_id, const char* remote_port, bool trusted_port, bundle* data) + * { + * } + * + * int main(int argc, char *argv[]) + * { + * bundle *b = bundle_create(); + * bundle_add(b, "key1", "value1"); + * bundle_add(b, "key2", "value2"); + * + * int id = messageport_register_local_port("HelloPort", OnMessageReceived); + * + * int ret = messageport_send_message(id, "0123456789.BasicApp", "BasicAppPort", b); + * + * bundle_free(b); + * } + */ +int messageport_send_bidirectional_message(int id, const char* remote_app_id, const char* remote_port, bundle* data); + +/** + * @brief Sends a trusted message to the message port of a remote application. This method is used for the bidirectional communication. + * + * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port() + * @param [in] remote_app_id The ID of the remote application + * @param [in] remote_port the name of the remote message port + * @param [in] message the message to be passed to the remote application + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND The message port of the remote application is not found + * @retval #MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH The remote application is not signed with the same certificate + * @retval #MESSAGEPORT_ERROR_MAX_EXCEEDED The size of message has exceeded the maximum limit + * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error + */ +int messageport_send_bidirectional_trusted_message(int id, const char* remote_app_id, const char* remote_port, bundle* data); + + +/** + * @brief Gets the name of the local message port. + * + * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port() + * @param [out] name The name of the local message port + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + * @remarks @a name must be released with free() by you + */ +int messageport_get_local_port_name(int id, char **name); + +/** + * @brief Checks if the local message port is trusted. + * + * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port() + * @param [out] @c true if the local message port is trusted + * @return 0 on success, otherwise a negative error value. + * @retval #MESSAGEPORT_ERROR_NONE Successful + * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory + */ +int messageport_check_trusted_local_port(int id, bool *trusted); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __APPFW_MESSAGE_PORT_H__ */ diff --git a/message-port.manifest b/message-port.manifest new file mode 100644 index 0000000..75b0fa5 --- /dev/null +++ b/message-port.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/message-port.pc.in b/message-port.pc.in new file mode 100755 index 0000000..bd96a4c --- /dev/null +++ b/message-port.pc.in @@ -0,0 +1,15 @@ + +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=/usr/lib +includedir=/usr/include/appfw + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} -lmessage-port +Cflags: -I${includedir} + diff --git a/packaging/message-port.spec b/packaging/message-port.spec new file mode 100755 index 0000000..9c147f9 --- /dev/null +++ b/packaging/message-port.spec @@ -0,0 +1,73 @@ +%define debug_package %{nil} +%define __strip /bin/true + +Name: message-port +Summary: Message Port library +Version: 1.2.1.0 +Release: 1 +Group: TO_BE/FILLED_IN +License: Apache License, Version 2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(bundle) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(chromium) +BuildRequires: pkgconfig(capi-appfw-app-manager) +BuildRequires: pkgconfig(capi-appfw-package-manager) + +# runtime requires +Requires: chromium + +Requires(post): /sbin/ldconfig +Requires(post): coreutils +Requires(postun): /sbin/ldconfig + +Provides: libmessage-port.so.1 + +%description +Message Port library + +%package devel +Summary: Message Port library (Development) +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description devel +Message Port library (DEV) + + +%prep +%setup -q + +%build +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} + +# Call make instruction with smp support +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} + +%make_install +mkdir -p %{buildroot}/usr/share/license +install LICENSE.APLv2 %{buildroot}/usr/share/license/%{name} + +%make_install + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + + +%files +%{_libdir}/libmessage-port.so.* +%manifest message-port.manifest +/usr/share/license/%{name} + +%files devel +%{_includedir}/appfw/*.h +%{_libdir}/pkgconfig/*.pc +%{_libdir}/libmessage-port.so + diff --git a/src/IIpcClientEventListener.h b/src/IIpcClientEventListener.h new file mode 100644 index 0000000..f34f813 --- /dev/null +++ b/src/IIpcClientEventListener.h @@ -0,0 +1,54 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file IIpcClientEventListener.h + * @brief This is the header file for the IIpcClientEventListener class. + * + * This file contains the declarations of IIpcClientEventListener. + */ + +#ifndef _IIPC_CLIENT_EVENT_LISTENER_H_ +#define _IIPC_CLIENT_EVENT_LISTENER_H_ + +namespace IPC { class Message; } + +class IpcClient; + +/** + * @interface IIpcClientEventListener + * @brief This interface provides the listener method for the response from IPC server. + */ +class IIpcClientEventListener +{ +public: + + /** + * This is the destructor for this class. + */ + virtual ~IIpcClientEventListener(void) {} + + /** + * Called when an IPC response message received. + * + * @param[in] client The IPC client + * @param[in] message The response message + */ + virtual void OnIpcResponseReceived(IpcClient& client, const IPC::Message& message) = 0; +}; // IIpcClientEventListener + +#endif //_IIPC_CLIENT_EVENT_LISTENER_H_ diff --git a/src/IpcClient.cpp b/src/IpcClient.cpp new file mode 100644 index 0000000..fe68374 --- /dev/null +++ b/src/IpcClient.cpp @@ -0,0 +1,583 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file IpcClient.cpp + * @brief This is the implementation file for the IpcClient class. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "message-port-log.h" + +#include "IpcClient.h" +#include "IIpcClientEventListener.h" + +using namespace IPC; +using namespace std; + + +IpcClient::IpcClient(void) + : __pReverseSource(NULL) + , __fdCount(0) + //, __pFdLock(NULL) + , __pListener(NULL) +{ + __messageBuffer[0] = '\0'; +} + +IpcClient::~IpcClient(void) +{ + int fd = 0; + + if (__pReverseSource != NULL) + { + g_source_destroy(__pReverseSource); + g_source_unref(__pReverseSource); + __pReverseSource = NULL; + } + + while (__fds.size() > 0) + { + fd = __fds.back(); + __fds.pop_back(); + + close(fd); + } + + //delete __pFdLock; +} + +int +IpcClient::Construct(const string& serverName, const IIpcClientEventListener* pListener) +{ + __name = serverName; + __pListener = const_cast (pListener); + + int ret = MakeConnection(); + if (ret != 0) + { + return ret; + } + + if (__pListener) + { + ret = MakeConnection(true); + if (ret != 0) + { + return ret; + } + } + + return 0; + +} + +struct HelloMessage +{ + int pid; + bool reverse; + char appId[256]; +}; + +int +IpcClient::MakeConnection(bool forReverse) +{ + int ret = 0; + + size_t socketNameLength = 0; + string socketName; + + socketName.append("/tmp/"); + socketName.append(__name); + + socketNameLength = socketName.size() + 1; + + HelloMessage helloMessage = {0, false}; + + helloMessage.pid = getpid(); + helloMessage.reverse = forReverse; + + if (__fdCount == 0) + { + char* pAppId = NULL; + ret = app_manager_get_app_id(helloMessage.pid, &pAppId); + _LOGD("app_id: %s", pAppId); + + if (ret < 0) + { + _LOGE("Failed to get_app_id: %d", ret); + return -1; + } + + strncpy(helloMessage.appId, pAppId, 255); + + _LOGD("app_id: %s", helloMessage.appId); + + __appId = pAppId; + + free(pAppId); + } + + struct sockaddr_un server; + + bzero(&server, sizeof(server)); + server.sun_family = AF_UNIX; + strncpy(server.sun_path, socketName.c_str(), socketNameLength); + socklen_t serverLen = sizeof(server); + + int client = socket(AF_UNIX, SOCK_STREAM, 0); + if (client < 0) + { + _LOGE("Failed to create a socket : %s.", strerror(errno)); + return -1; + } + + int flags = fcntl(client, F_GETFL, 0); + ret = fcntl(client, F_SETFL, flags | O_NONBLOCK); + if (ret != 0) + { + _LOGE("Failed to set file status flags (%d, %s).", errno, strerror(errno)); + goto CATCH; + } + + ret = connect(client, (struct sockaddr*) &server, serverLen); + if (ret != 0) + { + if (errno != EINPROGRESS) + { + _LOGE("Failed to connect to server(%s) : %s", socketName.c_str(), strerror(errno)); + goto CATCH; + } + + fd_set rset; + fd_set wset; + struct timeval timeout; + int length = 0; + int error = 0; + socklen_t socketLength = 0; + + FD_ZERO(&rset); + FD_SET(client, &rset); + wset = rset; + timeout.tv_sec = 10; // FIXME: replace 10 with const int + timeout.tv_usec = 0; + + while (true) + { + ret = select(client+1, &rset, &wset, NULL, &timeout); + if (ret < 0) + { + _LOGE("Failed to connect due to system error : %s.", strerror(errno)); + if (errno != EINTR) + { + goto CATCH; + } + + continue; + } + else if (ret == 0) + { + _LOGE("Failed to connect due to timeout."); + goto CATCH; + } + else + { + break; + } + } + + if (FD_ISSET(client, &rset) || FD_ISSET(client, &wset)) + { + length = sizeof(error); + ret = getsockopt(client, SOL_SOCKET, SO_ERROR, &error, &socketLength); + if (ret < 0) + { + _LOGE("Failed to connect to server(%s) : %s", socketName.c_str(), strerror(errno)); + goto CATCH; + } + } + else + { + _LOGE("Failed to connect due to system error."); + goto CATCH; + } + } + + ret = fcntl(client, F_SETFL, flags); + if (ret < 0) + { + _LOGE("Failed to set file status flags (%d, %s).", errno, strerror(errno)); + goto CATCH; + } + + ret = write(client, &helloMessage, sizeof(helloMessage)); + if (ret < 0) + { + goto CATCH; + } + + if (forReverse) + { + GError* pGError = NULL; + GSource* pGSource = NULL; + + GIOChannel* pChannel = g_io_channel_unix_new(client); + GMainContext* pGMainContext = g_main_context_default(); + + g_io_channel_set_encoding(pChannel, NULL, &pGError); + g_io_channel_set_flags(pChannel, G_IO_FLAG_NONBLOCK, &pGError); + g_io_channel_set_close_on_unref(pChannel, TRUE); + + pGSource = g_io_create_watch(pChannel, (GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_NVAL | G_IO_HUP)); + g_source_set_callback(pGSource, (GSourceFunc) OnReadMessage, this, NULL); + g_source_attach(pGSource, pGMainContext); + + g_io_channel_unref(pChannel); + __pReverseSource = pGSource; + } + else + { + ++__fdCount; + + ReleaseFd(client); + } + + return 0; + +CATCH: + if (client != -1) + { + close(client); + } + + return -1; + +} + +gboolean +IpcClient::OnReadMessage(GIOChannel* source, GIOCondition condition, gpointer data) +{ + IpcClient* pIpcClient = (IpcClient*) data; + + return pIpcClient->HandleReceivedMessage(source, condition); +} + +gboolean +IpcClient::HandleReceivedMessage(GIOChannel* source, GIOCondition condition) +{ + GError* pGError = NULL; + GIOStatus status; + IPC::Message* pMessage = NULL; + + if (condition & G_IO_HUP) + { + g_source_destroy(__pReverseSource); + g_source_unref(__pReverseSource); + __pReverseSource = NULL; + + return FALSE; + } + else if (condition & G_IO_IN) + { + gsize readSize = 0; + const char* pStart = NULL; + const char* pEnd = NULL; + const char* pEndOfMessage = NULL; + + while (true) + { + pGError = NULL; + status = g_io_channel_read_chars(source, (char*) __messageBuffer, __MAX_MESSAGE_BUFFER_SIZE, &readSize, &pGError); + if (status == G_IO_STATUS_EOF) + { + pGError = NULL; + + g_io_channel_shutdown(source, FALSE, &pGError); + + g_source_destroy(__pReverseSource); + g_source_unref(__pReverseSource); + __pReverseSource = NULL; + + return FALSE; + } + + if (readSize == 0) + { + break; + } + + if (__pending.empty()) + { + pStart = __messageBuffer; + pEnd = pStart + readSize; + } + else + { + __pending.append(__messageBuffer, readSize); + pStart = __pending.data(); + pEnd = pStart + __pending.size(); + } + + while (true) + { + pEndOfMessage = IPC::Message::FindNext(pStart, pEnd); + if (pEndOfMessage == NULL) + { + __pending.assign(pStart, pEnd - pStart); + break; + } + + pMessage = new (std::nothrow) IPC::Message(pStart, pEndOfMessage - pStart); + if (pMessage == NULL) + { + _LOGE("The memory is insufficient"); + return -2; + } + + if (__pListener) + { + __pListener->OnIpcResponseReceived(*this, *pMessage); + } + + delete pMessage; + + pStart = pEndOfMessage; + } + } + } + else + { + // empty statement. + } + + return TRUE; +} + +int +IpcClient::AcquireFd(void) +{ + int ret = 0; + int fd = -1; + + while (fd == -1) + { + //__pFdLock->Acquire(); + if (__fds.size() == 0) + { + //__pFdLock->Release(); + ret = MakeConnection(false); + if (ret < 0) + { + _LOGE("Failed to connect to the server."); + return -1; + } + + continue; + } + + fd = __fds.back(); + __fds.pop_back(); + + //__pFdLock->Release(); + } + + return fd; +} + +void +IpcClient::ReleaseFd(int fd) +{ + //__pFdLock->Acquire(); + + __fds.push_back(fd); + + //__pFdLock->Release(); +} + +int +IpcClient::SendAsync(IPC::Message* pMessage) +{ + char* pData = (char*) pMessage->data(); + int remain = pMessage->size(); + int fd = AcquireFd(); + if (fd == -1) + { + _LOGE("Failed to get fd."); + return -1; + } + + int written = 0; + while (remain > 0) + { + written = write(fd, (char*) pData, remain); + remain -= written; + pData += written; + } + + ReleaseFd(fd); + + return 0; +} + +int +IpcClient::SendSync(IPC::Message* pMessage) +{ + IPC::Message* pReply = NULL; + MessageReplyDeserializer* pReplyDeserializer = NULL; + IPC::SyncMessage* pSyncMessage = dynamic_cast (pMessage); + if (pSyncMessage == NULL) + { + _LOGE("pMessage is not a sync message."); + return -1; + } + + int messageId = SyncMessage::GetMessageId(*pSyncMessage); + + int fd = AcquireFd(); + if (fd < 0) + { + _LOGE("Failed to get fd."); + return -1; + } + + char* pData = (char*) pSyncMessage->data(); + int remain = pSyncMessage->size(); + int written = 0; + + while (remain > 0) + { + written = write(fd, (char*) pData, remain); + remain -= written; + pData += written; + } + + // Wait reply + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = POLLIN | POLLRDHUP; + pfd.revents = 0; + + char buffer[1024]; + std::string message; + int readSize = 0; + char* pEndOfMessage = NULL; + + while (true) + { + poll(&pfd, 1, -1); + + if (pfd.revents & POLLRDHUP) + { + return -1; + } + + if (pfd.revents & POLLIN) + { + readSize = read(fd, buffer, 1024); + } + + message.append(buffer, readSize); + + pEndOfMessage = (char*) IPC::Message::FindNext(message.data(), message.data() + message.size()); + if (pEndOfMessage) + { + pReply = new (std::nothrow) IPC::Message(message.data(), pEndOfMessage - message.data()); + if (pReply == NULL) + { + _LOGE("The memory is insufficient."); + return -2; + } + + break; + } + } + + pReplyDeserializer = pSyncMessage->GetReplyDeserializer(); + pReplyDeserializer->SerializeOutputParameters(*pReply); + + delete pReply; + delete pReplyDeserializer; + + ReleaseFd(fd); + + return 0; +} + +int +IpcClient::Send(IPC::Message* pMessage) +{ + int ret = 0; + + if (pMessage->is_sync()) + { + ret = SendSync(pMessage); + } + else + { + ret = SendAsync(pMessage); + } + + return ret; +} + +int +IpcClient::SendRequest(IPC::Message* pMessage) +{ + return Send(pMessage); +} + +int +IpcClient::SendRequest(const IPC::Message& message) +{ + int ret = 0; + + if (message.is_sync()) + { + ret = SendSync(const_cast(&message)); + } + else + { + ret = SendAsync(const_cast(&message)); + } + + return ret; +} + +string +IpcClient::GetAppId(void) +{ + return __appId; +} diff --git a/src/IpcClient.h b/src/IpcClient.h new file mode 100644 index 0000000..ac849ee --- /dev/null +++ b/src/IpcClient.h @@ -0,0 +1,143 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file IpcClient.h + * @brief This is the header file for the IpcClient class. + * + * This file contains the declarations of IpcClient. + */ + + +#ifndef _IPC_CLIENT_H_ +#define _IPC_CLIENT_H_ + +#include +#include +#include +#include +#include + +#include +#include + + +class IIpcClientEventListener; + +/** + * @class IpcClient + * @brief This class provides methods for sending a message to an IPC server. + * @since 2.1 + * + */ +class IpcClient +{ +public: + /** + * This is the default constructor for this class. + */ + IpcClient(void); + + /** + * This is the destructor for this class. + */ + virtual ~IpcClient(void); + + /** + * Constructs the instance of this class. + * + * @return An error code + * @param[in] serverName The name of the server + * @param[in] pListener Set if the client want to handle a message from the IPC server. + * @c NULL, otherwise. + * @exception E_SUCCESS The method was successful. + * @exception E_OBJ_NOT_FOUND The IPC server was not found. + * @exception E_OUT_OF_MEMORY Insufficient memory. + * @exception E_SYSTEM A system error occurred. + */ + int Construct(const std::string& serverName, const IIpcClientEventListener* pListener = NULL); + + /** + * Sends a request message to an IPC server. + * + * @code + * + * + * int + * CalculatorProxy::Add(int a , int b) + * { + * int c = 0; + * + * My_sum mySum(a, b, &c); + * + * __pIpcClient->SendRequest(mySum); + * + * return c; + * } + * + * @endcode + * @return An error code + * @param[in] message The message to send + * @exception E_SUCCESS The method was successful. + * @exception E_INVALID_STATE The instance is in an invalid state. + * @exception E_OUT_OF_MEMORY Insufficient memory. + * @exception E_SYSTEM A system error occurred. + * + */ + int SendRequest(const IPC::Message& message); + + int SendRequest(IPC::Message* pMessage); + + std::string GetAppId(void); + +private: + IpcClient(const IpcClient& value); + + IpcClient& operator =(const IpcClient& value); + + int Send(IPC::Message* pMessage); + + int SendAsync(IPC::Message* pMessage); + + int SendSync(IPC::Message* pMessage); + + int MakeConnection(bool forReverse = false); + + int AcquireFd(void); + + void ReleaseFd(int fd); + + static gboolean OnReadMessage(GIOChannel* source, GIOCondition condition, gpointer data); + + gboolean HandleReceivedMessage(GIOChannel* source, GIOCondition condition); + +private: + GSource* __pReverseSource; + + std::vector __fds; + int __fdCount; + //Tizen::Base::Runtime::Mutex* __pFdLock; + std::string __name; + std::string __appId; + IIpcClientEventListener* __pListener; + + static const int __MAX_MESSAGE_BUFFER_SIZE = 1024; + char __messageBuffer[__MAX_MESSAGE_BUFFER_SIZE]; + std::string __pending; +}; + +#endif // _IPC_CLIENT_H_ diff --git a/src/MessagePortProxy.cpp b/src/MessagePortProxy.cpp new file mode 100644 index 0000000..c203bad --- /dev/null +++ b/src/MessagePortProxy.cpp @@ -0,0 +1,663 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file MessagePortProxy.cpp + * @brief This is the implementation file for the MessagePortProxy class. + * + */ + + +#include +#include +#include + +#include + +#include "message-port.h" +#include "message-port-messages.h" +#include "message-port-log.h" + +#include "IpcClient.h" +#include "MessagePortProxy.h" + +using namespace std; + +static const char MESSAGE_TYPE[] = "MESSAGE_TYPE"; + +static const char LOCAL_APPID[] = "LOCAL_APPID"; +static const char LOCAL_PORT[] = "LOCAL_PORT"; +static const char TRUSTED_LOCAL[] = "TRUSTED_LOCAL"; + +static const char REMOTE_APPID[] = "REMOTE_APPID"; +static const char REMOTE_PORT[] = "REMOTE_PORT"; +static const char TRUSTED_REMOTE[] = "TRUSTED_REMOTE"; +static const char TRUSTED_MESSAGE[] = "TRUSTED_MESSAGE"; + +static const int MAX_MESSAGE_SIZE = 8 * 1024; + +MessagePortProxy::MessagePortProxy(void) + : __pIpcClient(NULL) + , __pMutex(NULL) +{ +} + +MessagePortProxy::~MessagePortProxy(void) +{ + pthread_mutex_destroy(__pMutex); +} + +int +MessagePortProxy::Construct(void) +{ + IpcClient* pIpcClient = new (std::nothrow) IpcClient(); + if (pIpcClient == NULL) + { + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + int ret = pIpcClient->Construct("message-port-server", this); + if (ret != 0) + { + delete pIpcClient; + + _LOGE("Failed to create ipc client: %d.", ret); + + return MESSAGEPORT_ERROR_IO_ERROR; + } + + pthread_mutex_t* pMutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)); + if (pMutex == NULL) + { + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + pthread_mutex_init(pMutex, NULL); + + __pMutex = pMutex; + __pIpcClient = pIpcClient; + __appId = pIpcClient->GetAppId(); + + return 0; +} + +void +MessagePortProxy::OnIpcResponseReceived(IpcClient& client, const IPC::Message& message) +{ + _LOGD("Message received, type %d", message.type()); + + IPC_BEGIN_MESSAGE_MAP(MessagePortProxy, message) + IPC_MESSAGE_HANDLER_EX(MessagePort_sendMessageAsync, &client, OnSendMessageInternal) + IPC_END_MESSAGE_MAP_EX() +} + +int +MessagePortProxy::RegisterMessagePort(const string& localPort, bool isTrusted, messageport_message_cb callback) +{ + _LOGD("Register a message port : [%s:%s]", __appId.c_str(), localPort.c_str()); + + int id = 0; + + // Check the message port is already registed + if (IsLocalPortRegisted(localPort, isTrusted, id)) + { + if (!isTrusted) + { + __listeners[localPort] = callback; + } + else + { + __trustedListeners[localPort] = callback; + } + + return id; + } + + bundle *b = bundle_create(); + + if (!isTrusted) + { + bundle_add(b, TRUSTED_LOCAL, "FALSE"); + } + else + { + bundle_add(b, TRUSTED_LOCAL, "TRUE"); + } + + bundle_add(b, LOCAL_APPID, __appId.c_str()); + bundle_add(b, LOCAL_PORT, localPort.c_str()); + + + // Create Bundle Buffer from bundle + BundleBuffer buffer; + buffer.b = b; + + int ret = 0; + int return_value = 0; + + IPC::Message* pMsg = new MessagePort_registerPort(buffer, &return_value); + if (pMsg == NULL) + { + bundle_free(b); + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + ret = __pIpcClient->SendRequest(pMsg); + + delete pMsg; + + bundle_free(b); + + if (ret != 0) + { + _LOGE("Failed to send a request: %d.", ret); + + return MESSAGEPORT_ERROR_IO_ERROR; + } + + + // Add a listener + if (!isTrusted) + { + // Local port id + id = GetNextId(); + + __listeners[localPort] = callback; + __idFromString[localPort] = id; + __ids[id] = localPort; + } + else + { + id = GetNextId(); + + __trustedListeners[localPort] = callback; + __trustedIdFromString[localPort] = id; + __trustedIds[id] = localPort; + } + + return id; +} + +int +MessagePortProxy::CheckRemotePort(const string& remoteAppId, const string& remotePort, bool isTrusted, bool *exist) +{ + _LOGD("Check a remote port : [%s:%s]", remoteAppId.c_str(), remotePort.c_str()); + + int ret = 0; + + // Check the certificate + if (isTrusted) + { + // Check the preloaded + if (!IsPreloaded(remoteAppId)) + { + ret = CheckCertificate(remoteAppId); + if (ret < 0) + { + return ret; + } + } + } + + bundle *b = bundle_create(); + bundle_add(b, REMOTE_APPID, remoteAppId.c_str()); + bundle_add(b, REMOTE_PORT, remotePort.c_str()); + + if (!isTrusted) + { + bundle_add(b, TRUSTED_REMOTE, "FALSE"); + } + else + { + bundle_add(b, TRUSTED_REMOTE, "TRUE"); + } + + // To Bundle Buffer + BundleBuffer buffer; + buffer.b = b; + + int return_value = 0; + IPC::Message* pMsg = new MessagePort_checkRemotePort(buffer, &return_value); + if (pMsg == NULL) + { + bundle_free(b); + + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + ret = __pIpcClient->SendRequest(pMsg); + + delete pMsg; + + bundle_free(b); + + if (ret < 0) + { + _LOGE("Failed to send a request: %d.", ret); + + return MESSAGEPORT_ERROR_IO_ERROR; + } + + if (return_value < 0) + { + if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) + { + *exist = false; + return 0; + } + else + { + _LOGE("Failed to check the remote messge port: %d.", return_value); + return MESSAGEPORT_ERROR_IO_ERROR; + } + } + + *exist = true; + return 0; +} + +int +MessagePortProxy::SendMessage(const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data) +{ + _LOGD("Send a message to : [%s:%s]", remoteAppId.c_str(), remotePort.c_str()); + + int ret = 0; + + // Check the certificate + if (trustedMessage) + { + // Check the preloaded + if (!IsPreloaded(remoteAppId)) + { + ret = CheckCertificate(remoteAppId); + if (ret < 0) + { + return ret; + } + } + } + + bundle_add(data, MESSAGE_TYPE, "UNI-DIR"); + + bundle_add(data, REMOTE_APPID, remoteAppId.c_str()); + bundle_add(data, REMOTE_PORT, remotePort.c_str()); + + if (!trustedMessage) + { + bundle_add(data, TRUSTED_MESSAGE, "FALSE"); + } + else + { + bundle_add(data, TRUSTED_MESSAGE, "TRUE"); + } + + BundleBuffer buffer; + buffer.b = data; + + ret = SendMessageInternal(buffer); + + return ret; +} + +int +MessagePortProxy::SendMessage(const string& localPort, bool trustedPort, const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data) +{ + _LOGD("Send a bidirectional message from [%s:%s] to [%s:%s]", __appId.c_str(), localPort.c_str(), remoteAppId.c_str(), remotePort.c_str()); + + int ret = 0; + + // Check the certificate + if (trustedMessage) + { + // Check the preloaded + if (!IsPreloaded(remoteAppId)) + { + ret = CheckCertificate(remoteAppId); + if (ret < 0) + { + return ret; + } + } + } + + bundle_add(data, MESSAGE_TYPE, "BI-DIR"); + + bundle_add(data, LOCAL_APPID, __appId.c_str()); + bundle_add(data, LOCAL_PORT, localPort.c_str()); + + if (!trustedPort) + { + bundle_add(data, TRUSTED_LOCAL, "FALSE"); + } + else + { + bundle_add(data, TRUSTED_LOCAL, "TRUE"); + } + + bundle_add(data, REMOTE_APPID, remoteAppId.c_str()); + bundle_add(data, REMOTE_PORT, remotePort.c_str()); + + if (!trustedMessage) + { + bundle_add(data, TRUSTED_MESSAGE, "FALSE"); + } + else + { + bundle_add(data, TRUSTED_MESSAGE, "TRUE"); + } + + BundleBuffer buffer; + buffer.b = data; + + ret = SendMessageInternal(buffer); + + return ret; +} + +int +MessagePortProxy::SendMessageInternal(const BundleBuffer& buffer) +{ + int ret = 0; + + IPC::Message* pMsg = new MessagePort_sendMessage(buffer, &ret); + if (pMsg == NULL) + { + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + // Check the message size + int len = 0; + bundle_raw* raw = NULL; + bundle_encode(buffer.b, &raw, &len); + + bundle_free_encoded_rawdata(&raw); + + if (len > MAX_MESSAGE_SIZE) + { + _LOGE("The size of message (%d) has exceeded the maximum limit.", len); + return MESSAGEPORT_ERROR_MAX_EXCEEDED; + } + + ret = __pIpcClient->SendRequest(pMsg); + delete pMsg; + + if (ret != 0) + { + _LOGE("Failed to send a request: %d.", ret); + return MESSAGEPORT_ERROR_IO_ERROR; + } + + return 0; +} + +char* +MessagePortProxy::GetLocalPortNameN(int id) +{ + string value; + + map::iterator it; + + it = __ids.find(id); + if (it == __ids.end()) + { + it = __trustedIds.find(id); + if (it == __ids.end()) + { + return NULL; + } + else + { + value = __trustedIds[id]; + return strdup(value.c_str()); + } + } + else + { + value = __ids[id]; + return strdup(value.c_str()); + } + + return NULL; +} + +int +MessagePortProxy::CheckTrustedLocalPort(int id, bool* trusted) +{ + map::iterator it; + + it = __ids.find(id); + if (it == __ids.end()) + { + it = __trustedIds.find(id); + if (it == __ids.end()) + { + return MESSAGEPORT_ERROR_INVALID_PARAMETER; + } + else + { + *trusted = true; + return 0; + } + } + else + { + *trusted = false; + return 0; + } + + return MESSAGEPORT_ERROR_INVALID_PARAMETER; +} + +MessagePortProxy* +MessagePortProxy::GetProxy(void) +{ + static MessagePortProxy* pProxy = NULL; + + if (pProxy == NULL) + { + MessagePortProxy* p = new MessagePortProxy(); + if (p == NULL) + { + return NULL; + } + + int ret = p->Construct(); + if (ret < 0) + { + return NULL; + } + + pProxy = p; + } + + return pProxy; +} + +int +MessagePortProxy::GetNextId(void) +{ + static int count = 0; + + pthread_mutex_lock(__pMutex); + ++count; + pthread_mutex_unlock(__pMutex); + + return count; +} + +bool +MessagePortProxy::IsLocalPortRegisted(const string& localPort, bool trusted, int &id) +{ + if (!trusted) + { + map::iterator port_it = __listeners.find(localPort); + if (port_it == __listeners.end()) + { + return false; + } + else + { + for (map::iterator it = __ids.begin(); it != __ids.end(); ++it) + { + if (localPort.compare(it->second) == 0) + { + id = it->first; + return true; + } + } + } + } + else + { + map::iterator port_it = __trustedListeners.find(localPort); + if (port_it == __trustedListeners.end()) + { + return false; + } + else + { + for (map::iterator it = __ids.begin(); it != __trustedIds.end(); ++it) + { + if (localPort.compare(it->second) == 0) + { + id = it->first; + return true; + } + } + } + } + + return false; +} + +int +MessagePortProxy::CheckCertificate(const std::string& remoteAppId) +{ + package_manager_compare_result_type_e res; + int ret = package_manager_compare_app_cert_info(__appId.c_str(), remoteAppId.c_str(), &res); + + if (ret == 0) + { + if (res != PACAKGE_MANAGER_COMPARE_MATCH) + { + _LOGE("The remote application (%s) is not signed with the same certificate", remoteAppId.c_str()); + return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH; + } + } + else + { + _LOGE("Failed to check the certificate: %d.", ret); + return MESSAGEPORT_ERROR_IO_ERROR; + } + + return 0; +} + +bool +MessagePortProxy::IsPreloaded(const std::string& remoteAppId) +{ + bool preload_local = false; + bool preload_remote = false; + + if (package_manager_is_preload_package_by_app_id(__appId.c_str(), &preload_local) == 0) + { + if (package_manager_is_preload_package_by_app_id(remoteAppId.c_str(), &preload_remote) == 0) + { + if (preload_local && preload_remote) + { + return true; + } + } + else + { + _LOGE("Failed to check the preloaded application."); + } + } + else + { + _LOGE("Failed to check the preloaded application."); + } + + return false; +} + +bool +MessagePortProxy::OnSendMessageInternal(const BundleBuffer& buffer) +{ + bundle* b = buffer.b; + + const char* pRemoteAppId = bundle_get_val(b, REMOTE_APPID); + const char* pRemotePort = bundle_get_val(b, REMOTE_PORT); + string trustedMessage = bundle_get_val(b, TRUSTED_MESSAGE); + + string messageType = bundle_get_val(b, MESSAGE_TYPE); + + _LOGD("Message received to AppId: %s, Port: %s, Trusted: %s", pRemoteAppId, pRemotePort, trustedMessage.c_str()); + + int id = 0; + messageport_message_cb callback; + + if (trustedMessage.compare("FALSE") == 0) + { + callback = __listeners[pRemotePort]; + id = __idFromString[pRemotePort]; + } + else + { + callback = __trustedListeners[pRemotePort]; + id = __trustedIdFromString[pRemotePort]; + } + + + if (callback) + { + // remove system data + bundle_del(b, REMOTE_APPID); + bundle_del(b, REMOTE_PORT); + bundle_del(b, TRUSTED_MESSAGE); + bundle_del(b, MESSAGE_TYPE); + + if (messageType.compare("UNI-DIR") == 0) + { + callback(id, NULL, NULL, false, b); + } + else + { + string localAppId = bundle_get_val(b, LOCAL_APPID); + string localPort = bundle_get_val(b, LOCAL_PORT); + string trustedLocal = bundle_get_val(b, TRUSTED_LOCAL); + + _LOGD("From AppId: %s, Port: %s, TrustedLocal: %s", localAppId.c_str(), localPort.c_str(), trustedLocal.c_str()); + + bool trustedPort = (trustedLocal.compare("TRUE") == 0); + + // remove system data + bundle_del(b, LOCAL_APPID); + bundle_del(b, LOCAL_PORT); + bundle_del(b, TRUSTED_LOCAL); + + callback(id, localAppId.c_str(), localPort.c_str(), trustedPort, b); + } + } + else + { + _LOGD("No callback"); + } + + return true; +} + diff --git a/src/MessagePortProxy.h b/src/MessagePortProxy.h new file mode 100644 index 0000000..129de9b --- /dev/null +++ b/src/MessagePortProxy.h @@ -0,0 +1,113 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file MessagePortProxy.h + * @brief This is the header file for the MessagePortProxy class. + * + * This file contains the declarations of MessagePortProxy. + */ + + +#ifndef _MESSAGE_PORT_PROXY_H_ +#define _MESSAGE_PORT_PROXY_H_ + +#include +#include +#include + +#include + +#include "message-port.h" +#include "message-port-data-types.h" + +#include "IIpcClientEventListener.h" + +namespace IPC { class Message; } + +class IpcClient; + +class MessagePortProxy + : public IIpcClientEventListener +{ +public: + virtual ~MessagePortProxy(void); + + int Construct(void); + + virtual void OnIpcResponseReceived(IpcClient& client, const IPC::Message& message); + + + int RegisterMessagePort(const std::string& localPort, + bool isTrusted, + messageport_message_cb callback); + + int CheckRemotePort(const std::string& remoteAppId, + const std::string& remotePort, + bool isTrusted, + bool *exist); + + int SendMessage(const std::string& remoteAppId, + const std::string& remotePort, + bool trustedMessage, + bundle* data); + + int SendMessage(const std::string& localPort, + bool trustedPort, + const std::string& remoteAppId, + const std::string& remotePort, + bool trustedMessage, + bundle* data); + + char* GetLocalPortNameN(int id); + + int CheckTrustedLocalPort(int id, bool* trusted); + + static MessagePortProxy* GetProxy(void); + +private: + MessagePortProxy(void); + + int SendMessageInternal(const BundleBuffer& buffer); + + bool OnSendMessageInternal(const BundleBuffer& buffer); + + int GetNextId(void); + + bool IsLocalPortRegisted(const std::string& localPort, bool trusted, int &id); + + int CheckCertificate(const std::string& remoteAppId); + + bool IsPreloaded(const std::string& remoteAppId); + +private: + IpcClient* __pIpcClient; + pthread_mutex_t* __pMutex; + + std::string __appId; + + std::map __listeners; + std::map __idFromString; + std::map __ids; + + std::map __trustedListeners; + std::map __trustedIdFromString; + std::map __trustedIds; + +}; // MessagePortProxy + +#endif // _MESSAGE_PORT_PROXY_H_ diff --git a/src/message-port-log.h b/src/message-port-log.h new file mode 100644 index 0000000..d2d1678 --- /dev/null +++ b/src/message-port-log.h @@ -0,0 +1,43 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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 __APPFW_MESSAGE_PORT_LOG_H__ +#define __APPFW_MESSAGE_PORT_LOG_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#undef LOG_TAG +#define LOG_TAG "MESSAGE_PORT" + +#define _LOGE(fmt, arg...) LOGE(fmt, ##arg) +#define _LOGD(fmt, arg...) LOGD(fmt, ##arg) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __APPFW_MESSAGE_PORT_LOG_H__ */ diff --git a/src/message-port-messages.cpp b/src/message-port-messages.cpp new file mode 100644 index 0000000..9ea580d --- /dev/null +++ b/src/message-port-messages.cpp @@ -0,0 +1,24 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file message-port-messages.cpp + * @brief This is the implementation file for the MessagePortMessages + */ + +#define IPC_MESSAGE_IMPL +#include "message-port-messages.h" diff --git a/src/message-port.cpp b/src/message-port.cpp new file mode 100644 index 0000000..f6f53cc --- /dev/null +++ b/src/message-port.cpp @@ -0,0 +1,184 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** + * @file message-port.cpp + * @brief This is the implementation file for the MessagePort. + */ + +#include + +#include "message-port.h" +#include "message-port-log.h" + +#include "MessagePortProxy.h" + +int +messageport_register_local_port(const char* local_port, messageport_message_cb callback) +{ + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + return pProxy->RegisterMessagePort(local_port, false, callback); + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + +int +messageport_register_trusted_local_port(const char* local_port, messageport_message_cb callback) +{ + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + return pProxy->RegisterMessagePort(local_port, true, callback); + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + +int +messageport_check_remote_port(const char* remote_app_id, const char *remote_port, bool* exist) +{ + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + return pProxy->CheckRemotePort(remote_app_id, remote_port, false, exist); + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + +int +messageport_check_trusted_remote_port(const char* remote_app_id, const char *remote_port, bool* exist) +{ + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + return pProxy->CheckRemotePort(remote_app_id, remote_port, true, exist); + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + +int +messageport_send_message(const char* remote_app_id, const char* remote_port, bundle* message) +{ + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + return pProxy->SendMessage(remote_app_id, remote_port, false, message); + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + +int +messageport_send_trusted_message(const char* remote_app_id, const char* remote_port, bundle* message) +{ + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + return pProxy->SendMessage(remote_app_id, remote_port, true, message); + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + +int +messageport_send_bidirectional_message(int id, const char* remote_app_id, const char* remote_port, bundle* message) +{ + int ret = 0; + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + char* pName = pProxy->GetLocalPortNameN(id); + bool trusted = false; + pProxy->CheckTrustedLocalPort(id, &trusted); + + ret = pProxy->SendMessage(pName, trusted, remote_app_id, remote_port, false, message); + + free(pName); + + return ret; + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + +int +messageport_send_bidirectional_trusted_message(int id, const char* remote_app_id, const char* remote_port, bundle* message) +{ + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + bool trusted = false; + int ret = pProxy->CheckTrustedLocalPort(id, &trusted); + if (ret < 0) + { + return ret; + } + + char* pName = pProxy->GetLocalPortNameN(id); + if (pName == NULL) + { + return MESSAGEPORT_ERROR_INVALID_PARAMETER; + } + + ret = pProxy->SendMessage(pName, trusted, remote_app_id, remote_port, true, message); + + free(pName); + + return ret; + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + +int +messageport_get_local_port_name(int id, char **name) +{ + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + char* pName = pProxy->GetLocalPortNameN(id); + if (pName == NULL) + { + return MESSAGEPORT_ERROR_INVALID_PARAMETER; + } + else + { + *name = pName; + return 0; + } + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + +int +messageport_check_trusted_local_port(int id, bool *trusted) +{ + MessagePortProxy* pProxy = MessagePortProxy::GetProxy(); + if (pProxy != NULL) + { + return pProxy->CheckTrustedLocalPort(id, trusted); + } + + return MESSAGEPORT_ERROR_IO_ERROR; +} + -- 2.7.4