diff options
author | Karol Lewandowski <k.lewandowsk@samsung.com> | 2021-06-02 18:38:50 +0200 |
---|---|---|
committer | Karol Lewandowski <k.lewandowsk@samsung.com> | 2021-06-04 12:01:46 +0200 |
commit | 0b98b4f2b50c32f9a76dc90bdf948cf5557795e0 (patch) | |
tree | 4e06b7776f0481f301d07ac8c1122a3308aa1f7e | |
parent | 4721fc8057fb0f937e94533e00804a03cbe01366 (diff) | |
download | peripheral-bus-tizen.tar.gz peripheral-bus-tizen.tar.bz2 peripheral-bus-tizen.zip |
i2c: Support private/shared clientstizen_6.5.m2_releasesubmit/tizen_6.5/20211028.162501submit/tizen/20210607.045229accepted/tizen/unified/20210607.124317accepted/tizen/6.5/unified/20211028.115421tizen_6.5tizenaccepted/tizen_unifiedaccepted/tizen_6.5_unified
Change-Id: I1d0672d682cd4dc5b69eaa80546c04a87c61285e
-rw-r--r-- | include/gdbus/peripheral_gdbus_i2c.h | 9 | ||||
-rw-r--r-- | include/handle/peripheral_handle.h | 6 | ||||
-rw-r--r-- | include/handle/peripheral_handle_i2c.h | 2 | ||||
-rw-r--r-- | packaging/peripheral-bus.spec | 2 | ||||
-rw-r--r-- | src/gdbus/peripheral_gdbus_i2c.c | 151 | ||||
-rw-r--r-- | src/gdbus/peripheral_io.xml | 8 | ||||
-rw-r--r-- | src/handle/peripheral_handle_i2c.c | 38 | ||||
-rw-r--r-- | src/peripheral_bus.c | 4 |
8 files changed, 184 insertions, 36 deletions
diff --git a/include/gdbus/peripheral_gdbus_i2c.h b/include/gdbus/peripheral_gdbus_i2c.h index 6fb3813..4c4878c 100644 --- a/include/gdbus/peripheral_gdbus_i2c.h +++ b/include/gdbus/peripheral_gdbus_i2c.h @@ -27,6 +27,15 @@ gboolean peripheral_gdbus_i2c_open( gint address, gpointer user_data); +gboolean peripheral_gdbus_i2c_open_flags( + PeripheralIoGdbusI2c *i2c, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + gint bus, + gint address, + gint flags, + gpointer user_data); + gboolean peripheral_gdbus_i2c_close( PeripheralIoGdbusI2c *i2c, GDBusMethodInvocation *invocation, diff --git a/include/handle/peripheral_handle.h b/include/handle/peripheral_handle.h index 66e1269..879c148 100644 --- a/include/handle/peripheral_handle.h +++ b/include/handle/peripheral_handle.h @@ -75,8 +75,12 @@ typedef struct { } peripheral_handle_spi_s; typedef struct { - uint watch_id; uint32_t handle_id; + uint watch_id; + + peripheral_open_flags_e open_flags; // used by i2c only for now + GList *watch_list; // ditto + GList **list; union { peripheral_handle_gpio_s gpio; diff --git a/include/handle/peripheral_handle_i2c.h b/include/handle/peripheral_handle_i2c.h index 55079e0..ae89911 100644 --- a/include/handle/peripheral_handle_i2c.h +++ b/include/handle/peripheral_handle_i2c.h @@ -17,7 +17,7 @@ #ifndef __PERIPHERAL_HANDLE_I2C_H__ #define __PERIPHERAL_HANDLE_I2C_H__ -int peripheral_handle_i2c_create(int bus, int address, peripheral_h *handle, gpointer user_data); +int peripheral_handle_i2c_create(int bus, int address, int flags, peripheral_h *handle, gpointer user_data); int peripheral_handle_i2c_destroy(peripheral_h handle); #endif /* __PERIPHERAL_HANDLE_I2C_H__ */ diff --git a/packaging/peripheral-bus.spec b/packaging/peripheral-bus.spec index 37dfc30..41afbe3 100644 --- a/packaging/peripheral-bus.spec +++ b/packaging/peripheral-bus.spec @@ -1,6 +1,6 @@ Name: peripheral-bus Summary: Tizen Peripheral Input & Output Service Daemon -Version: 0.1.4 +Version: 0.2.0 Release: 0 Group: System & System Tools License: Apache-2.0 diff --git a/src/gdbus/peripheral_gdbus_i2c.c b/src/gdbus/peripheral_gdbus_i2c.c index 7003f37..5fbe6df 100644 --- a/src/gdbus/peripheral_gdbus_i2c.c +++ b/src/gdbus/peripheral_gdbus_i2c.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <assert.h> #include <peripheral_io.h> #include <gio/gunixfdlist.h> @@ -25,20 +26,82 @@ #include "peripheral_interface_i2c.h" #include "peripheral_gdbus_i2c.h" +struct watch_data { + guint watch_id; + peripheral_h handle; + char *name; +}; + +static void __watch_remove_one(struct watch_data *watch_ptr) +{ + assert(watch_ptr); + peripheral_h i2c_handle = watch_ptr->handle; + assert(i2c_handle); + + g_bus_unwatch_name(watch_ptr->watch_id); + i2c_handle->watch_list = g_list_remove(i2c_handle->watch_list, watch_ptr); + + free(watch_ptr->name); + free(watch_ptr); +} + +static int __watch_remove(struct watch_data *watch_ptr) +{ + assert(watch_ptr); + peripheral_h i2c_handle = watch_ptr->handle; + assert(i2c_handle); + + int ret = PERIPHERAL_ERROR_NONE; + + __watch_remove_one(watch_ptr); + + if (!i2c_handle->watch_list) { + _D("Removed last referenced i2c client, dropping handle"); + + ret = peripheral_handle_i2c_destroy(i2c_handle); + if (ret != PERIPHERAL_ERROR_NONE) + _E("Failed to destroy i2c handle"); + } else + _D("Remaining %u client(s) for i2c handle remaining, keeping it for now", g_list_length(i2c_handle->watch_list)); + + return ret; +} + static void __i2c_on_name_vanished(GDBusConnection *connection, const gchar *name, gpointer user_data) { - int ret = PERIPHERAL_ERROR_NONE; - - peripheral_h i2c_handle = (peripheral_h)user_data; _D("appid [%s] vanished ", name); + (void)__watch_remove((struct watch_data *)user_data); +} + +static bool __do_watch(GDBusMethodInvocation *invocation, peripheral_h i2c_handle) +{ + assert(invocation); + assert(i2c_handle); + + char *name = strdup(g_dbus_method_invocation_get_sender(invocation)); + if (!name) + return false; - g_bus_unwatch_name(i2c_handle->watch_id); + struct watch_data *watch_ptr = malloc(sizeof(struct watch_data)); + if (!watch_ptr) { + free(name); + return false; + } + + watch_ptr->name = name; + watch_ptr->handle = i2c_handle; + watch_ptr->watch_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM, + name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, + __i2c_on_name_vanished, + watch_ptr, + NULL); + i2c_handle->watch_list = g_list_append(i2c_handle->watch_list, watch_ptr); - ret = peripheral_handle_i2c_destroy(i2c_handle); - if (ret != PERIPHERAL_ERROR_NONE) - _E("Failed to destroy i2c handle"); + return true; } gboolean peripheral_gdbus_i2c_open( @@ -68,20 +131,57 @@ gboolean peripheral_gdbus_i2c_open( goto out; } - ret = peripheral_handle_i2c_create(bus, address, &i2c_handle, user_data); + ret = peripheral_handle_i2c_create(bus, address, PERIPHERAL_OPEN_FLAGS_PRIVATE, &i2c_handle, user_data); if (ret != PERIPHERAL_ERROR_NONE) { _E("Failed to create i2c handle"); goto out; } - i2c_handle->watch_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM, - g_dbus_method_invocation_get_sender(invocation), - G_BUS_NAME_WATCHER_FLAGS_NONE, - NULL, - __i2c_on_name_vanished, - i2c_handle, - NULL); + if (!__do_watch(invocation, i2c_handle)) + goto out; +out: + peripheral_io_gdbus_i2c_complete_open(i2c, invocation, i2c_fd_list, PERIPHERAL_H_TO_ID(i2c_handle), ret); + peripheral_interface_i2c_fd_list_destroy(i2c_fd_list); + + return true; +} + +gboolean peripheral_gdbus_i2c_open_flags( + PeripheralIoGdbusI2c *i2c, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + gint bus, + gint address, + gint flags, + gpointer user_data) +{ + int ret = PERIPHERAL_ERROR_NONE; + + peripheral_info_s *info = (peripheral_info_s*)user_data; + peripheral_h i2c_handle = NULL; + GUnixFDList *i2c_fd_list = NULL; + + ret = peripheral_privilege_check(invocation, info->connection); + if (ret != 0) { + _E("Permission denied."); + ret = PERIPHERAL_ERROR_PERMISSION_DENIED; + goto out; + } + + ret = peripheral_interface_i2c_fd_list_create(bus, address, &i2c_fd_list); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("Failed to create i2c fd list"); + goto out; + } + ret = peripheral_handle_i2c_create(bus, address, flags, &i2c_handle, user_data); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("Failed to create i2c handle"); + goto out; + } + + if (!__do_watch(invocation, i2c_handle)) + goto out; out: peripheral_io_gdbus_i2c_complete_open(i2c, invocation, i2c_fd_list, PERIPHERAL_H_TO_ID(i2c_handle), ret); peripheral_interface_i2c_fd_list_destroy(i2c_fd_list); @@ -105,12 +205,21 @@ gboolean peripheral_gdbus_i2c_close( goto out; } - g_bus_unwatch_name(i2c_handle->watch_id); - - ret = peripheral_handle_i2c_destroy(i2c_handle); - if (ret != PERIPHERAL_ERROR_NONE) - _E("Failed to destroy i2c handle"); - + const char *name = g_dbus_method_invocation_get_sender(invocation); + struct watch_data *found = NULL; + for (GList *list = i2c_handle->watch_list; list; list = g_list_next(list)) { + struct watch_data *ptr = (struct watch_data *)list->data; + if (!strcmp(name, ptr->name)) { + found = ptr; + break; + } + } + if (found) + ret = __watch_remove(found); + else { + ret = PERIPHERAL_ERROR_INVALID_PARAMETER; + _E("i2c close called but referenced client not found"); + } out: peripheral_io_gdbus_i2c_complete_close(i2c, invocation, ret); diff --git a/src/gdbus/peripheral_io.xml b/src/gdbus/peripheral_io.xml index db72361..c868cdf 100644 --- a/src/gdbus/peripheral_io.xml +++ b/src/gdbus/peripheral_io.xml @@ -20,6 +20,14 @@ <arg type="u" name="handle" direction="out"/> <arg type="i" name="result" direction="out"/> </method> + <method name="OpenFlags"> + <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/> + <arg type="i" name="bus" direction="in"/> + <arg type="i" name="address" direction="in"/> + <arg type="i" name="flags" direction="in"/> + <arg type="u" name="handle" direction="out"/> + <arg type="i" name="result" direction="out"/> + </method> <method name="Close"> <arg type="u" name="handle" direction="in"/> <arg type="i" name="result" direction="out"/> diff --git a/src/handle/peripheral_handle_i2c.c b/src/handle/peripheral_handle_i2c.c index 8bce082..9c2a8ea 100644 --- a/src/handle/peripheral_handle_i2c.c +++ b/src/handle/peripheral_handle_i2c.c @@ -15,8 +15,9 @@ */ #include "peripheral_handle.h" +#include "peripheral_io.h" -static bool __peripheral_handle_i2c_is_creatable(int bus, int address, peripheral_info_s *info) +static bool __peripheral_handle_i2c_is_creatable(int bus, int address, peripheral_info_s *info, int flags, peripheral_h *out_handle) { pb_board_dev_s *i2c = NULL; peripheral_h handle; @@ -35,8 +36,13 @@ static bool __peripheral_handle_i2c_is_creatable(int bus, int address, periphera while (link) { handle = (peripheral_h)link->data; if (handle->type.i2c.bus == bus && handle->type.i2c.address == address) { - _E("Resource is in use, bus : %d, address : %d", bus, address); - return false; + if (handle->open_flags != PERIPHERAL_OPEN_FLAGS_SHARED || flags != PERIPHERAL_OPEN_FLAGS_SHARED) { + _E("Resource is in use, bus : %d, address : %d", bus, address); + return false; + } else { + *out_handle = handle; + return true; + } } link = g_list_next(link); } @@ -57,7 +63,7 @@ int peripheral_handle_i2c_destroy(peripheral_h handle) return ret; } -int peripheral_handle_i2c_create(int bus, int address, peripheral_h *handle, gpointer user_data) +int peripheral_handle_i2c_create(int bus, int address, int flags, peripheral_h *handle, gpointer user_data) { RETVM_IF(bus < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid i2c bus"); RETVM_IF(address < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid i2c address"); @@ -65,25 +71,33 @@ int peripheral_handle_i2c_create(int bus, int address, peripheral_h *handle, gpo peripheral_info_s *info = (peripheral_info_s*)user_data; + if (flags != PERIPHERAL_OPEN_FLAGS_PRIVATE && flags != PERIPHERAL_OPEN_FLAGS_SHARED) { + _E("Invalid open flags passed"); + return false; + } + peripheral_h i2c_handle = NULL; bool is_handle_creatable = false; - is_handle_creatable = __peripheral_handle_i2c_is_creatable(bus, address, info); + is_handle_creatable = __peripheral_handle_i2c_is_creatable(bus, address, info, flags, &i2c_handle); if (is_handle_creatable == false) { _E("bus : %d, address : 0x%x is not available", bus, address); return PERIPHERAL_ERROR_RESOURCE_BUSY; } - i2c_handle = peripheral_handle_new(&info->i2c_list); if (i2c_handle == NULL) { - _E("peripheral_handle_new error"); - return PERIPHERAL_ERROR_OUT_OF_MEMORY; + i2c_handle = peripheral_handle_new(&info->i2c_list); + if (i2c_handle == NULL) { + _E("peripheral_handle_new error"); + return PERIPHERAL_ERROR_OUT_OF_MEMORY; + } + i2c_handle->list = &info->i2c_list; + i2c_handle->type.i2c.bus = bus; + i2c_handle->type.i2c.address = address; + i2c_handle->open_flags = flags; + i2c_handle->watch_list = NULL; } - i2c_handle->list = &info->i2c_list; - i2c_handle->type.i2c.bus = bus; - i2c_handle->type.i2c.address = address; - *handle = i2c_handle; return PERIPHERAL_ERROR_NONE; diff --git a/src/peripheral_bus.c b/src/peripheral_bus.c index 53a6379..8392421 100644 --- a/src/peripheral_bus.c +++ b/src/peripheral_bus.c @@ -90,6 +90,10 @@ static gboolean __i2c_init(peripheral_info_s *info) G_CALLBACK(peripheral_gdbus_i2c_open), info); g_signal_connect(info->i2c_skeleton, + "handle-open-flags", + G_CALLBACK(peripheral_gdbus_i2c_open_flags), + info); + g_signal_connect(info->i2c_skeleton, "handle-close", G_CALLBACK(peripheral_gdbus_i2c_close), info); |