sync with master
authorJinkun Jang <jinkun.jang@samsung.com>
Sat, 16 Mar 2013 12:17:33 +0000 (21:17 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Sat, 16 Mar 2013 12:17:33 +0000 (21:17 +0900)
18 files changed:
CMakeLists.txt [new file with mode: 0755]
LICENSE.APLv2 [new file with mode: 0644]
NOTICE [new file with mode: 0644]
include/message-port-data-types.h [new file with mode: 0644]
include/message-port-messages.h [new file with mode: 0644]
include/message-port-param-traits.h [new file with mode: 0644]
include/message-port.h [new file with mode: 0755]
message-port.manifest [new file with mode: 0644]
message-port.pc.in [new file with mode: 0755]
packaging/message-port.spec [new file with mode: 0755]
src/IIpcClientEventListener.h [new file with mode: 0644]
src/IpcClient.cpp [new file with mode: 0644]
src/IpcClient.h [new file with mode: 0644]
src/MessagePortProxy.cpp [new file with mode: 0644]
src/MessagePortProxy.h [new file with mode: 0644]
src/message-port-log.h [new file with mode: 0644]
src/message-port-messages.cpp [new file with mode: 0644]
src/message-port.cpp [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..64adece
--- /dev/null
@@ -0,0 +1,85 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(this_target "message-port")
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+## OUTPUT PATHS
+SET(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/cmake_build_tmp/output)
+
+INCLUDE_DIRECTORIES (
+       /usr/include
+       /usr/include/appfw
+       /usr/include/dlog
+       /usr/include/glib-2.0
+       /usr/lib/glib-2.0/include
+       /usr/include/chromium
+       include
+       )
+
+SET (${this_target}_SOURCE_FILES
+       src/IpcClient.cpp
+       src/message-port.cpp
+       src/message-port-messages.cpp
+       src/MessagePortProxy.cpp
+)
+
+SET(requires "dlog bundle glib-2.0 chromium")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${this_target} REQUIRED ${requires})
+FOREACH(flag ${${this_target}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS  "${EXTRA_CFLAGS} -Wall" )
+
+## SET C COMPILER FLAGS
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+## SET CPP COMPILER FLAGS
+SET(CMAKE_CXX_FLAGS "${OSP_DEBUG_FLAGS} ${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}")
+
+IF("${ARCH}" STREQUAL "arm")
+    ADD_DEFINITIONS("-DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DSLP_DEBUG")
+
+## Create Library
+ADD_LIBRARY (${this_target} SHARED ${${this_target}_SOURCE_FILES})
+
+## SET LINKER FLAGS
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib")
+
+TARGET_LINK_LIBRARIES(${this_target} "-ldlog" )
+TARGET_LINK_LIBRARIES(${this_target} "-lbundle" )
+TARGET_LINK_LIBRARIES(${this_target} "-lglib-2.0" )
+TARGET_LINK_LIBRARIES(${this_target} "-lchromium" )
+TARGET_LINK_LIBRARIES(${this_target} "-lcapi-appfw-app-manager" )
+TARGET_LINK_LIBRARIES(${this_target} "-lcapi-appfw-package-manager" )
+
+SET_TARGET_PROPERTIES(${this_target}
+       PROPERTIES
+       VERSION ${FULLVER}
+       SOVERSION ${MAJORVER}
+       CLEAN_DIRECT_OUTPUT 1
+       )
+
+
+# pkgconfig file
+CONFIGURE_FILE(${this_target}.pc.in ${CMAKE_SOURCE_DIR}/${this_target}.pc @ONLY)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/${this_target}.pc DESTINATION lib/pkgconfig)
+
+INSTALL(TARGETS ${this_target} DESTINATION lib)
+
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/appfw FILES_MATCHING PATTERN "*.h")
+
+INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/ DESTINATION lib
+               FILES_MATCHING PATTERN "*.so*" 
+               PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ                      
+                    GROUP_EXECUTE GROUP_READ
+                    WORLD_EXECUTE WORLD_READ)
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..0e0f016
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache License terms and conditions.
diff --git a/include/message-port-data-types.h b/include/message-port-data-types.h
new file mode 100644 (file)
index 0000000..dc5940e
--- /dev/null
@@ -0,0 +1,33 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file               message-port-data-types.h
+ * @brief              This is the header file for data types for IPC.
+ */
+
+#ifndef _APPFW_MESSAGE_PORT_DATA_TYPES_H_
+#define _APPFW_MESSAGE_PORT_DATA_TYPES_H_
+
+#include <bundle.h>
+
+typedef struct
+{
+       bundle* b;
+} BundleBuffer;
+
+#endif //_APPFW_MESSAGE_PORT_DATA_TYPES_H_
diff --git a/include/message-port-messages.h b/include/message-port-messages.h
new file mode 100644 (file)
index 0000000..54d80e4
--- /dev/null
@@ -0,0 +1,38 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file        message-port-messages.h
+ * @brief              This is the header file for message types for IPC.
+ */
+
+#ifndef _APPFW_MESSAGE_PORT_MESSAGES_H_
+#define _APPFW_MESSAGE_PORT_MESSAGES_H_
+
+#include "ipc/ipc_message_macros.h"
+#include "message-port-data-types.h"
+#include "message-port-param-traits.h"
+
+#define MessagePortStart 0
+#define IPC_MESSAGE_START MessagePortStart
+
+IPC_SYNC_MESSAGE_CONTROL1_1(MessagePort_registerPort, BundleBuffer, int)
+IPC_SYNC_MESSAGE_CONTROL1_1(MessagePort_checkRemotePort, BundleBuffer, int)
+IPC_SYNC_MESSAGE_CONTROL1_1(MessagePort_sendMessage, BundleBuffer, int)
+IPC_MESSAGE_CONTROL1(MessagePort_sendMessageAsync, BundleBuffer)
+
+#endif //_APPFW_MESSAGE_PORT_MESSAGES_H_
diff --git a/include/message-port-param-traits.h b/include/message-port-param-traits.h
new file mode 100644 (file)
index 0000000..4142b8d
--- /dev/null
@@ -0,0 +1,99 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file               message-port-param-traits.h
+ * @brief              This is the header file for message port param traits for IPC.
+ */
+
+#ifndef _APPFW_MESSAGE_PORT_PARAM_TRAITS_H_
+#define _APPFW_MESSAGE_PORT_PARAM_TRAITS_H_
+#pragma once
+
+#include <base/tuple.h>
+#include <ipc/ipc_param_traits.h>
+
+#include <bundle.h>
+
+#include "message-port-data-types.h"
+
+namespace IPC
+{
+
+template<>
+struct ParamTraits <BundleBuffer>
+{
+       typedef BundleBuffer param_type;
+
+       static void Write(Message* m, const param_type& p)
+       {
+               int len = 0;
+               bundle_raw* raw = NULL;
+               bundle_encode(p.b, &raw, &len);
+
+
+               m->WriteInt(len);
+               m->WriteBytes((const void*) raw, len);
+
+               m->WriteInt(len);
+
+               bundle_free_encoded_rawdata(&raw);
+       }
+
+       static bool Read(const Message* m, void** iter, param_type* r)
+       {
+               int len = 0;
+               const char* pBuffer = NULL;
+
+               if (!m->ReadLength(iter, &len))
+               {
+                       return false;
+               }
+
+               if (!m->ReadBytes(iter, &pBuffer, len))
+               {
+                       return false;
+               }
+
+               if (!m->ReadLength(iter, &len))
+               {
+                       return false;
+               }
+
+               if (pBuffer != NULL)
+               {
+                       // Truncated
+                       ((char*)pBuffer)[len] = '\0';
+               }
+               else
+               {
+                       return false;
+               }
+
+               r->b = bundle_decode((const bundle_raw*)pBuffer, len);
+
+               return true;
+       }
+
+       static void Log(const param_type& p, std::string* l)
+       {
+       }
+};
+
+}
+
+#endif //_APPFW_MESSAGE_PORT_PARAM_TRAITS_H_
diff --git a/include/message-port.h b/include/message-port.h
new file mode 100755 (executable)
index 0000000..65aec02
--- /dev/null
@@ -0,0 +1,259 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+
+#ifndef __APPFW_MESSAGE_PORT_H__
+#define __APPFW_MESSAGE_PORT_H__
+
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Enumerations of error code for Application.
+ */
+typedef enum
+{
+       MESSAGEPORT_ERROR_NONE = 0, /**< Successful */
+       MESSAGEPORT_ERROR_IO_ERROR = -1,                /**< Internal I/O error */
+       MESSAGEPORT_ERROR_OUT_OF_MEMORY = -2,           /**< Out of memory */
+       MESSAGEPORT_ERROR_INVALID_PARAMETER = -3,       /**< Invalid parameter */
+       MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND = -4,           /**< The message port of the remote application is not found */
+       MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH = -5,   /**< The remote application is not signed with the same certificate */
+       MESSAGEPORT_ERROR_MAX_EXCEEDED = -6,    /**< The size of message has exceeded the maximum limit */
+} messageport_error_e;
+
+
+/**
+ * @brief   Called when a message is received from the remote application.
+ *
+ * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port()
+ * @param [in] remote_app_id The ID of the remote application which has sent this message
+ * @param [in] remote_port The name of the remote message port
+ * @param [in] trusted_message @c true if the trusted remote message port is ready to receive the response data
+ * @param [in] data the data passed from the remote application
+ * @remarks @a data must be released with bundle_free() by you
+ * @remark @a remote_app_id and @a remote_port will be set if the remote application sends a bidirectional message, otherwise they are NULL.
+ */
+typedef void (*messageport_message_cb)(int id, const char* remote_app_id, const char* remote_port, bool trusted_message, bundle* data);
+
+
+/**
+ * @brief Registers the local message port.
+ *
+ * @param [in] local_port the name of the local message port
+ * @param [in] callback The callback function to be called when a message is received
+ * @return A message port id on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error
+ */
+int messageport_register_local_port(const char* local_port, messageport_message_cb callback);
+
+/**
+ * @brief Registers the trusted local message port.
+ *
+ * @param [in] local_port the name of the local message port
+ * @param [in] callback The callback function to be called when a message is received
+ * @return A message port id on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error
+ */
+int messageport_register_trusted_local_port(const char* local_port, messageport_message_cb callback);
+
+
+/**
+ * @brief Unregisters the local message port.
+ *
+ * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port()
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int messageport_unregister_local_port(int id);
+
+/**
+ * @brief Checks if the message port of a remote application is registered.
+ *
+ * @param [in] remote_app_id The ID of the remote application
+ * @param [in] remote_port the name of the remote message port
+ * @param [out] exist @c true if the message port of the remote application exists, otherwise @c false
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error
+ */
+int messageport_check_remote_port(const char* remote_app_id, const char *remote_port, bool* exist);
+
+/**
+ * @brief Checks if the trusted message port of a remote application is registered.
+ *
+ * @param [in] remote_app_id The ID of the remote application
+ * @param [in] remote_port the name of the remote message port
+ * @param [out] exist @c true if the message port of the remote application exists, otherwise @c false
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH The remote application is not signed with the same certificate
+ * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error
+ */
+int messageport_check_trusted_remote_port(const char* remote_app_id, const char *remote_port, bool* exist);
+
+/**
+ * @brief Sends a message to the message port of a remote application.
+ *
+ * @param [in] remote_app_id The ID of the remote application
+ * @param [in] remote_port the name of the remote message port
+ * @param [in] message the message to be passed to the remote application
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND The message port of the remote application is not found
+ * @retval #MESSAGEPORT_ERROR_MAX_EXCEEDED The size of message has exceeded the maximum limit
+ * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error
+ *
+ * @code
+ * #include <message-port.h>
+ *
+ * bundle *b = bundle_create();
+ * bundle_add(b, "key1", "value1");
+ * bundle_add(b, "key2", "value2");
+ *
+ * int ret = messageport_send_message("0123456789.BasicApp", "BasicAppPort", b);
+ *
+ * bundle_free(b);
+ * @endcode
+ */
+int messageport_send_message(const char* remote_app_id, const char* remote_port, bundle* message);
+
+/**
+ * @brief Sends a trusted message to the message port of a remote application.
+ *
+ * @param [in] remote_app_id The ID of the remote application
+ * @param [in] remote_port the name of the remote message port
+ * @param [in] message the message to be passed to the remote application
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND The message port of the remote application is not found
+ * @retval #MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH The remote application is not signed with the same certificate
+ * @retval #MESSAGEPORT_ERROR_MAX_EXCEEDED The size of message has exceeded the maximum limit
+ * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error
+ */
+int messageport_send_trusted_message(const char* remote_app_id, const char* remote_port, bundle* message);
+
+/**
+ * @brief Sends a message to the message port of a remote application. This method is used for the bidirectional communication.
+ *
+ * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port()
+ * @param [in] remote_app_id The ID of the remote application
+ * @param [in] remote_port the name of the remote message port
+ * @param [in] message the message to be passed to the remote application
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND The message port of the remote application is not found
+ * @retval #MESSAGEPORT_ERROR_MAX_EXCEEDED The size of message has exceeded the maximum limit
+ * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error
+ *
+ * @code
+ * #include <message-port.h>
+ *
+ * static void
+ * OnMessageReceived(int id, const char* remote_app_id, const char* remote_port, bool trusted_port, bundle* data)
+ * {
+ * }
+ *
+ * int main(int argc, char *argv[])
+ * {
+ *   bundle *b = bundle_create();
+ *   bundle_add(b, "key1", "value1");
+ *   bundle_add(b, "key2", "value2");
+ *
+ *   int id = messageport_register_local_port("HelloPort", OnMessageReceived);
+ *
+ *   int ret = messageport_send_message(id, "0123456789.BasicApp", "BasicAppPort", b);
+ *
+ *   bundle_free(b);
+ * }
+ */
+int messageport_send_bidirectional_message(int id, const char* remote_app_id, const char* remote_port, bundle* data);
+
+/**
+ * @brief Sends a trusted message to the message port of a remote application. This method is used for the bidirectional communication.
+ *
+ * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port()
+ * @param [in] remote_app_id The ID of the remote application
+ * @param [in] remote_port the name of the remote message port
+ * @param [in] message the message to be passed to the remote application
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND The message port of the remote application is not found
+ * @retval #MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH The remote application is not signed with the same certificate
+ * @retval #MESSAGEPORT_ERROR_MAX_EXCEEDED The size of message has exceeded the maximum limit
+ * @retval #MESSAGEPORT_ERROR_IO_ERROR Internal I/O error
+ */
+int messageport_send_bidirectional_trusted_message(int id, const char* remote_app_id, const char* remote_port, bundle* data);
+
+
+/**
+ * @brief Gets the name of the local message port.
+ *
+ * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port()
+ * @param [out] name The name of the local message port
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @remarks @a name must be released with free() by you
+ */
+int messageport_get_local_port_name(int id, char **name);
+
+/**
+ * @brief Checks if the local message port is trusted.
+ *
+ * @param [in] id The message port id returned by messageport_register_local_port() or messageport_register_trusted_local_port()
+ * @param [out] @c true if the local message port is trusted
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESSAGEPORT_ERROR_NONE Successful
+ * @retval #MESSAGEPORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESSAGEPORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int messageport_check_trusted_local_port(int id, bool *trusted);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPFW_MESSAGE_PORT_H__ */
diff --git a/message-port.manifest b/message-port.manifest
new file mode 100644 (file)
index 0000000..75b0fa5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_"/>
+    </request>
+</manifest>
diff --git a/message-port.pc.in b/message-port.pc.in
new file mode 100755 (executable)
index 0000000..bd96a4c
--- /dev/null
@@ -0,0 +1,15 @@
+
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=/usr/lib
+includedir=/usr/include/appfw
+
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} -lmessage-port
+Cflags: -I${includedir}
+
diff --git a/packaging/message-port.spec b/packaging/message-port.spec
new file mode 100755 (executable)
index 0000000..9c147f9
--- /dev/null
@@ -0,0 +1,73 @@
+%define debug_package %{nil}
+%define __strip /bin/true
+
+Name:       message-port
+Summary:    Message Port library
+Version:       1.2.1.0
+Release:    1
+Group:         TO_BE/FILLED_IN
+License:    Apache License, Version 2.0
+Source0:    %{name}-%{version}.tar.gz
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(bundle)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(chromium)
+BuildRequires:  pkgconfig(capi-appfw-app-manager)
+BuildRequires:  pkgconfig(capi-appfw-package-manager)
+
+# runtime requires
+Requires: chromium
+
+Requires(post): /sbin/ldconfig  
+Requires(post): coreutils
+Requires(postun): /sbin/ldconfig
+
+Provides:   libmessage-port.so.1
+
+%description
+Message Port library
+
+%package devel
+Summary:  Message Port library (Development)
+Group:    TO_BE/FILLED_IN
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Message Port library (DEV)
+
+
+%prep
+%setup -q
+
+%build
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
+
+# Call make instruction with smp support
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+
+%make_install
+mkdir -p %{buildroot}/usr/share/license
+install LICENSE.APLv2  %{buildroot}/usr/share/license/%{name}
+
+%make_install
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+%files
+%{_libdir}/libmessage-port.so.*
+%manifest message-port.manifest
+/usr/share/license/%{name}
+
+%files devel
+%{_includedir}/appfw/*.h
+%{_libdir}/pkgconfig/*.pc
+%{_libdir}/libmessage-port.so
+
diff --git a/src/IIpcClientEventListener.h b/src/IIpcClientEventListener.h
new file mode 100644 (file)
index 0000000..f34f813
--- /dev/null
@@ -0,0 +1,54 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file       IIpcClientEventListener.h
+ * @brief      This is the header file for the IIpcClientEventListener class.
+ *
+ * This file contains the declarations of  IIpcClientEventListener.
+ */
+
+#ifndef _IIPC_CLIENT_EVENT_LISTENER_H_
+#define _IIPC_CLIENT_EVENT_LISTENER_H_
+
+namespace IPC { class Message; }
+
+class IpcClient;
+
+/**
+ * @interface IIpcClientEventListener
+ * @brief     This interface provides the listener method for the response from IPC server.
+ */
+class IIpcClientEventListener
+{
+public:
+
+       /**
+        * This is the destructor for this class.
+        */
+       virtual ~IIpcClientEventListener(void) {}
+
+       /**
+        * Called when an IPC response message received.
+        *
+        * @param[in] client       The IPC client
+        * @param[in] message      The response message
+        */
+       virtual void OnIpcResponseReceived(IpcClient& client, const IPC::Message& message) = 0;
+}; // IIpcClientEventListener
+
+#endif //_IIPC_CLIENT_EVENT_LISTENER_H_
diff --git a/src/IpcClient.cpp b/src/IpcClient.cpp
new file mode 100644 (file)
index 0000000..fe68374
--- /dev/null
@@ -0,0 +1,583 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file       IpcClient.cpp
+ * @brief      This is the implementation file for the IpcClient class.
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <poll.h>
+#include <pthread.h>
+#include <fcntl.h>
+
+#include <iostream>
+#include <queue>
+#include <map>
+
+#include <app_manager.h>
+
+#include "message-port-log.h"
+
+#include "IpcClient.h"
+#include "IIpcClientEventListener.h"
+
+using namespace IPC;
+using namespace std;
+
+
+IpcClient::IpcClient(void)
+       : __pReverseSource(NULL)
+       , __fdCount(0)
+       //, __pFdLock(NULL)
+       , __pListener(NULL)
+{
+       __messageBuffer[0] = '\0';
+}
+
+IpcClient::~IpcClient(void)
+{
+       int fd = 0;
+
+       if (__pReverseSource != NULL)
+       {
+               g_source_destroy(__pReverseSource);
+               g_source_unref(__pReverseSource);
+               __pReverseSource = NULL;
+       }
+
+       while (__fds.size() > 0)
+       {
+               fd = __fds.back();
+               __fds.pop_back();
+
+               close(fd);
+       }
+
+       //delete __pFdLock;
+}
+
+int
+IpcClient::Construct(const string& serverName, const IIpcClientEventListener* pListener)
+{
+       __name = serverName;
+       __pListener = const_cast <IIpcClientEventListener*>(pListener);
+
+       int ret = MakeConnection();
+       if (ret != 0)
+       {
+               return ret;
+       }
+
+       if (__pListener)
+       {
+               ret = MakeConnection(true);
+               if (ret != 0)
+               {
+                       return ret;
+               }
+       }
+
+       return 0;
+
+}
+
+struct HelloMessage
+{
+       int pid;
+       bool reverse;
+       char appId[256];
+};
+
+int
+IpcClient::MakeConnection(bool forReverse)
+{
+       int ret = 0;
+
+       size_t socketNameLength = 0;
+       string socketName;
+
+       socketName.append("/tmp/");
+       socketName.append(__name);
+
+       socketNameLength = socketName.size() + 1;
+
+       HelloMessage helloMessage = {0, false};
+
+       helloMessage.pid = getpid();
+       helloMessage.reverse = forReverse;
+
+       if (__fdCount == 0)
+       {
+               char* pAppId = NULL;
+               ret = app_manager_get_app_id(helloMessage.pid, &pAppId);
+               _LOGD("app_id: %s", pAppId);
+
+               if (ret < 0)
+               {
+                       _LOGE("Failed to get_app_id: %d", ret);
+                       return -1;
+               }
+
+               strncpy(helloMessage.appId, pAppId, 255);
+
+               _LOGD("app_id: %s", helloMessage.appId);
+
+               __appId = pAppId;
+
+               free(pAppId);
+       }
+
+       struct sockaddr_un server;
+
+       bzero(&server, sizeof(server));
+       server.sun_family = AF_UNIX;
+       strncpy(server.sun_path, socketName.c_str(), socketNameLength);
+       socklen_t serverLen = sizeof(server);
+
+       int client = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (client < 0)
+       {
+               _LOGE("Failed to create a socket : %s.", strerror(errno));
+               return -1;
+       }
+
+       int flags = fcntl(client, F_GETFL, 0);
+       ret = fcntl(client, F_SETFL, flags | O_NONBLOCK);
+       if (ret != 0)
+       {
+               _LOGE("Failed to set file status flags (%d, %s).", errno, strerror(errno));
+               goto CATCH;
+       }
+
+       ret = connect(client, (struct sockaddr*) &server, serverLen);
+       if (ret != 0)
+       {
+               if (errno != EINPROGRESS)
+               {
+                       _LOGE("Failed to connect to server(%s) : %s", socketName.c_str(), strerror(errno));
+                       goto CATCH;
+               }
+
+               fd_set rset;
+               fd_set wset;
+               struct timeval timeout;
+               int length = 0;
+               int error = 0;
+               socklen_t socketLength = 0;
+
+               FD_ZERO(&rset);
+               FD_SET(client, &rset);
+               wset = rset;
+               timeout.tv_sec = 10; // FIXME: replace 10 with const int
+               timeout.tv_usec = 0;
+
+               while (true)
+               {
+                       ret = select(client+1, &rset, &wset, NULL, &timeout);
+                       if (ret < 0)
+                       {
+                               _LOGE("Failed to connect due to system error : %s.", strerror(errno));
+                               if (errno != EINTR)
+                               {
+                                       goto CATCH;
+                               }
+
+                               continue;
+                       }
+                       else if (ret == 0)
+                       {
+                               _LOGE("Failed to connect due to timeout.");
+                               goto CATCH;
+                       }
+                       else
+                       {
+                               break;
+                       }
+               }
+
+               if (FD_ISSET(client, &rset) || FD_ISSET(client, &wset))
+               {
+                       length = sizeof(error);
+                       ret = getsockopt(client, SOL_SOCKET, SO_ERROR, &error, &socketLength);
+                       if (ret < 0)
+                       {
+                               _LOGE("Failed to connect to server(%s) : %s", socketName.c_str(), strerror(errno));
+                               goto CATCH;
+                       }
+               }
+               else
+               {
+                       _LOGE("Failed to connect due to system error.");
+                       goto CATCH;
+               }
+       }
+
+       ret = fcntl(client, F_SETFL, flags);
+       if (ret < 0)
+       {
+               _LOGE("Failed to set file status flags (%d, %s).", errno, strerror(errno));
+               goto CATCH;
+       }
+
+       ret = write(client, &helloMessage, sizeof(helloMessage));
+       if (ret < 0)
+       {
+               goto CATCH;
+       }
+
+       if (forReverse)
+       {
+               GError* pGError = NULL;
+               GSource* pGSource = NULL;
+
+               GIOChannel* pChannel = g_io_channel_unix_new(client);
+               GMainContext* pGMainContext = g_main_context_default();
+
+               g_io_channel_set_encoding(pChannel, NULL, &pGError);
+               g_io_channel_set_flags(pChannel, G_IO_FLAG_NONBLOCK, &pGError);
+               g_io_channel_set_close_on_unref(pChannel, TRUE);
+
+               pGSource = g_io_create_watch(pChannel, (GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_NVAL | G_IO_HUP));
+               g_source_set_callback(pGSource, (GSourceFunc) OnReadMessage, this, NULL);
+               g_source_attach(pGSource, pGMainContext);
+
+               g_io_channel_unref(pChannel);
+               __pReverseSource = pGSource;
+       }
+       else
+       {
+               ++__fdCount;
+
+               ReleaseFd(client);
+       }
+
+       return 0;
+
+CATCH:
+       if (client != -1)
+       {
+               close(client);
+       }
+
+       return -1;
+
+}
+
+gboolean
+IpcClient::OnReadMessage(GIOChannel* source, GIOCondition condition, gpointer data)
+{
+       IpcClient* pIpcClient = (IpcClient*) data;
+
+       return pIpcClient->HandleReceivedMessage(source, condition);
+}
+
+gboolean
+IpcClient::HandleReceivedMessage(GIOChannel* source, GIOCondition condition)
+{
+       GError* pGError = NULL;
+       GIOStatus status;
+       IPC::Message* pMessage = NULL;
+
+       if (condition & G_IO_HUP)
+       {
+               g_source_destroy(__pReverseSource);
+               g_source_unref(__pReverseSource);
+               __pReverseSource = NULL;
+
+               return FALSE;
+       }
+       else if (condition & G_IO_IN)
+       {
+               gsize readSize = 0;
+               const char* pStart = NULL;
+               const char* pEnd = NULL;
+               const char* pEndOfMessage = NULL;
+
+               while (true)
+               {
+                       pGError = NULL;
+                       status = g_io_channel_read_chars(source, (char*) __messageBuffer, __MAX_MESSAGE_BUFFER_SIZE, &readSize, &pGError);
+                       if (status == G_IO_STATUS_EOF)
+                       {
+                               pGError = NULL;
+
+                               g_io_channel_shutdown(source, FALSE, &pGError);
+
+                               g_source_destroy(__pReverseSource);
+                               g_source_unref(__pReverseSource);
+                               __pReverseSource = NULL;
+
+                               return FALSE;
+                       }
+
+                       if (readSize == 0)
+                       {
+                               break;
+                       }
+
+                       if (__pending.empty())
+                       {
+                               pStart = __messageBuffer;
+                               pEnd = pStart + readSize;
+                       }
+                       else
+                       {
+                               __pending.append(__messageBuffer, readSize);
+                               pStart = __pending.data();
+                               pEnd = pStart + __pending.size();
+                       }
+
+                       while (true)
+                       {
+                               pEndOfMessage = IPC::Message::FindNext(pStart, pEnd);
+                               if (pEndOfMessage == NULL)
+                               {
+                                       __pending.assign(pStart, pEnd - pStart);
+                                       break;
+                               }
+
+                               pMessage = new (std::nothrow) IPC::Message(pStart, pEndOfMessage - pStart);
+                               if (pMessage == NULL)
+                               {
+                                       _LOGE("The memory is insufficient");
+                                       return -2;
+                               }
+
+                               if (__pListener)
+                               {
+                                       __pListener->OnIpcResponseReceived(*this, *pMessage);
+                               }
+
+                               delete pMessage;
+
+                               pStart = pEndOfMessage;
+                       }
+               }
+       }
+       else
+       {
+               // empty statement.
+       }
+
+       return TRUE;
+}
+
+int
+IpcClient::AcquireFd(void)
+{
+       int ret = 0;
+       int fd = -1;
+
+       while (fd == -1)
+       {
+               //__pFdLock->Acquire();
+               if (__fds.size() == 0)
+               {
+                       //__pFdLock->Release();
+                       ret = MakeConnection(false);
+                       if (ret < 0)
+                       {
+                               _LOGE("Failed to connect to the server.");
+                               return -1;
+                       }
+
+                       continue;
+               }
+
+               fd = __fds.back();
+               __fds.pop_back();
+
+               //__pFdLock->Release();
+       }
+
+       return fd;
+}
+
+void
+IpcClient::ReleaseFd(int fd)
+{
+       //__pFdLock->Acquire();
+
+       __fds.push_back(fd);
+
+       //__pFdLock->Release();
+}
+
+int
+IpcClient::SendAsync(IPC::Message* pMessage)
+{
+       char* pData = (char*) pMessage->data();
+       int remain = pMessage->size();
+       int fd = AcquireFd();
+       if (fd == -1)
+       {
+               _LOGE("Failed to get fd.");
+               return -1;
+       }
+
+       int written = 0;
+       while (remain > 0)
+       {
+               written = write(fd, (char*) pData, remain);
+               remain -= written;
+               pData += written;
+       }
+
+       ReleaseFd(fd);
+
+       return 0;
+}
+
+int
+IpcClient::SendSync(IPC::Message* pMessage)
+{
+       IPC::Message* pReply = NULL;
+       MessageReplyDeserializer* pReplyDeserializer = NULL;
+       IPC::SyncMessage* pSyncMessage = dynamic_cast <IPC::SyncMessage*>(pMessage);
+       if (pSyncMessage == NULL)
+       {
+               _LOGE("pMessage is not a sync message.");
+               return -1;
+       }
+
+       int messageId = SyncMessage::GetMessageId(*pSyncMessage);
+
+       int fd = AcquireFd();
+       if (fd < 0)
+       {
+               _LOGE("Failed to get fd.");
+               return -1;
+       }
+
+       char* pData = (char*) pSyncMessage->data();
+       int remain = pSyncMessage->size();
+       int written = 0;
+
+       while (remain > 0)
+       {
+               written = write(fd, (char*) pData, remain);
+               remain -= written;
+               pData += written;
+       }
+
+       // Wait reply
+       struct pollfd pfd;
+
+       pfd.fd = fd;
+       pfd.events = POLLIN | POLLRDHUP;
+       pfd.revents = 0;
+
+       char buffer[1024];
+       std::string message;
+       int readSize = 0;
+       char* pEndOfMessage = NULL;
+
+       while (true)
+       {
+               poll(&pfd, 1, -1);
+
+               if (pfd.revents & POLLRDHUP)
+               {
+                       return -1;
+               }
+
+               if (pfd.revents & POLLIN)
+               {
+                       readSize = read(fd, buffer, 1024);
+               }
+
+               message.append(buffer, readSize);
+
+               pEndOfMessage = (char*) IPC::Message::FindNext(message.data(), message.data() + message.size());
+               if (pEndOfMessage)
+               {
+                       pReply = new (std::nothrow) IPC::Message(message.data(), pEndOfMessage - message.data());
+                       if (pReply == NULL)
+                       {
+                               _LOGE("The memory is insufficient.");
+                               return -2;
+                       }
+
+                       break;
+               }
+       }
+
+       pReplyDeserializer = pSyncMessage->GetReplyDeserializer();
+       pReplyDeserializer->SerializeOutputParameters(*pReply);
+
+       delete pReply;
+       delete pReplyDeserializer;
+
+       ReleaseFd(fd);
+
+       return 0;
+}
+
+int
+IpcClient::Send(IPC::Message* pMessage)
+{
+       int ret = 0;
+
+       if (pMessage->is_sync())
+       {
+               ret = SendSync(pMessage);
+       }
+       else
+       {
+               ret = SendAsync(pMessage);
+       }
+
+       return ret;
+}
+
+int
+IpcClient::SendRequest(IPC::Message* pMessage)
+{
+       return Send(pMessage);
+}
+
+int
+IpcClient::SendRequest(const IPC::Message& message)
+{
+       int ret = 0;
+
+       if (message.is_sync())
+       {
+               ret = SendSync(const_cast<IPC::Message*>(&message));
+       }
+       else
+       {
+               ret = SendAsync(const_cast<IPC::Message*>(&message));
+       }
+
+       return ret;
+}
+
+string 
+IpcClient::GetAppId(void)
+{
+       return __appId;
+}
diff --git a/src/IpcClient.h b/src/IpcClient.h
new file mode 100644 (file)
index 0000000..ac849ee
--- /dev/null
@@ -0,0 +1,143 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file       IpcClient.h
+ * @brief      This is the header file for the IpcClient class.
+ *
+ * This file contains the declarations of IpcClient.
+ */
+
+
+#ifndef _IPC_CLIENT_H_
+#define _IPC_CLIENT_H_
+
+#include <string.h>
+#include <vector>
+#include <stdio.h>
+#include <pthread.h>
+#include <glib.h>
+
+#include <ipc/ipc_message_macros.h>
+#include <ipc/ipc_message_utils.h>
+
+
+class IIpcClientEventListener;
+
+/**
+ * @class IpcClient
+ * @brief This class provides methods for sending a message to an IPC server.
+ * @since 2.1
+ *
+ */
+class IpcClient
+{
+public:
+       /**
+        * This is the default constructor for this class.
+        */
+       IpcClient(void);
+
+       /**
+        * This is the destructor for this class.
+        */
+       virtual ~IpcClient(void);
+
+       /**
+        * Constructs the instance of this class.
+        *
+        * @return An error code
+        * @param[in] serverName        The name of the server
+        * @param[in] pListener Set if the client want to handle a message from the IPC server.
+        *                                 @c NULL, otherwise.
+        * @exception E_SUCCESS         The method was successful.
+        * @exception E_OBJ_NOT_FOUND   The IPC server was not found.
+        * @exception E_OUT_OF_MEMORY   Insufficient memory.
+        * @exception E_SYSTEM          A system error occurred.
+        */
+       int Construct(const std::string& serverName, const IIpcClientEventListener* pListener = NULL);
+
+       /**
+        * Sends a request message to an IPC server.
+        *
+        * @code
+        *
+        *
+        * int
+        * CalculatorProxy::Add(int a , int b)
+        * {
+        *    int c = 0;
+        *
+        *    My_sum mySum(a, b, &c);
+        *
+        *    __pIpcClient->SendRequest(mySum);
+        *
+        *    return c;
+        * }
+        *
+        * @endcode
+        * @return An error code
+        * @param[in] message   The message to send
+        * @exception E_SUCCESS         The method was successful.
+        * @exception E_INVALID_STATE   The instance is in an invalid state.
+        * @exception E_OUT_OF_MEMORY   Insufficient memory.
+        * @exception E_SYSTEM          A system error occurred.
+        *
+        */
+       int SendRequest(const IPC::Message& message);
+
+       int SendRequest(IPC::Message* pMessage);
+
+       std::string GetAppId(void);
+
+private:
+       IpcClient(const IpcClient& value);
+
+       IpcClient& operator =(const IpcClient& value);
+
+       int Send(IPC::Message* pMessage);
+
+       int SendAsync(IPC::Message* pMessage);
+
+       int SendSync(IPC::Message* pMessage);
+
+       int MakeConnection(bool forReverse = false);
+
+       int AcquireFd(void);
+
+       void ReleaseFd(int fd);
+
+       static gboolean OnReadMessage(GIOChannel* source, GIOCondition condition, gpointer data);
+
+       gboolean HandleReceivedMessage(GIOChannel* source, GIOCondition condition);
+
+private:
+       GSource* __pReverseSource;
+
+       std::vector <int> __fds;
+       int __fdCount;
+       //Tizen::Base::Runtime::Mutex* __pFdLock;
+       std::string __name;
+       std::string __appId;
+       IIpcClientEventListener* __pListener;
+
+       static const int __MAX_MESSAGE_BUFFER_SIZE = 1024;
+       char __messageBuffer[__MAX_MESSAGE_BUFFER_SIZE];
+       std::string __pending;
+};
+
+#endif // _IPC_CLIENT_H_
diff --git a/src/MessagePortProxy.cpp b/src/MessagePortProxy.cpp
new file mode 100644 (file)
index 0000000..c203bad
--- /dev/null
@@ -0,0 +1,663 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file       MessagePortProxy.cpp
+ * @brief      This is the implementation file for the MessagePortProxy class.
+ *
+ */
+
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sstream>
+
+#include <package_manager.h>
+
+#include "message-port.h"
+#include "message-port-messages.h"
+#include "message-port-log.h"
+
+#include "IpcClient.h"
+#include "MessagePortProxy.h"
+
+using namespace std;
+
+static const char MESSAGE_TYPE[] = "MESSAGE_TYPE";
+
+static const char LOCAL_APPID[] = "LOCAL_APPID";
+static const char LOCAL_PORT[] = "LOCAL_PORT";
+static const char TRUSTED_LOCAL[] = "TRUSTED_LOCAL";
+
+static const char REMOTE_APPID[] = "REMOTE_APPID";
+static const char REMOTE_PORT[] = "REMOTE_PORT";
+static const char TRUSTED_REMOTE[] = "TRUSTED_REMOTE";
+static const char TRUSTED_MESSAGE[] = "TRUSTED_MESSAGE";
+
+static const int MAX_MESSAGE_SIZE = 8 * 1024;
+
+MessagePortProxy::MessagePortProxy(void)
+       : __pIpcClient(NULL)
+       , __pMutex(NULL)
+{
+}
+
+MessagePortProxy::~MessagePortProxy(void)
+{
+       pthread_mutex_destroy(__pMutex);
+}
+
+int
+MessagePortProxy::Construct(void)
+{
+       IpcClient* pIpcClient = new (std::nothrow) IpcClient();
+       if (pIpcClient == NULL)
+       {
+               return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
+       }
+
+       int ret = pIpcClient->Construct("message-port-server", this);
+       if (ret != 0)
+       {
+               delete pIpcClient;
+
+               _LOGE("Failed to create ipc client: %d.", ret);
+
+               return MESSAGEPORT_ERROR_IO_ERROR;
+       }
+
+       pthread_mutex_t* pMutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
+       if (pMutex == NULL)
+       {
+               return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
+       }
+
+       pthread_mutex_init(pMutex, NULL);
+
+       __pMutex = pMutex;
+       __pIpcClient = pIpcClient;
+       __appId = pIpcClient->GetAppId();
+
+       return 0;
+}
+
+void
+MessagePortProxy::OnIpcResponseReceived(IpcClient& client, const IPC::Message& message)
+{
+       _LOGD("Message received, type %d", message.type());
+
+       IPC_BEGIN_MESSAGE_MAP(MessagePortProxy, message)
+       IPC_MESSAGE_HANDLER_EX(MessagePort_sendMessageAsync, &client, OnSendMessageInternal)
+       IPC_END_MESSAGE_MAP_EX()
+}
+
+int
+MessagePortProxy::RegisterMessagePort(const string& localPort, bool isTrusted,  messageport_message_cb callback)
+{
+       _LOGD("Register a message port : [%s:%s]", __appId.c_str(), localPort.c_str());
+
+       int id = 0;
+
+       // Check the message port is already registed
+       if (IsLocalPortRegisted(localPort, isTrusted, id))
+       {
+               if (!isTrusted)
+               {
+                       __listeners[localPort] = callback;
+               }
+               else
+               {
+                       __trustedListeners[localPort] = callback;
+               }
+
+               return id;
+       }
+
+       bundle *b = bundle_create();
+
+       if (!isTrusted)
+       {
+               bundle_add(b, TRUSTED_LOCAL, "FALSE");
+       }
+       else
+       {
+               bundle_add(b, TRUSTED_LOCAL, "TRUE");
+       }
+
+       bundle_add(b, LOCAL_APPID, __appId.c_str());
+       bundle_add(b, LOCAL_PORT, localPort.c_str());
+
+
+       // Create Bundle Buffer from bundle
+       BundleBuffer buffer;
+       buffer.b = b;
+
+       int ret = 0;
+       int return_value = 0;
+
+       IPC::Message* pMsg = new MessagePort_registerPort(buffer, &return_value);
+       if (pMsg == NULL)
+       {
+               bundle_free(b);
+               return  MESSAGEPORT_ERROR_OUT_OF_MEMORY;
+       }
+
+       ret = __pIpcClient->SendRequest(pMsg);
+
+       delete pMsg;
+
+       bundle_free(b);
+
+       if (ret != 0)
+       {
+               _LOGE("Failed to send a request: %d.", ret);
+
+               return MESSAGEPORT_ERROR_IO_ERROR;
+       }
+
+
+       // Add a listener
+       if (!isTrusted)
+       {
+               // Local port id
+               id = GetNextId();
+
+               __listeners[localPort] = callback;
+               __idFromString[localPort] = id;
+               __ids[id] = localPort;
+       }
+       else
+       {
+               id = GetNextId();
+
+               __trustedListeners[localPort] = callback;
+               __trustedIdFromString[localPort] = id;
+               __trustedIds[id] = localPort;
+       }
+
+       return id;
+}
+
+int
+MessagePortProxy::CheckRemotePort(const string& remoteAppId, const string& remotePort, bool isTrusted, bool *exist)
+{
+       _LOGD("Check a remote port : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
+
+       int ret = 0;
+
+       // Check the certificate
+       if (isTrusted)
+       {
+               // Check the preloaded
+               if (!IsPreloaded(remoteAppId))
+               {
+                       ret = CheckCertificate(remoteAppId);
+                       if (ret < 0)
+                       {
+                               return ret;
+                       }
+               }
+       }
+
+       bundle *b = bundle_create();
+       bundle_add(b, REMOTE_APPID, remoteAppId.c_str());
+       bundle_add(b, REMOTE_PORT, remotePort.c_str());
+
+       if (!isTrusted)
+       {
+               bundle_add(b, TRUSTED_REMOTE, "FALSE");
+       }
+       else
+       {
+               bundle_add(b, TRUSTED_REMOTE, "TRUE");
+       }
+
+       // To Bundle Buffer
+       BundleBuffer buffer;
+       buffer.b = b;
+
+       int return_value = 0;
+       IPC::Message* pMsg = new MessagePort_checkRemotePort(buffer, &return_value);
+       if (pMsg == NULL)
+       {
+               bundle_free(b);
+
+               return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
+       }
+
+       ret = __pIpcClient->SendRequest(pMsg);
+
+       delete pMsg;
+
+       bundle_free(b);
+
+       if (ret < 0)
+       {
+               _LOGE("Failed to send a request: %d.", ret);
+
+               return MESSAGEPORT_ERROR_IO_ERROR;
+       }
+
+       if (return_value < 0)
+       {
+               if (return_value == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND)
+               {
+                       *exist = false;
+                       return 0;
+               }
+               else
+               {
+                       _LOGE("Failed to check the remote messge port: %d.", return_value);
+                       return MESSAGEPORT_ERROR_IO_ERROR;
+               }
+       }
+
+       *exist = true;
+       return 0;
+}
+
+int
+MessagePortProxy::SendMessage(const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
+{
+       _LOGD("Send a message to : [%s:%s]", remoteAppId.c_str(), remotePort.c_str());
+
+       int ret = 0;
+
+       // Check the certificate
+       if (trustedMessage)
+       {
+               // Check the preloaded
+               if (!IsPreloaded(remoteAppId))
+               {
+                       ret = CheckCertificate(remoteAppId);
+                       if (ret < 0)
+                       {
+                               return ret;
+                       }
+               }
+       }
+
+       bundle_add(data, MESSAGE_TYPE, "UNI-DIR");
+
+       bundle_add(data, REMOTE_APPID, remoteAppId.c_str());
+       bundle_add(data, REMOTE_PORT, remotePort.c_str());
+
+       if (!trustedMessage)
+       {
+               bundle_add(data, TRUSTED_MESSAGE, "FALSE");
+       }
+       else
+       {
+               bundle_add(data, TRUSTED_MESSAGE, "TRUE");
+       }
+
+       BundleBuffer buffer;
+       buffer.b = data;
+
+       ret = SendMessageInternal(buffer);
+
+       return ret;
+}
+
+int
+MessagePortProxy::SendMessage(const string& localPort, bool trustedPort, const string& remoteAppId, const string& remotePort, bool trustedMessage, bundle* data)
+{
+       _LOGD("Send a bidirectional message from [%s:%s] to [%s:%s]", __appId.c_str(), localPort.c_str(), remoteAppId.c_str(), remotePort.c_str());
+
+       int ret = 0;
+
+       // Check the certificate
+       if (trustedMessage)
+       {
+               // Check the preloaded
+               if (!IsPreloaded(remoteAppId))
+               {
+                       ret = CheckCertificate(remoteAppId);
+                       if (ret < 0)
+                       {
+                               return ret;
+                       }
+               }
+       }
+
+       bundle_add(data, MESSAGE_TYPE, "BI-DIR");
+
+       bundle_add(data, LOCAL_APPID, __appId.c_str());
+       bundle_add(data, LOCAL_PORT, localPort.c_str());
+
+       if (!trustedPort)
+       {
+               bundle_add(data, TRUSTED_LOCAL, "FALSE");
+       }
+       else
+       {
+               bundle_add(data, TRUSTED_LOCAL, "TRUE");
+       }
+
+       bundle_add(data, REMOTE_APPID, remoteAppId.c_str());
+       bundle_add(data, REMOTE_PORT, remotePort.c_str());
+
+       if (!trustedMessage)
+       {
+               bundle_add(data, TRUSTED_MESSAGE, "FALSE");
+       }
+       else
+       {
+               bundle_add(data, TRUSTED_MESSAGE, "TRUE");
+       }
+
+       BundleBuffer buffer;
+       buffer.b = data;
+
+       ret = SendMessageInternal(buffer);
+
+       return ret;
+}
+
+int
+MessagePortProxy::SendMessageInternal(const BundleBuffer& buffer)
+{
+       int ret = 0;
+
+       IPC::Message* pMsg = new MessagePort_sendMessage(buffer, &ret);
+       if (pMsg == NULL)
+       {
+               return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
+       }
+
+       // Check the message size
+       int len = 0;
+       bundle_raw* raw = NULL;
+       bundle_encode(buffer.b, &raw, &len);
+
+       bundle_free_encoded_rawdata(&raw);
+
+       if (len > MAX_MESSAGE_SIZE)
+       {
+               _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
+               return MESSAGEPORT_ERROR_MAX_EXCEEDED;
+       }
+
+       ret = __pIpcClient->SendRequest(pMsg);
+       delete pMsg;
+
+       if (ret != 0)
+       {
+               _LOGE("Failed to send a request: %d.", ret);
+               return MESSAGEPORT_ERROR_IO_ERROR;
+       }
+
+       return 0;
+}
+
+char*
+MessagePortProxy::GetLocalPortNameN(int id)
+{
+       string value;
+
+       map<int, std::string>::iterator it;
+
+       it = __ids.find(id);
+       if (it == __ids.end())
+       {
+               it = __trustedIds.find(id);
+               if (it == __ids.end())
+               {
+                       return NULL;
+               }
+               else
+               {
+                       value = __trustedIds[id];
+                       return strdup(value.c_str());
+               }
+       }
+       else
+       {
+               value = __ids[id];
+               return strdup(value.c_str());
+       }
+
+       return NULL;
+}
+
+int
+MessagePortProxy::CheckTrustedLocalPort(int id, bool* trusted)
+{
+       map<int, std::string>::iterator it;
+
+       it = __ids.find(id);
+       if (it == __ids.end())
+       {
+               it = __trustedIds.find(id);
+               if (it == __ids.end())
+               {
+                       return MESSAGEPORT_ERROR_INVALID_PARAMETER;
+               }
+               else
+               {
+                       *trusted = true;
+                       return 0;
+               }
+       }
+       else
+       {
+               *trusted = false;
+               return 0;
+       }
+
+       return MESSAGEPORT_ERROR_INVALID_PARAMETER;
+}
+
+MessagePortProxy*
+MessagePortProxy::GetProxy(void)
+{
+       static MessagePortProxy* pProxy = NULL;
+
+       if (pProxy == NULL)
+       {
+               MessagePortProxy* p = new MessagePortProxy();
+               if (p == NULL)
+               {
+                       return NULL;
+               }
+
+               int ret = p->Construct();
+               if (ret < 0)
+               {
+                       return NULL;
+               }
+
+               pProxy = p;
+       }
+
+       return pProxy;
+}
+
+int
+MessagePortProxy::GetNextId(void)
+{
+       static int count = 0;
+
+       pthread_mutex_lock(__pMutex);
+       ++count;
+       pthread_mutex_unlock(__pMutex);
+
+       return count;
+}
+
+bool
+MessagePortProxy::IsLocalPortRegisted(const string& localPort, bool trusted, int &id)
+{
+       if (!trusted)
+       {
+               map<string, messageport_message_cb>::iterator port_it = __listeners.find(localPort);
+               if (port_it == __listeners.end())
+               {
+                       return false;
+               }
+               else
+               {
+                       for (map<int, string>::iterator it = __ids.begin(); it != __ids.end(); ++it)
+                       {
+                               if (localPort.compare(it->second) == 0)
+                               {
+                                       id = it->first;
+                                       return true;
+                               }
+                       }
+               }
+       }
+       else
+       {
+               map<string, messageport_message_cb>::iterator port_it = __trustedListeners.find(localPort);
+               if (port_it == __trustedListeners.end())
+               {
+                       return false;
+               }
+               else
+               {
+                       for (map<int, string>::iterator it = __ids.begin(); it != __trustedIds.end(); ++it)
+                       {
+                               if (localPort.compare(it->second) == 0)
+                               {
+                                       id = it->first;
+                                       return true;
+                               }
+                       }
+               }
+       }
+
+       return false;
+}
+
+int
+MessagePortProxy::CheckCertificate(const std::string& remoteAppId)
+{
+       package_manager_compare_result_type_e res;
+       int ret = package_manager_compare_app_cert_info(__appId.c_str(), remoteAppId.c_str(), &res);
+
+       if (ret == 0)
+       {
+               if (res != PACAKGE_MANAGER_COMPARE_MATCH)
+               {
+                       _LOGE("The remote application (%s) is not signed with the same certificate", remoteAppId.c_str());
+                       return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
+               }
+       }
+       else
+       {
+               _LOGE("Failed to check the certificate: %d.", ret);
+               return MESSAGEPORT_ERROR_IO_ERROR;
+       }
+
+       return 0;
+}
+
+bool
+MessagePortProxy::IsPreloaded(const std::string& remoteAppId)
+{
+       bool preload_local = false;
+       bool preload_remote = false;
+
+       if (package_manager_is_preload_package_by_app_id(__appId.c_str(), &preload_local) == 0)
+       {
+               if (package_manager_is_preload_package_by_app_id(remoteAppId.c_str(), &preload_remote) == 0)
+               {
+                       if (preload_local && preload_remote)
+                       {
+                               return true;
+                       }
+               }
+               else
+               {
+                       _LOGE("Failed to check the preloaded application.");
+               }
+       }
+       else
+       {
+               _LOGE("Failed to check the preloaded application.");
+       }
+
+       return false;
+}
+
+bool
+MessagePortProxy::OnSendMessageInternal(const BundleBuffer& buffer)
+{
+       bundle* b = buffer.b;
+
+       const char* pRemoteAppId = bundle_get_val(b, REMOTE_APPID);
+       const char* pRemotePort = bundle_get_val(b, REMOTE_PORT);
+       string trustedMessage = bundle_get_val(b, TRUSTED_MESSAGE);
+
+       string messageType = bundle_get_val(b, MESSAGE_TYPE);
+
+       _LOGD("Message received to AppId: %s, Port: %s, Trusted: %s", pRemoteAppId, pRemotePort, trustedMessage.c_str());
+
+       int id = 0;
+       messageport_message_cb callback;
+
+       if (trustedMessage.compare("FALSE") == 0)
+       {
+               callback = __listeners[pRemotePort];
+               id = __idFromString[pRemotePort];
+       }
+       else
+       {
+               callback = __trustedListeners[pRemotePort];
+               id = __trustedIdFromString[pRemotePort];
+       }
+
+
+       if (callback)
+       {
+               // remove system data
+               bundle_del(b, REMOTE_APPID);
+               bundle_del(b, REMOTE_PORT);
+               bundle_del(b, TRUSTED_MESSAGE);
+               bundle_del(b, MESSAGE_TYPE);
+
+               if (messageType.compare("UNI-DIR") == 0)
+               {
+                       callback(id, NULL, NULL, false, b);
+               }
+               else
+               {
+                       string localAppId = bundle_get_val(b, LOCAL_APPID);
+                       string localPort = bundle_get_val(b, LOCAL_PORT);
+                       string trustedLocal = bundle_get_val(b, TRUSTED_LOCAL);
+
+                       _LOGD("From AppId: %s, Port: %s, TrustedLocal: %s", localAppId.c_str(), localPort.c_str(), trustedLocal.c_str());
+
+                       bool trustedPort = (trustedLocal.compare("TRUE") == 0);
+
+                       // remove system data
+                       bundle_del(b, LOCAL_APPID);
+                       bundle_del(b, LOCAL_PORT);
+                       bundle_del(b, TRUSTED_LOCAL);
+
+                       callback(id, localAppId.c_str(), localPort.c_str(), trustedPort, b);
+               }
+       }
+       else
+       {
+               _LOGD("No callback");
+       }
+
+       return true;
+}
+
diff --git a/src/MessagePortProxy.h b/src/MessagePortProxy.h
new file mode 100644 (file)
index 0000000..129de9b
--- /dev/null
@@ -0,0 +1,113 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file       MessagePortProxy.h
+ * @brief      This is the header file for the MessagePortProxy class.
+ *
+ * This file contains the declarations of MessagePortProxy.
+ */
+
+
+#ifndef _MESSAGE_PORT_PROXY_H_
+#define _MESSAGE_PORT_PROXY_H_
+
+#include <string>
+#include <map>
+#include <pthread.h>
+
+#include <bundle.h>
+
+#include "message-port.h"
+#include "message-port-data-types.h"
+
+#include "IIpcClientEventListener.h"
+
+namespace IPC { class Message; }
+
+class IpcClient;
+
+class MessagePortProxy
+       : public IIpcClientEventListener
+{
+public:
+       virtual ~MessagePortProxy(void);
+
+       int Construct(void);
+
+       virtual void OnIpcResponseReceived(IpcClient& client, const IPC::Message& message);
+
+
+       int RegisterMessagePort(const std::string& localPort,
+                                                       bool isTrusted,
+                                                       messageport_message_cb callback);
+
+       int CheckRemotePort(const std::string& remoteAppId,
+                                               const std::string& remotePort,
+                                               bool isTrusted,
+                                               bool *exist);
+
+       int SendMessage(const std::string& remoteAppId,
+                                       const std::string& remotePort,
+                                       bool trustedMessage,
+                                       bundle* data);
+
+       int SendMessage(const std::string& localPort,
+                                       bool trustedPort,
+                                       const std::string& remoteAppId,
+                                       const std::string& remotePort,
+                                       bool trustedMessage,
+                                       bundle* data);
+
+       char* GetLocalPortNameN(int id);
+
+       int CheckTrustedLocalPort(int id, bool* trusted);
+
+       static MessagePortProxy* GetProxy(void);
+
+private:
+       MessagePortProxy(void);
+
+       int SendMessageInternal(const BundleBuffer& buffer);
+
+       bool OnSendMessageInternal(const BundleBuffer& buffer);
+
+       int GetNextId(void);
+
+       bool IsLocalPortRegisted(const std::string& localPort, bool trusted, int &id);
+
+       int CheckCertificate(const std::string& remoteAppId);
+
+       bool IsPreloaded(const std::string& remoteAppId);
+
+private:
+       IpcClient* __pIpcClient;
+       pthread_mutex_t* __pMutex;
+
+       std::string __appId;
+
+       std::map<std::string, messageport_message_cb> __listeners;
+       std::map<std::string, int> __idFromString;
+       std::map<int, std::string> __ids;
+
+       std::map<std::string, messageport_message_cb> __trustedListeners;
+       std::map<std::string, int> __trustedIdFromString;
+       std::map<int, std::string> __trustedIds;
+
+}; // MessagePortProxy
+
+#endif // _MESSAGE_PORT_PROXY_H_
diff --git a/src/message-port-log.h b/src/message-port-log.h
new file mode 100644 (file)
index 0000000..d2d1678
--- /dev/null
@@ -0,0 +1,43 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+
+#ifndef __APPFW_MESSAGE_PORT_LOG_H__
+#define __APPFW_MESSAGE_PORT_LOG_H__
+
+#include <dlog.h>
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef LOG_TAG
+#define LOG_TAG "MESSAGE_PORT"
+
+#define _LOGE(fmt, arg...) LOGE(fmt, ##arg)
+#define _LOGD(fmt, arg...) LOGD(fmt, ##arg)
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPFW_MESSAGE_PORT_LOG_H__ */
diff --git a/src/message-port-messages.cpp b/src/message-port-messages.cpp
new file mode 100644 (file)
index 0000000..9ea580d
--- /dev/null
@@ -0,0 +1,24 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file       message-port-messages.cpp
+ * @brief      This is the implementation file for the MessagePortMessages
+ */
+
+#define IPC_MESSAGE_IMPL
+#include "message-port-messages.h"
diff --git a/src/message-port.cpp b/src/message-port.cpp
new file mode 100644 (file)
index 0000000..f6f53cc
--- /dev/null
@@ -0,0 +1,184 @@
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file       message-port.cpp
+ * @brief      This is the implementation file for the MessagePort.
+ */
+
+#include <stdlib.h>
+
+#include "message-port.h"
+#include "message-port-log.h"
+
+#include "MessagePortProxy.h"
+
+int
+messageport_register_local_port(const char* local_port, messageport_message_cb callback)
+{
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               return pProxy->RegisterMessagePort(local_port, false, callback);
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+
+int
+messageport_register_trusted_local_port(const char* local_port, messageport_message_cb callback)
+{
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               return pProxy->RegisterMessagePort(local_port, true, callback);
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+
+int
+messageport_check_remote_port(const char* remote_app_id, const char *remote_port, bool* exist)
+{
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               return pProxy->CheckRemotePort(remote_app_id, remote_port, false, exist);
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+
+int
+messageport_check_trusted_remote_port(const char* remote_app_id, const char *remote_port, bool* exist)
+{
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               return pProxy->CheckRemotePort(remote_app_id, remote_port, true, exist);
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+
+int
+messageport_send_message(const char* remote_app_id, const char* remote_port, bundle* message)
+{
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               return pProxy->SendMessage(remote_app_id, remote_port, false, message);
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+
+int
+messageport_send_trusted_message(const char* remote_app_id, const char* remote_port, bundle* message)
+{
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               return pProxy->SendMessage(remote_app_id, remote_port, true, message);
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+
+int
+messageport_send_bidirectional_message(int id, const char* remote_app_id, const char* remote_port, bundle* message)
+{
+       int ret = 0;
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               char* pName = pProxy->GetLocalPortNameN(id);
+               bool trusted = false;
+               pProxy->CheckTrustedLocalPort(id, &trusted);
+
+               ret = pProxy->SendMessage(pName, trusted, remote_app_id, remote_port, false, message);
+
+               free(pName);
+
+               return ret;
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+
+int
+messageport_send_bidirectional_trusted_message(int id, const char* remote_app_id, const char* remote_port, bundle* message)
+{
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               bool trusted = false;
+               int ret = pProxy->CheckTrustedLocalPort(id, &trusted);
+               if (ret < 0)
+               {
+                       return ret;
+               }
+
+               char* pName = pProxy->GetLocalPortNameN(id);
+               if (pName == NULL)
+               {
+                       return MESSAGEPORT_ERROR_INVALID_PARAMETER;
+               }
+
+               ret = pProxy->SendMessage(pName, trusted, remote_app_id, remote_port, true, message);
+
+               free(pName);
+
+               return ret;
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+
+int
+messageport_get_local_port_name(int id, char **name)
+{
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               char* pName = pProxy->GetLocalPortNameN(id);
+               if (pName == NULL)
+               {
+                       return MESSAGEPORT_ERROR_INVALID_PARAMETER;
+               }
+               else
+               {
+                       *name = pName;
+                       return 0;
+               }
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+
+int
+messageport_check_trusted_local_port(int id, bool *trusted)
+{
+       MessagePortProxy* pProxy = MessagePortProxy::GetProxy();
+       if (pProxy != NULL)
+       {
+               return pProxy->CheckTrustedLocalPort(id, trusted);
+       }
+
+       return MESSAGEPORT_ERROR_IO_ERROR;
+}
+