diff options
| -rw-r--r-- | input/Makefile.am | 3 | ||||
| -rw-r--r-- | input/device.c | 58 | ||||
| -rw-r--r-- | input/device.h | 15 | 
3 files changed, 55 insertions, 21 deletions
| diff --git a/input/Makefile.am b/input/Makefile.am index 958e4acc..cb56f812 100644 --- a/input/Makefile.am +++ b/input/Makefile.am @@ -12,7 +12,8 @@ service_PROGRAMS = bluetoothd-service-input  bluetoothd_service_input_SOURCES = main.c \  	manager.h manager.c \ -	server.h server.c device.h device.c storage.h storage.c +	server.h server.c device.h device.c storage.h storage.c \ +	fakehid.c fakehid.h  LDADD = $(top_builddir)/common/libhelper.a \  		@GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ diff --git a/input/device.c b/input/device.c index 9eee6e5a..46214217 100644 --- a/input/device.c +++ b/input/device.c @@ -52,6 +52,7 @@  #include "error.h"  #include "manager.h"  #include "storage.h" +#include "fakehid.h"  #define INPUT_DEVICE_INTERFACE	"org.bluez.input.Device" @@ -63,16 +64,6 @@  struct device; -struct fake_input { -	int		flags; -	GIOChannel	*io; -	int		rfcomm; /* RFCOMM socket */ -	int		uinput;	/* uinput socket */ -	uint8_t		ch;	/* RFCOMM channel number */ -	gboolean	(*connect)(struct device *idev); -	int		(*disconnect)(struct device *idev); -}; -  struct device {  	bdaddr_t		src;  	bdaddr_t		dst; @@ -1336,24 +1327,47 @@ int input_device_close_channels(bdaddr_t *src, bdaddr_t *dst)  	return 0;  } +static gboolean fake_hid_connect(struct device *dev) +{ +	struct fake_hid *fhid = dev->fake->priv; + +	return fhid->connect(dev->fake); +} + +static int fake_hid_disconnect(struct device *dev) +{ +	struct fake_hid *fhid = dev->fake->priv; + +	return fhid->disconnect(dev->fake); +} +  int input_device_connadd(bdaddr_t *src, bdaddr_t *dst)  {  	struct device *idev; +	struct fake_hid *fake_hid; +	struct fake_input *fake = NULL;  	int err;  	idev = find_device(src, dst);  	if (!idev)  		return -ENOENT; -	err = hidp_connadd(src, dst, idev->ctrl_sk, idev->intr_sk, idev->name); -	if (err < 0) { -		close(idev->ctrl_sk); -		close(idev->intr_sk); -		idev->ctrl_sk = -1; -		idev->intr_sk = -1; +	fake_hid = get_fake_hid(idev->vendor, idev->product); +	if (fake_hid) { +		fake = g_try_new0(struct fake_input, 1); +		if (!fake) { +			err = -ENOMEM; +			goto error; +		} -		return err; -	} +		fake->connect = fake_hid_connect; +		fake->disconnect = fake_hid_disconnect; +		fake->priv = fake_hid; +		err = fake_hid_connadd(fake, idev->intr_sk, fake_hid); +	} else +		err = hidp_connadd(src, dst, idev->ctrl_sk, idev->intr_sk, idev->name); +	if (err < 0) +		goto error;  	idev->intr_watch = create_watch(idev->intr_sk, intr_watch_cb, idev);  	idev->ctrl_watch = create_watch(idev->ctrl_sk, ctrl_watch_cb, idev); @@ -1363,4 +1377,12 @@ int input_device_connadd(bdaddr_t *src, bdaddr_t *dst)  			"Connected",  			DBUS_TYPE_INVALID);  	return 0; + +error: +	close(idev->ctrl_sk); +	close(idev->intr_sk); +	idev->ctrl_sk = -1; +	idev->intr_sk = -1; +	g_free(fake); +	return err;  } diff --git a/input/device.h b/input/device.h index 92ca6896..aef4a915 100644 --- a/input/device.h +++ b/input/device.h @@ -24,6 +24,19 @@  #define L2CAP_PSM_HIDP_CTRL	0x11  #define L2CAP_PSM_HIDP_INTR	0x13 +struct device; + +struct fake_input { +	int		flags; +	GIOChannel	*io; +	int		uinput;		/* uinput socket */ +	int		rfcomm;		/* RFCOMM socket */ +	uint8_t		ch;		/* RFCOMM channel number */ +	gboolean 	(*connect) (struct device *dev); +	int		(*disconnect) (struct device *dev); +	void		*priv; +}; +  int input_device_register(DBusConnection *conn, bdaddr_t *src, bdaddr_t *dst,  			struct hidp_connadd_req *hidp, const char **ppath);  int fake_input_register(DBusConnection *conn, bdaddr_t *src, @@ -33,9 +46,7 @@ int input_device_unregister(DBusConnection *conn, const char *path);  gboolean input_device_is_registered(bdaddr_t *src, bdaddr_t *dst);  int input_device_set_channel(bdaddr_t *src, bdaddr_t *dst, int psm, int nsk); -  int input_device_close_channels(bdaddr_t *src, bdaddr_t *dst); -  int input_device_connadd(bdaddr_t *src, bdaddr_t *dst);  int l2cap_connect(bdaddr_t *src, bdaddr_t *dst, | 
