- The gpio methods will pass handle instead of device informations.
- Add gpio routines to handle exceptional case of client close
Change-Id: I000f59f658f8b8f7c2e439b9181a1437732b7936
Signed-off-by: Sungguk Na <sungguk.na@samsung.com>
#include "peripheral_common.h"
#include "peripheral_bus_util.h"
+static void __gpio_on_name_vanished(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ pb_gpio_data_h gpio_handle = (pb_gpio_data_h)user_data;
+ _D("appid [%s] vanished ", name);
+
+ g_bus_unwatch_name(gpio_handle->watch_id);
+ peripheral_bus_gpio_close(gpio_handle);
+}
+
static void __i2c_on_name_vanished(GDBusConnection *connection,
const gchar *name,
gpointer user_data)
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
- gint edge;
- gint direction;
+ peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+ pb_gpio_data_h gpio_handle;
- ret = peripheral_bus_gpio_open(pin, &edge, &direction, user_data);
- peripheral_io_gdbus_gpio_complete_open(gpio, invocation, edge, direction, ret);
+ ret = peripheral_bus_gpio_open(pin, &gpio_handle, user_data);
+
+ if (ret == PERIPHERAL_ERROR_NONE) {
+ if (peripheral_bus_get_client_info(invocation, pb_data, &gpio_handle->client_info) == 0)
+ _D("gpio : %d, id = %s", gpio_handle->pin, gpio_handle->client_info.id);
+ else
+ ret = PERIPHERAL_ERROR_UNKNOWN;
+ }
+
+ gpio_handle->watch_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM ,
+ gpio_handle->client_info.id,
+ G_BUS_NAME_WATCHER_FLAGS_NONE ,
+ NULL,
+ __gpio_on_name_vanished,
+ gpio_handle,
+ NULL);
+
+ peripheral_io_gdbus_gpio_complete_open(gpio, invocation, GPOINTER_TO_UINT(gpio_handle), ret);
return true;
}
gboolean handle_gpio_close(
PeripheralIoGdbusGpio *gpio,
GDBusMethodInvocation *invocation,
- gint pin,
+ gint handle,
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_gpio_data_h gpio_handle = GUINT_TO_POINTER(handle);
+ const gchar *id;
+
+ /* Handle validation */
+ if (!gpio_handle || !gpio_handle->client_info.id) {
+ _E("gpio handle is not valid");
+ ret = PERIPHERAL_ERROR_UNKNOWN;
+ goto out;
+ }
- ret = peripheral_bus_gpio_close(pin, user_data);
+ id = g_dbus_method_invocation_get_sender(invocation);
+ if (strcmp(gpio_handle->client_info.id, id)) {
+ _E("Invalid access, handle id : %s, current id : %s", gpio_handle->client_info.id, id);
+ ret = PERIPHERAL_ERROR_INVALID_OPERATION;
+ goto out;
+ }
+
+ g_bus_unwatch_name(gpio_handle->watch_id);
+ ret = peripheral_bus_gpio_close(gpio_handle);
+out:
peripheral_io_gdbus_gpio_complete_close(gpio, invocation, ret);
return true;
gboolean handle_gpio_get_direction(
PeripheralIoGdbusGpio *gpio,
GDBusMethodInvocation *invocation,
- gint pin,
+ gint handle,
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_gpio_data_h gpio_handle = GUINT_TO_POINTER(handle);
gint direction;
- ret = peripheral_bus_gpio_get_direction(pin, &direction, user_data);
+ ret = peripheral_bus_gpio_get_direction(gpio_handle, &direction);
peripheral_io_gdbus_gpio_complete_get_direction(gpio, invocation, direction, ret);
return true;
gboolean handle_gpio_set_direction(
PeripheralIoGdbusGpio *gpio,
GDBusMethodInvocation *invocation,
- gint pin,
+ gint handle,
gint direction,
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_gpio_data_h gpio_handle = GUINT_TO_POINTER(handle);
- ret = peripheral_bus_gpio_set_direction(pin, direction, user_data);
+ ret = peripheral_bus_gpio_set_direction(gpio_handle, direction);
peripheral_io_gdbus_gpio_complete_set_direction(gpio, invocation, ret);
return true;
gboolean handle_gpio_read(
PeripheralIoGdbusGpio *gpio,
GDBusMethodInvocation *invocation,
- gint pin,
+ gint handle,
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_gpio_data_h gpio_handle = GUINT_TO_POINTER(handle);
gint read_value = 0;
- ret = peripheral_bus_gpio_read(pin, &read_value, user_data);
+ ret = peripheral_bus_gpio_read(gpio_handle, &read_value);
peripheral_io_gdbus_gpio_complete_read(gpio, invocation, read_value, ret);
return true;
gboolean handle_gpio_write(
PeripheralIoGdbusGpio *gpio,
GDBusMethodInvocation *invocation,
- gint pin,
+ gint handle,
gint value,
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_gpio_data_h gpio_handle = GUINT_TO_POINTER(handle);
- ret = peripheral_bus_gpio_write(pin, value, user_data);
+ ret = peripheral_bus_gpio_write(gpio_handle, value);
peripheral_io_gdbus_gpio_complete_write(gpio, invocation, ret);
return true;
gboolean handle_gpio_get_edge_mode(
PeripheralIoGdbusGpio *gpio,
GDBusMethodInvocation *invocation,
- gint pin,
+ gint handle,
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_gpio_data_h gpio_handle = GUINT_TO_POINTER(handle);
gint edge;
- ret = peripheral_bus_gpio_get_edge(pin, &edge, user_data);
+ ret = peripheral_bus_gpio_get_edge(gpio_handle, &edge);
peripheral_io_gdbus_gpio_complete_get_edge_mode(gpio, invocation, edge, ret);
return true;
gboolean handle_gpio_set_edge_mode(
PeripheralIoGdbusGpio *gpio,
GDBusMethodInvocation *invocation,
- gint pin,
+ gint handle,
gint edge,
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_gpio_data_h gpio_handle = GUINT_TO_POINTER(handle);
- ret = peripheral_bus_gpio_set_edge(pin, edge, user_data);
+ ret = peripheral_bus_gpio_set_edge(gpio_handle, edge);
peripheral_io_gdbus_gpio_complete_set_edge_mode(gpio, invocation, ret);
return true;
gboolean handle_gpio_register_irq(
PeripheralIoGdbusGpio *gpio,
GDBusMethodInvocation *invocation,
- gint pin,
+ gint handle,
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_gpio_data_h gpio_handle = GUINT_TO_POINTER(handle);
- ret = peripheral_bus_gpio_register_irq(pin, user_data);
+ ret = peripheral_bus_gpio_register_irq(gpio_handle);
peripheral_io_gdbus_gpio_complete_register_irq(gpio, invocation, ret);
return true;
gboolean handle_gpio_unregister_irq(
PeripheralIoGdbusGpio *gpio,
GDBusMethodInvocation *invocation,
- gint pin,
+ gint handle,
gpointer user_data)
{
peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_gpio_data_h gpio_handle = GUINT_TO_POINTER(handle);
- ret = peripheral_bus_gpio_unregister_irq(pin, user_data);
+ ret = peripheral_bus_gpio_unregister_irq(gpio_handle);
peripheral_io_gdbus_gpio_complete_unregister_irq(gpio, invocation, ret);
return true;
int value_fd;
GIOChannel *io;
guint io_id;
+ uint watch_id;
+ GList **list;
+ /* client info */
+ pb_client_info_s client_info;
/* gdbus variable */
PeripheralIoGdbusGpio *gpio_skeleton;
} peripheral_bus_gpio_data_s;
return NULL;
}
-static pb_gpio_data_h peripheral_bus_gpio_data_new(int pin, GList **list)
+static pb_gpio_data_h peripheral_bus_gpio_data_new(GList **list)
{
GList *gpio_list = *list;
pb_gpio_data_h gpio_data;
*list = g_list_append(gpio_list, gpio_data);
- gpio_data->pin = pin;
-
return gpio_data;
}
-static void peripheral_bus_gpio_data_free(int pin, GList **list)
+static int peripheral_bus_gpio_data_free(pb_gpio_data_h gpio_handle, GList **gpio_list)
{
- GList *gpio_list = *list;
GList *link;
- pb_gpio_data_h gpio_data;
- if (gpio_list == NULL)
- return;
-
- link = gpio_list;
- while (link) {
- gpio_data = (pb_gpio_data_h)link->data;
+ RETVM_IF(gpio_handle == NULL, -1, "handle is null");
- if (gpio_data->pin == pin) {
- *list = g_list_remove_link(gpio_list, link);
- free(link->data);
- g_list_free(link);
- return;
- }
- link = g_list_next(link);
+ link = g_list_find(*gpio_list, gpio_handle);
+ if (!link) {
+ _E("handle does not exist in list");
+ return -1;
}
+
+ *gpio_list = g_list_remove_link(*gpio_list, link);
+ free(gpio_handle);
+ g_list_free(link);
+
+ return 0;
}
-int peripheral_bus_gpio_open(gint pin, gint *edge, gint *direction, gpointer user_data)
+int peripheral_bus_gpio_open(gint pin, pb_gpio_data_h *gpio, gpointer user_data)
{
peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
- pb_gpio_data_h gpio;
+ pb_gpio_data_h gpio_handle;
+ int edge, direction;
int ret;
- gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
- if (gpio) {
+ gpio_handle = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
+ if (gpio_handle) {
_E("gpio %d is busy", pin);
return PERIPHERAL_ERROR_RESOURCE_BUSY;
}
goto open_err;
}
- if ((ret = gpio_get_edge_mode(pin, (gpio_edge_e*)edge)) < 0) {
+ if ((ret = gpio_get_edge_mode(pin, (gpio_edge_e*)&edge)) < 0) {
_E("gpio_get_edge_mode error (%d)", ret);
goto err;
}
- if ((ret = gpio_get_direction(pin, (gpio_direction_e*)direction)) < 0) {
+ if ((ret = gpio_get_direction(pin, (gpio_direction_e*)&direction)) < 0) {
_E("gpio_get_direction error (%d)", ret);
goto err;
}
- gpio = peripheral_bus_gpio_data_new(pin, &pb_data->gpio_list);
- if (!gpio) {
+ gpio_handle = peripheral_bus_gpio_data_new(&pb_data->gpio_list);
+ if (!gpio_handle) {
_E("peripheral_bus_gpio_data_new error");
ret = PERIPHERAL_ERROR_UNKNOWN;
goto err;
}
- gpio->pin = pin;
- gpio->edge = *edge;
- gpio->direction = *direction;
- gpio->gpio_skeleton = pb_data->gpio_skeleton;
+ gpio_handle->pin = pin;
+ gpio_handle->edge = edge;
+ gpio_handle->direction = direction;
+ gpio_handle->list = &pb_data->gpio_list;
+ gpio_handle->gpio_skeleton = pb_data->gpio_skeleton;
+
+ *gpio = gpio_handle;
return PERIPHERAL_ERROR_NONE;
return ret;
}
-int peripheral_bus_gpio_set_direction(gint pin, gint direction, gpointer user_data)
+int peripheral_bus_gpio_set_direction(pb_gpio_data_h gpio, gint direction)
{
- peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
- pb_gpio_data_h gpio;
int ret;
- gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
- if (!gpio) {
- _E("peripheral_bus_gpio_data_get error");
- return PERIPHERAL_ERROR_UNKNOWN;
- }
-
gpio->direction = direction;
- if ((ret = gpio_set_direction(pin, (gpio_direction_e)direction)) < 0) {
+ if ((ret = gpio_set_direction(gpio->pin, (gpio_direction_e)direction)) < 0) {
_E("gpio_set_direction error (%d)", ret);
return ret;
}
return PERIPHERAL_ERROR_NONE;
}
-int peripheral_bus_gpio_get_direction(gint pin, gint *direction, gpointer user_data)
+int peripheral_bus_gpio_get_direction(pb_gpio_data_h gpio, gint *direction)
{
- peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
- pb_gpio_data_h gpio;
gint value;
int ret;
- gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
- if (!gpio) {
- _E("peripheral_bus_gpio_data_get error");
- return PERIPHERAL_ERROR_UNKNOWN;
- }
-
- if ((ret = gpio_get_direction(pin, (gpio_direction_e*)direction)) < 0) {
+ if ((ret = gpio_get_direction(gpio->pin, (gpio_direction_e*)direction)) < 0) {
_E("gpio_get_direction error (%d)", ret);
return ret;
}
if (*direction == GPIO_DIRECTION_OUT) {
- if ((ret = gpio_read(pin, &value)) < 0)
+ if ((ret = gpio_read(gpio->pin, &value)) < 0)
return ret;
/* Update direction state with the current value */
*direction = GPIO_DIRECTION_OUT + value;
- gpio->direction = *direction;
}
+ gpio->direction = *direction;
+
return PERIPHERAL_ERROR_NONE;
}
-int peripheral_bus_gpio_set_edge(gint pin, gint edge, gpointer user_data)
+int peripheral_bus_gpio_set_edge(pb_gpio_data_h gpio, gint edge)
{
- peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
- pb_gpio_data_h gpio;
int ret;
- gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
- if (!gpio) {
- _E("peripheral_bus_gpio_data_get error");
- return PERIPHERAL_ERROR_UNKNOWN;
- }
-
- gpio->edge = edge;
-
- if ((ret = gpio_set_edge_mode(pin, (gpio_edge_e)edge)) < 0) {
+ if ((ret = gpio_set_edge_mode(gpio->pin, (gpio_edge_e)edge)) < 0) {
_E("gpio_set_edge_mode error (%d)", ret);
return ret;
}
+ gpio->edge = edge;
+
return PERIPHERAL_ERROR_NONE;
}
-int peripheral_bus_gpio_get_edge(gint pin, gint *edge, gpointer user_data)
+int peripheral_bus_gpio_get_edge(pb_gpio_data_h gpio, gint *edge)
{
- peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
- pb_gpio_data_h gpio;
int ret;
- gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
- if (!gpio) {
- _E("peripheral_bus_gpio_data_get error");
- return PERIPHERAL_ERROR_UNKNOWN;
- }
-
- if ((ret = gpio_get_edge_mode(pin, (gpio_edge_e*)edge)) < 0) {
+ if ((ret = gpio_get_edge_mode(gpio->pin, (gpio_edge_e*)edge)) < 0) {
_E("gpio_get_edge_mode error (%d)", ret);
return ret;
}
return PERIPHERAL_ERROR_NONE;
}
-int peripheral_bus_gpio_write(gint pin, gint value, gpointer user_data)
+int peripheral_bus_gpio_write(pb_gpio_data_h gpio, gint value)
{
- peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
- pb_gpio_data_h gpio;
int ret;
- gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
- if (!gpio) {
- _E("peripheral_bus_gpio_data_get error");
- return PERIPHERAL_ERROR_UNKNOWN;
- }
-
/* Return error if direction is input mode */
if (gpio->direction == GPIO_DIRECTION_IN)
return PERIPHERAL_ERROR_IO_ERROR;
- if ((ret = gpio_write(pin, value)) < 0) {
+ if ((ret = gpio_write(gpio->pin, value)) < 0) {
_E("gpio_write error (%d)", ret);
return ret;
}
return PERIPHERAL_ERROR_NONE;
}
-int peripheral_bus_gpio_read(gint pin, gint *value, gpointer user_data)
+int peripheral_bus_gpio_read(pb_gpio_data_h gpio, gint *value)
{
- peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
- pb_gpio_data_h gpio;
int ret;
- gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
- if (!gpio) {
- _E("peripheral_bus_gpio_data_get error");
- return PERIPHERAL_ERROR_UNKNOWN;
- }
-
- if ((ret = gpio_read(pin, value)) < 0) {
+ if ((ret = gpio_read(gpio->pin, value)) < 0) {
_E("gpio_read error (%d)", ret);
return ret;
}
return TRUE;
}
-int peripheral_bus_gpio_register_irq(gint pin, gpointer user_data)
+int peripheral_bus_gpio_register_irq(pb_gpio_data_h gpio)
{
- peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
- pb_gpio_data_h gpio;
GIOStatus status;
gchar* strval;
- gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
- if (!gpio) {
- _E("peripheral_bus_gpio_data_get error");
- return PERIPHERAL_ERROR_UNKNOWN;
- }
-
- if ((gpio->value_fd = gpio_open_isr(pin)) < 0)
+ if ((gpio->value_fd = gpio_open_isr(gpio->pin)) < 0)
goto err_open_isr;
gpio->io = g_io_channel_unix_new(gpio->value_fd);
return PERIPHERAL_ERROR_UNKNOWN;
}
-int peripheral_bus_gpio_unregister_irq(gint pin, gpointer user_data)
+int peripheral_bus_gpio_unregister_irq(pb_gpio_data_h gpio)
{
- peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
- pb_gpio_data_h gpio;
-
- gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
- if (!gpio) {
- _E("peripheral_bus_gpio_data_get error");
- return PERIPHERAL_ERROR_UNKNOWN;
- }
-
if (gpio->io) {
gpio->irq_en = 0;
g_source_remove(gpio->io_id);
return PERIPHERAL_ERROR_NONE;
}
-int peripheral_bus_gpio_close(gint pin, gpointer user_data)
+int peripheral_bus_gpio_close(pb_gpio_data_h gpio)
{
- peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
int ret;
+ int pin = gpio->pin;
- peripheral_bus_gpio_data_free(pin, &pb_data->gpio_list);
+ if (peripheral_bus_gpio_data_free(gpio, gpio->list) < 0)
+ _E("Failed to free gpio data");
if ((ret = gpio_close(pin)) < 0) {
_E("gpio_close error (%d)", ret);
#ifndef __PERIPHERAL_BUS_GPIO_H__
#define __PERIPHERAL_BUS_GPIO_H__
-int peripheral_bus_gpio_open(gint pin, gint *edge, gint *direction, gpointer user_data);
-int peripheral_bus_gpio_set_direction(gint pin, gint direction, gpointer user_data);
-int peripheral_bus_gpio_get_direction(gint pin, gint *direction, gpointer user_data);
-int peripheral_bus_gpio_set_edge(gint pin, gint edge, gpointer user_data);
-int peripheral_bus_gpio_get_edge(gint pin, gint *edge, gpointer user_data);
-int peripheral_bus_gpio_write(gint pin, gint value, gpointer user_data);
-int peripheral_bus_gpio_read(gint pin, gint *value, gpointer user_data);
-int peripheral_bus_gpio_register_irq(gint pin, gpointer user_data);
-int peripheral_bus_gpio_unregister_irq(gint pin, gpointer user_data);
-int peripheral_bus_gpio_close(gint pin, gpointer user_data);
+int peripheral_bus_gpio_open(gint pin, pb_gpio_data_h *gpio, gpointer user_data);
+int peripheral_bus_gpio_set_direction(pb_gpio_data_h gpio, gint direction);
+int peripheral_bus_gpio_get_direction(pb_gpio_data_h gpio, gint *direction);
+int peripheral_bus_gpio_set_edge(pb_gpio_data_h gpio, gint edge);
+int peripheral_bus_gpio_get_edge(pb_gpio_data_h gpio, gint *edge);
+int peripheral_bus_gpio_write(pb_gpio_data_h gpio, gint value);
+int peripheral_bus_gpio_read(pb_gpio_data_h gpio, gint *value);
+int peripheral_bus_gpio_register_irq(pb_gpio_data_h gpio);
+int peripheral_bus_gpio_unregister_irq(pb_gpio_data_h gpio);
+int peripheral_bus_gpio_close(pb_gpio_data_h gpio);
#endif /* __PERIPHERAL_BUS_GPIO_H__ */
<interface name="org.tizen.peripheral_io.gpio">
<method name="Open">
<arg type="i" name="pin" direction="in"/>
- <arg type="i" name="edge" direction="out"/>
- <arg type="i" name="direction" direction="out"/>
+ <arg type="u" name="handle" direction="out"/>
<arg type="i" name="result" direction="out"/>
</method>
<method name="Close">
- <arg type="i" name="pin" direction="in"/>
+ <arg type="u" name="handle" direction="in"/>
<arg type="i" name="result" direction="out"/>
</method>
<method name="GetDirection">
- <arg type="i" name="pin" direction="in"/>
+ <arg type="u" name="handle" direction="in"/>
<arg type="i" name="direction" direction="out"/>
<arg type="i" name="result" direction="out"/>
</method>
<method name="SetDirection">
- <arg type="i" name="pin" direction="in"/>
+ <arg type="u" name="handle" direction="in"/>
<arg type="i" name="direction" direction="in"/>
<arg type="i" name="result" direction="out"/>
</method>
<method name="Read">
- <arg type="i" name="pin" direction="in"/>
+ <arg type="u" name="handle" direction="in"/>
<arg type="i" name="value" direction="out"/>
<arg type="i" name="result" direction="out"/>
</method>
<method name="Write">
- <arg type="i" name="pin" direction="in"/>
+ <arg type="u" name="handle" direction="in"/>
<arg type="i" name="value" direction="in"/>
<arg type="i" name="result" direction="out"/>
</method>
<method name="GetEdgeMode">
- <arg type="i" name="pin" direction="in"/>
+ <arg type="u" name="handle" direction="in"/>
<arg type="i" name="edge" direction="out"/>
<arg type="i" name="result" direction="out"/>
</method>
<method name="SetEdgeMode">
- <arg type="i" name="pin" direction="in"/>
+ <arg type="u" name="handle" direction="in"/>
<arg type="i" name="edge" direction="in"/>
<arg type="i" name="result" direction="out"/>
</method>
<method name="RegisterIrq">
- <arg type="i" name="pin" direction="in"/>
+ <arg type="u" name="handle" direction="in"/>
<arg type="i" name="result" direction="out"/>
</method>
<method name="UnregisterIrq">
- <arg type="i" name="pin" direction="in"/>
+ <arg type="u" name="handle" direction="in"/>
<arg type="i" name="result" direction="out"/>
</method>
<signal name='GpioChanged'>