Add information about GPIO pin value in callback. 67/255967/5 accepted/tizen/unified/20210413.021248 submit/tizen/20210412.185901
authorErnest Borowski <e.borowski@samsung.com>
Thu, 25 Mar 2021 16:16:35 +0000 (16:16 +0000)
committerErnest Borowski <e.borowski@samsung.com>
Thu, 8 Apr 2021 10:30:02 +0000 (10:30 +0000)
Change-Id: Ibc6ddc9c094b488236706cf2b9455c251b60f3ce
Signed-off-by: Ernest Borowski <e.borowski@samsung.com>
include/peripheral_handle.h
src/interface/peripheral_interface_gpio.c
src/peripheral_gpio.c

index 9023b4e..b3ca528 100644 (file)
 #define __PERIPHERAL_HANDLE_H__
 
 #include <gio/gio.h>
+#include "peripheral_io.h"
 
 typedef struct _peripheral_gpio_interrupted_cb_info_s {
+       // vermagic value is used to verify structure inside csapi
+       // do not move it and value field to different place inside structure
+       // otherwise update csapi accordingly
+       int vermagic;
+       int value;
        GThread *thread;
        peripheral_gpio_interrupted_cb cb;
        peripheral_error_e error;
@@ -31,13 +37,17 @@ typedef struct _peripheral_gpio_interrupted_cb_info_s {
  * @brief Internal struct for gpio context
  */
 struct _peripheral_gpio_s {
+       // vermagic value is used to verify structure inside csapi
+       // do not move it and callback info field to different place inside structure
+       // otherwise update csapi accordingly
+       int vermagic;
+       interrupted_cb_info_s cb_info;
        uint handle;
        int fd_direction;
        int fd_edge;
        int fd_value;
        peripheral_gpio_direction_e direction;
        peripheral_gpio_edge_e edge;
-       interrupted_cb_info_s cb_info;
 };
 
 /**
index ce9be7f..f4765f7 100644 (file)
@@ -15,6 +15,8 @@
  */
 
 #include <poll.h>
+#include <string.h>
+#include "peripheral_handle.h"
 #include "peripheral_interface_gpio.h"
 
 #define GPIO_INTERRUPTED_CALLBACK_UNSET 0
@@ -196,6 +198,8 @@ static gboolean __peripheral_interface_gpio_interrupted_cb_invoke(gpointer data)
 {
        peripheral_gpio_h gpio = (peripheral_gpio_h)data;
        gpio->cb_info.cb(gpio, gpio->cb_info.error, gpio->cb_info.user_data);
+       free(gpio);
+       gpio = NULL;
        return FALSE;
 }
 
@@ -244,7 +248,17 @@ static gpointer __peripheral_interface_gpio_poll(void *data)
                        continue;
 
                gpio->cb_info.error = PERIPHERAL_ERROR_NONE;
-               g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_interface_gpio_interrupted_cb_invoke, gpio, NULL);
+               gpio->cb_info.value = value;
+
+               // copy structure for callback to prevent race condition
+               // otherwise e.g. gpio pin value could be changed during callback call
+               peripheral_gpio_h gpio_copy = (peripheral_gpio_h)calloc(1, sizeof(struct _peripheral_gpio_s));
+               if (gpio_copy == NULL) {
+                       _E("memory allocation for callback failed.");
+                       continue;
+               }
+               memcpy(gpio_copy, gpio, sizeof(struct _peripheral_gpio_s));
+               g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_interface_gpio_interrupted_cb_invoke, gpio_copy, NULL);
        }
 
        return NULL;
index addadc9..c75f911 100644 (file)
@@ -28,6 +28,8 @@
 #define GPIO_FEATURE_UNKNOWN -1
 #define GPIO_FEATURE_FALSE    0
 #define GPIO_FEATURE_TRUE     1
+#define GPIO_STRUCTURE_VERMAGIC 13712
+#define GPIO_CALLBACK_STRUCTURE_VERMAGIC 14469
 
 static int gpio_feature = GPIO_FEATURE_UNKNOWN;
 
@@ -63,6 +65,9 @@ int peripheral_gpio_open(int gpio_pin, peripheral_gpio_h *gpio)
                _E("Failed to allocate peripheral_gpio_h");
                return PERIPHERAL_ERROR_OUT_OF_MEMORY;
        }
+       // set gpio_s_vermagic and callback vermagic so csapi can verify structure
+       handle->vermagic = GPIO_STRUCTURE_VERMAGIC;
+       handle->cb_info.vermagic = GPIO_CALLBACK_STRUCTURE_VERMAGIC;
 
        ret = peripheral_gdbus_gpio_open(handle, gpio_pin);
        if (ret != PERIPHERAL_ERROR_NONE) {