#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;
* @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;
};
/**
*/
#include <poll.h>
+#include <string.h>
+#include "peripheral_handle.h"
#include "peripheral_interface_gpio.h"
#define GPIO_INTERRUPTED_CALLBACK_UNSET 0
{
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;
}
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;
#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;
_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) {