ADD_SUBDIRECTORY(efl_base)
ADD_SUBDIRECTORY(widget_base)
ADD_SUBDIRECTORY(efl_widget_base)
+ADD_SUBDIRECTORY(port)
ADD_DEPENDENCIES(component-based-app-control component-based-uri)
ADD_DEPENDENCIES(component-based-core-base component-based-app-control)
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(component-based-port CXX)
+
+SET(PREFIX "${CMAKE_INSTALL_PREFIX}")
+SET(EXEC_PREFIX "\${prefix}")
+SET(PROJECT_NAME "${PROJECT_NAME}")
+SET(LIBDIR ${LIB_INSTALL_DIR})
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION ${FULLVER})
+
+INCLUDE(FindPkgConfig)
+
+SET(requires "glib-2.0 gio-2.0 dlog parcel cynara-client cynara-creds-socket aul")
+
+pkg_check_modules(component-based-port REQUIRED ${requires})
+
+FOREACH(flag ${component-based-port_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline")
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++14")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCES)
+ADD_LIBRARY (${PROJECT_NAME} SHARED ${SOURCES})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${FULLVER})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${MAJORVER})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${component-based-port_LDFLAGS} -lpthread)
+
+SET(PC_NAME component-based-port)
+SET(PC_REQUIRED ${pc_requires})
+
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/api/component_port.h
+ DESTINATION ${INCLUDE_INSTALL_DIR}/component_based/port/api)
+
+SET(HEADER_PORT
+ export_api.hh
+ port.hh
+)
+
+FOREACH(hfile ${HEADER_PORT})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${hfile}
+ DESTINATION ${INCLUDE_INSTALL_DIR}/component_based/port)
+ENDFOREACH(hfile)
--- /dev/null
+/*
+ * Copyright (c) 2020 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 __COMPONENT_PORT_H__
+#define __COMPONRNT_PORT_H__
+
+#include <parcel.h>
+
+/**
+ * @addtogroup COMPONENT_BASED_APPLICATION_MODULE
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief The component port handle.
+ * @since_tizen 6.5
+ */
+typedef void *component_port_h;
+
+/**
+ * @brief Enumeration for error codes for the component port.
+ * @since_tizen 6.5
+ */
+typedef enum {
+ COMPONENT_PORT_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ COMPONENT_PORT_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ COMPONENT_PORT_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O Error */
+ COMPONENT_PORT_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+ COMPONENT_PORT_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+} component_port_error_e;
+
+/**
+ * @brief Called when the port received the request.
+ * @details The function is called when the port received the request from the other port.
+ * The @a request MUST NOT release using parcel_destroy(). It's managed by Platform.
+ * @since_tizen 6.5
+ * @param[in] sender The name of the sender
+ * @param[in] request The request data
+ * @param[in] user_data The user data passed from the registration function
+ * @see component_port_set_request_cb()
+ */
+typedef void (*component_port_request_cb)(const char *sender, parcel_h request, void *user_data);
+
+/**
+ * @brief Called when the port received the request synchronously.
+ * @details The function is called when the port received the request from the other port.
+ * The @a response data should be set.
+ * The @a request and @a response MUST NOT release using parcel_destroy(). The parameters are managed by Platform.
+ * @since_tizen 6.5
+ * @param[in] sender The name of the sender
+ * @param[in] request The request data
+ * @param[out] response the response data
+ * @param[in] user_data The user data passed from the registration function
+ * @see component_port_set_sync_request_cb()
+ */
+typedef void (*component_port_sync_request_cb)(const char *sender, parcel_h request, parcel_h response, void *user_data);
+
+/**
+ * @brief Creates the component port handle.
+ * @since_tizen 6.5
+ * @param[in] port_name The port name
+ * @param[out] port The component port handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #COMPONENT_PORT_ERROR_NONE Successful
+ * @retval #COMPONENT_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #COMPONENT_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #COMPONENT_PORT_ERROR_IO_ERROR I/O Error
+ * @see component_port_destroy()
+ */
+int component_port_create(const char *port_name, component_port_h *port);
+
+/**
+ * @brief Destroys the component port handle.
+ * @since_tizen 6.5
+ * @param[in] port The component port handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #COMPONENT_PORT_ERROR_NONE Successful
+ * @retval #COMPONENT_PORT_ERROR_INVALID_PARAMETER Invalid prameter
+ * @see component_port_create()
+ */
+int component_port_destroy(component_port_h port);
+
+/**
+ * @brief Sets the request callback function to the component port handle.
+ * @details The callback function is called when a component sends the request using component_port_send().
+ * @since_tizen 6.5
+ * @param[in] port The component port handle
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #COMPONENT_PORT_ERROR_NONE Successful
+ * @retval #COMPONENT_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see component_port_request_cb()
+ * @see component_port_send()
+ */
+int component_port_set_request_cb(component_port_h port, component_port_request_cb callback, void *user_data);
+
+/**
+ * @brief Sets the synchornous request callback function to the component port handle.
+ * @detials The callback function is called when a component sends the request using comopnent_port_send_sync().
+ * @since_tizen 6.5
+ * @param[in] port The component port handle
+ * @param[in] callback The callback function to invoke
+ * @param[in] useR_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #COMPONENT_PORT_ERROR_NONE Successful
+ * @retval #COMPONENT_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see component_port_sync_request_cb()
+ */
+int component_port_set_sync_request_cb(component_port_h port, component_port_sync_request_cb callback, void *user_data);
+
+/**
+ * @brief Adds a privilege to the component port handle.
+ * @details When a component sends the request, the privilege will be checked.
+ * If the sender doesn't have a permission, the request will be rejected.
+ * @since_tizen 6.5
+ * @param[in] port The component port handle
+ * @param[in] privilege The privilege
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #COMPONENT_PORT_ERROR_NONE Successful
+ * @retval #COMPONENT_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see component_port_sync_request_cb()
+ */
+int component_port_add_privilege(component_port_h port, const char *privilege);
+
+/**
+ * @brief Waits for events on the component port.
+ * @details This function runs a main loop until component_port_cancel() is called.
+ * @since_tizen 6.5
+ * @param[in] port The component port handle
+ * @see component_port_cancel()
+ * @see get_last_result()
+ */
+void component_port_wait_for_event(component_port_h port);
+
+/**
+ * @brief Cancels waiting for events on the component port.
+ * @since_tizen 6.5
+ * @param[in] port The component port handle
+ * @see component_port_wait_for_event()
+ * @see get_last_result()
+ */
+void component_port_cancel(component_port_h port);
+
+/**
+ * @brief Sends the request data.
+ * @details Specifying a negative value or a zero value in @a timeout means an infinite timeout.
+ * @since_tizen 6.5
+ * @param[in] port The component port handle
+ * @param[in] endpoint The endpoint name
+ * @param[in] timeout The interval of milliseconds
+ * @param[in] request The request data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #COMPONENT_PORT_ERROR_NONE Successful
+ * @retval #COMPONENT_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #COMPONENT_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #COMPONENT_PORT_ERROR_IO_ERRO I/O error
+ * @retval #COMPONENT_PORT_ERROR_PERMISSION_DENIED Permission denied
+ */
+int component_port_send(component_port_h port, const char *endpoint, int timeout, parcel_h request);
+
+/**
+ * @breif Sends the request data synchrnously.
+ * @details Specifying a negative value or a zero value in @a timeout means an infinite timeout.
+ * @details The @a response should be destroyed using parcel_destroy() if it is no longer needed.
+ * @since_tizen 6.5
+ * @param[in] port The component port handle
+ * @param[in] endpoint The endpoint name
+ * @param[in] timeout The interval of milliseconds
+ * @param[in] request The request data
+ * @param[out] response The response data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #COMPONENT_PORT_ERROR_NONE Successful
+ * @retval #COMPONENT_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #COMPONENT_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #COMPONENT_PORT_ERROR_IO_ERRO I/O error
+ * @retval #COMPONENT_PORT_ERROR_PERMISSION_DENIED Permission denied
+ */
+int component_port_send_sync(component_port_h port, const char *endpoint, int timeout, parcel_h request, parcel_h *response);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* __COMPONENT_PORT_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <aul_component_port.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <tizen.h>
+#include <unistd.h>
+
+#include "component_based/port/client.hh"
+#include "component_based/port/log_private.hh"
+#include "component_based/port/util.hh"
+
+namespace component_based {
+
+Client::Client(int fd, pid_t pid) : Socket(fd), pid_(pid) {
+}
+
+Client::~Client() {
+}
+
+Client* Client::Create(const std::string& name, int timeout) {
+ std::string path = Socket::GetSocketPath(name);
+ bool exist = false;
+ aul_component_port_exist(name.c_str(), &exist);
+ if (!exist) {
+ _E("port(%s) doesn't exist", name.c_str());
+ return nullptr;
+ }
+
+ int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (fd < 0) {
+ _E("socket() is failed. path(%s), errno(%d)", path.c_str(), errno);
+ return nullptr;
+ }
+
+ int retry = 3;
+ struct sockaddr_un addr = { 0, };
+ addr.sun_family = AF_UNIX;
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path.c_str());
+ struct sockaddr* addr_ptr = reinterpret_cast<struct sockaddr*>(&addr);
+ while (connect(fd, addr_ptr, sizeof(addr)) < 0) {
+ if (errno != ETIMEDOUT || retry <= 0) {
+ _E("connect() is failed. path(%s), errno(%d)", path.c_str(), errno);
+ close(fd);
+ return nullptr;
+ }
+
+ usleep(100 * 1000);
+ retry--;
+ _W("Retry to connect to %s. count(%d)", path.c_str(), retry);
+ }
+
+ if (timeout > 0) {
+ time_t sec = timeout / 1000;
+ suseconds_t usec = (timeout - sec * 1000) * 1000;
+ struct timeval tv = { sec, usec };
+ int ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+ if (ret < 0) {
+ _E("setsockopt(SO_RCVTIMEO) is failed. fd(%d), errno(%d)", fd, errno);
+ close(fd);
+ return nullptr;
+ }
+ }
+
+ return new (std::nothrow) Client(fd);
+}
+
+int Client::Send(const std::vector<uint8_t>& data) {
+ size_t size = data.size();
+ auto* p = reinterpret_cast<void*>(&size);
+ int ret = Socket::Send(p, sizeof(size));
+ if (ret != 0) {
+ _E("Send() is failed. error(%d)", ret);
+ return ret;
+ }
+
+ auto* dp = reinterpret_cast<const void*>(&data[0]);
+ ret = Socket::Send(dp, data.size());
+ if (ret != 0)
+ _E("Send() is failed. error(%d)", ret);
+
+ if (getenv("PORT_DEBUG"))
+ Util::Hexdump("Send", data);
+ return ret;
+}
+
+int Client::Recv(std::vector<uint8_t>& data) {
+ size_t size = 0;
+ auto* p = reinterpret_cast<void*>(&size);
+ int ret = Socket::Read(p, sizeof(size));
+ if (ret != 0) {
+ _E("Read() is failed. error(%d)", ret);
+ return ret;
+ }
+
+ std::vector<uint8_t> buf(size);
+ p = reinterpret_cast<void*>(&buf[0]);
+ ret = Socket::Read(p, size);
+ if (ret != 0) {
+ _E("Read() is failed. error(%d)", ret);
+ return ret;
+ }
+
+ std::copy(buf.begin(), buf.end(), std::back_inserter(data));
+ if (getenv("PORT_DEBUG"))
+ Util::Hexdump("Recv", data);
+ return ret;
+}
+
+pid_t Client::GetPid() const {
+ return pid_;
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_CLIENT_HH_
+#define COMPONENT_BASED_PORT_CLIENT_HH_
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include "component_based/port/socket.hh"
+
+namespace component_based {
+
+class Client : public Socket {
+ public:
+ Client(int fd, pid_t pid = -1);
+ virtual ~Client();
+
+ static Client* Create(const std::string& name, int timeout = 0);
+
+ int Send(const std::vector<uint8_t>& data);
+ int Recv(std::vector<uint8_t>& data);
+
+ pid_t GetPid() const;
+
+ private:
+ pid_t pid_ = -1;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_CLIENT_HH_
--- /dev/null
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@
+
+Name: @PC_NAME@
+Description: Support development of the Tizen Component-based App Model port
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} -lcomponent-based-port
+Cflags: -I${includedir} -I${includedir}/appfw -I${includedir}/component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_EXCEPTION_HH_
+#define COMPONENT_BASED_PORT_EXCEPTION_HH_
+
+#include <string>
+#include <exception>
+
+#include "component_based/port/log_private.hh"
+
+#define THROW(error_code) throw Exception(error_code, __FILE__, __LINE__)
+
+namespace component_based {
+
+class Exception : public std::exception {
+ public:
+ explicit Exception(int error_code, std::string file = __FILE__,
+ int line = __LINE__ ) {
+ error_code_ = error_code;
+ message_ = file.substr(file.find_last_of("/") + 1) + ":"
+ + std::to_string(line) + " code:" + std::to_string(error_code_);
+ _E("%s", message_.c_str());
+ }
+
+ virtual ~Exception() {}
+
+ virtual const char *what(void) const noexcept {
+ return message_.c_str();
+ }
+
+ int GetErrorCode() {
+ return error_code_;
+ }
+
+ private:
+ int error_code_;
+ std::string message_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_EXCEPTION_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_EXPORT_API_HH_
+#define COMPONENT_BASED_PORT_EXPORT_API_HH_
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+#endif // COMPONENT_BASED_PORT_EXPORT_API_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_LOG_PRIVATE_HH_
+#define COMPONENT_BASED_PORT_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "COMPONENT_BASED_PORT"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif // COMPONENT_BASED_PORT_LOG_PRIVATE_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "component_based/port/log_private.hh"
+#include "component_based/port/main_loop.hh"
+
+namespace component_based {
+
+MainLoop::MainLoop() = default;
+
+MainLoop::~MainLoop() {
+ if (thread_default_)
+ g_main_context_pop_thread_default(context_);
+
+ if (loop_) {
+ if (g_main_loop_is_running(loop_))
+ g_main_loop_quit(loop_);
+
+ g_main_loop_unref(loop_);
+ }
+
+ if (context_)
+ g_main_context_unref(context_);
+}
+
+void MainLoop::Run() {
+ if (context_ == nullptr) {
+ if (gettid() != getpid()) {
+ _W("Sub thread");
+ context_ = g_main_context_get_thread_default();
+ if (context_ == nullptr) {
+ context_ = g_main_context_new();
+ g_main_context_push_thread_default(context_);
+ thread_default_ = true;
+ } else {
+ context_ = g_main_context_ref_thread_default();
+ }
+ } else {
+ _W("Main thread");
+ context_ = g_main_context_ref(g_main_context_default());
+ }
+ }
+
+ if (loop_ == nullptr)
+ loop_ = g_main_loop_new(context_, FALSE);
+
+ if (!g_main_loop_is_running(loop_)) {
+ _W("Run");
+ g_main_loop_run(loop_);
+ } else {
+ _W("Loop is already running");
+ }
+}
+
+void MainLoop::Quit() {
+ if (g_main_loop_is_running(loop_)) {
+ _W("Quit");
+ g_main_loop_quit(loop_);
+ } else {
+ _W("Loop is not running");
+ }
+}
+
+GMainContext* MainLoop::GetContext() const {
+ return context_;
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_MAIN_LOOP_HH_
+#define COMPONENT_BASED_PORT_MAIN_LOOP_HH_
+
+#include <glib.h>
+
+namespace component_based {
+
+class MainLoop {
+ public:
+ MainLoop();
+ virtual ~MainLoop();
+
+ void Run();
+ void Quit();
+
+ GMainContext* GetContext() const;
+
+ private:
+ bool thread_default_ = false;
+ GMainContext* context_ = nullptr;
+ GMainLoop* loop_ = nullptr;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_MAIN_LOOP_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <cynara-creds-socket.h>
+#include <cynara-error.h>
+#include <cynara-session.h>
+
+#include <memory>
+
+#include "component_based/port/log_private.hh"
+#include "component_based/port/peer_creds.hh"
+
+namespace component_based {
+
+PeerCreds::PeerCreds(pid_t pid, std::string user, std::string client,
+ std::string session)
+ : pid_(pid),
+ user_(std::move(user)),
+ client_(std::move(client)),
+ session_(std::move(session)) {
+}
+
+PeerCreds::~PeerCreds() = default;
+
+pid_t PeerCreds::GetPid() const {
+ return pid_;
+}
+
+const std::string& PeerCreds::GetUser() const {
+ return user_;
+}
+
+const std::string& PeerCreds::GetClient() const {
+ return client_;
+}
+
+const std::string& PeerCreds::GetSession() const {
+ return session_;
+}
+
+PeerCreds* PeerCreds::Get(int fd) {
+ pid_t pid;
+ int ret = cynara_creds_socket_get_pid(fd, &pid);
+ if (ret != CYNARA_API_SUCCESS) {
+ char err[128];
+ cynara_strerror(ret, err, sizeof(err));
+ _E("cynara_creds_socket_get_pid() is failed. error(%s)", err);
+ return nullptr;
+ }
+
+ const char* session = "";
+
+ char* user = nullptr;
+ ret = cynara_creds_socket_get_user(fd, USER_METHOD_DEFAULT, &user);
+ if (ret != CYNARA_API_SUCCESS) {
+ char err[128];
+ cynara_strerror(ret, err, sizeof(err));
+ _E("cynara_creds_socket_get_user() is failed. error(%s)", err);
+ return nullptr;
+ }
+ auto user_ptr = std::unique_ptr<char, decltype(std::free)*>(user, std::free);
+
+ char* client = nullptr;
+ ret = cynara_creds_socket_get_client(fd, CLIENT_METHOD_DEFAULT, &client);
+ if (ret != CYNARA_API_SUCCESS) {
+ char err[128];
+ cynara_strerror(ret, err, sizeof(err));
+ _E("cynara_creds_socket_get_client() is failed. error(%s)", err);
+ return nullptr;
+ }
+ auto client_ptr = std::unique_ptr<char, decltype(std::free)*>(client,
+ std::free);
+
+ return new (std::nothrow) PeerCreds(pid, user, client, session);
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_PEER_CREDS_HH_
+#define COMPONENT_BASED_PORT_PEER_CREDS_HH_
+
+#include <sys/types.h>
+
+#include <string>
+
+namespace component_based {
+
+class PeerCreds {
+ public:
+ PeerCreds(pid_t pid, std::string user, std::string client,
+ std::string session);
+ virtual ~PeerCreds();
+
+ pid_t GetPid() const;
+ const std::string& GetUser() const;
+ const std::string& GetClient() const;
+ const std::string& GetSession() const;
+
+ static PeerCreds* Get(int fd);
+
+ private:
+ pid_t pid_;
+ std::string user_;
+ std::string client_;
+ std::string session_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_PEER_CREDS_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <errno.h>
+#include <tizen.h>
+
+#include "component_based/port/client.hh"
+#include "component_based/port/exception.hh"
+#include "component_based/port/log_private.hh"
+#include "component_based/port/port.hh"
+#include "component_based/port/port_implementation.hh"
+#include "component_based/port/request.hh"
+#include "component_based/port/response.hh"
+
+namespace component_based {
+
+Port::Impl::~Impl() {
+}
+
+Port::Impl::Impl(Port* parent, std::string name, Port::IEvent* listener)
+ : parent_(parent),
+ name_(std::move(name)),
+ listener_(listener),
+ server_(Server::Create(name_, this)) {
+}
+
+void Port::Impl::WaitForEvent() {
+ server_->Poll();
+}
+
+void Port::Impl::Cancel() {
+ server_->Cancel();
+}
+
+void Port::Impl::AddPrivilege(const std::string& privilege) {
+ server_->AddPrivilege(privilege);
+}
+
+int Port::Impl::Send(const std::string& endpoint, int timeout,
+ const std::shared_ptr<tizen_base::Parcel>& request) {
+ auto client = std::unique_ptr<Client>(Client::Create(endpoint, timeout));
+ if (client.get() == nullptr) {
+ _E("Client::Create() is failed");
+ return -EIO;
+ }
+
+ Request req(std::string(name_), false, request->GetRaw());
+ tizen_base::Parcel req_parcel;
+ req_parcel.WriteParcelable(req);
+ int ret = client->Send(req_parcel.GetRaw());
+ if (ret != 0) {
+ _E("Send() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
+ return ret;
+ }
+
+ std::vector<uint8_t> data;
+ ret = client->Recv(data);
+ if (ret != 0) {
+ _E("Recv() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
+ return ret;
+ }
+
+ Response res;
+ auto* p = reinterpret_cast<void*>(&data[0]);
+ tizen_base::Parcel res_parcel(p, data.size());
+ res_parcel.ReadParcelable(&res);
+ return res.GetResult();
+}
+
+int Port::Impl::SendSync(const std::string& endpoint, int timeout,
+ const std::shared_ptr<tizen_base::Parcel>& request,
+ std::shared_ptr<tizen_base::Parcel>& response) {
+ auto client = std::unique_ptr<Client>(Client::Create(endpoint, timeout));
+ if (client.get() == nullptr) {
+ _E("Client::Create() is failed");
+ return -EIO;
+ }
+
+ Request req(std::string(name_), true, request->GetRaw());
+ tizen_base::Parcel req_parcel;
+ req_parcel.WriteParcelable(req);
+ int ret = client->Send(req_parcel.GetRaw());
+ if (ret != 0) {
+ _E("Send() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
+ return ret;
+ }
+
+ std::vector<uint8_t> data;
+ ret = client->Recv(data);
+ if (ret != 0) {
+ _E("Recv() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
+ return ret;
+ }
+
+ Response res;
+ auto* p = reinterpret_cast<void*>(&data[0]);
+ tizen_base::Parcel res_parcel(p, data.size());
+ res_parcel.ReadParcelable(&res);
+ auto& res_data = res.GetData();
+ if (res_data.size() > 0) {
+ auto *p = reinterpret_cast<const void*>(&res_data[0]);
+ response->Write(p, res_data.size());
+ }
+
+ return res.GetResult();
+}
+
+void Port::Impl::OnSyncRequestReceived(const std::string& sender, pid_t pid,
+ const std::vector<uint8_t>& request, std::vector<uint8_t>& response) {
+ auto sender_info = std::make_shared<SenderInfo>(sender, pid);
+ auto req = std::shared_ptr<tizen_base::Parcel>(
+ new (std::nothrow) tizen_base::Parcel());
+ auto* p = reinterpret_cast<const void*>(&request[0]);
+ req->Write(p, request.size());
+ auto res = std::shared_ptr<tizen_base::Parcel>(
+ new (std::nothrow) tizen_base::Parcel());
+ listener_->OnSyncRequest(sender_info, req, res);
+}
+
+void Port::Impl::OnRequestReceived(const std::string& sender, pid_t pid,
+ const std::vector<uint8_t>& request) {
+ auto sender_info = std::make_shared<SenderInfo>(sender, pid);
+ auto req = std::shared_ptr<tizen_base::Parcel>(
+ new (std::nothrow) tizen_base::Parcel());
+ auto* p = reinterpret_cast<const void*>(&request[0]);
+ req->Write(p, request.size());
+ listener_->OnRequest(sender_info, req);
+}
+
+Port::Port(std::string name, IEvent* listener)
+ : impl_(new Impl(this, name, listener)) {
+ if (impl_->server_.get() == nullptr) {
+ _E("Failed to create server. error(%d)", get_last_result());
+ THROW(get_last_result());
+ }
+}
+
+Port::~Port() {
+}
+
+void Port::WaitForEvent() {
+ impl_->WaitForEvent();
+}
+
+void Port::Cancel() {
+ impl_->Cancel();
+}
+
+void Port::AddPrivilege(const std::string& privilege) {
+ impl_->AddPrivilege(privilege);
+}
+
+int Port::Send(const std::string& endpoint, int timeout,
+ const std::shared_ptr<tizen_base::Parcel>& request) {
+ return impl_->Send(endpoint, timeout, request);
+}
+
+int Port::SendSync(const std::string& endpoint, int timeout,
+ const std::shared_ptr<tizen_base::Parcel>& request,
+ std::shared_ptr<tizen_base::Parcel>& response) {
+ return impl_->SendSync(endpoint, timeout, request, response);
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_PORT_HH_
+#define COMPONENT_BASED_PORT_PORT_HH_
+
+#include <parcel.hh>
+
+#include <memory>
+#include <string>
+
+#include "component_based/port/export_api.hh"
+#include "component_based/port/sender_info.hh"
+
+namespace component_based {
+
+class EXPORT_API Port {
+ public:
+ class IEvent {
+ public:
+ virtual void OnRequest(const std::shared_ptr<SenderInfo>& sender,
+ const std::shared_ptr<tizen_base::Parcel>& request) = 0;
+ virtual void OnSyncRequest(const std::shared_ptr<SenderInfo>& sender,
+ const std::shared_ptr<tizen_base::Parcel>& request,
+ std::shared_ptr<tizen_base::Parcel>& response) = 0;
+ };
+
+ Port(std::string name, IEvent* listener);
+ virtual ~Port();
+
+ void WaitForEvent();
+ void Cancel();
+ void AddPrivilege(const std::string& privilege);
+
+ int Send(const std::string& endpoint, int timeout,
+ const std::shared_ptr<tizen_base::Parcel>& request);
+ int SendSync(const std::string& endpoint, int timeout,
+ const std::shared_ptr<tizen_base::Parcel>& request,
+ std::shared_ptr<tizen_base::Parcel>& response);
+
+ private:
+ class Impl;
+ std::unique_ptr<Impl> impl_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_PORT_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_PORT_IMPLEMENTATION_HH_
+#define COMPONENT_BASED_PORT_PORT_IMPLEMENTATION_HH_
+
+#include <list>
+#include <memory>
+#include <string>
+
+#include "component_based/port/port.hh"
+#include "component_based/port/server.hh"
+
+namespace component_based {
+
+class Port::Impl : public Server::IEvent {
+ public:
+ virtual ~Impl();
+
+ void AddPrivilege(const std::string& privilege);
+ void WaitForEvent();
+ void Cancel();
+ int Send(const std::string& endpoint, int timeout,
+ const std::shared_ptr<tizen_base::Parcel>& request);
+ int SendSync(const std::string& endpoint, int timeout,
+ const std::shared_ptr<tizen_base::Parcel>& request,
+ std::shared_ptr<tizen_base::Parcel>& response);
+
+ private:
+ friend class Port;
+ explicit Impl(Port* parent, std::string name, Port::IEvent* listener);
+
+ void OnSyncRequestReceived(const std::string& sender, pid_t pid,
+ const std::vector<uint8_t>& request,
+ std::vector<uint8_t>& response) override;
+ void OnRequestReceived(const std::string& sender, pid_t pid,
+ const std::vector<uint8_t>& request) override;
+
+ private:
+ Port* parent_;
+ std::string name_;
+ Port::IEvent* listener_;
+ std::unique_ptr<Server> server_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_PORT_IMPLEMENTATION_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <cynara-error.h>
+#include <errno.h>
+
+#include "component_based/port/log_private.hh"
+#include "component_based/port/peer_creds.hh"
+#include "component_based/port/privilege_checker.hh"
+
+namespace component_based {
+
+PrivilegeChecker::PrivilegeChecker(cynara* handle)
+ : cynara_(handle, cynara_finish) {
+}
+
+PrivilegeChecker::~PrivilegeChecker() {
+}
+
+void PrivilegeChecker::AddPrivilege(const std::string& privilege) {
+ privileges_.push_back(privilege);
+}
+
+int PrivilegeChecker::Check(int fd) {
+ auto creds = std::shared_ptr<PeerCreds>(PeerCreds::Get(fd));
+ if (creds.get() == nullptr) {
+ _E("Failed to get peer credentials");
+ return -EIO;
+ }
+
+ for (auto& privilege : privileges_) {
+ int ret = cynara_check(cynara_.get(), creds->GetClient().c_str(),
+ creds->GetSession().c_str(), creds->GetUser().c_str(),
+ privilege.c_str());
+ if (ret != CYNARA_API_ACCESS_ALLOWED) {
+ char err[128];
+ cynara_strerror(ret, err, sizeof(err));
+ _E("cynara_check() is not allowed. %s:%s:%s, error(%s)",
+ creds->GetClient().c_str(),
+ creds->GetUser().c_str(),
+ privilege.c_str(),
+ err);
+ if (ret == CYNARA_API_ACCESS_DENIED)
+ return -EPERM;
+
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+PrivilegeChecker* PrivilegeChecker::Create() {
+ cynara* cynara = nullptr;
+ int ret = cynara_initialize(&cynara, nullptr);
+ if (ret != CYNARA_API_SUCCESS) {
+ char err[128];
+ cynara_strerror(ret, err, sizeof(err));
+ _E("cynara_initialize() is failed. error(%s)", err);
+ return nullptr;
+ }
+
+ return new (std::nothrow) PrivilegeChecker(cynara);
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_PRIVILEGE_CHECKER_HH_
+#define COMPONENT_BASED_PORT_PRIVILEGE_CHECKER_HH_
+
+#include <cynara-client.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace component_based {
+
+class PrivilegeChecker {
+ public:
+ explicit PrivilegeChecker(cynara* handle);
+ virtual ~PrivilegeChecker();
+
+ void AddPrivilege(const std::string& privilege);
+ int Check(int fd);
+
+ static PrivilegeChecker* Create();
+
+ private:
+ std::unique_ptr<cynara, decltype(cynara_finish)*> cynara_;
+ std::vector<std::string> privileges_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_PRIVILEGE_CHECKER_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <memory>
+
+#include "component_based/port/log_private.hh"
+#include "component_based/port/request.hh"
+
+namespace component_based {
+
+Request::Request(std::string sender, bool sync, std::vector<uint8_t> data)
+ : sender_(std::move(sender)), sync_(sync), data_(std::move(data)) {
+}
+
+Request::Request() = default;
+
+Request::~Request() = default;
+
+void Request::WriteToParcel(tizen_base::Parcel* parcel) const {
+ parcel->WriteString(sender_);
+ parcel->WriteBool(sync_);
+ parcel->WriteUInt32(data_.size());
+ if (data_.size() > 0) {
+ auto* p = reinterpret_cast<const void*>(&data_[0]);
+ parcel->Write(p, data_.size());
+ }
+}
+
+void Request::ReadFromParcel(tizen_base::Parcel* parcel) {
+ sender_ = parcel->ReadString();
+ parcel->ReadBool(&sync_);
+ data_.clear();
+ uint32_t size = 0;
+ parcel->ReadUInt32(&size);
+ if (size > 0) {
+ auto* data = new (std::nothrow) uint8_t [size];
+ if (data == nullptr) {
+ _E("Out of memory");
+ return;
+ }
+
+ auto data_ptr = std::unique_ptr<uint8_t[]>(data);
+ parcel->Read(data, size);
+ std::copy(data, data + size, std::back_inserter(data_));
+ }
+}
+
+const std::string& Request::GetSender() const {
+ return sender_;
+}
+
+bool Request::IsSync() const {
+ return sync_;
+}
+
+const std::vector<uint8_t>& Request::GetData() const {
+ return data_;
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_REQUEST_HH_
+#define COMPONENT_BASED_PORT_REQUEST_HH_
+
+#include <parcel.hh>
+#include <parcelable.hh>
+
+#include <string>
+#include <vector>
+
+namespace component_based {
+
+class Request : public tizen_base::Parcelable {
+ public:
+ Request(std::string sender, bool sync, std::vector<uint8_t> data);
+ Request();
+ virtual ~Request();
+
+ void WriteToParcel(tizen_base::Parcel* parcel) const override;
+ void ReadFromParcel(tizen_base::Parcel* parcel) override;
+
+ const std::string& GetSender() const;
+ bool IsSync() const;
+ const std::vector<uint8_t>& GetData() const;
+
+ private:
+ std::string sender_;
+ bool sync_ = false;
+ std::vector<uint8_t> data_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_REQUEST_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <memory>
+
+#include "component_based/port/log_private.hh"
+#include "component_based/port/response.hh"
+
+namespace component_based {
+
+Response::Response(int32_t result, std::vector<uint8_t> data)
+ : result_(result), data_(std::move(data)) {
+}
+
+Response::Response() = default;
+
+Response::~Response() = default;
+
+void Response::WriteToParcel(tizen_base::Parcel* parcel) const {
+ parcel->WriteInt32(result_);
+ parcel->WriteUInt32(data_.size());
+ if (data_.size() > 0) {
+ auto* p = reinterpret_cast<const void*>(&data_[0]);
+ parcel->Write(p, data_.size());
+ }
+}
+
+void Response::ReadFromParcel(tizen_base::Parcel* parcel) {
+ parcel->ReadInt32(&result_);
+ data_.clear();
+ uint32_t size = 0;
+ parcel->ReadUInt32(&size);
+ if (size > 0) {
+ auto* data = new (std::nothrow) uint8_t [size];
+ if (data == nullptr) {
+ _E("Out of memory");
+ return;
+ }
+
+ auto data_ptr = std::unique_ptr<uint8_t[]>(data);
+ parcel->Read(data, size);
+ std::copy(data, data + size, std::back_inserter(data_));
+ }
+}
+
+int32_t Response::GetResult() const {
+ return result_;
+}
+
+const std::vector<uint8_t>& Response::GetData() const {
+ return data_;
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_RESPONSE_HH_
+#define COMPONENT_BASED_PORT_RESPONSE_HH_
+
+#include <parcel.hh>
+#include <parcelable.hh>
+
+#include <string>
+#include <vector>
+
+namespace component_based {
+
+class Response : public tizen_base::Parcelable {
+ public:
+ Response(int32_t result, std::vector<uint8_t> data);
+ Response();
+ virtual ~Response();
+
+ void WriteToParcel(tizen_base::Parcel* parcel) const override;
+ void ReadFromParcel(tizen_base::Parcel* parcel) override;
+
+ int32_t GetResult() const;
+ const std::vector<uint8_t>& GetData() const;
+
+ private:
+ int32_t result_;
+ std::vector<uint8_t> data_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_RESPONSE_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include "component_based/port/sender_info.hh"
+
+namespace component_based {
+
+SenderInfo::SenderInfo(std::string name, pid_t pid)
+ : name_(std::move(name)), pid_(pid) {
+}
+
+SenderInfo::~SenderInfo() = default;
+
+const std::string& SenderInfo::GetName() const {
+ return name_;
+}
+
+pid_t SenderInfo::GetPid() const {
+ return pid_;
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_SENDER_INFO_HH_
+#define COMPONENT_BASED_PORT_SENDER_INFO_HH_
+
+#include <string>
+
+#include "component_based/port/export_api.hh"
+
+namespace component_based {
+
+class EXPORT_API SenderInfo {
+ public:
+ SenderInfo(std::string name, pid_t pid);
+ virtual ~SenderInfo();
+
+ const std::string& GetName() const;
+ pid_t GetPid() const;
+
+ private:
+ std::string name_;
+ pid_t pid_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_SENDER_INFO_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <aul_component_port.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <iostream>
+
+#include "component_based/port/log_private.hh"
+#include "component_based/port/request.hh"
+#include "component_based/port/response.hh"
+#include "component_based/port/server.hh"
+
+namespace component_based {
+
+Server::Server(int fd, std::string name, IEvent* listener)
+ : fd_(fd),
+ name_(std::move(name)),
+ listener_(listener),
+ checker_(PrivilegeChecker::Create()) {
+ channel_ = g_io_channel_unix_new(fd_);
+ source_ = g_io_create_watch(channel_,
+ static_cast<GIOCondition>(G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_ERR));
+ g_source_set_callback(source_, reinterpret_cast<GSourceFunc>(GIOFunc), this,
+ nullptr);
+ g_source_set_priority(source_, G_PRIORITY_DEFAULT);
+ g_source_attach(source_, loop_.GetContext());
+ g_source_unref(source_);
+}
+
+Server::~Server() {
+ if (channel_) {
+ GError* error = nullptr;
+ g_io_channel_shutdown(channel_, TRUE, &error);
+ if (error) {
+ _E("g_io_channel_shutdown() is failed. error(%s)", error->message);
+ g_error_free(error);
+ }
+
+ g_io_channel_unref(channel_);
+ }
+
+ if (source_) {
+ if (g_source_is_destroyed(source_))
+ g_source_destroy(source_);
+ }
+
+ if (fd_ > 0)
+ close(fd_);
+
+ aul_component_port_destroy(name_.c_str());
+}
+
+void Server::Poll() {
+ loop_.Run();
+}
+
+void Server::Cancel() {
+ loop_.Quit();
+}
+
+void Server::AddPrivilege(const std::string& privilege) {
+ checker_->AddPrivilege(privilege);
+}
+
+Server* Server::Create(const std::string& name, IEvent* listener) {
+ int fd = -1;
+ int ret = aul_component_port_create(name.c_str(), &fd);
+ if (ret != AUL_R_OK) {
+ set_last_result(ret);
+ _E("aul_component_port_create() is failed. error(%d)", ret);
+ return nullptr;
+ }
+
+ ret = listen(fd, 128);
+ if (ret < 0) {
+ set_last_result(-errno);
+ _E("listen() is failed. port_name(%s), errno(%d)", name.c_str(), errno);
+ close(fd);
+ return nullptr;
+ }
+
+ return new Server(fd, std::string(name), listener);
+}
+
+Client* Server::Accept() {
+ struct sockaddr_un addr = { 0, };
+ auto* addr_ptr = reinterpret_cast<struct sockaddr*>(&addr);
+ socklen_t addr_size = sizeof(addr);
+ int client_fd = accept(fd_, addr_ptr, &addr_size);
+ if (client_fd < 0) {
+ _E("accept() is failed. errno(%d)", errno);
+ return nullptr;
+ }
+
+ struct ucred cred = { 0, };
+ socklen_t cred_size = sizeof(cred);
+ int ret = getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &cred, &cred_size);
+ if (ret < 0) {
+ _E("getsockopt(SO_PEEDCRED) is failed. errno(%d)", errno);
+ close(client_fd);
+ return nullptr;
+ }
+
+ _W("client pid(%d), uid(%u)", cred.pid, cred.uid);
+ return new (std::nothrow) Client(client_fd, cred.pid);
+}
+
+int Server::CheckPrivilege(int fd) {
+ return checker_->Check(fd);
+}
+
+gboolean Server::GIOFunc(GIOChannel* source, GIOCondition cond, gpointer data) {
+ auto* handle = static_cast<Server*>(data);
+ auto client = std::unique_ptr<Client>(handle->Accept());
+ int ret = handle->CheckPrivilege(client->GetFd());
+ if (ret != 0) {
+ _E("Request is denied");
+ std::vector<uint8_t> dummy;
+ Response res(ret, dummy);
+ tizen_base::Parcel res_parcel;
+ res_parcel.WriteParcelable(res);
+ client->Send(res_parcel.GetRaw());
+ return G_SOURCE_CONTINUE;
+ }
+
+ auto* listener = handle->listener_;
+ if (listener) {
+ std::vector<uint8_t> buf;
+ client->Recv(buf);
+ auto* p = reinterpret_cast<void*>(&buf[0]);
+ tizen_base::Parcel parcel(p, buf.size());
+ Request req;
+ parcel.ReadParcelable(&req);
+ _W("Sender(%s), sync(%s)",
+ req.GetSender().c_str(), req.IsSync() ? "true" : "false");
+ if (req.IsSync()) {
+ std::vector<uint8_t> res_data;
+ listener->OnSyncRequestReceived(req.GetSender(), client->GetPid(),
+ req.GetData(), res_data);
+ Response res(0, res_data);
+ tizen_base::Parcel res_parcel;
+ res_parcel.WriteParcelable(res);
+ client->Send(res_parcel.GetRaw());
+ } else {
+ std::vector<uint8_t> dummy;
+ Response res(0, dummy);
+ tizen_base::Parcel res_parcel;
+ res_parcel.WriteParcelable(res);
+ client->Send(res_parcel.GetRaw());
+ listener->OnRequestReceived(req.GetSender(), client->GetPid(),
+ req.GetData());
+ }
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_SERVER_HH_
+#define COMPONENT_BASED_PORT_SERVER_HH_
+
+#include <gio/gio.h>
+#include <glib.h>
+
+#include <memory>
+#include <string>
+
+#include "component_based/port/client.hh"
+#include "component_based/port/main_loop.hh"
+#include "component_based/port/privilege_checker.hh"
+
+namespace component_based {
+
+class Server {
+ public:
+ class IEvent {
+ public:
+ virtual void OnRequestReceived(const std::string& sender, pid_t pid,
+ const std::vector<uint8_t>& request) = 0;
+ virtual void OnSyncRequestReceived(const std::string& sender, pid_t pid,
+ const std::vector<uint8_t>& request,
+ std::vector<uint8_t>& response) = 0;
+ };
+
+ Server(int fd, std::string name, IEvent* listener);
+ virtual ~Server();
+
+ void Poll();
+ void Cancel();
+ void AddPrivilege(const std::string& privilege);
+
+ static Server* Create(const std::string& name, IEvent* listener);
+
+ private:
+ static gboolean GIOFunc(GIOChannel* source, GIOCondition cond, gpointer data);
+ Client* Accept();
+ int CheckPrivilege(int fd);
+
+ private:
+ int fd_;
+ std::string name_;
+ IEvent* listener_;
+ std::unique_ptr<PrivilegeChecker> checker_;
+ MainLoop loop_;
+ GIOChannel* channel_;
+ GSource* source_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_SERVER_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "component_based/port/log_private.hh"
+#include "component_based/port/socket.hh"
+
+namespace component_based {
+
+Socket::Socket(int fd) : fd_(fd) {
+}
+
+Socket::~Socket() {
+ if (fd_ > 0)
+ close(fd_);
+}
+
+int Socket::Send(const void* buf, size_t size) {
+ if (buf == nullptr || size == 0) {
+ _E("Invalid parameter");
+ return -EINVAL;
+ }
+
+ const uint8_t* buffer = static_cast<const uint8_t*>(buf);
+ size_t left = size;
+ while (left) {
+ ssize_t bytes = send(fd_, buffer, left, MSG_NOSIGNAL);
+ if (bytes < 0) {
+ int ret = -errno;
+ _E("send() is failed. fd(%d), errno(%d)", fd_, errno);
+ return ret;
+ }
+
+ left -= bytes;
+ buffer += bytes;
+ }
+
+ return 0;
+}
+
+int Socket::Read(void* buf, size_t size) {
+ if (buf == nullptr || size == 0) {
+ _E("Invalid parameter");
+ return -EINVAL;
+ }
+
+ uint8_t* buffer = static_cast<uint8_t*>(buf);
+ size_t left = size;
+ while (left) {
+ ssize_t bytes = read(fd_, buffer, left);
+ if (bytes == 0) {
+ _W("EOF. fd(%d)", fd_);
+ return -EIO;
+ } else if (bytes < 0) {
+ return -errno;
+ }
+
+ left -= bytes;
+ buffer += bytes;
+ }
+
+ return 0;
+}
+
+int Socket::GetFd() const {
+ return fd_;
+}
+
+std::string Socket::GetSocketPath(const std::string& name) {
+ return std::string("/run/aul/port/" + std::to_string(getuid()) +
+ "/." + name + "-port");
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_SOCKET_HH_
+#define COMPONENT_BASED_PORT_SOCKET_HH_
+
+#include <string>
+
+namespace component_based {
+
+class Socket {
+ public:
+ Socket(int fd);
+ virtual ~Socket();
+
+ virtual int Send(const void* buf, size_t size);
+ virtual int Read(void* buf, size_t size);
+
+ int GetFd() const;
+ static std::string GetSocketPath(const std::string& name);
+
+ private:
+ int fd_;
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_SOCKET_HH_
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include "component_based/port/api/component_port.h"
+#include "component_based/port/exception.hh"
+#include "component_based/port/export_api.hh"
+#include "component_based/port/log_private.hh"
+#include "component_based/port/port.hh"
+
+namespace {
+using namespace component_based;
+
+class PortStub : public Port,
+ public Port::IEvent {
+ public:
+ PortStub(std::string name)
+ : Port(std::move(name), this) {
+ }
+
+ virtual ~PortStub() = default;
+
+ void SetRequestCb(component_port_request_cb cb, void* user_data) {
+ request_cb_ = cb;
+ request_cb_user_data_ = user_data;
+ }
+
+ void SetSyncRequestCb(component_port_sync_request_cb cb, void* user_data) {
+ sync_request_cb_ = cb;
+ sync_request_cb_user_data_ = user_data;
+ }
+
+ private:
+ void OnRequest(const std::shared_ptr<SenderInfo>& sender,
+ const std::shared_ptr<tizen_base::Parcel>& request) override {
+ if (request_cb_) {
+ parcel_h parcel = static_cast<parcel_h>(request.get());
+ request_cb_(sender->GetName().c_str(), parcel, request_cb_user_data_);
+ }
+ }
+
+ void OnSyncRequest(const std::shared_ptr<SenderInfo>& sender,
+ const std::shared_ptr<tizen_base::Parcel>& request,
+ std::shared_ptr<tizen_base::Parcel>& response) override {
+ if (sync_request_cb_) {
+ parcel_h req_parcel = static_cast<parcel_h>(request.get());
+ parcel_h res_parcel = static_cast<parcel_h>(response.get());
+ sync_request_cb_(sender->GetName().c_str(), req_parcel, res_parcel,
+ request_cb_user_data_);
+ }
+ }
+
+ private:
+ component_port_request_cb request_cb_ = nullptr;
+ void* request_cb_user_data_ = nullptr;
+ component_port_sync_request_cb sync_request_cb_ = nullptr;
+ void* sync_request_cb_user_data_ = nullptr;
+};
+
+} // namespace
+
+extern "C" EXPORT_API int component_port_create(const char* port_name,
+ component_port_h* port) {
+ if (port_name == nullptr || port == nullptr) {
+ _E("Invalid parameter");
+ return COMPONENT_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ::PortStub* p = nullptr;
+ try {
+ p = new (std::nothrow) ::PortStub(std::string(port_name));
+ if (p == nullptr) {
+ _E("Out of memory");
+ return COMPONENT_PORT_ERROR_OUT_OF_MEMORY;
+ }
+ } catch (Exception& e) {
+ _E("Failed to create port");
+ return COMPONENT_PORT_ERROR_IO_ERROR;
+ }
+
+ *port = static_cast<component_port_h>(p);
+ return COMPONENT_PORT_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int component_port_destroy(component_port_h port) {
+ if (port == nullptr) {
+ _E("Invalid parameter");
+ return COMPONENT_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* p = static_cast<::PortStub*>(port);
+ delete p;
+ return COMPONENT_PORT_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int component_port_set_request_cb(component_port_h port,
+ component_port_request_cb callback, void *user_data) {
+ if (port == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return COMPONENT_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* p = static_cast<::PortStub*>(port);
+ p->SetRequestCb(callback, user_data);
+ return COMPONENT_PORT_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int component_port_set_sync_request_cb(
+ component_port_h port, component_port_sync_request_cb callback,
+ void *user_data) {
+ if (port == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return COMPONENT_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* p = static_cast<::PortStub*>(port);
+ p->SetSyncRequestCb(callback, user_data);
+ return COMPONENT_PORT_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int component_port_add_privilege(component_port_h port,
+ const char *privilege) {
+ if (port == nullptr || privilege == nullptr) {
+ _E("Invalid parameter");
+ return COMPONENT_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ auto* p = static_cast<::PortStub*>(port);
+ p->AddPrivilege(std::string(privilege));
+ return COMPONENT_PORT_ERROR_NONE;
+}
+
+extern "C" EXPORT_API void component_port_wait_for_event(
+ component_port_h port) {
+ if (port == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(COMPONENT_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ _W("Wait for events...");
+ auto* p = static_cast<::PortStub*>(port);
+ p->WaitForEvent();
+ set_last_result(COMPONENT_PORT_ERROR_NONE);
+}
+
+extern "C" EXPORT_API void component_port_cancel(component_port_h port) {
+ if (port == nullptr) {
+ _E("Invaid parameter");
+ set_last_result(COMPONENT_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ _W("Cancel!!!");
+ auto* p = static_cast<::PortStub*>(port);
+ p->Cancel();
+ set_last_result(COMPONENT_PORT_ERROR_NONE);
+}
+
+extern "C" EXPORT_API int component_port_send(component_port_h port,
+ const char *endpoint, int timeout, parcel_h request) {
+ if (port == nullptr || endpoint == nullptr || request == nullptr) {
+ _E("Invalid parameter");
+ return COMPONENT_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ void* raw = nullptr;
+ size_t size = 0;
+ parcel_get_raw(request, &raw, &size);
+ auto req = std::make_shared<tizen_base::Parcel>(raw, size);
+ auto* p = static_cast<::PortStub*>(port);
+ int ret = p->Send(endpoint, timeout, req);
+ if (ret != 0) {
+ if (ret == -EPERM) {
+ _E("Permission denied");
+ return COMPONENT_PORT_ERROR_PERMISSION_DENIED;
+ }
+
+ return COMPONENT_PORT_ERROR_IO_ERROR;
+ }
+
+ return COMPONENT_PORT_ERROR_NONE;
+}
+
+extern "C" EXPORT_API int component_port_send_sync(component_port_h port,
+ const char *endpoint, int timeout, parcel_h request, parcel_h *response) {
+ if (port == nullptr || endpoint == nullptr || request == nullptr ||
+ response == nullptr) {
+ _E("Invalid parameter");
+ return COMPONENT_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ void* raw = nullptr;
+ size_t size = 0;
+ parcel_get_raw(request, &raw, &size);
+ auto req = std::make_shared<tizen_base::Parcel>(raw, size);
+ auto res = std::make_shared<tizen_base::Parcel>();
+ auto* p = static_cast<::PortStub*>(port);
+ int ret = p->SendSync(endpoint, timeout, req, res);
+ if (ret != 0) {
+ if (ret == -EPERM) {
+ _E("Permission denied");
+ return COMPONENT_PORT_ERROR_PERMISSION_DENIED;
+ }
+
+ return COMPONENT_PORT_ERROR_IO_ERROR;
+ }
+
+ parcel_h res_parcel = nullptr;
+ parcel_create(&res_parcel);
+ auto& res_data = res->GetRaw();
+ auto* res_p = reinterpret_cast<const void*>(&res_data[0]);
+ parcel_burst_write(res_parcel, res_p, res_data.size());
+ *response = res_parcel;
+ return COMPONENT_PORT_ERROR_NONE;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+#include "component_based/port/log_private.hh"
+#include "component_based/port/util.hh"
+
+namespace component_based {
+
+void Util::Hexdump(const std::string& tag, const std::vector<uint8_t>& data) {
+ unsigned int address = 0;
+ unsigned int row = 0;
+ unsigned int nread = 0;
+ std::vector<std::string> lines;
+ std::stringstream ds;
+ for (int i = 0; i <= 75; ++i)
+ ds << '=';
+ lines.push_back(ds.str());
+
+ while (true) {
+ std::stringstream ss;
+ ss << std::hex << std::setfill('0');
+ if (address >= data.size())
+ break;
+
+ ss << std::setw(8) << address;
+ nread = ((data.size() - address) > 16) ? 16 : (data.size() - address);
+
+ for (unsigned int i = 0; i < 16; ++i) {
+ if (i % 8 == 0)
+ ss << ' ';
+
+ if (i < nread) {
+ ss << ' ' << std::setw(2) <<
+ static_cast<int>(data[16 * row + i]);
+ } else {
+ ss << " ";
+ }
+ }
+
+ ss << " ";
+ for (unsigned int i = 0; i < nread ; ++i) {
+ if (data[16 * row + i] < 32)
+ ss << '.';
+ else
+ ss << data[16 * row + i];
+ }
+
+ address += 16;
+ row++;
+ lines.push_back(ss.str());
+ }
+ lines.push_back(ds.str());
+
+ _W("[%s] Hexdump", tag.c_str());
+ for (auto& s : lines)
+ _W("%s", s.c_str());
+ _W("");
+}
+
+} // namespace component_based
--- /dev/null
+/*
+ * Copyright (c) 2020 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 COMPONENT_BASED_PORT_UTIL_HH_
+#define COMPONENT_BASED_PORT_UTIL_HH_
+
+#include <string>
+#include <vector>
+
+namespace component_based {
+
+class Util {
+ public:
+ static void Hexdump(const std::string& tag, const std::vector<uint8_t>& data);
+};
+
+} // namespace component_based
+
+#endif // COMPONENT_BASED_PORT_UTIL_HH_
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
Source1002: %{name}-application.manifest
Source1003: %{name}-widget.manifest
Source1004: %{name}-widget-application.manifest
+Source1005: %{name}-port.manifest
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
BuildRequires: pkgconfig(capi-appfw-app-common)
BuildRequires: pkgconfig(widget_service)
BuildRequires: pkgconfig(screen_connector_provider)
+BuildRequires: pkgconfig(parcel)
+BuildRequires: pkgconfig(cynara-client)
+BuildRequires: pkgconfig(cynara-creds-socket)
%if 0%{?gcov:1}
BuildRequires: lcov
%description -n %{name}-application-devel
Header & package configuration files to support development of the component-based application.
-
-
#################################################
# component-based-widget
#################################################
%description -n %{name}-widget-devel
Header & package configuration files to support development of the component-based widget
-
#################################################
# component-based-widget-application
#################################################
%description -n %{name}-widget-application-devel
Header & package configuration files to support development of the component-based efl widget application.
+#################################################
+# component-based-port
+#################################################
+%package -n %{name}-port
+Summary: Library for developing the component-based port
+Group: Application Framework/Core
+License: Apache-2.0
+
+%description -n %{name}-port
+Component-based port library package.
+
+%package -n %{name}-port-devel
+Summary: Component-based port development library (dev)
+Group: Development/Libraries
+Requires: %{name}-port = %{version}-%{release}
+
+%description -n %{name}-port-devel
+Component-based port library package. (devel)
#################################################
# unittests
cp %{SOURCE1002} .
cp %{SOURCE1003} .
cp %{SOURCE1004} .
+cp %{SOURCE1005} .
%build
%if 0%{?gcov:1}
%{_libdir}/pkgconfig/component-based-application.pc
%{_libdir}/libcomponent-based-application.so
-
#################################################
# component-based-widget
#################################################
%{_libdir}/pkgconfig/component-based-core-widget-base.pc
%{_libdir}/libcomponent-based-core-widget-base.so
-
#################################################
# component-based-widget-application
#################################################
%{_libdir}/pkgconfig/component-based-widget-application.pc
%{_libdir}/libcomponent-based-widget-application.so
+#################################################
+# component-based-port
+#################################################
+%files -n %{name}-port
+%license LICENSE
+%manifest %{name}-port.manifest
+%attr(0644,root,root) %{_libdir}/libcomponent-based-port.so.*
+
+%files -n %{name}-port-devel
+%{_includedir}/component_based/port/*.hh
+%{_includedir}/component_based/port/api/*.h
+%{_libdir}/pkgconfig/component-based-port.pc
+%{_libdir}/libcomponent-based-port.so
+
#################################################
# unittests
#################################################