From 8c5560922ff9fddb3d8913a340b19ed982feafb9 Mon Sep 17 00:00:00 2001 From: Jiwoong Im Date: Fri, 5 Jun 2015 16:22:10 +0900 Subject: [PATCH] update source from tizen 2.4 - implementation based on gdbus - This repository contain capi-message-port and message-port. To provide 2 packages, install 2 pc files. Change-Id: Iaaa83771690d6e1701e07eead6ab6d9a467c7475 Signed-off-by: Jiwoong Im --- CMakeLists.txt | 67 +- capi-message-port.pc.in | 15 + include/message-port-messages.h | 38 - include/message-port-param-traits.h | 99 -- include/message-port.h | 37 +- include/message_port.h | 374 ++++++ include/message_port_error.h | 39 + include/message_port_internal.h | 33 + message-port.pc.in | 2 +- packaging/message-port.changes | 34 - packaging/message-port.manifest | 6 +- packaging/message-port.spec | 25 +- src/CMakeLists.txt | 62 + src/IIpcClientEventListener.h | 61 - src/IpcClient.cpp | 656 ---------- src/IpcClient.h | 127 -- src/MessagePortProxy.cpp | 633 ---------- src/MessagePortProxy.h | 109 -- src/{ => inc}/message-port-log.h | 0 .../inc/message_port_log.h | 24 +- src/message-port-messages.cpp | 24 - src/message-port.c | 1282 ++++++++++++++++++++ src/message-port.cpp | 189 --- src/message_port.c | 290 +++++ src/message_port_internal.c | 41 + 25 files changed, 2188 insertions(+), 2079 deletions(-) mode change 100755 => 100644 CMakeLists.txt create mode 100644 capi-message-port.pc.in delete mode 100644 include/message-port-messages.h delete mode 100644 include/message-port-param-traits.h mode change 100755 => 100644 include/message-port.h create mode 100644 include/message_port.h create mode 100644 include/message_port_error.h create mode 100755 include/message_port_internal.h mode change 100755 => 100644 message-port.pc.in delete mode 100644 packaging/message-port.changes mode change 100755 => 100644 packaging/message-port.spec create mode 100755 src/CMakeLists.txt delete mode 100644 src/IIpcClientEventListener.h delete mode 100644 src/IpcClient.cpp delete mode 100644 src/IpcClient.h delete mode 100644 src/MessagePortProxy.cpp delete mode 100644 src/MessagePortProxy.h rename src/{ => inc}/message-port-log.h (100%) rename include/message-port-data-types.h => src/inc/message_port_log.h (61%) delete mode 100644 src/message-port-messages.cpp create mode 100755 src/message-port.c delete mode 100644 src/message-port.cpp create mode 100644 src/message_port.c create mode 100644 src/message_port_internal.c diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index 4f21406..ea30bdb --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,78 +1,17 @@ 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 ( - 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 aul 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 -fvisibility=hidden") -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} -fvisibility=hidden -fvisibility-inlines-hidden") +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DSLP_DEBUG") 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=${LIB_INSTALL_DIR}") - -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} "-laul" ) - -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_INSTALL_DIR}/pkgconfig) - -INSTALL(TARGETS ${this_target} DESTINATION ${LIB_INSTALL_DIR}) - -INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/appfw FILES_MATCHING PATTERN "*.h") +ADD_SUBDIRECTORY(src) -INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/ DESTINATION ${LIB_INSTALL_DIR} - FILES_MATCHING PATTERN "*.so*" - PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - GROUP_EXECUTE GROUP_READ - WORLD_EXECUTE WORLD_READ) diff --git a/capi-message-port.pc.in b/capi-message-port.pc.in new file mode 100644 index 0000000..8724ba1 --- /dev/null +++ b/capi-message-port.pc.in @@ -0,0 +1,15 @@ + +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@/appfw + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: capi-base-common +Libs: -L${libdir} -lmessage-port +Cflags: -I${includedir} + diff --git a/include/message-port-messages.h b/include/message-port-messages.h deleted file mode 100644 index 1ced3da..0000000 --- a/include/message-port-messages.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// 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_CONTROL2_1(MessagePort_sendMessage, BundleBuffer, BundleBuffer, int) -IPC_MESSAGE_CONTROL2(MessagePort_sendMessageAsync, BundleBuffer, BundleBuffer) - -#endif //_APPFW_MESSAGE_PORT_MESSAGES_H_ diff --git a/include/message-port-param-traits.h b/include/message-port-param-traits.h deleted file mode 100644 index e99a0da..0000000 --- a/include/message-port-param-traits.h +++ /dev/null @@ -1,99 +0,0 @@ -// -// 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_raw(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_raw((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 old mode 100755 new mode 100644 index aa10b99..83c04f9 --- a/include/message-port.h +++ b/include/message-port.h @@ -28,28 +28,13 @@ #endif #include +#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_RESOURCE_UNAVAILABLE = -7, /**< Resource temporarily unavailable */ -} 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() @@ -62,6 +47,18 @@ typedef enum */ typedef void (*messageport_message_cb)(int id, const char* remote_app_id, const char* remote_port, bool trusted_message, bundle* data); +/** + * @brief Unregisters the local message port. @n + * + * @param [in] local_port_id the id of the local message port + * @param [in] trusted_port true if target port is trusted port + * @return Return positive 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 + */ +EXPORT_API int messageport_unregister_local_port(int local_port_id, bool trusted_port); /** * @brief Registers the local message port. @n @@ -74,6 +71,7 @@ typedef void (*messageport_message_cb)(int id, const char* remote_app_id, const * @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 + * @retval #MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE Resource temporarily unavailable */ EXPORT_API int messageport_register_local_port(const char* local_port, messageport_message_cb callback); @@ -89,6 +87,7 @@ EXPORT_API int messageport_register_local_port(const char* local_port, messagepo * @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 + * @retval #MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE Resource temporarily unavailable */ EXPORT_API int messageport_register_trusted_local_port(const char* local_port, messageport_message_cb callback); @@ -103,6 +102,7 @@ EXPORT_API int messageport_register_trusted_local_port(const char* local_port, m * @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 + * @retval #MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE Resource temporarily unavailable */ EXPORT_API int messageport_check_remote_port(const char* remote_app_id, const char *remote_port, bool* exist); @@ -118,6 +118,7 @@ EXPORT_API int messageport_check_remote_port(const char* remote_app_id, const ch * @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 + * @retval #MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE Resource temporarily unavailable */ EXPORT_API int messageport_check_trusted_remote_port(const char* remote_app_id, const char *remote_port, bool* exist); @@ -134,6 +135,7 @@ EXPORT_API int messageport_check_trusted_remote_port(const char* remote_app_id, * @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 + * @retval #MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE Resource temporarily unavailable * * @code * #include @@ -164,6 +166,7 @@ EXPORT_API int messageport_send_message(const char* remote_app_id, const char* r * @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 + * @retval #MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE Resource temporarily unavailable */ EXPORT_API int messageport_send_trusted_message(const char* remote_app_id, const char* remote_port, bundle* message); @@ -181,6 +184,7 @@ EXPORT_API int messageport_send_trusted_message(const char* remote_app_id, const * @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 + * @retval #MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE Resource temporarily unavailable * * @code * #include @@ -221,6 +225,7 @@ EXPORT_API int messageport_send_bidirectional_message(int id, const char* remote * @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 + * @retval #MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE Resource temporarily unavailable */ EXPORT_API int messageport_send_bidirectional_trusted_message(int id, const char* remote_app_id, const char* remote_port, bundle* data); diff --git a/include/message_port.h b/include/message_port.h new file mode 100644 index 0000000..d9ee2ad --- /dev/null +++ b/include/message_port.h @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2014 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_APPFW_MESSAGE_PORT_H__ +#define __TIZEN_APPFW_MESSAGE_PORT_H__ + +#ifdef __GNUC__ +# ifndef EXPORT_API +# define EXPORT_API __attribute__((visibility("default"))) +# endif +#else +# define EXPORT_API +#endif + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup CAPI_MESSAGE_PORT_MODULE + * @{ + */ + +/** + * @brief Enumeration for error codes of a message port. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum +{ + MESSAGE_PORT_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + MESSAGE_PORT_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< Internal I/O error */ + MESSAGE_PORT_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + MESSAGE_PORT_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + MESSAGE_PORT_ERROR_PORT_NOT_FOUND = TIZEN_ERROR_MESSAGE_PORT | 0x01, /**< The message port of the remote application is not found */ + MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH = TIZEN_ERROR_MESSAGE_PORT | 0x02, /**< The remote application is not signed with the same certificate */ + MESSAGE_PORT_ERROR_MAX_EXCEEDED = TIZEN_ERROR_MESSAGE_PORT | 0x03, /**< The size of the message has exceeded the maximum limit */ + MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE = TIZEN_ERROR_MESSAGE_PORT | 0x04 /**< Resource is temporarily unavailable */ +} message_port_error_e; + +/** + * @brief Called when a message is received. + * @details The function is called when a message is received from the remote application. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks You can keep @a message using bundle_dup(). @n + * @a remote_port will be set only if the remote application sends a message with its port information using message_port_send_message_with_local_port(), otherwise it is @c NULL. @n + * When message is sent from remote application by message_port_send_message_with_local_port() in bidirectional communication, trusted_remote_port is used to check whether remote port is trusted port or not. + * This callback is called only in the main thread. + * + * @param[in] local_port_id The local message port ID returned by message_port_register_local_port() + * @param[in] remote_app_id The ID of the remote application that sent this message + * @param[in] remote_port The name of the remote message port + * @param[in] trusted_remote_port If @c true the remote port is a trusted port, otherwise if @c false it is not + * @param[in] message The message passed from the remote application + * @param[in] user_data The user data passed from the register function + * @pre Either message_port_send_message() or message_port_send_message_with_local_port() from the remote application will invoke this function if you register it using message_port_register_local_port(). + * @see message_port_register_local_port() + * @see message_port_unregister_local_port() + * @see message_port_send_message() + * @see message_port_send_message_with_local_port() + */ +typedef void (*message_port_message_cb)(int local_port_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, bundle *messagem, void *user_data); + +/** + * @brief Called when a trusted message is received. + * @details This function is called when a trusted message is received from the remote application. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks You can keep @a message using bundle_dup(). @n + * @a remote_port will be set only if the remote application sends a message with its port information using message_port_send_trusted_message_with_local_port(), otherwise it is @c NULL. @n + * When message is sent from remote application by message_port_send_trusted_message_with_local_port() in bidirectional communication, trusted_remote_port is used to check whether remote port is trusted port or not. + * This callback is called only in the main thread. + * @param[in] trusted_local_port_id The message port ID returned by message_port_register_trusted_local_port() + * @param[in] remote_app_id The ID of the remote application that sent this message + * @param[in] remote_port The name of the remote message port + * @param[in] trusted_remote_port If @c true the remote port is a trusted port, otherwise if @c false it is not + * @param[in] message The message passed from the remote application + * @param[in] user_data The user data passed from the register function + * @pre Either message_port_send_trusted_message() or message_port_send_trusted_message_with_local_port() from the remote application will invoke this function if you register it using message_port_register_trusted_local_port(). + * @see message_port_register_trusted_local_port() + * @see message_port_unregister_trusted_local_port() + * @see message_port_send_trusted_message() + * @see message_port_send_trusted_message_with_local_port() + */ +typedef void (*message_port_trusted_message_cb)(int trusted_local_port_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, bundle *message, void *user_data); + +/** + * @brief Registers the local message port. + * @details If the message port name is already registered, the previous local message port ID returns and the callback function is changed. \n + * Multiple message ports can be registered. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks The specified callback is called only in the main thread. + * @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 + * @param[in] user_data The user data to be passed to the callback function + * + * @return A local message port ID on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a local_port or @a callback is NULL + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see message_port_unregister_local_port() + */ +EXPORT_API int message_port_register_local_port(const char *local_port, message_port_message_cb callback, void *user_data); + +/** + * @brief Registers the trusted local message port. + * @details If the message port name is already registered, the previous local message port ID returns and the callback function is changed. @n + * It allows communications only if the applications are signed with the same certificate which is uniquely assigned to the developer. @n + * Multiple message ports can be registered. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks The specified callback is called only in the main thread. + * @param[in] trusted_local_port The name of the trusted local message port + * @param[in] callback The callback function to be called when a trusted message is received + * @param[in] user_data The user data to be passed to the callback function + * @return A trusted local message port ID on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a trusted_local_port or @a callback is NULL + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see message_port_unregister_trusted_local_port() + */ +EXPORT_API int message_port_register_trusted_local_port(const char *trusted_local_port, message_port_trusted_message_cb callback, void *user_data); + +/** + * @brief Unregisters the local message port. + * @details This method unregisters the callback function with the specified local port ID. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] local_port_id The local message port ID + * @return 0 on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_NONE Successful + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a local_port_id is not positive + * @retval #MESSAGE_PORT_ERROR_PORT_NOT_FOUND The specified @a local_port_id cannot be found + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see message_port_register_local_port() + */ +EXPORT_API int message_port_unregister_local_port(int local_port_id); + +/** + * @brief Registers the trusted local message port. + * @details This method unregisters the callback function with the specified local port ID. @n + * It allows communications only if the applications are signed with the same certificate which is uniquely assigned to the developer. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @param[in] trusted_local_port_id The trusted local message port ID + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_NONE Successful + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a trusted_local_port_id is not positive + * @retval #MESSAGE_PORT_ERROR_PORT_NOT_FOUND The specified @a trusted_local_port_id cannot be found + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @see message_port_register_trusted_local_port() + */ +EXPORT_API int message_port_unregister_trusted_local_port(int trusted_local_port_id); + +/** + * @brief Checks whether the message port of a remote application is registered. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks If this function returns a negative error value, the out parameter @a exist will not be changed. + * @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 If @c true the message port of the remote application exists, + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_NONE Successful + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id or @a remote_port is NULL + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + */ +EXPORT_API int message_port_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist); + +/** + * @brief Checks whether the trusted message port of a remote application is registered. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks If this function returns a negative error value, the out parameter @a exist will not be changed. + * @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 If @c true the message port of the remote application exists, + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_NONE Successful + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id or @a remote_port is @c NULL + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH The remote application is not signed with the same certificate + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + */ +EXPORT_API int message_port_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. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks @a message must be released with bundle_free() after sending the message. + * @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, the recommended message size is under 4KB + * @return 0 on success, otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_NONE Successful + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id, @a remote_port or @a message is NULL + * @retval #MESSAGE_PORT_ERROR_PORT_NOT_FOUND The message port of the remote application cannot be found + * @retval #MESSAGE_PORT_ERROR_MAX_EXCEEDED The size of message has exceeded the maximum limit + * @retval #MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE Resource temporarily unavailable + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @post It invokes message_port_message_cb() on the remote application. + * @see message_port_message_cb() + * @see message_port_register_local_port() + * @see message_port_unregister_local_port() + * + * @code + * #include + * + * bundle *b = bundle_create(); + * bundle_add(b, "key1", "value1"); + * bundle_add(b, "key2", "value2"); + * + * int ret = message_port_send_message("0123456789.BasicApp", "BasicAppPort", b); + * + * bundle_free(b); + * @endcode + */ +EXPORT_API int message_port_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. + * @details This method allows communication only if the applications are signed with the same certificate which is uniquely assigned to the developer. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks You must release @a message using bundle_free() after sending the message. + * @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, the recommended message size is under 4KB + * @return 0 on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_NONE Successful + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id, @a remote_port or @a message is @c NULL + * @retval #MESSAGE_PORT_ERROR_PORT_NOT_FOUND The message port of the remote application cannot be found + * @retval #MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH The remote application is not signed with the same certificate + * @retval #MESSAGE_PORT_ERROR_MAX_EXCEEDED The size of the message has exceeded the maximum limit + * @retval #MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE Resource is temporarily unavailable + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @post It invokes message_port_trusted_message_cb() on the remote application. + * @see message_port_trusted_message_cb() + * @see message_port_register_trusted_local_port() + * @see message_port_unregister_trusted_local_port() + */ +EXPORT_API int message_port_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message); + +/** + * @brief Sends a message with local port information to the message port of a remote application. + * @details This method is used for bidirectional communication. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks You must releas @a message using bundle_free() after sending the message. + * @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, the recommended message size is under 4KB + * @param[in] local_port_id The message port ID returned by message_port_register_local_port() or message_port_register_trusted_local_port() + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_NONE Successful + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id, @a remote_port or @a message is @c NULL and + The specified @a local_port_id is not positive + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_PORT_NOT_FOUND The port of the local or remote application cannot be found + * @retval #MESSAGE_PORT_ERROR_MAX_EXCEEDED The size of the message has exceeded the maximum limit + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @post It invokes message_port_message_cb() on the remote application. + * @see message_port_message_cb() + * @see message_port_register_local_port() + * @see message_port_unregister_local_port() + * + * @code + * #include + * + * static void + * message_port_receive_cb(int local_port_id, const char *remote_app_id, const char *remote_port, bundle *message) + * { + * } + * + * int main(int argc, char *argv[]) + * { + * bundle *b = bundle_create(); + * bundle_add(b, "key1", "value1"); + * bundle_add(b, "key2", "value2"); + * + * int local_port_id = message_port_register_local_port("HelloPort", message_port_receive_cb); + * + * int ret = message_port_send_message_with_local_port("0123456789.BasicApp", "BasicAppPort", b, local_port_id); + * + * bundle_free(b); + * } + * @endcode + */ +EXPORT_API int message_port_send_message_with_local_port(const char *remote_app_id, const char *remote_port, bundle *message, int local_port_id); + +/** + * @brief Sends a trusted message with local port information to the message port of a remote application. + * @details This method is used for bidirectional communication. @n + * It allows communications only if the applications are signed with the same certificate which is uniquely assigned to the developer. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks You muse release @a message using bundle_free() after sending the message. + * @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, the recommended message size is under 4KB + * @param[in] local_port_id The message port ID returned by message_port_register_local_port() or message_port_register_trusted_local_port() + * @return 0 on success, + * otherwise a negative error value + * @retval #MESSAGE_PORT_ERROR_NONE Successful + * @retval #MESSAGE_PORT_ERROR_INVALID_PARAMETER The specified @a remote_app_id, @a remote_port or @a message is @c NULL and + specified @a local_port_id is not positive + * @retval #MESSAGE_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #MESSAGE_PORT_ERROR_PORT_NOT_FOUND The port of the local or remote application cannot be found. + * @retval #MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH The remote application is not signed with the same certificate. + * @retval #MESSAGE_PORT_ERROR_MAX_EXCEEDED The size of the message has exceeded the maximum limit. + * @retval #MESSAGE_PORT_ERROR_IO_ERROR Internal I/O error + * @post It invokes message_port_trusted_message_cb() on the remote application. + * @see message_port_trusted_message_cb() + * @see message_port_register_trusted_local_port() + * @see message_port_unregister_trusted_local_port() + */ +EXPORT_API int message_port_send_trusted_message_with_local_port(const char *remote_app_id, const char *remote_port, bundle *message, int local_port_id); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_APPFW_MESSAGE_PORT_H__ */ diff --git a/include/message_port_error.h b/include/message_port_error.h new file mode 100644 index 0000000..d15a2df --- /dev/null +++ b/include/message_port_error.h @@ -0,0 +1,39 @@ +// +// 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_ERROR_H__ +#define __APPFW_MESSAGE_PORT_ERROR_H__ + +#include + +/** + * @brief Enumerations of error code for Application. + */ +typedef enum +{ + MESSAGEPORT_ERROR_NONE = 0, /**< Successful */ + MESSAGEPORT_ERROR_IO_ERROR = -EIO, /**< Internal I/O error */ + MESSAGEPORT_ERROR_OUT_OF_MEMORY = -ENOMEM, /**< Out of memory */ + MESSAGEPORT_ERROR_INVALID_PARAMETER = -EINVAL, /**< Invalid parameter */ + MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND = -ENOKEY, /**< The message port of the remote application is not found */ + MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH = -EACCES, /**< The remote application is not signed with the same certificate */ + MESSAGEPORT_ERROR_MAX_EXCEEDED = -EMSGSIZE, /**< The size of message has exceeded the maximum limit */ + MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE = -EBUSY, /**< Resource temporarily unavailable */ +} messageport_error_e; + +#endif /* __APPFW_MESSAGE_PORT_ERROR_H__ */ diff --git a/include/message_port_internal.h b/include/message_port_internal.h new file mode 100755 index 0000000..d97ba29 --- /dev/null +++ b/include/message_port_internal.h @@ -0,0 +1,33 @@ +/* + * 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_APPFW_MESSAGE_PORT_INTERNAL_H__ +#define __TIZEN_APPFW_MESSAGE_PORT_INTERNAL_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int convert_to_tizen_error(messageport_error_e error); + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_APPFW_MESSAGE_PORT_INTERNAL_H__ */ diff --git a/message-port.pc.in b/message-port.pc.in old mode 100755 new mode 100644 index bd7816a..8724ba1 --- a/message-port.pc.in +++ b/message-port.pc.in @@ -9,7 +9,7 @@ includedir=@INCLUDE_INSTALL_DIR@/appfw Name: @PC_NAME@ Description: @PACKAGE_DESCRIPTION@ Version: @VERSION@ -Requires: @PC_REQUIRED@ +Requires: capi-base-common Libs: -L${libdir} -lmessage-port Cflags: -I${includedir} diff --git a/packaging/message-port.changes b/packaging/message-port.changes deleted file mode 100644 index e0ad778..0000000 --- a/packaging/message-port.changes +++ /dev/null @@ -1,34 +0,0 @@ -* Wed Sep 04 2013 Maciej Wereski accepted/tizen/20130710.221523@4e83e1b -- Fix RPMLINT errors -- Sync with tizen_2.2 -- Fix a memory leak in Deserializer -- Update to use the aul api instead of app-manager -- Remove the pid info in the hello message -- Add to check the EXPORT_API define -- Change the default visibility to hidden -- Apply the secure logs -- Update document -- resetting manifest requested domain to floor -- Change LOGD to LOGI -- Change version to 2.2 -- Fix a prevent issue -- Add an error-checking in write() -- Fix an issue on registering the same port -- Add a retry logic -- Prevent fix -- Update documents -- Merge "Change to use bundle_encode_raw" into tizen_2.1 -- Change to use bundle_encode_raw -- Add a debug pkg -- remove message_port_unregister -- Remove uninitialised bytes -- Get appid from pid -- Apply secure logs -- Add an OnIpcServerDisconnected in IpcClient -- Separate the metadata -- Fix for 64 bit compatibility. -- Move a cert check to channel-service -- Merge from master -- sync with master -- Initial empty repository - diff --git a/packaging/message-port.manifest b/packaging/message-port.manifest index 017d22d..75b0fa5 100644 --- a/packaging/message-port.manifest +++ b/packaging/message-port.manifest @@ -1,5 +1,5 @@ - - - + + + diff --git a/packaging/message-port.spec b/packaging/message-port.spec old mode 100755 new mode 100644 index 58ecc87..96f4dd8 --- a/packaging/message-port.spec +++ b/packaging/message-port.spec @@ -1,26 +1,25 @@ Name: message-port Summary: Message Port library -Version: 1.2.2.1 +Version: 1.2.2.1 Release: 0 -Group: Application Framework/Libraries +Group: Application Framework/Libraries License: Apache-2.0 Source0: %{name}-%{version}.tar.gz -Source1001: message-port.manifest +Source1001: %{name}.manifest BuildRequires: cmake BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(bundle) BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(chromium) BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(pkgmgr) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(openssl) -# runtime requires -Requires: chromium - -Requires(post): /sbin/ldconfig +Requires(post): /sbin/ldconfig Requires(post): coreutils Requires(postun): /sbin/ldconfig -Provides: libmessage-port.so.1 +Provides: capi-message-port %description Message Port library package. @@ -31,7 +30,7 @@ Group: Application Framework/Development Requires: %{name} = %{version}-%{release} %description devel -Message Port library (Development) package. +Message Port library (Development) package. %prep %setup -q @@ -45,6 +44,7 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` %install rm -rf %{buildroot} + %make_install %post -p /sbin/ldconfig @@ -53,11 +53,10 @@ rm -rf %{buildroot} %files %manifest %{name}.manifest -%{_libdir}/libmessage-port.so.* +%attr(0644,root,root) %{_libdir}/lib%{name}.so.* %license LICENSE.APLv2 %files devel -%manifest %{name}.manifest %{_includedir}/appfw/*.h %{_libdir}/pkgconfig/*.pc -%{_libdir}/libmessage-port.so +%{_libdir}/lib%{name}.so diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100755 index 0000000..8fe809e --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,62 @@ +SET(this_target message-port) + +INCLUDE_DIRECTORIES ( + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/src/inc + ) + +SET(${this_target}_SOURCE_FILES + message-port.c + message_port_internal.c + message_port.c + ) + +SET(${this_target}_requires "dlog bundle glib-2.0 gio-2.0 aul openssl capi-base-common pkgmgr-info") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${this_target} REQUIRED ${${this_target}_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 -fvisibility=hidden") +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} -fvisibility=hidden") + + +## Create Library +ADD_LIBRARY (${this_target} SHARED ${${this_target}_SOURCE_FILES}) + +## SET LINKER FLAGS +SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed -Wl,--no-undefined -Wl,--rpath=${LIB_INSTALL_DIR}") + +TARGET_LINK_LIBRARIES(${this_target} ${${this_target}_LDFLAGS}) + +SET_TARGET_PROPERTIES(${this_target} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 + ) + +# pkgconfig file +SET(PC_NAME ${this_target}) +SET(PACKAGE_DESCRIPTION "Message Port internal library") +SET(VERSION ${FULLVER}) +SET(PC_REQUIRED ${${this_target}_requires}) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/${this_target}.pc.in ${CMAKE_SOURCE_DIR}/${this_target}.pc @ONLY) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/${this_target}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/capi-${this_target}.pc.in ${CMAKE_SOURCE_DIR}/capi-${this_target}.pc @ONLY) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/capi-${this_target}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +INSTALL(TARGETS ${this_target} DESTINATION ${LIB_INSTALL_DIR}) + +INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/appfw FILES_MATCHING PATTERN "*.h") + +INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/ DESTINATION ${LIB_INSTALL_DIR} FILES_MATCHING PATTERN "*.so*") diff --git a/src/IIpcClientEventListener.h b/src/IIpcClientEventListener.h deleted file mode 100644 index 6a321ee..0000000 --- a/src/IIpcClientEventListener.h +++ /dev/null @@ -1,61 +0,0 @@ -// -// 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; - - /** - * Called when an IPC server disconnected. - * - * @param[in] client The IPC client - */ - virtual void OnIpcServerDisconnected(IpcClient& client) {} -}; // IIpcClientEventListener - -#endif //_IIPC_CLIENT_EVENT_LISTENER_H_ diff --git a/src/IpcClient.cpp b/src/IpcClient.cpp deleted file mode 100644 index 35fd1b4..0000000 --- a/src/IpcClient.cpp +++ /dev/null @@ -1,656 +0,0 @@ -// -// 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 "message-port.h" -#include "message-port-log.h" - -#include "IpcClient.h" -#include "IIpcClientEventListener.h" - -using namespace IPC; -using namespace std; - - -IpcClient::IpcClient(void) - : __pReverseSource(NULL) - , __pMutex(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); - } - - pthread_mutex_destroy(__pMutex); -} - -int -IpcClient::Construct(const string& serverName, const IIpcClientEventListener* pListener) -{ - __name = serverName; - __pListener = const_cast (pListener); - - 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; - - int ret = MakeConnection(); - if (ret != 0) - { - return ret; - } - - if (__pListener) - { - ret = MakeConnection(true); - if (ret != 0) - { - return ret; - } - } - - return MESSAGEPORT_ERROR_NONE; - -} - -string -IpcClient::GetName(void) const -{ - return __name; -} - -struct HelloMessage -{ - int reverse; -}; - -int -IpcClient::MakeConnection(bool forReverse) -{ - int ret = 0; - int retry = 0; - - size_t socketNameLength = 0; - string socketName; - - socketName.append("/var/run/osp/"); - socketName.append(__name); - - socketNameLength = socketName.size() + 1; - - HelloMessage helloMessage = {0}; - - if (forReverse) - { - helloMessage.reverse = 1; - } - else - { - helloMessage.reverse = 0; - } - - 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 MESSAGEPORT_ERROR_IO_ERROR; - } - - 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; - } - - // Retry if the server is not ready - retry = 5; - while (retry > 0) - { - ret = connect(client, (struct sockaddr*) &server, serverLen); - if (ret < 0 && errno == ENOENT) - { - _LOGI("The server is not ready. %d", retry); - - usleep(1000 * 1000); - - --retry; - } - else - { - break; - } - } - - if (ret < 0) - { - if (errno != EINPROGRESS) - { - _LOGE("Failed to connect to server(%s) : %d, %s", socketName.c_str(), errno, 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; - 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) - { - _LOGE("Failed to send a hello message: %d, %s", errno, strerror(errno)); - 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 - { - ReleaseFd(client); - } - - return MESSAGEPORT_ERROR_NONE; - -CATCH: - if (client != -1) - { - close(client); - } - - return MESSAGEPORT_ERROR_IO_ERROR; - -} - -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) - { - _LOGI("G_IO_HUP, the connection is closed."); - - g_source_destroy(__pReverseSource); - g_source_unref(__pReverseSource); - __pReverseSource = NULL; - - if (__pListener) - { - __pListener->OnIpcServerDisconnected(*this); - } - - 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 || status == G_IO_STATUS_ERROR) - { - if (status == G_IO_STATUS_EOF) - { - _LOGI("G_IO_STATUS_EOF, the connection is closed."); - } - else - { - _LOGI("G_IO_STATUS_ERROR, the connection is closed."); - } - - pGError = NULL; - - g_io_channel_shutdown(source, FALSE, &pGError); - - g_source_destroy(__pReverseSource); - g_source_unref(__pReverseSource); - __pReverseSource = NULL; - - if (__pListener) - { - __pListener->OnIpcServerDisconnected(*this); - } - - 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 MESSAGEPORT_ERROR_OUT_OF_MEMORY; - } - - 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) - { - pthread_mutex_lock(__pMutex); - if (__fds.size() == 0) - { - pthread_mutex_unlock(__pMutex); - ret = MakeConnection(false); - if (ret < 0) - { - _LOGE("Failed to connect to the server."); - return MESSAGEPORT_ERROR_IO_ERROR; - } - - continue; - } - - fd = __fds.back(); - __fds.pop_back(); - - pthread_mutex_unlock(__pMutex); - } - - return fd; -} - -void -IpcClient::ReleaseFd(int fd) -{ - pthread_mutex_lock(__pMutex); - - __fds.push_back(fd); - - pthread_mutex_unlock(__pMutex); -} - -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 MESSAGEPORT_ERROR_IO_ERROR; - } - - int written = 0; - while (remain > 0) - { - written = write(fd, (char*) pData, remain); - if (written < 0) - { - _LOGE("Failed to send a request: %d, %s", errno, strerror(errno)); - - ReleaseFd(fd); - return MESSAGEPORT_ERROR_IO_ERROR; - } - - remain -= written; - pData += written; - } - - ReleaseFd(fd); - - return MESSAGEPORT_ERROR_NONE; -} - -int -IpcClient::SendSync(IPC::Message* pMessage) -{ - int error = MESSAGEPORT_ERROR_NONE; - int ret = 0; - - int readSize = 0; - char buffer[1024]; - char* pEndOfMessage = NULL; - - std::string message; - - IPC::Message* pReply = NULL; - IPC::SyncMessage* pSyncMessage = dynamic_cast (pMessage); - if (pSyncMessage == NULL) - { - _LOGE("pMessage is not a sync message."); - return MESSAGEPORT_ERROR_IO_ERROR; - } - - MessageReplyDeserializer* pReplyDeserializer = pSyncMessage->GetReplyDeserializer(); - int messageId = SyncMessage::GetMessageId(*pSyncMessage); - - int fd = AcquireFd(); - if (fd < 0) - { - _LOGE("Failed to get fd."); - - delete pReplyDeserializer; - return MESSAGEPORT_ERROR_IO_ERROR; - } - - char* pData = (char*) pSyncMessage->data(); - int remain = pSyncMessage->size(); - int written = 0; - - while (remain > 0) - { - written = write(fd, (char*) pData, remain); - if (written < 0) - { - _LOGE("Failed to send a request: %d, %s", errno, strerror(errno)); - - error = MESSAGEPORT_ERROR_IO_ERROR; - goto CATCH; - } - - remain -= written; - pData += written; - } - - // Wait reply - struct pollfd pfd; - - pfd.fd = fd; - pfd.events = POLLIN | POLLRDHUP; - pfd.revents = 0; - - while (true) - { - ret = poll(&pfd, 1, -1); - if (ret < 0) - { - if (errno == EINTR) - { - continue; - } - - _LOGE("Failed to poll (%d, %s).", errno, strerror(errno)); - - error = MESSAGEPORT_ERROR_IO_ERROR; - goto CATCH; - } - - if (pfd.revents & POLLRDHUP) - { - _LOGE("POLLRDHUP"); - - error = MESSAGEPORT_ERROR_IO_ERROR; - goto CATCH; - } - - if (pfd.revents & POLLIN) - { - readSize = read(fd, buffer, 1024); - } - - if (readSize > 0) - { - 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."); - - error = MESSAGEPORT_ERROR_OUT_OF_MEMORY; - goto CATCH; - } - - break; - } - } - - pReplyDeserializer->SerializeOutputParameters(*pReply); - delete pReply; - -CATCH: - delete pReplyDeserializer; - - ReleaseFd(fd); - - return error; -} - -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; -} - diff --git a/src/IpcClient.h b/src/IpcClient.h deleted file mode 100644 index ba1abfe..0000000 --- a/src/IpcClient.h +++ /dev/null @@ -1,127 +0,0 @@ -// -// 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 0 on success, otherwise a negative error value. - * @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. - * @retval MESSAGEPORT_ERROR_OUT_OF_MEMORY Insufficient memory. - * @retval MESSAGEPORT_ERROR_IO_ERROR A system error occurred. - */ - int Construct(const std::string& serverName, const IIpcClientEventListener* pListener = NULL); - - /** - * Returns the name of the IPC server. - * - * @return The name of the IPC server. - */ - std::string GetName(void) const; - - /** - * Sends a request message to an IPC server. - * - * @return 0 on success, otherwise a negative error value. - * @param [in] message The message to send - * @retval MESSAGEPORT_ERROR_OUT_OF_MEMORY Insufficient memory. - * @retval MESSAGEPORT_ERROR_IO_ERROR A system error occurred. - * - */ - int SendRequest(const IPC::Message& message); - - int SendRequest(IPC::Message* pMessage); - -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; - pthread_mutex_t* __pMutex; - - std::vector __fds; - 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 deleted file mode 100644 index 0f40e53..0000000 --- a/src/MessagePortProxy.cpp +++ /dev/null @@ -1,633 +0,0 @@ -// -// 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 = 16 * 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) - { - _LOGE("Out of memory"); - 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) - { - _LOGE("Out of memory"); - return MESSAGEPORT_ERROR_OUT_OF_MEMORY; - } - - pthread_mutex_init(pMutex, NULL); - - __pMutex = pMutex; - __pIpcClient = pIpcClient; - - int pid = getpid(); - char buffer[256] = {0, }; - - ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer)); - if (ret != AUL_R_OK) - { - _LOGE("Failed to get the application ID: %d", ret); - - return MESSAGEPORT_ERROR_IO_ERROR; - } - - __appId = buffer; - - return MESSAGEPORT_ERROR_NONE; -} - -void -MessagePortProxy::OnIpcResponseReceived(IpcClient& client, const IPC::Message& message) -{ - 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) -{ - _SECURE_LOGI("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); - - _LOGE("Out of memory"); - 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) -{ - _SECURE_LOGI("Check a remote port : [%s:%s]", remoteAppId.c_str(), remotePort.c_str()); - - bundle *b = bundle_create(); - - bundle_add(b, LOCAL_APPID, __appId.c_str()); - - 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); - - _LOGE("Out of memory"); - return MESSAGEPORT_ERROR_OUT_OF_MEMORY; - } - - int 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) - { - _LOGE("The remote message port (%s) is not found.", remotePort.c_str()); - - *exist = false; - return MESSAGEPORT_ERROR_NONE; - } - else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH) - { - _SECURE_LOGI("The remote application (%s) is not signed with the same certificate", remoteAppId.c_str()); - - *exist = true; - return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH; - } - else - { - _LOGE("Failed to check the remote messge port: %d.", return_value); - return MESSAGEPORT_ERROR_IO_ERROR; - } - } - - *exist = true; - return MESSAGEPORT_ERROR_NONE; -} - -int -MessagePortProxy::SendMessage(const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data) -{ - _SECURE_LOGI("Send a message to : [%s:%s]", remoteAppId.c_str(), remotePort.c_str()); - - int ret = 0; - - bundle *b = bundle_create(); - bundle_add(b, MESSAGE_TYPE, "UNI-DIR"); - - bundle_add(b, LOCAL_APPID, __appId.c_str()); - - bundle_add(b, REMOTE_APPID, remoteAppId.c_str()); - bundle_add(b, REMOTE_PORT, remotePort.c_str()); - - if (!trustedMessage) - { - bundle_add(b, TRUSTED_MESSAGE, "FALSE"); - } - else - { - bundle_add(b, TRUSTED_MESSAGE, "TRUE"); - } - - BundleBuffer metadata; - metadata.b = b; - - BundleBuffer buffer; - buffer.b = data; - - ret = SendMessageInternal(metadata, buffer); - - bundle_free(b); - - return ret; -} - -int -MessagePortProxy::SendMessage(const string& localPort, bool trustedPort, const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data) -{ - _SECURE_LOGI("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; - - bundle *b = bundle_create(); - bundle_add(b, MESSAGE_TYPE, "BI-DIR"); - - bundle_add(b, LOCAL_APPID, __appId.c_str()); - bundle_add(b, LOCAL_PORT, localPort.c_str()); - - if (!trustedPort) - { - bundle_add(b, TRUSTED_LOCAL, "FALSE"); - } - else - { - bundle_add(b, TRUSTED_LOCAL, "TRUE"); - } - - bundle_add(b, REMOTE_APPID, remoteAppId.c_str()); - bundle_add(b, REMOTE_PORT, remotePort.c_str()); - - if (!trustedMessage) - { - bundle_add(b, TRUSTED_MESSAGE, "FALSE"); - } - else - { - bundle_add(b, TRUSTED_MESSAGE, "TRUE"); - } - - BundleBuffer metadata; - metadata.b = b; - - BundleBuffer buffer; - buffer.b = data; - - ret = SendMessageInternal(metadata, buffer); - - bundle_free(b); - - return ret; -} - -int -MessagePortProxy::SendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer) -{ - int return_value = 0; - IPC::Message* pMsg = new MessagePort_sendMessage(metadata, buffer, &return_value); - if (pMsg == NULL) - { - _LOGE("Out of memory"); - return MESSAGEPORT_ERROR_OUT_OF_MEMORY; - } - - // Check the message size - int len = 0; - bundle_raw* raw = NULL; - bundle_encode_raw(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); - - delete pMsg; - return MESSAGEPORT_ERROR_MAX_EXCEEDED; - } - - int ret = __pIpcClient->SendRequest(pMsg); - delete pMsg; - - 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) - { - _LOGE("The remote message port is not found."); - - return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; - } - else if (return_value == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH) - { - _LOGE("The remote application is not signed with the same certificate."); - - return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH; - } - else if (return_value == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) - { - _LOGE("The socket receiver buffer of remote port is temporarily full."); - - return MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE; - } - else - { - _LOGE("Failed to check the remote messge port: %d.", return_value); - - return MESSAGEPORT_ERROR_IO_ERROR; - } - } - - return MESSAGEPORT_ERROR_NONE; -} - -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()) - { - _LOGE("Invalid value %d", id); - 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()) - { - _LOGE("Invalid value %d", id); - return MESSAGEPORT_ERROR_INVALID_PARAMETER; - } - else - { - *trusted = true; - return MESSAGEPORT_ERROR_NONE; - } - } - else - { - *trusted = false; - return MESSAGEPORT_ERROR_NONE; - } - - return MESSAGEPORT_ERROR_INVALID_PARAMETER; -} - -MessagePortProxy* -MessagePortProxy::GetProxy(void) -{ - static MessagePortProxy* pProxy = NULL; - - if (pProxy == NULL) - { - MessagePortProxy* p = new MessagePortProxy(); - if (p == NULL) - { - _LOGE("Out of memory"); - 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 - { - _LOGI("MessagePort name is already registered."); - 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 - { - _LOGI("MessagePort name is already registered."); - for (map::iterator it = __trustedIds.begin(); it != __trustedIds.end(); ++it) - { - if (localPort.compare(it->second) == 0) - { - id = it->first; - return true; - } - } - } - } - - return false; -} - -bool -MessagePortProxy::OnSendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer) -{ - bundle* b = metadata.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); - - _SECURE_LOGI("Message received to App: %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) - { - if (messageType.compare("UNI-DIR") == 0) - { - callback(id, NULL, NULL, false, buffer.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); - - _SECURE_LOGI("From App: %s, Port: %s, TrustedLocal: %s", localAppId.c_str(), localPort.c_str(), trustedLocal.c_str()); - - bool trustedPort = (trustedLocal.compare("TRUE") == 0); - - callback(id, localAppId.c_str(), localPort.c_str(), trustedPort, buffer.b); - } - - } - else - { - _LOGI("No callback"); - } - - bundle_free(b); - - return true; -} - diff --git a/src/MessagePortProxy.h b/src/MessagePortProxy.h deleted file mode 100644 index 97f5c16..0000000 --- a/src/MessagePortProxy.h +++ /dev/null @@ -1,109 +0,0 @@ -// -// 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& metadata, const BundleBuffer& buffer); - - bool OnSendMessageInternal(const BundleBuffer& metadata, const BundleBuffer& buffer); - - int GetNextId(void); - - bool IsLocalPortRegisted(const std::string& localPort, bool trusted, int &id); - -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/inc/message-port-log.h similarity index 100% rename from src/message-port-log.h rename to src/inc/message-port-log.h diff --git a/include/message-port-data-types.h b/src/inc/message_port_log.h similarity index 61% rename from include/message-port-data-types.h rename to src/inc/message_port_log.h index dc5940e..76b86f1 100644 --- a/include/message-port-data-types.h +++ b/src/inc/message_port_log.h @@ -15,19 +15,19 @@ // 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_ +#ifndef __TIZEN_APPFW_MESSAGE_PORT_LOG_H__ +#define __TIZEN_APPFW_MESSAGE_PORT_LOG_H__ -#include +#include -typedef struct -{ - bundle* b; -} BundleBuffer; +#undef LOG_TAG +#define LOG_TAG "MESSAGE_PORT" -#endif //_APPFW_MESSAGE_PORT_DATA_TYPES_H_ +#define _LOGE(fmt, arg...) LOGE(fmt, ##arg) +#define _LOGI(fmt, arg...) LOGI(fmt, ##arg) + +#define _SECURE_LOGE(fmt, arg...) SECURE_LOGE(fmt, ##arg) +#define _SECURE_LOGI(fmt, arg...) SECURE_LOGI(fmt, ##arg) + +#endif /* __TIZEN_APPFW_MESSAGE_PORT_LOG_H__ */ diff --git a/src/message-port-messages.cpp b/src/message-port-messages.cpp deleted file mode 100644 index 9ea580d..0000000 --- a/src/message-port-messages.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// 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.c b/src/message-port.c new file mode 100755 index 0000000..c916eaf --- /dev/null +++ b/src/message-port.c @@ -0,0 +1,1282 @@ + +// Message Port +// Copyright (c) 2015 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 +#include +#include +#include +#include +#include +#include + +#include "message-port.h" +#include "message-port-log.h" + + +#define MAX_PACKAGE_STR_SIZE 512 +#define MESSAGEPORT_BUS_NAME_PREFIX "org.tizen.messageport._" +#define MESSAGEPORT_OBJECT_PATH "/org/tizen/messageport" +#define MESSAGEPORT_INTERFACE "org.tizen.messageport" + + + +#define retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + _LOGE(fmt, ##arg); \ + _LOGE("(%s) -> %s() return", #expr, __func__); \ + return val; \ + } \ +} while (0) + +#define retv_if(expr, val) do { \ + if (expr) { \ + _LOGE("(%s) -> %s() return", #expr, __func__); \ + return val; \ + } \ +} while (0) + +#define FREE_AND_NULL(ptr) do { \ + if (ptr) { \ + free((void *)ptr); \ + ptr = NULL; \ + } \ +} while (0) + +static bool _initialized = false; +static GDBusConnection *__gdbus_conn = NULL; +static char *__app_id; +static GHashTable *__local_port_info = NULL; +static GHashTable *__remote_port_info = NULL;; +static GHashTable *__sender_appid_hash = NULL;; +static GHashTable *__checked_app_list_hash = NULL; +static GHashTable *__trusted_app_list_hash = NULL; +static const int MAX_MESSAGE_SIZE = 16 * 1024; + + + +enum __certificate_info_type { + UNKNOWN = 0, + CERTIFICATE_MATCH, + CERTIFICATE_NOT_MATCH, +}; + +typedef struct message_port_local_port_info { + messageport_message_cb callback; + bool is_trusted; + char *port_name; + int local_id; +} message_port_local_port_info_s; + +typedef struct message_port_remote_port_info { + char *encoded_bus_name; + char *sender_id; + char *remote_app_id; + int certificate_info; + int watcher_id; + GList *port_list; +} message_port_remote_app_info_s; + +typedef struct port_list_info { + char *port_name; + bool is_trusted; + bool exist; +} port_list_info_s; + +static char *__get_encoded_bus_name(const char *bus_name, const char *prefix, int len) +{ + unsigned char c[MD5_DIGEST_LENGTH] = {0}; + char *md5_interface = NULL; + char *temp; + int index = 0; + MD5_CTX mdContext; + int interface_len = len + (MD5_DIGEST_LENGTH * 2) + 1; + + MD5_Init(&mdContext); + MD5_Update(&mdContext, bus_name, strlen(bus_name)); + MD5_Final(c, &mdContext); + + md5_interface = (char *)calloc(interface_len , sizeof(char)); + if (md5_interface == NULL) { + _LOGI("Malloc failed!!"); + return 0; + } + + snprintf(md5_interface, interface_len, "%s", prefix); + temp = md5_interface; + temp += len; + + for (index = 0; index < MD5_DIGEST_LENGTH; index++) { + snprintf(temp, 3, "%02x", c[index]); + temp += 2; + } + + return md5_interface; +} + +static char *__get_bus_name(const char *remote_app_id) +{ + char *bus_name = NULL; + + bus_name = __get_encoded_bus_name(remote_app_id, MESSAGEPORT_BUS_NAME_PREFIX, strlen(MESSAGEPORT_BUS_NAME_PREFIX)); + if (!bus_name) { + _LOGE("fail to get bus name"); + } + return bus_name; +} + +int __get_next_id(void) +{ + static int count = 0; + + ++count; + return count; +} + +static int __remote_port_compare_cb(gconstpointer a, gconstpointer b) +{ + port_list_info_s *key1 = (port_list_info_s *)a; + port_list_info_s *key2 = (port_list_info_s *)b; + + if (key1->is_trusted == key2->is_trusted) { + return strcmp(key1->port_name, key2->port_name); + } + + return 1; +} + + +static bool __is_preloaded(const char *local_appid, const char *remote_appid) +{ + _LOGI("IsPreloaded"); + + bool preload_local = false; + bool preload_remote = false; + + pkgmgrinfo_appinfo_h handle = NULL; + int ret = pkgmgrinfo_appinfo_get_usr_appinfo(local_appid, getuid(), &handle); + if (ret != PMINFO_R_OK) { + _LOGE("Failed to get the appinfo. %d", ret); + pkgmgrinfo_appinfo_destroy_appinfo(handle); + return false; + } + ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_local); + if (ret != PMINFO_R_OK) { + _LOGE("Failed to check the preloaded application. %d", ret); + pkgmgrinfo_appinfo_destroy_appinfo(handle); + return false; + } + ret = pkgmgrinfo_appinfo_get_usr_appinfo(remote_appid, getuid(), &handle); + if (ret != PMINFO_R_OK) { + _LOGE("Failed to get the appinfo. %d", ret); + pkgmgrinfo_appinfo_destroy_appinfo(handle); + return false; + } + ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_remote); + if (ret != PMINFO_R_OK) { + _LOGE("Failed to check the preloaded application. %d", ret); + pkgmgrinfo_appinfo_destroy_appinfo(handle); + return false; + } + + if (preload_local && preload_remote) { + pkgmgrinfo_appinfo_destroy_appinfo(handle); + return true; + } + pkgmgrinfo_appinfo_destroy_appinfo(handle); + return false; +} + +static int __check_certificate(const char *local_appid, const char *remote_appid) +{ + _LOGI("CheckCertificate"); + + pkgmgrinfo_cert_compare_result_type_e res; + int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(local_appid, + remote_appid, getuid(), &res); + if (ret < 0) { + _LOGE(":CheckCertificate() Failed"); + return MESSAGEPORT_ERROR_IO_ERROR; + } + if (res != PMINFO_CERT_COMPARE_MATCH) { + _LOGE("CheckCertificate() Failed : MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH"); + return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH; + } + + return MESSAGEPORT_ERROR_NONE; +} + +static void on_name_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + _LOGI("name appeared : %s %s", __app_id, name); +} + +static void on_name_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + _LOGI("name vanished : %s", name); + message_port_remote_app_info_s *remote_app_info = (message_port_remote_app_info_s *)user_data; + g_bus_unwatch_name(remote_app_info->watcher_id); + g_hash_table_remove(__remote_port_info, remote_app_info->remote_app_id); +} + +static void __hash_destory_list_value(gpointer data) +{ + GList *list = (GList *)data; + g_list_foreach(list, (GFunc)g_free, NULL); + g_list_free(list); + list = NULL; +} + +static void __set_checked_app_list(message_port_local_port_info_s *mi, char *remote_appid) { + + GList *app_list = (GList *)g_hash_table_lookup(__checked_app_list_hash, mi->port_name); + if (app_list == NULL) { + app_list = g_list_append(app_list, strdup(remote_appid)); + _LOGI("set checked_app_list appid: %s", remote_appid); + g_hash_table_insert(__checked_app_list_hash, mi->port_name, app_list); + } else { + GList *app = g_list_find(app_list, (gpointer)remote_appid); + if (app == NULL) { + app_list = g_list_append(app_list, strdup(remote_appid)); + _LOGI("set checked_app_list appid: %s", remote_appid); + } + } +} + +static int __get_local_port_info(int id, message_port_local_port_info_s **info) +{ + message_port_local_port_info_s *mi = (message_port_local_port_info_s *)g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(id)); + + if (mi == NULL) { + return MESSAGEPORT_ERROR_INVALID_PARAMETER; + } + *info = mi; + + return MESSAGEPORT_ERROR_NONE; +} + +static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted) +{ + int ret_val = MESSAGEPORT_ERROR_NONE; + port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s)); + + if (!port_info) { + ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY; + goto out; + } + port_info->port_name = strdup(remote_port); + if (!port_info->port_name) { + ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY; + goto out; + } + port_info->is_trusted = is_trusted; + + out: + if (ret_val != MESSAGEPORT_ERROR_NONE) { + if (port_info) { + FREE_AND_NULL(port_info->port_name); + free(port_info); + } + return NULL; + } + return port_info; +} + +static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted) +{ + port_list_info_s *port_info = NULL; + message_port_remote_app_info_s *remote_app_info = NULL; + int ret_val = MESSAGEPORT_ERROR_NONE; + + remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s)); + if (!remote_app_info) { + ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY; + goto out; + } + + remote_app_info->encoded_bus_name = __get_bus_name(remote_app_id); + if (remote_app_info->encoded_bus_name == NULL) { + ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY; + goto out; + } + + remote_app_info->remote_app_id = strdup(remote_app_id); + if (remote_app_info->remote_app_id == NULL) { + ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;; + goto out; + } + + remote_app_info->watcher_id = g_bus_watch_name(G_BUS_TYPE_SESSION, + remote_app_info->encoded_bus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + on_name_appeared, + on_name_vanished, + remote_app_info, + NULL); + + port_info = __set_remote_port_info(remote_app_id, remote_port, is_trusted); + if (port_info == NULL) { + ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY; + goto out; + } + + remote_app_info->port_list = g_list_append(remote_app_info->port_list, port_info); + + out: + if (ret_val != MESSAGEPORT_ERROR_NONE) { + if (remote_app_info) { + FREE_AND_NULL(remote_app_info->encoded_bus_name); + FREE_AND_NULL(remote_app_info->remote_app_id); + FREE_AND_NULL(remote_app_info); + } + return NULL; + } + return remote_app_info; +} + +static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted, + message_port_remote_app_info_s **mri, port_list_info_s **pli) +{ + message_port_remote_app_info_s *remote_app_info = NULL; + port_list_info_s port_info; + GList *cb_list = NULL; + + remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_port_info, remote_app_id); + + if (remote_app_info == NULL) { + remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted); + retvm_if(!remote_app_info, MESSAGEPORT_ERROR_OUT_OF_MEMORY, "fail to create message_port_remote_app_info_s"); + g_hash_table_insert(__remote_port_info, remote_app_info->remote_app_id, remote_app_info); + + } + *mri = remote_app_info; + + port_info.port_name = strdup(remote_port); + port_info.is_trusted = is_trusted; + cb_list = g_list_find_custom(remote_app_info->port_list, &port_info, + (GCompareFunc)__remote_port_compare_cb); + if (port_info.port_name) + free(port_info.port_name); + if (cb_list == NULL) { + port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted); + retvm_if(!tmp, MESSAGEPORT_ERROR_OUT_OF_MEMORY, "fail to create port_list_info_s"); + remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp); + *pli = tmp; + } else { + *pli = (port_list_info_s *)cb_list->data; + } + return MESSAGEPORT_ERROR_NONE; +} + +static bool __is_local_port_registed(const char *local_port, bool trusted, int *local_id, message_port_local_port_info_s **lpi) +{ + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init(&iter, __local_port_info); + + while (g_hash_table_iter_next(&iter, &key, &value)) { + message_port_local_port_info_s *mi = (message_port_local_port_info_s *)value; + + if ((mi->is_trusted == trusted) && strcmp(mi->port_name, local_port) == 0) { + *local_id = mi->local_id; + if (lpi != NULL) { + *lpi = mi; + } + return true; + } + } + return false; +} + +static int __get_sender_pid(GDBusConnection *conn, const char *sender_name) +{ + GDBusMessage *msg = NULL; + GDBusMessage *reply = NULL; + GError *err = NULL; + GVariant *body; + int pid = 0; + + msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", + "org.freedesktop.DBus", "GetConnectionUnixProcessID"); + if (!msg) { + _LOGE("Can't allocate new method call"); + goto out; + } + + g_dbus_message_set_body (msg, g_variant_new ("(s)", sender_name)); + reply = g_dbus_connection_send_message_with_reply_sync(conn, msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, 500, NULL, NULL, &err); + + if (!reply) { + if (err != NULL) { + _LOGE("Failed to get pid [%s]", err->message); + g_error_free(err); + } + goto out; + } + + body = g_dbus_message_get_body(reply); + g_variant_get(body, "(u)", &pid); + +out: + if (msg) + g_object_unref(msg); + if (reply) + g_object_unref(reply); + + return pid; +} + + +static bool send_message(GVariant *parameters) +{ + char *local_port = NULL; + char *local_appid = NULL; + char *remote_appid = NULL; + char *remote_port = NULL; + gboolean local_trusted = false; + gboolean remote_trusted = false; + gboolean bi_dir = false; + int len = 0; + + bundle *data = NULL; + bundle_raw *raw = NULL; + message_port_local_port_info_s *mi; + int local_reg_id = 0; + + g_variant_get(parameters, "(ssbbssbus)", &local_appid, &local_port, &local_trusted, &bi_dir, + &remote_appid, &remote_port, &remote_trusted, &len, &raw); + + if (!remote_port) { + _LOGE("Invalid argument : remote_port is NULL"); + goto out; + } + if (!remote_appid) { + _LOGE("Invalid argument : remote_appid is NULL"); + goto out; + } + if (!__is_local_port_registed(remote_port, remote_trusted, &local_reg_id, &mi)) { + _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, remote_trusted); + goto out; + } + if (!local_appid) { + _LOGE("Invalid argument : local_appid"); + goto out; + } + if (!local_port) { + _LOGE("Invalid argument : local_port"); + goto out; + } + if (strcmp(remote_appid, __app_id) != 0) { + _LOGE("Invalid argument : remote_appid (%s)", remote_appid); + goto out; + } + if (strcmp(remote_port, mi->port_name) != 0) { + _LOGE("Invalid argument : remote_port (%s)", remote_port); + goto out; + } + if (!len) { + _LOGE("Invalid argument : data_len"); + goto out; + } + if (remote_trusted) { + if (g_hash_table_lookup(__trusted_app_list_hash, (gpointer)local_appid) == NULL) { + if (!__is_preloaded(local_appid, remote_appid)) { + // Check the certificate + int ret = __check_certificate(local_appid, remote_appid); + if (ret == MESSAGEPORT_ERROR_NONE) { + g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE"); + } else { + _LOGE("The application (%s) is not signed with the same certificate", + local_appid); + goto out; + } + } + } + } + + data = bundle_decode(raw, len); + bundle_free_encoded_rawdata(&raw); + + if (!data) { + _LOGE("Invalid argument : message"); + goto out; + } + + if (bi_dir) { + mi->callback(mi->local_id, local_appid, local_port, local_trusted, data); + } else { + mi->callback(mi->local_id, local_appid, NULL, false, data); + } +out: + + return true; +} + +static int unregister_port(GVariant *parameters) +{ + int ret = MESSAGEPORT_ERROR_NONE; + char *remote_appid = NULL; + char *remote_port = NULL; + bool is_trusted; + port_list_info_s *port_info = NULL; + message_port_remote_app_info_s *remote_app_info = NULL; + + g_variant_get(parameters, "(sbs)", &remote_appid, &is_trusted, &remote_port); + + if (!remote_appid) { + _LOGE("Invalid argument : remote_appid"); + ret = MESSAGEPORT_ERROR_INVALID_PARAMETER; + goto out; + } + if (!remote_port) { + _LOGE("Invalid argument : remote_port"); + ret = MESSAGEPORT_ERROR_INVALID_PARAMETER; + goto out; + } + + ret = __get_remote_port_info(remote_appid, remote_port, is_trusted, &remote_app_info, &port_info); + if (ret != MESSAGEPORT_ERROR_NONE) { + goto out; + } + port_info->exist = false; + + + out: + if (remote_appid) + g_free(remote_appid); + if (remote_port) + g_free(remote_port); + + return ret; +} +static int __check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist) +{ + _LOGI("Check a remote port : [%s:%s]", remote_app_id, remote_port); + + GDBusMessage *msg = NULL; + GDBusMessage *reply = NULL; + GError *err = NULL; + GVariant *body; + int ret_val = MESSAGEPORT_ERROR_NONE; + char *bus_name = NULL; + message_port_remote_app_info_s *remote_app_info = NULL; + port_list_info_s *port_info = NULL; + int local_reg_id = 0; + message_port_local_port_info_s *mi = NULL; + + _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id); + + ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info); + if (ret_val != MESSAGEPORT_ERROR_NONE) { + return ret_val; + } + + if (strcmp(remote_app_id, __app_id) == 0) { + + _LOGI("__is_local_port_registed "); + if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi)) { + *exist = false; + } else { + *exist = true; + } + _LOGI("__is_local_port_registed : %d ", *exist); + return MESSAGEPORT_ERROR_NONE; + } + + *exist = false; + port_info->exist = false; + bus_name = remote_app_info->encoded_bus_name; + + msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, + MESSAGEPORT_INTERFACE, "check_remote_port"); + _LOGI("bus_name, remote app id:[%s : %s] ", bus_name, remote_app_id); + if (!msg) { + _LOGI("Can't allocate new method call"); + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + g_dbus_message_set_body(msg, g_variant_new("(sbss)", __app_id, is_trusted, remote_app_id, remote_port)); + reply = g_dbus_connection_send_message_with_reply_sync( + __gdbus_conn, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + 500, + NULL, + NULL, + &err); + + if (err || (reply == NULL)) { + if (err) { + _LOGE("No reply. error = %s", err->message); + g_error_free(err); + } + ret_val = MESSAGEPORT_ERROR_IO_ERROR; + } else { + if (g_dbus_message_to_gerror(reply, &err)) { + _LOGE("error = %s", err->message); + g_error_free(err); + ret_val = MESSAGEPORT_ERROR_NONE; + *exist = false; + } else { + body = g_dbus_message_get_body(reply); + g_variant_get(body, "(i)", &ret_val); + + if (ret_val == MESSAGEPORT_ERROR_NONE) { + *exist = true; + port_info->exist = true; + } else if (ret_val == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH) { + _SECURE_LOGI("The remote application (%s) is not signed with the same certificate", remote_app_id); + } + } + } + + if (msg) + g_object_unref(msg); + if (reply) + g_object_unref(reply); + + return ret_val; +} + +static int check_remote_port(GVariant *parameters) +{ + int ret = MESSAGEPORT_ERROR_NONE; + char *remote_appid = NULL; + char *remote_port = NULL; + char *local_appid = NULL; + bool is_trusted; + int local_reg_id = 0; + message_port_local_port_info_s *mi = NULL; + + g_variant_get(parameters, "(sbss)", &local_appid, &is_trusted, &remote_appid, &remote_port); + + if (!local_appid) { + _LOGE("Invalid argument : local_appid"); + ret = MESSAGEPORT_ERROR_INVALID_PARAMETER; + goto out; + } + if (!remote_appid) { + _LOGE("Invalid argument : remote_appid"); + ret = MESSAGEPORT_ERROR_INVALID_PARAMETER; + goto out; + } + if (!remote_port) { + _LOGE("Invalid argument : remote_port"); + ret = MESSAGEPORT_ERROR_INVALID_PARAMETER; + goto out; + } + if (strcmp(remote_appid, __app_id) != 0) { + _LOGE("Invalid argument : remote_appid (%s)", remote_appid); + ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; + goto out; + } + if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi)) { + _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, is_trusted); + ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; + goto out; + } + if (is_trusted) { + // Check the preloaded + if (!__is_preloaded(local_appid, remote_appid)) { + // Check the certificate + ret = __check_certificate(local_appid, remote_appid); + if (ret == MESSAGEPORT_ERROR_NONE) { + g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE"); + } + } + } + + __set_checked_app_list(mi, local_appid); + +out : + + return ret; +} + +static bool __check_sender_validation(GVariant *parameters, const char *sender, GDBusConnection *conn) +{ + int ret = 0; + char buffer[MAX_PACKAGE_STR_SIZE] = {0, }; + char *local_appid = NULL; + int pid = __get_sender_pid(conn, sender); + + ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer)); + retvm_if(ret != AUL_R_OK, false, "Failed to get the sender ID: (%s) (%d)", sender, pid); + + g_variant_get_child(parameters, 0, "s", &local_appid); + retvm_if(!local_appid, false, "remote_appid is NULL (%s) (%d)", sender, pid); + + if (strncmp(buffer, local_appid, MAX_PACKAGE_STR_SIZE) == 0) { + g_hash_table_insert(__sender_appid_hash, strdup(sender), GINT_TO_POINTER(pid)); + g_free(local_appid); + } else { + g_free(local_appid); + return false; + } + return true; +} + +static void __dbus_method_call_handler(GDBusConnection *conn, + const gchar *sender, const gchar *object_path, + const gchar *iface_name, const gchar *method_name, + GVariant *parameters, GDBusMethodInvocation *invocation, + gpointer user_data) +{ + _LOGI("method_name: %s", method_name); + gpointer sender_pid = g_hash_table_lookup(__sender_appid_hash, sender); + int ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; + if (sender_pid == NULL) { + if (!__check_sender_validation(parameters, sender, conn)) + return; + } + if (g_strcmp0(method_name, "send_message") == 0) { + ret =send_message(parameters); + } else if (g_strcmp0(method_name, "check_remote_port") == 0) { + ret = check_remote_port(parameters); + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", ret)); + } else if (g_strcmp0(method_name, "unregister_port") == 0) { + ret = unregister_port(parameters); + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", ret)); + } + + +} + +static const GDBusInterfaceVTable interface_vtable = { + __dbus_method_call_handler, + NULL, + NULL +}; + +static int __dbus_init(void) +{ + static gchar introspection[] = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + + int owner_id = 0; + int registration_id = 0; + char *bus_name = NULL; + bool ret = false; + GError *error = NULL; + GDBusNodeInfo *introspection_data = NULL; + + bus_name = __get_bus_name(__app_id); + retvm_if(!bus_name, false, "bus_name is NULL"); + + __gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); + if (__gdbus_conn == NULL) { + if (error != NULL) { + _LOGE("Failed to get dbus [%s]", error->message); + g_error_free(error); + } + goto out; + } + + owner_id = g_bus_own_name_on_connection(__gdbus_conn, bus_name, + G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); + + if (owner_id == 0) { + _LOGE("Acquiring the own name is failed"); + goto out; + } + + introspection_data = g_dbus_node_info_new_for_xml(introspection, NULL); + if (!introspection_data) { + _LOGE("g_dbus_node_info_new_for_xml() is failed."); + goto out; + } + + registration_id = g_dbus_connection_register_object(__gdbus_conn, + MESSAGEPORT_OBJECT_PATH, introspection_data->interfaces[0], + &interface_vtable, NULL, NULL, NULL); + + _LOGE("registration_id %d", registration_id); + + if (registration_id == 0) { + _LOGE("Failed to g_dbus_connection_register_object"); + goto out; + } + ret = true; + +out: + FREE_AND_NULL(bus_name); + if (!__gdbus_conn) + g_object_unref(__gdbus_conn); + if (introspection_data) + g_dbus_node_info_unref(introspection_data); + + return ret; + +} + +void __list_free_port_list(gpointer data) +{ + port_list_info_s *n = (port_list_info_s *)data; + + FREE_AND_NULL(n->port_name); + FREE_AND_NULL(n); +} + +static void __hash_destory_local_value(gpointer data) +{ + message_port_local_port_info_s *mli = (message_port_local_port_info_s *)data; + if (mli->port_name) + free(mli->port_name); +} +static void __hash_destory_remote_value(gpointer data) +{ + message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data; + + if (mri) { + FREE_AND_NULL(mri->encoded_bus_name); + FREE_AND_NULL(mri->sender_id); + FREE_AND_NULL(mri->remote_app_id); + if (mri->port_list) { + g_list_free_full(mri->port_list, __list_free_port_list); + } + } +} + +static bool __initialize(void) +{ + + int pid = getpid(); + int ret = 0; + char buffer[MAX_PACKAGE_STR_SIZE] = {0, }; + + _LOGI("initialize"); + ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer)); + retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret); + + __app_id = strdup(buffer); + retvm_if(!__app_id, false, "Malloc failed"); + _LOGI("init : %s", __app_id); + + if (__local_port_info == NULL) { + __local_port_info = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __hash_destory_local_value); + retvm_if(!__local_port_info, false, "fail to create __local_port_info"); + } + + if (__remote_port_info == NULL) { + __remote_port_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value); + retvm_if(!__remote_port_info, false, "fail to create __remote_port_info"); + } + + if (__sender_appid_hash == NULL) { + __sender_appid_hash = g_hash_table_new(g_str_hash, g_str_equal); + retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash"); + } + + if (__trusted_app_list_hash == NULL) + __trusted_app_list_hash = g_hash_table_new(g_str_hash, g_str_equal); + + if (__checked_app_list_hash == NULL) + __checked_app_list_hash = + g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_list_value); + + + if (!__dbus_init()) { + return false; + } + _initialized = true; + + return true; +} + + +static bool __message_port_register_port(const int local_id, const char *local_port, bool is_trusted, messageport_message_cb callback) +{ + message_port_local_port_info_s *mi = (message_port_local_port_info_s *)calloc(1, sizeof(message_port_local_port_info_s)); + retvm_if(!mi, false, "Malloc failed"); + + mi->callback = callback; + mi->is_trusted = is_trusted; + mi->port_name = strdup(local_port); + if (mi->port_name == NULL) { + _LOGE("Malloc failed (%s)", local_port); + free(mi); + return false; + } + mi->local_id = local_id; + + g_hash_table_insert(__local_port_info, GINT_TO_POINTER(mi->local_id), mi); + return true; +} + +static int __register_message_port(const char *local_port, bool is_trusted, messageport_message_cb callback) +{ + _SECURE_LOGI("Register a message port : [%s:%s]", __app_id, local_port); + + int local_id = 0; + + // Check the message port is already registed + if (__is_local_port_registed(local_port, is_trusted, &local_id, NULL)) { + return local_id; + } + + local_id = __get_next_id(); + + if (!__message_port_register_port(local_id, local_port, is_trusted, callback)) { + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + return local_id; +} + +static int __message_port_send_message(const char *remote_appid, const char *remote_port, + const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message) +{ + int ret = MESSAGEPORT_ERROR_NONE; + int len = 0; + bundle_raw *raw = NULL; + char *bus_name = NULL; + + message_port_remote_app_info_s *remote_app_info = NULL; + port_list_info_s *port_info = NULL; + GDBusMessage *msg = NULL; + GError *err = NULL; + GVariant *body = NULL; + + ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info); + if (ret != MESSAGEPORT_ERROR_NONE) { + return ret; + } + + if (trusted_message) { + if (remote_app_info->certificate_info != CERTIFICATE_MATCH) { + if (!__is_preloaded(__app_id, remote_appid)) { + if (__check_certificate(__app_id, remote_appid) != MESSAGEPORT_ERROR_NONE) { + ret = MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH; + goto out; + } + } + remote_app_info->certificate_info = CERTIFICATE_MATCH; + } + } + + if (port_info->exist == false) { + bool exist = false; + _LOGI("port exist check !!"); + ret = __check_remote_port(remote_appid, remote_port, trusted_message, &exist); + if (ret != MESSAGEPORT_ERROR_NONE) { + goto out; + } else if (!exist) { + ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; + goto out; + } + } + + bus_name = remote_app_info->encoded_bus_name; + + if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) { + ret = MESSAGEPORT_ERROR_INVALID_PARAMETER; + goto out; + } + + if (MAX_MESSAGE_SIZE < len) { + _LOGE("The size of message (%d) has exceeded the maximum limit.", len); + ret = MESSAGEPORT_ERROR_MAX_EXCEEDED; + } + + body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir, + remote_appid, remote_port, trusted_message, len, raw); + + msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, MESSAGEPORT_INTERFACE, "send_message"); + if (!msg) { + _LOGE("Can't allocate new method call"); + ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY; + goto out; + } + + g_dbus_message_set_body(msg, body); + g_dbus_message_set_flags(msg, G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED); + g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err); + if (err != NULL) { + _LOGE("No reply. error = %s", err->message); + g_error_free(err); + ret = MESSAGEPORT_ERROR_IO_ERROR; + goto out; + } + + out: + if (msg) + g_object_unref(msg); + if (raw) + bundle_free_encoded_rawdata(&raw); + return ret; +} + +int __message_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port, bool trusted_message, bundle *message) +{ + message_port_local_port_info_s *local_info; + int ret = __get_local_port_info(id, &local_info); + if (ret != MESSAGEPORT_ERROR_NONE) { + return ret; + } + + _LOGE("bidirectional_message %s", local_info->port_name); + return __message_port_send_message(remote_app_id, remote_port, + local_info->port_name, trusted_message, local_info->is_trusted, true, message); +} + +int messageport_unregister_local_port(int local_port_id, bool trusted_port) +{ + + GDBusMessage *msg = NULL; + GDBusMessage *reply = NULL; + GError *err = NULL; + GVariant *body; + char *bus_name = NULL; + GList *checked_app_list = NULL; + GList *checked_app = NULL; + + _LOGE("unregister : %d", local_port_id); + + message_port_local_port_info_s *mi = + (message_port_local_port_info_s *) + g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(local_port_id)); + if (mi == NULL) + return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; + + if (mi->is_trusted != trusted_port) + return MESSAGEPORT_ERROR_INVALID_PARAMETER; + + checked_app_list = (GList *)g_hash_table_lookup(__checked_app_list_hash, mi->port_name); + checked_app = NULL; + for (checked_app = checked_app_list; checked_app != NULL; + checked_app = checked_app->next) { + + char *checked_app_id = (char *)checked_app->data; + + _LOGI("unregister appid: %s", checked_app_id); + bus_name = __get_bus_name(checked_app_id); + msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, + MESSAGEPORT_INTERFACE, "unregister_port"); + if (!msg) { + _LOGI("Can't allocate new method call"); + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + g_dbus_message_set_body(msg, + g_variant_new("(sbs)", __app_id, mi->is_trusted, mi->port_name)); + reply = g_dbus_connection_send_message_with_reply_sync( + __gdbus_conn, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + 500, + NULL, + NULL, + &err); + + if (err || (reply == NULL)) { + if (err) { + _LOGE("No reply. error = %s", err->message); + g_error_free(err); + } + } else { + if (g_dbus_message_to_gerror(reply, &err)) { + if (err) { + _LOGE("error = %s", err->message); + g_error_free(err); + } + } else { + int ret_val = MESSAGEPORT_ERROR_NONE; + + body = g_dbus_message_get_body(reply); + g_variant_get(body, "(u)", &ret_val); + + if (ret_val == MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH) { + _SECURE_LOGI("The remote application (%s) is not signed with the same certificate" + , checked_app_id); + } + } + } + if (msg) + g_object_unref(msg); + if (reply) + g_object_unref(reply); + + + } + g_hash_table_remove(__checked_app_list_hash, mi->port_name); + g_hash_table_remove(__local_port_info, GINT_TO_POINTER(local_port_id)); + + if (msg) + g_object_unref(msg); + if (reply) + g_object_unref(reply); + + return MESSAGEPORT_ERROR_NONE; +} + +int messageport_register_local_port(const char *local_port, messageport_message_cb callback) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + + return __register_message_port(local_port, false, callback); +} + +int messageport_register_trusted_local_port(const char *local_port, messageport_message_cb callback) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + + return __register_message_port(local_port, true, callback); + +} + +int messageport_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + + return __check_remote_port(remote_app_id, remote_port, false, exist); +} + +int messageport_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + + return __check_remote_port(remote_app_id, remote_port, true, exist); +} + +int messageport_send_message(const char *remote_app_id, const char *remote_port, bundle *message) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + + return __message_port_send_message(remote_app_id, remote_port, NULL, false, false, false, message); +} + +int messageport_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + + return __message_port_send_message(remote_app_id, remote_port, NULL, true, false, false, message); +} + +int messageport_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port, + bundle *message) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + + return __message_send_bidirectional_message(id, remote_app_id, remote_port, false, message); +} + +int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port, + bundle *message) +{ + if (!_initialized) { + if (!__initialize()) + return MESSAGEPORT_ERROR_IO_ERROR; + } + return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message); +} + +int messageport_get_local_port_name(int id, char **name) +{ + message_port_local_port_info_s *local_info; + int ret = __get_local_port_info(id, &local_info); + + if (ret != MESSAGEPORT_ERROR_NONE) { + return ret; + } + + *name = strdup(local_info->port_name); + + if (*name == NULL) { + return MESSAGEPORT_ERROR_OUT_OF_MEMORY; + } + + return MESSAGEPORT_ERROR_NONE; +} + +int messageport_check_trusted_local_port(int id, bool *trusted) +{ + message_port_local_port_info_s *local_info; + int ret = __get_local_port_info(id, &local_info); + + if (ret != MESSAGEPORT_ERROR_NONE) { + return ret; + } + + *trusted = local_info->is_trusted; + + return MESSAGEPORT_ERROR_NONE;; +} + diff --git a/src/message-port.cpp b/src/message-port.cpp deleted file mode 100644 index 577fab4..0000000 --- a/src/message-port.cpp +++ /dev/null @@ -1,189 +0,0 @@ -// -// 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; - ret = pProxy->CheckTrustedLocalPort(id, &trusted); - if (ret < 0) - { - free(pName); - return MESSAGEPORT_ERROR_INVALID_PARAMETER; - } - - 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; -} - diff --git a/src/message_port.c b/src/message_port.c new file mode 100644 index 0000000..79a50d7 --- /dev/null +++ b/src/message_port.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2014 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 "message_port_internal.h" +#include "message_port_log.h" +#include "message_port.h" + +typedef struct message_port_callback_item_s { + message_port_message_cb callback; + void *user_data; +} message_port_callback_item; + +static GHashTable *__listeners; +static GHashTable *__trusted_listeners; +static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER; + +static void do_callback(message_port_message_cb callback, int local_port_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, bundle *message, void *user_data) +{ + if (callback) + { + callback(local_port_id, remote_app_id, remote_port, trusted_remote_port, message, user_data); + bundle_free(message); + } + else + { + _LOGI("Ignored"); + } +} + +static void message_dispatcher(int local_port_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, bundle *message) +{ + _SECURE_LOGI("A message has been received to specific local port id (%d) from%s remote port (%s):(%s).", + local_port_id, trusted_remote_port ? " trusted" : "", remote_app_id, remote_port); + + message_port_callback_item *item = + (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id)); + do_callback(item->callback, local_port_id, remote_app_id, remote_port, trusted_remote_port, message, item->user_data); +} + +static void trusted_message_dispatcher(int trusted_local_port_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, bundle *message) +{ + _SECURE_LOGI("A message has been received to specific trusted local port id (%d) from%s remote port (%s):(%s).", + trusted_local_port_id, trusted_remote_port ? " trusted" : "", remote_app_id, remote_port); + message_port_callback_item *item = + (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id)); + do_callback(item->callback, trusted_local_port_id, remote_app_id, remote_port, trusted_remote_port, message, item->user_data); +} + +int message_port_register_local_port(const char *local_port, message_port_message_cb callback, void *user_data) +{ + if (local_port == NULL || callback == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + + int local_port_id = messageport_register_local_port(local_port, message_dispatcher); + if (local_port_id > 0) + { + _SECURE_LOGI("Register local port ID (%d).", local_port_id); + + if (__listeners == NULL) { + __listeners = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + } + pthread_mutex_lock(&__mutex); + message_port_callback_item *item = + (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id)); + if (item == NULL) { + item = (message_port_callback_item *)calloc(1, sizeof(message_port_callback_item)); + if (item == NULL) { + return MESSAGE_PORT_ERROR_OUT_OF_MEMORY; + } + g_hash_table_insert(__listeners, GINT_TO_POINTER(local_port_id), item); + } + + + item->callback = callback; + item->user_data = user_data; + pthread_mutex_unlock(&__mutex); + + } else { + _SECURE_LOGI("Register local port fail (%d).", local_port_id); + + } + return convert_to_tizen_error((messageport_error_e)local_port_id); +} + +int message_port_register_trusted_local_port(const char *local_port, message_port_trusted_message_cb callback, void *user_data) +{ + if (local_port == NULL || callback == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + + int trusted_local_port_id = messageport_register_trusted_local_port(local_port, trusted_message_dispatcher); + if (trusted_local_port_id > 0) + { + _SECURE_LOGI("Register trusted local port ID (%d).", trusted_local_port_id); + + if (__trusted_listeners == NULL) { + __trusted_listeners = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + } + pthread_mutex_lock(&__mutex); + message_port_callback_item *item = + (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id)); + if (item == NULL) { + item = (message_port_callback_item *)calloc(1, sizeof(message_port_callback_item)); + if (item == NULL) { + return MESSAGE_PORT_ERROR_OUT_OF_MEMORY; + } + g_hash_table_insert(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id), item); + } + + item->callback = callback; + item->user_data = user_data; + pthread_mutex_unlock(&__mutex); + } else { + _SECURE_LOGI("Register trusted local port fail (%d).", trusted_local_port_id); + + } + + return convert_to_tizen_error((messageport_error_e)trusted_local_port_id); +} + +int message_port_unregister_local_port(int local_port_id) +{ + int res = MESSAGE_PORT_ERROR_NONE; + if (local_port_id <= 0) + { + _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + else { + res = messageport_unregister_local_port(local_port_id, false); + g_hash_table_remove(__listeners, GINT_TO_POINTER(local_port_id)); + } + return convert_to_tizen_error((messageport_error_e)res); +} + +int message_port_unregister_trusted_local_port(int trusted_local_port_id) +{ + + int res = MESSAGE_PORT_ERROR_NONE; + if (trusted_local_port_id <= 0) + { + _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + else { + res = messageport_unregister_local_port(trusted_local_port_id, true); + g_hash_table_remove(__trusted_listeners, GINT_TO_POINTER(trusted_local_port_id)); + } + + return convert_to_tizen_error((messageport_error_e)res); +} + +int message_port_check_remote_port(const char* remote_app_id, const char *remote_port, bool* exist) +{ + if (remote_app_id == NULL || remote_port == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + _SECURE_LOGI("Check remote port (%s):(%s).", remote_app_id, remote_port); + return convert_to_tizen_error((messageport_error_e)messageport_check_remote_port(remote_app_id, remote_port, exist)); +} + +int message_port_check_trusted_remote_port(const char* remote_app_id, const char *remote_port, bool *exist) +{ + if (remote_app_id == NULL || remote_port == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + _SECURE_LOGI("Check trusted remote port (%s):(%s).", remote_app_id, remote_port); + return convert_to_tizen_error((messageport_error_e)messageport_check_trusted_remote_port(remote_app_id, remote_port, exist)); +} + +int message_port_send_message(const char *remote_app_id, const char *remote_port, bundle *message) +{ + if (remote_app_id == NULL || remote_port == NULL || message == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + _SECURE_LOGI("Send a message to the remote port (%s):(%s).", remote_app_id, remote_port); + return convert_to_tizen_error((messageport_error_e)messageport_send_message(remote_app_id, remote_port, message)); +} + +int message_port_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message) +{ + if (remote_app_id == NULL || remote_port == NULL || message == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + _SECURE_LOGI("Send a trusted message to the remote port (%s):(%s).", remote_app_id, remote_port); + return convert_to_tizen_error((messageport_error_e)messageport_send_trusted_message(remote_app_id, remote_port, message)); +} + +int message_port_send_message_with_local_port(const char *remote_app_id, const char *remote_port, bundle *message, int local_port_id) +{ + if (remote_app_id == NULL || remote_port == NULL || message == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + else if (local_port_id <= 0) + { + _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + else { + + message_port_callback_item *item = NULL; + message_port_callback_item *trusted_item = NULL; + + if (__listeners != NULL) { + item = (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id)); + } + if (item == NULL && __trusted_listeners != NULL) { + trusted_item = (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(local_port_id)); + + } + + if (item == NULL && trusted_item == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_PORT_NOT_FOUND] The local port ID (%d) is not registered.", local_port_id); + return MESSAGE_PORT_ERROR_PORT_NOT_FOUND; + } + } + + _SECURE_LOGI("Send a message to (%s):(%s) and listen at the local port ID (%d).", remote_app_id, remote_port, local_port_id); + return convert_to_tizen_error((messageport_error_e)messageport_send_bidirectional_message(local_port_id, remote_app_id, remote_port, message)); +} + +int message_port_send_trusted_message_with_local_port(const char* remote_app_id, const char *remote_port, bundle* message, int local_port_id) +{ + if (remote_app_id == NULL || remote_port == NULL || message == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_INVALID_PARAMETER] NULL value is not allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + else if (local_port_id <= 0) + { + _LOGE("[MESSAGEPORT_ERROR_INVALID_PARAMETER] Neither 0 nor negative value is allowed."); + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + } + else { + message_port_callback_item *item = NULL; + message_port_callback_item *trusted_item = NULL; + + if (__listeners != NULL) { + item = (message_port_callback_item *)g_hash_table_lookup(__listeners, GINT_TO_POINTER(local_port_id)); + } + if (item == NULL && __trusted_listeners != NULL) { + trusted_item = (message_port_callback_item *)g_hash_table_lookup(__trusted_listeners, GINT_TO_POINTER(local_port_id)); + + } + + if (item == NULL && trusted_item == NULL) + { + _LOGE("[MESSAGE_PORT_ERROR_PORT_NOT_FOUND] The local port ID (%d) is not registered.", local_port_id); + return MESSAGE_PORT_ERROR_PORT_NOT_FOUND; + } + } + + _SECURE_LOGI("Send a trusted message to (%s):(%s) and listen at the local port ID (%d).", remote_app_id, remote_port, local_port_id); + return convert_to_tizen_error((messageport_error_e)messageport_send_bidirectional_trusted_message(local_port_id, remote_app_id, remote_port, message)); +} + diff --git a/src/message_port_internal.c b/src/message_port_internal.c new file mode 100644 index 0000000..1373005 --- /dev/null +++ b/src/message_port_internal.c @@ -0,0 +1,41 @@ +/* + * 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 "message_port.h" +#include "message_port_internal.h" + +int convert_to_tizen_error(messageport_error_e error) +{ + switch (error) { + case MESSAGEPORT_ERROR_NONE: + return MESSAGE_PORT_ERROR_NONE; + case MESSAGEPORT_ERROR_IO_ERROR: + return MESSAGE_PORT_ERROR_IO_ERROR; + case MESSAGEPORT_ERROR_OUT_OF_MEMORY: + return MESSAGE_PORT_ERROR_OUT_OF_MEMORY; + case MESSAGEPORT_ERROR_INVALID_PARAMETER: + return MESSAGE_PORT_ERROR_INVALID_PARAMETER; + case MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND: + return MESSAGE_PORT_ERROR_PORT_NOT_FOUND; + case MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH: + return MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH; + case MESSAGEPORT_ERROR_MAX_EXCEEDED: + return MESSAGE_PORT_ERROR_MAX_EXCEEDED; + case MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE: + return MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE; + default: + return error; + } +} -- 2.7.4