ua-api: Add support for product API's 91/253391/1
authorAbhay Agarwal <ay.agarwal@samsung.com>
Fri, 5 Feb 2021 09:14:52 +0000 (14:44 +0530)
committerAbhay Agarwal <ay.agarwal@samsung.com>
Tue, 9 Feb 2021 10:49:32 +0000 (16:19 +0530)
This patch adds support in ua-api to handle product API's.

Change-Id: Ied7769ad1f550a81e643a7ab894625860924c5ba
Signed-off-by: Abhay Agarwal <ay.agarwal@samsung.com>
include/product/ua-api-product.h [new file with mode: 0644]
include/product/ua-internal-product.h [new file with mode: 0644]
packaging/ua-manager.spec
ua-api/CMakeLists.txt
ua-api/product/include/ua-common-product.h [new file with mode: 0644]
ua-api/product/include/ua-event-handler-product.h [new file with mode: 0644]
ua-api/product/include/ua-request-sender-product.h [new file with mode: 0644]
ua-api/product/ua-api-product.c [new file with mode: 0644]
ua-api/product/ua-common-product.c [new file with mode: 0644]
ua-api/product/ua-event-handler-product.c [new file with mode: 0644]
ua-api/product/ua-request-sender-product.c [new file with mode: 0644]

diff --git a/include/product/ua-api-product.h b/include/product/ua-api-product.h
new file mode 100644 (file)
index 0000000..8163007
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Author: Abhay Agarwal <ay.agarwal@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __TIZEN_UA_NETWORK_UA_API_PRODUCT_H__
+#define __TIZEN_UA_NETWORK_UA_API_PRODUCT_H__
+
+#include <gmodule.h>
+#include <tizen_error.h>
+
+#ifndef TIZEN_ERROR_UA
+#define TIZEN_ERROR_UA 0x11170000 /**< To-Do: This should move to tizen_error.h */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Macro for event enum.
+ * @since_tizen 6.5
+ */
+#define GENERATE_PRODUCT_EVENT_ENUM(ENUM) ENUM,
+
+/**
+ * @brief Macro to print event string out.
+ * @since_tizen 6.5
+ */
+#define GENERATE_PRODUCT_EVENT_STRING(STRING) #STRING,
+
+/**
+ * @brief Enumerations macro of UA framework product event codes.
+ * @since_tizen 6.5
+ */
+typedef enum {
+       UAM_PRODUCT_EVENT_TEST, /** Test */
+       UAM_PRODUCT_EVENT_MAX, /**< Max. event number */
+} uam_product_event_e;
+
+/**
+ * @brief Event data structure.
+ * @since_tizen 6.5
+ */
+typedef struct {
+       int result; /**< Result code */
+       void *data; /**< Data pointer */
+} uam_product_event_data_s;
+
+/**
+ * @brief Callback to be invoked when receiving product events.
+ * @since_tizen 6.5
+ *
+ * @remarks The @a event_param should not be released.
+ * @remarks The @a event_param can be used only in the callback.
+ *
+ * @param[in] event Event type.
+ * @param[in] event_param The event data structure.
+ * @param[in] user_data The user data passed in _uam_product_init()
+ *
+ * @exception
+ * @pre
+ * @post
+ *
+ * @see _uam_product_init()
+ */
+typedef void (*uam_product_event_cb)(int event, uam_product_event_data_s *event_param, void *user_data);
+
+/**
+ * @brief Initializes client library.
+ * @since_tizen 6.5
+ *
+ * @param[in] cb Callback handler
+ * @param[in] user_data The user data.
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #UAM_ERROR_NONE Successful
+ * @retval #UAM_ERROR_INVALID_PARAMETER Invalid parameters
+ * @rerval #UAM_ERROR_ALREADY_REGISTERED Already registered
+ * @retval #UAM_ERROR_INTERNAL Internal error
+ *
+ * @exception
+ * @pre
+ * @post
+ */
+int _uam_product_init(uam_product_event_cb cb, void *user_data);
+
+/**
+ * @brief De-initializes client library.
+ * @since_tizen 6.5
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #UAM_ERROR_NONE Successful
+ * @rerval #UAM_ERROR_NOT_REGISTERED Not registered
+ * @retval #UAM_ERROR_INTERNAL Internal error
+ *
+ * @exception
+ * @pre
+ * @post
+ */
+int _uam_product_deinit(void);
+
+/**
+ * @brief Test.
+ * @since_tizen 6.5
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #UAM_ERROR_NONE Successful
+ * @retval #UAM_ERROR_INVALID_PARAMETER Invalid parameters
+ * @retval #UAM_ERROR_INTERNAL Internal error
+ *
+ * @exception
+ * @pre
+ * @post
+ */
+int _uam_product_test();
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __TIZEN_UA_NETWORK_UA_API_PRODUCT_H__ */
diff --git a/include/product/ua-internal-product.h b/include/product/ua-internal-product.h
new file mode 100644 (file)
index 0000000..c0ddb2b
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Author: Abhay Agarwal <ay.agarwal@samsung.com>
+ *
+ * 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 __UAM_INTERNAL_PRODUCT_H__
+#define __UAM_INTERNAL_PRODUCT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UAM_PRODUCT_DBUS_NAME "net.uamd_product"
+#define UAM_PRODUCT_DAEMON_PATH "/net/uamd_product"
+
+#define UAM_PRODUCT_EVENT_INTERFACE "net.ua.event_product"
+#define UAM_PRODUCT_EVENT_PATH "/net/ua/event_product"
+
+#define FOREACH_PRODUCT_REQUEST(REQUEST) \
+       REQUEST(UAM_PRODUCT_REQUEST_TEST) \
+       REQUEST(UAM_PRODUCT_REQUEST_MAX)
+
+#define GENERATE_PRODUCT_REQUEST_ENUM(ENUM) ENUM,
+#define GENERATE_PRODUCT_REQUEST_STRING(STRING) #STRING,
+
+typedef enum {
+       FOREACH_PRODUCT_REQUEST(GENERATE_PRODUCT_REQUEST_ENUM)
+} uam_product_request_e;
+
+#define UAM_PRODUCT_SIGNAL_TEST "Test"
+
+#define CASE_TO_STR(x) case x: return #x;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __UAM_INTERNAL_PRODUCT_H__ */
index 492f992..76196a7 100644 (file)
@@ -115,6 +115,7 @@ cp ua-manager.service %{buildroot}%{_unitdir}/ua-manager.service
 %files devel
 %defattr(-, root, root)
 %{_includedir}/ua-manager/ua-api.h
