diff options
| -rw-r--r-- | hcid/device.c | 61 | ||||
| -rw-r--r-- | hcid/device.h | 1 | 
2 files changed, 60 insertions, 2 deletions
| diff --git a/hcid/device.c b/hcid/device.c index 76bb90d1..500a401c 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -30,6 +30,7 @@  #include <errno.h>  #include <stdlib.h>  #include <stdarg.h> +#include <unistd.h>  #include <sys/time.h>  #include <sys/stat.h>  #include <sys/ioctl.h> @@ -64,7 +65,8 @@  #include "dbus-sdp.h"  #include "sdp-xml.h" -#define MAX_DEVICES 16 +#define MAX_DEVICES		16 +#define DISCONNECT_TIMER	2  #define DEVICE_INTERFACE "org.bluez.Device" @@ -773,6 +775,9 @@ static void device_free(gpointer user_data)  	g_slist_foreach(device->uuids, (GFunc) g_free, NULL);  	g_slist_free(device->uuids); +	if (device->disconn_timer) +		g_source_remove(device->disconn_timer); +  	g_free(device->address);  	g_free(device->path);  	g_free(device); @@ -1043,10 +1048,62 @@ static DBusMessage *cancel_discover(DBusConnection *conn,  	return dbus_message_new_method_return(msg);  } +static gboolean disconnect_timeout(gpointer user_data) +{ +	struct device *device = user_data; +	struct active_conn_info *ci; +	GSList *l; +	disconnect_cp cp; +	bdaddr_t bda; +	int dd; + +	device->disconn_timer = 0; + +	str2ba(device->address, &bda); +	l = g_slist_find_custom(device->adapter->active_conn, +				&bda, active_conn_find_by_bdaddr); +	if (!l) +		return FALSE; + +	ci = l->data; +	dd = hci_open_dev(device->adapter->dev_id); +	if (dd < 0) +		goto fail; + +	memset(&cp, 0, sizeof(cp)); +	cp.handle = htobs(ci->handle); +	cp.reason = HCI_OE_USER_ENDED_CONNECTION; + +	hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT, +			DISCONNECT_CP_SIZE, &cp); + +	close(dd); + +fail: +	return FALSE; +} +  static DBusMessage *disconnect(DBusConnection *conn,  					DBusMessage *msg, void *user_data)  { -	/* FIXME disconnect device */ +	struct device *device = user_data; +	GSList *l; +	bdaddr_t bda; + +	str2ba(device->address, &bda); +	l = g_slist_find_custom(device->adapter->active_conn, +				&bda, active_conn_find_by_bdaddr); +	if (!l) +		return g_dbus_create_error(msg, +				ERROR_INTERFACE ".NotConnected", +				"Device is not connected"); + +	g_dbus_emit_signal(conn, device->path, +			DEVICE_INTERFACE, "DisconnectRequested", +			DBUS_TYPE_INVALID); + +	device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER, +						disconnect_timeout, device);  	return dbus_message_new_method_return(msg);  } diff --git a/hcid/device.h b/hcid/device.h index 88aa8aeb..a3d5c903 100644 --- a/hcid/device.h +++ b/hcid/device.h @@ -39,6 +39,7 @@ struct device {  	GSList		*drivers;  	gboolean	temporary;  	struct agent	*agent; +	guint		disconn_timer;  };  struct device *device_create(DBusConnection *conn, struct adapter *adapter, | 