+%{_includedir}/ua-manager/ua-api-product.h
 %{_libdir}/pkgconfig/ua-api.pc
 %%attr(644,-,-) %{_libdir}/libua-api.so
 
index d365c5d..17945fb 100644 (file)
@@ -10,6 +10,9 @@ SET(LIB_PKGCONFIG_DIR "${LIB_PATH}/pkgconfig")
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/product)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/product)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/product/include)
 
 INCLUDE(FindPkgConfig)
 pkg_check_modules(PKGS REQUIRED
@@ -41,10 +44,15 @@ SET(SRCS
        src/ua-common.c
        src/ua-event-handler.c
        src/ua-request-sender.c
+       product/ua-api-product.c
+       product/ua-common-product.c
+       product/ua-event-handler-product.c
+       product/ua-request-sender-product.c
        )
 
 SET(HEADERS
        ua-api.h
+       product/ua-api-product.h
        )
 
 ADD_LIBRARY(${LIB_NAME} SHARED ${SRCS})
diff --git a/ua-api/product/include/ua-common-product.h b/ua-api/product/include/ua-common-product.h
new file mode 100644 (file)
index 0000000..8e195c9
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Author: Abhay Agarwal <ay.agarwal@samsung.com>
+ *
+ * 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 __UAM_COMMON_PRODUCT_H__
+#define __UAM_COMMON_PRODUCT_H__
+
+#include <dlog.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GDBusConnection *_uam_product_get_gdbuam_conn(void);
+
+const char *_uam_product_request_to_str(unsigned int req);
+const char *_uam_product_event_to_str(unsigned int event);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __UAM_COMMON_PRODUCT_H__ */
diff --git a/ua-api/product/include/ua-event-handler-product.h b/ua-api/product/include/ua-event-handler-product.h
new file mode 100644 (file)
index 0000000..f9acb80
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Author: Abhay Agarwal <ay.agarwal@samsung.com>
+ *
+ * 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 __UAM_EVENT_HANDLER_PRODUCT_H__
+#define __UAM_EVENT_HANDLER_PRODUCT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _uam_product_register_event_handler(
+       uam_product_event_cb event_cb, void *user_data);
+
+int _uam_product_unregister_event_handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __UAM_EVENT_HANDLER_PRODUCT_H__ */
diff --git a/ua-api/product/include/ua-request-sender-product.h b/ua-api/product/include/ua-request-sender-product.h
new file mode 100644 (file)
index 0000000..f515ca2
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Author: Abhay Agarwal <ay.agarwal@samsung.com>
+ *
+ * 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 __UAM_REQUEST_SENDER_PRODUCT_H__
+#define __UAM_REQUEST_SENDER_PRODUCT_H__
+
+#include "ua-api-product.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _uam_product_gdbuam_deinit_proxy(void);
+
+int _uam_product_sync_request(
+               int req_func, GArray *in_param1,
+               GArray *in_param2, GArray *in_param3,
+               GArray *in_param4, GArray **out_param);
+
+int _uam_product_async_request(int req_func,
+               GArray *in_param1, GArray *in_param2,
+               GArray *in_param3, GArray *in_param4,
+               uam_product_event_cb callback, void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __UAM_REQUEST_SENDER_PRODUCT_H__ */
diff --git a/ua-api/product/ua-api-product.c b/ua-api/product/ua-api-product.c
new file mode 100644 (file)
index 0000000..ddfe54a
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Author: Abhay Agarwal <ay.agarwal@samsung.com>
+ *
+ * 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 <ua-api.h>
+#include <ua-common.h>
+#include <ua-api-product.h>
+#include <ua-internal-product.h>
+#include <ua-common-product.h>
+#include <ua-event-handler-product.h>
+#include <ua-request-sender-product.h>
+
+typedef struct {
+       void *callback;
+       void *user_data;
+} uam_product_callback_info_t;
+
+static uam_product_callback_info_t cb_info;
+
+UAM_EXPORT_API int _uam_product_init(uam_product_event_cb cb, void *user_data)
+{
+       FUNC_ENTRY;
+       int ret;
+
+       ret = _uam_product_register_event_handler(cb, user_data);
+       if (UAM_ERROR_NONE == ret || UAM_ERROR_ALREADY_REGISTERED == ret) {
+               cb_info.callback = cb;
+               cb_info.user_data = user_data;
+               return UAM_ERROR_NONE;
+       }
+
+       FUNC_EXIT;
+       return ret;
+}
+
+UAM_EXPORT_API int _uam_product_deinit(void)
+{
+       FUNC_ENTRY;
+       int ret;
+
+       ret = _uam_product_unregister_event_handler();
+
+       if (UAM_ERROR_NONE != ret && UAM_ERROR_NOT_REGISTERED != ret)
+               return ret;
+
+       FUNC_EXIT;
+       return ret;
+}
+
+UAM_EXPORT_API int _uam_product_test()
+{
+       FUNC_ENTRY;
+       int ret;
+
+       UAM_INIT_PARAMS();
+       UAM_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       ret = _uam_product_sync_request(UAM_PRODUCT_REQUEST_TEST,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       UAM_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       FUNC_EXIT;
+       return ret;
+}
diff --git a/ua-api/product/ua-common-product.c b/ua-api/product/ua-common-product.c
new file mode 100644 (file)
index 0000000..274d80e
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Author: Abhay Agarwal <ay.agarwal@samsung.com>
+ *
+ * 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 "ua-api.h"
+#include "ua-common.h"
+#include "ua-internal-product.h"
+#include "ua-api-product.h"
+
+static const char *request_string[] = {
+       FOREACH_PRODUCT_REQUEST(GENERATE_PRODUCT_REQUEST_STRING)
+};
+
+static GDBusConnection *gdbuam_conn = NULL;
+
+static GDBusConnection *__uam_product_get_shared_gdbuam_conn(void)
+{
+       FUNC_ENTRY;
+       GError *error = NULL;
+       GDBusConnection *shared_conn = NULL;
+
+       shared_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (!shared_conn) {
+               UAM_ERR("Unable to connect to dbus");
+               if (error) {
+                       UAM_ERR("Error: %s", error->message);
+                       g_clear_error(&error);
+               }
+               return NULL;
+       }
+
+       FUNC_EXIT;
+       return shared_conn;
+}
+
+GDBusConnection *_uam_product_get_gdbuam_conn(void)
+{
+       FUNC_ENTRY;
+
+       if (gdbuam_conn) {
+               if (g_dbus_connection_is_closed(gdbuam_conn))
+                       gdbuam_conn = __uam_product_get_shared_gdbuam_conn();
+
+               FUNC_EXIT;
+               return gdbuam_conn;
+       }
+
+       gdbuam_conn = __uam_product_get_shared_gdbuam_conn();
+       FUNC_EXIT;
+       return gdbuam_conn;
+}
+
+const char *_uam_product_request_to_str(unsigned int req)
+{
+       retv_if(UAM_PRODUCT_REQUEST_MAX <= req, NULL);
+
+       return request_string[req];
+}
+
+const char *_uam_product_event_to_str(unsigned int event)
+{
+       retv_if(UAM_PRODUCT_EVENT_MAX <= event, NULL);
+
+       switch (event) {
+       CASE_TO_STR(UAM_PRODUCT_EVENT_TEST)
+       default:
+               return "UNKNOWN ERROR";
+       }
+}
diff --git a/ua-api/product/ua-event-handler-product.c b/ua-api/product/ua-event-handler-product.c
new file mode 100644 (file)
index 0000000..9b473e0
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Author: Abhay Agarwal <ay.agarwal@samsung.com>
+ *
+ * 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 "ua-common.h"
+#include "ua-api.h"
+#include "ua-internal-product.h"
+#include "ua-common-product.h"
+#include "ua-api-product.h"
+
+typedef struct {
+       guint id;
+       void *cb;
+       void *user_data;
+} uam_product_event_handler_data_t;
+
+static gboolean is_registered = FALSE;
+static uam_product_event_handler_data_t *event_handler_data = NULL;
+
+static void __uam_product_send_event(int event, int result,
+               void *data, void *callback, void *user_data)
+{
+       FUNC_ENTRY;
+       uam_product_event_data_s event_data;
+
+       UAM_INFO("Event: %s [0x%4.4X], result= %s [0x%4.4X]",
+                       _uam_product_event_to_str(event), event,
+                       _uam_error_to_str(result), result);
+
+       ret_if(NULL == callback);
+
+       memset(&event_data, 0x00, sizeof(uam_product_event_data_s));
+       event_data.result = result;
+       event_data.data = data;
+
+       ((uam_product_event_cb)callback)(event, &event_data, user_data);
+
+       FUNC_EXIT;
+}
+
+static void __uam_product_event_handler(GDBusConnection *connection,
+               const gchar *sender_name,
+               const gchar *object_path,
+               const gchar *interface_name,
+               const gchar *signal_name,
+               GVariant *parameters,
+               gpointer user_data)
+{
+       FUNC_ENTRY;
+       int result = UAM_ERROR_NONE;
+       int event = -1;
+
+       uam_product_event_handler_data_t *event_info = user_data;
+
+       ret_if(NULL == event_info);
+
+       if (0 != strcasecmp(object_path, UAM_PRODUCT_EVENT_PATH))
+               return;
+
+       if (0 != strcasecmp(interface_name, UAM_PRODUCT_EVENT_INTERFACE))
+               return;
+
+       if (0 == strcasecmp(signal_name, UAM_PRODUCT_SIGNAL_TEST)) {
+               UAM_DBG("signal received: %s", signal_name);
+
+               event = UAM_PRODUCT_EVENT_TEST;
+
+               __uam_product_send_event(event, result, NULL,
+                               event_info->cb, event_info->user_data);
+       } else {
+               UAM_WARN("Unknown signal received: %s", signal_name);
+       }
+
+       FUNC_EXIT;
+}
+
+int _uam_product_register_event_handler(uam_product_event_cb event_cb, void *user_data)
+{
+       FUNC_ENTRY;
+       GDBusConnection *conn;
+       const char *path = UAM_PRODUCT_EVENT_PATH;
+       const char *interface = UAM_PRODUCT_EVENT_INTERFACE;
+       GDBusSignalCallback event_func = __uam_product_event_handler;
+
+       retv_if(TRUE == is_registered, UAM_ERROR_ALREADY_REGISTERED);
+
+       conn = _uam_product_get_gdbuam_conn();
+       retv_if(NULL == conn, UAM_ERROR_INTERNAL);
+
+       event_handler_data = g_malloc0(sizeof(uam_product_event_handler_data_t));
+       if (event_handler_data) {
+               event_handler_data->cb = event_cb;
+               event_handler_data->user_data = user_data;
+               event_handler_data->id = g_dbus_connection_signal_subscribe(conn,
+                                               NULL, interface, NULL, path, NULL, 0,
+                                               event_func, event_handler_data, NULL);
+       } else {
+               UAM_ERR("Memory allocation error");
+               return UAM_ERROR_OUT_OF_MEMORY;
+       }
+
+       is_registered = TRUE;
+
+       FUNC_EXIT;
+       return UAM_ERROR_NONE;
+}
+
+int _uam_product_unregister_event_handler(void)
+{
+       FUNC_ENTRY;
+       GDBusConnection *conn;
+
+       retv_if(FALSE == is_registered, UAM_ERROR_NOT_REGISTERED);
+       is_registered = FALSE;
+
+       retv_if(NULL == event_handler_data, UAM_ERROR_INTERNAL);
+
+       conn = _uam_product_get_gdbuam_conn();
+       retv_if(NULL == conn, UAM_ERROR_INTERNAL);
+
+       g_dbus_connection_signal_unsubscribe(conn, event_handler_data->id);
+       memset(event_handler_data, 0, sizeof(uam_product_event_handler_data_t));
+       g_free(event_handler_data);
+       event_handler_data = NULL;
+
+       FUNC_EXIT;
+       return UAM_ERROR_NONE;
+}
diff --git a/ua-api/product/ua-request-sender-product.c b/ua-api/product/ua-request-sender-product.c
new file mode 100644 (file)
index 0000000..4a9c3d5
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Author: Abhay Agarwal <ay.agarwal@samsung.com>
+ *
+ * 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 "ua-api.h"
+#include "ua-common.h"
+#include "ua-internal-product.h"
+#include "ua-common-product.h"
+#include "ua-request-sender-product.h"
+#include "ua-event-handler-product.h"
+#include "ua-api-product.h"
+
+typedef struct {
+       int req_func;
+       void *cb;
+       void *user_data;
+} uam_product_req_info_t;
+
+static GSList *pending_requests;
+static GDBusProxy *uam_product_proxy;
+
+static GDBusProxy *__uam_product_gdbuam_init_proxy(void)
+{
+       FUNC_ENTRY;
+       GDBusConnection *conn;
+       GDBusProxy *proxy;
+       GError *err = NULL;
+
+       conn = _uam_product_get_gdbuam_conn();
+       retv_if(NULL == conn, NULL);
+
+       proxy =  g_dbus_proxy_new_sync(conn,
+                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       UAM_PRODUCT_DBUS_NAME,
+                       UAM_PRODUCT_DAEMON_PATH,
+                       UAM_PRODUCT_DBUS_NAME,
+                       NULL, &err);
+       if (!proxy) {
+               UAM_ERR("Unable to create proxy");
+               if (err) {
+                       UAM_ERR("Error: %s", err->message);
+                       g_clear_error(&err);
+               }
+
+               return NULL;
+       }
+
+       uam_product_proxy = proxy;
+       FUNC_EXIT;
+       return proxy;
+}
+
+static GDBusProxy *__uam_product_gdbuam_get_proxy(void)
+{
+       return (uam_product_proxy) ? uam_product_proxy : __uam_product_gdbuam_init_proxy();
+}
+
+void _uam_product_gdbuam_deinit_proxy(void)
+{
+       FUNC_ENTRY;
+
+       if (uam_product_proxy) {
+               g_object_unref(uam_product_proxy);
+               uam_product_proxy = NULL;
+       }
+
+       FUNC_EXIT;
+}
+
+static void __uam_product_get_event_info(int req_func, GArray *output,
+                       int *event, void **param_data)
+{
+       ret_if(event == NULL);
+
+       UAM_DBG("Request function : %s (0x%x)",
+                       _uam_product_request_to_str(req_func), req_func);
+
+       switch (req_func) {
+       default:
+               UAM_ERR("Unknown request function");
+               return;
+       }
+}
+
+static void __uam_product_fill_garray_from_variant(GVariant *var, GArray *param)
+{
+       FUNC_ENTRY;
+
+       char *data;
+       int size;
+
+       size = g_variant_get_size(var);
+       if (size > 0) {
+               data = (char *)g_variant_get_data(var);
+               if (data)
+                       g_array_append_vals(param, data, size);
+       }
+
+       FUNC_EXIT;
+}
+
+int _uam_product_sync_request(
+               int req_func,
+               GArray *in_param1,
+               GArray *in_param2,
+               GArray *in_param3,
+               GArray *in_param4,
+               GArray **out_param
+               )
+{
+       FUNC_ENTRY;
+       int result = UAM_ERROR_NONE;
+       gint timeout;
+       GDBusProxy *proxy = NULL;
+       GVariant *ret = NULL;
+       GVariant *param1 = NULL;
+       GVariant *param2 = NULL;
+       GVariant *param3 = NULL;
+       GVariant *param4 = NULL;
+
+       GVariant *input_param = NULL;
+       GVariant *result_param = NULL;
+       GError *error = NULL;
+
+       UAM_INFO_C("Request function : %s (0x%x)",
+                       _uam_product_request_to_str(req_func), req_func);
+
+       proxy = __uam_product_gdbuam_get_proxy();
+       retv_if(NULL == proxy, UAM_ERROR_INTERNAL);
+
+       param1 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param1->data, in_param1->len,
+                       TRUE, NULL, NULL);
+       param2 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param2->data, in_param2->len,
+                       TRUE, NULL, NULL);
+       param3 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param3->data, in_param3->len,
+                       TRUE, NULL, NULL);
+       param4 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param4->data, in_param4->len,
+                       TRUE, NULL, NULL);
+
+       timeout = 10000;
+
+       input_param = g_variant_new("(i@ay@ay@ay@ay)", req_func, param1,
+               param2, param3, param4);
+
+       ret = g_dbus_proxy_call_sync(proxy, "uam_product_request",
+                       input_param, G_DBUS_CALL_FLAGS_NONE, timeout,
+                       NULL, &error);
+       /*
+        * Note: params1~4 and in_params are unreferenced within the g_dbus_proxy_call_sync function.
+        *
+        * ------------------------------------------------------------------------------
+        * Call flow:
+        *  g_dbus_proxy_call_sync_internal -> g_dbus_connection_call_sync ->
+        *  g_dbus_connection_call_sync_internal -> g_dbus_message_set_body  ->
+        *  g_variant_unref(message->body);
+        * ------------------------------------------------------------------------------
+        */
+       if (!ret) {
+               UAM_ERR("dBUS-RPC failed");
+               if (error != NULL) {
+                       UAM_ERR("D-Bus API failure: errCode[%x], message[%s]",
+                                       error->code, error->message);
+                       g_clear_error(&error);
+               }
+
+               return UAM_ERROR_INTERNAL;
+       }
+
+       g_variant_get(ret, "(iv)", &result, &result_param);
+
+       if (result_param) {
+               *out_param = g_array_new(TRUE, TRUE, sizeof(gchar));
+               __uam_product_fill_garray_from_variant(result_param, *out_param);
+               g_variant_unref(result_param);
+       }
+
+       g_variant_unref(ret);
+
+       FUNC_EXIT;
+       return result;
+}
+
+static void __uam_product_async_request_cb(
+               GObject *object,
+               GAsyncResult *res,
+               gpointer user_data
+               )
+{
+       FUNC_ENTRY;
+       int event = -1;
+       int result = UAM_ERROR_NONE;
+       uam_product_event_data_s event_data;
+       uam_product_req_info_t *req_info = user_data;
+
+       GError *error = NULL;
+       GVariant *value;
+       GVariant *param1;
+       GArray *out_param = NULL;
+
+       memset(&event_data, 0x00, sizeof(uam_product_event_data_s));
+
+       value = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error);
+       if (!value) {
+               UAM_ERR("D-Bus API failed");
+               if (error) {
+                       /* dBUS gives error cause */
+                       UAM_ERR("Error: [%s]", error->message);
+                       g_clear_error(&error);
+               }
+
+               ret_if(req_info == NULL);
+
+               result = UAM_ERROR_TIMED_OUT;
+       } else {
+               g_variant_get(value, "(iv)", &result, &param1);
+               g_variant_unref(value);
+
+               if (param1) {
+                       out_param = g_array_new(TRUE, TRUE, sizeof(gchar));
+                       __uam_product_fill_garray_from_variant(param1, out_param);
+                       g_variant_unref(param1);
+               }
+
+               /* Callback should be invoked only in case of failure */
+               if (UAM_ERROR_NONE == result)
+                       goto done;
+
+               if (!req_info || !req_info->cb)
+                       goto done;
+       }
+
+       UAM_INFO("result= %s [0x%4.4X]", _uam_error_to_str(result), result);
+       event_data.result = result;
+
+       if (req_info && req_info->req_func) {
+               __uam_product_get_event_info(req_info->req_func, out_param,
+                               &event, &event_data.data);
+
+               ((uam_product_event_cb)req_info->cb)(
+                       event, &event_data, req_info->user_data);
+       }
+
+done:
+       if (out_param)
+               g_array_unref(out_param);
+
+       if (req_info) {
+               pending_requests = g_slist_remove(
+                               pending_requests, (void *)req_info);
+               g_free(req_info);
+               req_info = NULL;
+       }
+       FUNC_EXIT;
+}
+
+int _uam_product_async_request(
+               int req_func,
+               GArray *in_param1,
+               GArray *in_param2,
+               GArray *in_param3,
+               GArray *in_param4,
+               uam_product_event_cb callback,
+               void *user_data
+               )
+{
+       FUNC_ENTRY;
+       int result = UAM_ERROR_NONE;
+       uam_product_req_info_t *req_info;
+       gint timeout = -1;
+       GDBusProxy *proxy;
+       GVariant *param1 = NULL;
+       GVariant *param2 = NULL;
+       GVariant *param3 = NULL;
+       GVariant *param4 = NULL;
+       GVariant *input_param = NULL;
+
+       UAM_INFO_C("Request function : %s (0x%x)",
+                       _uam_product_request_to_str(req_func), req_func);
+
+       proxy = __uam_product_gdbuam_get_proxy();
+       retv_if(NULL == proxy, UAM_ERROR_INTERNAL);
+
+       req_info = g_malloc0(sizeof(uam_product_req_info_t));
+       if (req_info) {
+               req_info->req_func = req_func;
+               req_info->cb = callback;
+               req_info->user_data = user_data;
+       } else {
+               UAM_ERR("Memory allocation error");
+               return UAM_ERROR_OUT_OF_MEMORY;
+       }
+       param1 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param1->data, in_param1->len,
+                       TRUE, NULL, NULL);
+       param2 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param2->data, in_param2->len,
+                       TRUE, NULL, NULL);
+       param3 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param3->data, in_param3->len,
+                       TRUE, NULL, NULL);
+       param4 = g_variant_new_from_data((const GVariantType *)"ay",
+                       in_param4->data, in_param4->len,
+                       TRUE, NULL, NULL);
+
+       input_param = g_variant_new("(i@ay@ay@ay@ay)", req_func, param1,
+               param2, param3, param4);
+
+       g_dbus_proxy_call(proxy, "uam_product_request",
+                       input_param,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       timeout, NULL,
+                       __uam_product_async_request_cb, req_info);
+       /*
+        * Note: In_params is unreferenced within the g_dbus_proxy_call_sync function.
+        *
+        * ------------------------------------------------------------------------------
+        * Call flow:
+        *  g_dbus_proxy_call_sync_internal -> g_dbus_connection_call_sync ->
+        *  g_dbus_connection_call_sync_internal -> g_dbus_message_set_body  ->
+        *  g_variant_unref(message->body);
+        * ------------------------------------------------------------------------------
+        */
+
+       pending_requests = g_slist_append(pending_requests, req_info);
+
+       FUNC_EXIT;
+       return result;
+}