diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2012-09-10 15:51:23 +0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-09-11 11:29:58 +0300 |
commit | 2e16cbf32569d834750f47107ee9c19954dd28bf (patch) | |
tree | 7e495a90fb65a49c8a7ac5f79232f6a3e2967fdf /profiles | |
parent | 96f60e1411514fb4b0d8690aca1c02b3c6b32b9c (diff) |
input: Remove fakhid functionality
The HSP code conflicts with a real HSP implementation and the PS3
support should be done through the kernel.
Diffstat (limited to 'profiles')
-rw-r--r-- | profiles/input/device.c | 361 | ||||
-rw-r--r-- | profiles/input/device.h | 16 | ||||
-rw-r--r-- | profiles/input/fakehid.c | 448 | ||||
-rw-r--r-- | profiles/input/fakehid.h | 40 | ||||
-rw-r--r-- | profiles/input/manager.c | 46 |
5 files changed, 12 insertions, 899 deletions
diff --git a/profiles/input/device.c b/profiles/input/device.c index c42f137e..f1885040 100644 --- a/profiles/input/device.c +++ b/profiles/input/device.c @@ -50,7 +50,6 @@ #include "device.h" #include "error.h" -#include "fakehid.h" #include "btio.h" #include "sdp-client.h" @@ -64,7 +63,6 @@ #define FI_FLAG_CONNECTED 1 struct input_conn { - struct fake_input *fake; DBusMessage *pending_connect; char *uuid; GIOChannel *ctrl_io; @@ -137,7 +135,6 @@ static void input_conn_free(struct input_conn *iconn) g_io_channel_unref(iconn->ctrl_io); g_free(iconn->uuid); - g_free(iconn->fake); g_free(iconn); } @@ -153,231 +150,6 @@ static void input_device_free(struct input_device *idev) g_free(idev); } -static int uinput_create(char *name) -{ - struct uinput_dev dev; - int fd, err; - - fd = open("/dev/uinput", O_RDWR); - if (fd < 0) { - fd = open("/dev/input/uinput", O_RDWR); - if (fd < 0) { - fd = open("/dev/misc/uinput", O_RDWR); - if (fd < 0) { - err = -errno; - error("Can't open input device: %s (%d)", - strerror(-err), -err); - return err; - } - } - } - - memset(&dev, 0, sizeof(dev)); - if (name) - strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE - 1); - - dev.id.bustype = BUS_BLUETOOTH; - dev.id.vendor = 0x0000; - dev.id.product = 0x0000; - dev.id.version = 0x0000; - - if (write(fd, &dev, sizeof(dev)) < 0) { - err = -errno; - error("Can't write device information: %s (%d)", - strerror(-err), -err); - close(fd); - return err; - } - - ioctl(fd, UI_SET_EVBIT, EV_KEY); - ioctl(fd, UI_SET_EVBIT, EV_REL); - ioctl(fd, UI_SET_EVBIT, EV_REP); - - ioctl(fd, UI_SET_KEYBIT, KEY_UP); - ioctl(fd, UI_SET_KEYBIT, KEY_PAGEUP); - ioctl(fd, UI_SET_KEYBIT, KEY_DOWN); - ioctl(fd, UI_SET_KEYBIT, KEY_PAGEDOWN); - - if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) { - err = -errno; - error("Can't create uinput device: %s (%d)", - strerror(-err), -err); - close(fd); - return err; - } - - return fd; -} - -static int decode_key(const char *str) -{ - static int mode = UPDOWN_ENABLED, gain = 0; - - uint16_t key; - int new_gain; - - /* Switch from key up/down to page up/down */ - if (strncmp("AT+CKPD=200", str, 11) == 0) { - mode = ~mode; - return KEY_RESERVED; - } - - if (strncmp("AT+VG", str, 5)) - return KEY_RESERVED; - - /* Gain key pressed */ - if (strlen(str) != 10) - return KEY_RESERVED; - - new_gain = strtol(&str[7], NULL, 10); - if (new_gain <= gain) - key = (mode == UPDOWN_ENABLED ? KEY_UP : KEY_PAGEUP); - else - key = (mode == UPDOWN_ENABLED ? KEY_DOWN : KEY_PAGEDOWN); - - gain = new_gain; - - return key; -} - -static int send_event(int fd, uint16_t type, uint16_t code, int32_t value) -{ - struct uinput_event event; - - memset(&event, 0, sizeof(event)); - event.type = type; - event.code = code; - event.value = value; - - return write(fd, &event, sizeof(event)); -} - -static void send_key(int fd, uint16_t key) -{ - /* Key press */ - send_event(fd, EV_KEY, key, 1); - send_event(fd, EV_SYN, SYN_REPORT, 0); - /* Key release */ - send_event(fd, EV_KEY, key, 0); - send_event(fd, EV_SYN, SYN_REPORT, 0); -} - -static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, gpointer data) -{ - struct fake_input *fake = data; - const char *ok = "\r\nOK\r\n"; - char buf[BUF_SIZE]; - ssize_t bread = 0, bwritten; - uint16_t key; - int fd; - - if (cond & G_IO_NVAL) - return FALSE; - - if (cond & (G_IO_HUP | G_IO_ERR)) { - error("Hangup or error on rfcomm server socket"); - goto failed; - } - - fd = g_io_channel_unix_get_fd(chan); - - memset(buf, 0, BUF_SIZE); - bread = read(fd, buf, sizeof(buf) - 1); - if (bread < 0) { - error("IO Channel read error"); - goto failed; - } - - DBG("Received: %s", buf); - - bwritten = write(fd, ok, 6); - if (bwritten < 0) { - error("IO Channel write error"); - goto failed; - } - - key = decode_key(buf); - if (key != KEY_RESERVED) - send_key(fake->uinput, key); - - return TRUE; - -failed: - ioctl(fake->uinput, UI_DEV_DESTROY); - close(fake->uinput); - fake->uinput = -1; - g_io_channel_unref(fake->io); - - return FALSE; -} - -static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data) -{ - struct input_conn *iconn = user_data; - struct input_device *idev = iconn->idev; - struct fake_input *fake = iconn->fake; - DBusMessage *reply; - - if (err) { - reply = btd_error_failed(iconn->pending_connect, err->message); - goto failed; - } - - fake->rfcomm = g_io_channel_unix_get_fd(chan); - - /* - * FIXME: Some headsets required a sco connection - * first to report volume gain key events - */ - fake->uinput = uinput_create(idev->name); - if (fake->uinput < 0) { - int err = fake->uinput; - - g_io_channel_shutdown(chan, TRUE, NULL); - reply = btd_error_failed(iconn->pending_connect, - strerror(-err)); - goto failed; - } - - fake->io = g_io_channel_unix_new(fake->rfcomm); - g_io_channel_set_close_on_unref(fake->io, TRUE); - g_io_add_watch(fake->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, - (GIOFunc) rfcomm_io_cb, fake); - - /* Replying to the requestor */ - reply = dbus_message_new_method_return(iconn->pending_connect); - g_dbus_send_message(idev->conn, reply); - - dbus_message_unref(iconn->pending_connect); - iconn->pending_connect = NULL; - - return; - -failed: - g_dbus_send_message(idev->conn, reply); - dbus_message_unref(iconn->pending_connect); - iconn->pending_connect = NULL; -} - -static gboolean rfcomm_connect(struct input_conn *iconn, GError **err) -{ - struct input_device *idev = iconn->idev; - GIOChannel *io; - - io = bt_io_connect(rfcomm_connect_cb, iconn, - NULL, err, - BT_IO_OPT_SOURCE_BDADDR, &idev->src, - BT_IO_OPT_DEST_BDADDR, &idev->dst, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_INVALID); - if (!io) - return FALSE; - - g_io_channel_unref(io); - - return TRUE; -} - static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { struct input_conn *iconn = data; @@ -440,20 +212,6 @@ static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data return FALSE; } -static gboolean fake_hid_connect(struct input_conn *iconn, GError **err) -{ - struct fake_hid *fhid = iconn->fake->priv; - - return fhid->connect(iconn->fake, err); -} - -static int fake_hid_disconnect(struct input_conn *iconn) -{ - struct fake_hid *fhid = iconn->fake->priv; - - return fhid->disconnect(iconn->fake); -} - static void epox_endian_quirk(unsigned char *data, int size) { /* USAGE_PAGE (Keyboard) 05 07 @@ -598,8 +356,6 @@ static int hidp_add_connection(const struct input_device *idev, struct input_conn *iconn) { struct hidp_connadd_req *req; - struct fake_hid *fake_hid; - struct fake_input *fake; uint8_t dst_type; sdp_record_t *rec; char src_addr[18], dst_addr[18]; @@ -631,22 +387,6 @@ static int hidp_add_connection(const struct input_device *idev, req->product = btd_device_get_product(idev->device); req->version = btd_device_get_version(idev->device); - fake_hid = get_fake_hid(req->vendor, req->product); - if (fake_hid) { - err = 0; - fake = g_new0(struct fake_input, 1); - fake->connect = fake_hid_connect; - fake->disconnect = fake_hid_disconnect; - fake->priv = fake_hid; - fake->idev = idev; - fake = fake_hid_connadd(fake, iconn->intr_io, fake_hid); - if (fake == NULL) - err = -ENOMEM; - else - fake->flags |= FI_FLAG_CONNECTED; - goto cleanup; - } - if (idev->name) strncpy(req->name, idev->name, sizeof(req->name) - 1); @@ -680,14 +420,9 @@ cleanup: static int is_connected(struct input_conn *iconn) { struct input_device *idev = iconn->idev; - struct fake_input *fake = iconn->fake; struct hidp_conninfo ci; int ctl; - /* Fake input */ - if (fake) - return fake->flags & FI_FLAG_CONNECTED; - /* Standard HID */ ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP); if (ctl < 0) @@ -711,19 +446,10 @@ static int is_connected(struct input_conn *iconn) static int connection_disconnect(struct input_conn *iconn, uint32_t flags) { struct input_device *idev = iconn->idev; - struct fake_input *fake = iconn->fake; struct hidp_conndel_req req; struct hidp_conninfo ci; int ctl, err = 0; - /* Fake input disconnect */ - if (fake) { - err = fake->disconnect(iconn); - if (err == 0) - fake->flags &= ~FI_FLAG_CONNECTED; - return err; - } - /* Standard HID disconnect */ if (iconn->intr_io) g_io_channel_shutdown(iconn->intr_io, TRUE, NULL); @@ -917,26 +643,6 @@ failed: iconn->pending_connect = NULL; } -static int fake_disconnect(struct input_conn *iconn) -{ - struct fake_input *fake = iconn->fake; - - if (!fake->io) - return -ENOTCONN; - - g_io_channel_shutdown(fake->io, TRUE, NULL); - g_io_channel_unref(fake->io); - fake->io = NULL; - - if (fake->uinput >= 0) { - ioctl(fake->uinput, UI_DEV_DESTROY); - close(fake->uinput); - fake->uinput = -1; - } - - return 0; -} - /* * Input Device methods */ @@ -945,9 +651,9 @@ static DBusMessage *input_device_connect(DBusConnection *conn, { struct input_device *idev = data; struct input_conn *iconn; - struct fake_input *fake; DBusMessage *reply; GError *err = NULL; + GIOChannel *io; iconn = find_connection(idev->connections, HID_UUID); if (!iconn) @@ -960,28 +666,18 @@ static DBusMessage *input_device_connect(DBusConnection *conn, return btd_error_already_connected(msg); iconn->pending_connect = dbus_message_ref(msg); - fake = iconn->fake; - if (fake) { - /* Fake input device */ - if (fake->connect(iconn, &err)) - fake->flags |= FI_FLAG_CONNECTED; - } else { - /* HID devices */ - GIOChannel *io; - - if (idev->disable_sdp) - bt_clear_cached_session(&idev->src, &idev->dst); - - io = bt_io_connect(control_connect_cb, iconn, - NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &idev->src, - BT_IO_OPT_DEST_BDADDR, &idev->dst, - BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_INVALID); - iconn->ctrl_io = io; - } + if (idev->disable_sdp) + bt_clear_cached_session(&idev->src, &idev->dst); + + io = bt_io_connect(control_connect_cb, iconn, + NULL, &err, + BT_IO_OPT_SOURCE_BDADDR, &idev->src, + BT_IO_OPT_DEST_BDADDR, &idev->dst, + BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL, + BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, + BT_IO_OPT_INVALID); + iconn->ctrl_io = io; if (err == NULL) return NULL; @@ -1156,31 +852,6 @@ int input_device_register(DBusConnection *conn, struct btd_device *device, return 0; } -int fake_input_register(DBusConnection *conn, struct btd_device *device, - const char *path, const char *uuid, uint8_t channel) -{ - struct input_device *idev; - struct input_conn *iconn; - - idev = find_device_by_path(devices, path); - if (!idev) { - idev = input_device_new(conn, device, path, 0, FALSE); - if (!idev) - return -EINVAL; - devices = g_slist_append(devices, idev); - } - - iconn = input_conn_new(idev, uuid, 0); - iconn->fake = g_new0(struct fake_input, 1); - iconn->fake->ch = channel; - iconn->fake->connect = rfcomm_connect; - iconn->fake->disconnect = fake_disconnect; - - idev->connections = g_slist_append(idev->connections, iconn); - - return 0; -} - static struct input_device *find_device(const bdaddr_t *src, const bdaddr_t *dst) { @@ -1308,11 +979,3 @@ int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst) return 0; } - -void input_device_request_disconnect(struct fake_input *fake) -{ - if (fake == NULL || fake->idev == NULL) - return; - - device_request_disconnect(fake->idev->device, NULL); -} diff --git a/profiles/input/device.h b/profiles/input/device.h index d8baa2ce..06325701 100644 --- a/profiles/input/device.h +++ b/profiles/input/device.h @@ -27,21 +27,6 @@ struct input_device; struct input_conn; -struct fake_input { - int flags; - GIOChannel *io; - int uinput; /* uinput socket */ - int rfcomm; /* RFCOMM socket */ - uint8_t ch; /* RFCOMM channel number */ - guint timeout_id; /* Disconnect timeout ID */ - gboolean (*connect) (struct input_conn *iconn, GError **err); - int (*disconnect) (struct input_conn *iconn); - void *priv; - const struct input_device *idev; -}; - -int fake_input_register(DBusConnection *conn, struct btd_device *device, - const char *path, const char *uuid, uint8_t channel); int input_device_register(DBusConnection *conn, struct btd_device *device, const char *path, const char *uuid, const sdp_record_t *rec, int timeout); @@ -50,4 +35,3 @@ int input_device_unregister(const char *path, const char *uuid); int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm, GIOChannel *io); int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst); -void input_device_request_disconnect(struct fake_input *fake); diff --git a/profiles/input/fakehid.c b/profiles/input/fakehid.c deleted file mode 100644 index 05f5894c..00000000 --- a/profiles/input/fakehid.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdbool.h> -#include <fcntl.h> -#include <unistd.h> - -#include <bluetooth/bluetooth.h> - -#include <glib.h> - -#include "../src/adapter.h" -#include "../src/device.h" - -#include "log.h" -#include "device.h" -#include "fakehid.h" -#include "uinput.h" - -/* Timeout to get the PS3 remote disconnected, in seconds */ -#define PS3_REMOTE_TIMEOUT 10 * 60 - -enum ps3remote_special_keys { - PS3R_BIT_PS = 0, - PS3R_BIT_ENTER = 3, - PS3R_BIT_L2 = 8, - PS3R_BIT_R2 = 9, - PS3R_BIT_L1 = 10, - PS3R_BIT_R1 = 11, - PS3R_BIT_TRIANGLE = 12, - PS3R_BIT_CIRCLE = 13, - PS3R_BIT_CROSS = 14, - PS3R_BIT_SQUARE = 15, - PS3R_BIT_SELECT = 16, - PS3R_BIT_L3 = 17, - PS3R_BIT_R3 = 18, - PS3R_BIT_START = 19, - PS3R_BIT_UP = 20, - PS3R_BIT_RIGHT = 21, - PS3R_BIT_DOWN = 22, - PS3R_BIT_LEFT = 23, -}; - -static unsigned int ps3remote_bits[] = { - [PS3R_BIT_ENTER] = 0x0b, - [PS3R_BIT_PS] = 0x43, - [PS3R_BIT_SQUARE] = 0x5f, - [PS3R_BIT_CROSS] = 0x5e, - [PS3R_BIT_CIRCLE] = 0x5d, - [PS3R_BIT_TRIANGLE] = 0x5c, - [PS3R_BIT_R1] = 0x5b, - [PS3R_BIT_L1] = 0x5a, - [PS3R_BIT_R2] = 0x59, - [PS3R_BIT_L2] = 0x58, - [PS3R_BIT_LEFT] = 0x57, - [PS3R_BIT_DOWN] = 0x56, - [PS3R_BIT_RIGHT] = 0x55, - [PS3R_BIT_UP] = 0x54, - [PS3R_BIT_START] = 0x53, - [PS3R_BIT_R3] = 0x52, - [PS3R_BIT_L3] = 0x51, - [PS3R_BIT_SELECT] = 0x50, -}; - -static unsigned int ps3remote_keymap[] = { - [0x16] = KEY_EJECTCD, - [0x64] = KEY_AUDIO, - [0x65] = KEY_ANGLE, - [0x63] = KEY_SUBTITLE, - [0x0f] = KEY_CLEAR, - [0x28] = KEY_TIME, - [0x00] = KEY_1, - [0x01] = KEY_2, - [0x02] = KEY_3, - [0x03] = KEY_4, - [0x04] = KEY_5, - [0x05] = KEY_6, - [0x06] = KEY_7, - [0x07] = KEY_8, - [0x08] = KEY_9, - [0x09] = KEY_0, - [0x81] = KEY_RED, - [0x82] = KEY_GREEN, - [0x80] = KEY_BLUE, - [0x83] = KEY_YELLOW, - [0x70] = KEY_INFO, /* display */ - [0x1a] = KEY_MENU, /* top menu */ - [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ - [0x0e] = KEY_ESC, /* return */ - [0x5c] = KEY_OPTION, /* options/triangle */ - [0x5d] = KEY_BACK, /* back/circle */ - [0x5f] = KEY_SCREEN, /* view/square */ - [0x5e] = BTN_0, /* cross */ - [0x54] = KEY_UP, - [0x56] = KEY_DOWN, - [0x57] = KEY_LEFT, - [0x55] = KEY_RIGHT, - [0x0b] = KEY_ENTER, - [0x5a] = BTN_TL, /* L1 */ - [0x58] = BTN_TL2, /* L2 */ - [0x51] = BTN_THUMBL, /* L3 */ - [0x5b] = BTN_TR, /* R1 */ - [0x59] = BTN_TR2, /* R2 */ - [0x52] = BTN_THUMBR, /* R3 */ - [0x43] = KEY_HOMEPAGE, /* PS button */ - [0x50] = KEY_SELECT, - [0x53] = BTN_START, - [0x33] = KEY_REWIND, /* scan back */ - [0x32] = KEY_PLAY, - [0x34] = KEY_FORWARD, /* scan forward */ - [0x30] = KEY_PREVIOUS, - [0x38] = KEY_STOP, - [0x31] = KEY_NEXT, - [0x60] = KEY_FRAMEBACK, /* slow/step back */ - [0x39] = KEY_PAUSE, - [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ - [0xff] = KEY_MAX, -}; - -static int ps3remote_decode(char *buff, int size, unsigned int *value) -{ - static unsigned int lastkey = 0; - static unsigned int lastmask = 0; - unsigned int i, mask; - int retval; - guint8 key; - - if (size < 12) { - error("Got a shorter packet! (size %i)\n", size); - return KEY_RESERVED; - } - - mask = (buff[2] << 16) + (buff[3] << 8) + buff[4]; - key = buff[5]; - - /* first, check flags */ - for (i = 0; i < 24; i++) { - if ((lastmask & (1 << i)) == (mask & (1 << i))) - continue; - if (ps3remote_bits[i] == 0) - goto error; - retval = ps3remote_keymap[ps3remote_bits[i]]; - if (mask & (1 << i)) - /* key pressed */ - *value = 1; - else - /* key released */ - *value = 0; - - goto out; - } - - *value = buff[11]; - if (buff[11] == 1) { - retval = ps3remote_keymap[key]; - } else - retval = lastkey; - - if (retval == KEY_RESERVED) - goto error; - if (retval == KEY_MAX) - return retval; - - lastkey = retval; - -out: - fflush(stdout); - - lastmask = mask; - - return retval; - -error: - error("ps3remote: unrecognized sequence [%#x][%#x][%#x][%#x] [%#x]," - "last: [%#x][%#x][%#x][%#x]", - buff[2], buff[3], buff[4], buff[5], buff[11], - lastmask >> 16, lastmask >> 8 & 0xff, - lastmask & 0xff, lastkey); - return -1; -} - -static gboolean ps3_remote_timeout_cb(gpointer user_data) -{ - struct fake_input *fake = user_data; - - input_device_request_disconnect(fake); - DBG("Disconnected PS3 BD Remote after timeout"); - - fake->timeout_id = 0; - - return FALSE; -} - -static void ps3remote_set_timeout(struct fake_input *fake) -{ - fake->timeout_id = g_timeout_add_seconds(PS3_REMOTE_TIMEOUT, - ps3_remote_timeout_cb, fake); -} - -static gboolean ps3remote_event(GIOChannel *chan, GIOCondition cond, - gpointer data) -{ - struct fake_input *fake = data; - struct uinput_event event; - unsigned int key, value = 0; - ssize_t size; - char buff[50]; - int fd; - - if (cond & G_IO_NVAL) - return FALSE; - - if (cond & (G_IO_HUP | G_IO_ERR)) { - error("Hangup or error on rfcomm server socket"); - goto failed; - } - - fd = g_io_channel_unix_get_fd(chan); - - memset(buff, 0, sizeof(buff)); - size = read(fd, buff, sizeof(buff)); - if (size < 0) { - error("IO Channel read error"); - goto failed; - } - - key = ps3remote_decode(buff, size, &value); - if (key == KEY_RESERVED) { - error("Got invalid key from decode"); - goto failed; - } else if (key == KEY_MAX) - return TRUE; - - memset(&event, 0, sizeof(event)); - gettimeofday(&event.time, NULL); - event.type = EV_KEY; - event.code = key; - event.value = value; - if (write(fake->uinput, &event, sizeof(event)) != sizeof(event)) { - error("Error writing to uinput device"); - goto failed; - } - - memset(&event, 0, sizeof(event)); - gettimeofday(&event.time, NULL); - event.type = EV_SYN; - event.code = SYN_REPORT; - if (write(fake->uinput, &event, sizeof(event)) != sizeof(event)) { - error("Error writing to uinput device"); - goto failed; - } - - if (fake->timeout_id > 0) - g_source_remove(fake->timeout_id); - ps3remote_set_timeout(fake); - - return TRUE; - -failed: - if (fake->timeout_id > 0) { - g_source_remove(fake->timeout_id); - fake->timeout_id = 0; - } - ioctl(fake->uinput, UI_DEV_DESTROY); - close(fake->uinput); - fake->uinput = -1; - g_io_channel_unref(fake->io); - - return FALSE; -} - -static int ps3remote_setup_uinput(struct fake_input *fake, - struct fake_hid *fake_hid) -{ - struct uinput_dev dev; - int i; - - fake->uinput = open("/dev/input/uinput", O_RDWR); - if (fake->uinput < 0) { - fake->uinput = open("/dev/uinput", O_RDWR); - if (fake->uinput < 0) { - fake->uinput = open("/dev/misc/uinput", O_RDWR); - if (fake->uinput < 0) { - error("Error opening uinput device file"); - return 1; - } - } - } - - memset(&dev, 0, sizeof(dev)); - snprintf(dev.name, sizeof(dev.name), "%s", "PS3 Remote Controller"); - dev.id.bustype = BUS_BLUETOOTH; - dev.id.vendor = fake_hid->vendor; - dev.id.product = fake_hid->product; - - if (write(fake->uinput, &dev, sizeof(dev)) != sizeof(dev)) { - error("Error creating uinput device"); - goto err; - } - - /* enabling key events */ - if (ioctl(fake->uinput, UI_SET_EVBIT, EV_KEY) < 0) { - error("Error enabling uinput device key events"); - goto err; - } - - /* enabling keys */ - for (i = 0; i < 0xff; i++) - if (ps3remote_keymap[i] != KEY_RESERVED) - if (ioctl(fake->uinput, UI_SET_KEYBIT, - ps3remote_keymap[i]) < 0) { - error("Error enabling uinput key %i", - ps3remote_keymap[i]); - goto err; - } - - /* creating the device */ - if (ioctl(fake->uinput, UI_DEV_CREATE) < 0) { - error("Error creating uinput device"); - goto err; - } - - ps3remote_set_timeout(fake); - - return 0; - -err: - close(fake->uinput); - return 1; -} - -static gboolean fake_hid_common_connect(struct fake_input *fake, GError **err) -{ - return TRUE; -} - -static int fake_hid_common_disconnect(struct fake_input *fake) -{ - return 0; -} - -static struct fake_hid fake_hid_table[] = { - /* Sony PS3 remote device */ - { - .vendor = 0x054c, - .product = 0x0306, - .connect = fake_hid_common_connect, - .disconnect = fake_hid_common_disconnect, - .event = ps3remote_event, - .setup_uinput = ps3remote_setup_uinput, - .devices = NULL, - }, - /* Logitech Harmony Adapter for PS3 */ - { - .vendor = 0x046d, - .product = 0x0306, - .connect = fake_hid_common_connect, - .disconnect = fake_hid_common_disconnect, - .event = ps3remote_event, - .setup_uinput = ps3remote_setup_uinput, - .devices = NULL, - }, - - { }, -}; - -static inline int fake_hid_match_device(uint16_t vendor, uint16_t product, - struct fake_hid *fhid) -{ - return vendor == fhid->vendor && product == fhid->product; -} - -struct fake_hid *get_fake_hid(uint16_t vendor, uint16_t product) -{ - int i; - - for (i = 0; fake_hid_table[i].vendor != 0; i++) - if (fake_hid_match_device(vendor, product, &fake_hid_table[i])) - return &fake_hid_table[i]; - - return NULL; -} - -struct fake_input *fake_hid_connadd(struct fake_input *fake, - GIOChannel *intr_io, - struct fake_hid *fake_hid) -{ - GList *l; - struct fake_input *old = NULL; - - /* Look for an already setup device */ - for (l = fake_hid->devices; l != NULL; l = l->next) { - old = l->data; - if (old->idev == fake->idev) { - if (fake->timeout_id > 0) - g_source_remove(fake->timeout_id); - g_free(fake); - fake = old; - fake_hid->connect(fake, NULL); - break; - } - old = NULL; - } - - /* New device? Add it to the list of known devices, - * and create the uinput necessary */ - if (old == NULL || old->uinput < 0) { - if (fake_hid->setup_uinput(fake, fake_hid)) { - error("Error setting up uinput"); - g_free(fake); - return NULL; - } - } - - if (old == NULL) - fake_hid->devices = g_list_append(fake_hid->devices, fake); - - fake->io = g_io_channel_ref(intr_io); - g_io_channel_set_close_on_unref(fake->io, TRUE); - g_io_add_watch(fake->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, - (GIOFunc) fake_hid->event, fake); - - return fake; -} diff --git a/profiles/input/fakehid.h b/profiles/input/fakehid.h deleted file mode 100644 index 3a5d7c42..00000000 --- a/profiles/input/fakehid.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -struct fake_hid; -struct fake_input; - -struct fake_hid { - uint16_t vendor; - uint16_t product; - gboolean (*connect) (struct fake_input *fake_input, GError **err); - int (*disconnect) (struct fake_input *fake_input); - gboolean (*event) (GIOChannel *chan, GIOCondition cond, gpointer data); - int (*setup_uinput) (struct fake_input *fake, struct fake_hid *fake_hid); - GList *devices; -}; - -struct fake_hid *get_fake_hid(uint16_t vendor, uint16_t product); - -struct fake_input *fake_hid_connadd(struct fake_input *fake, GIOChannel *intr_io, - struct fake_hid *fake_hid); diff --git a/profiles/input/manager.c b/profiles/input/manager.c index 3b494f5f..13096c74 100644 --- a/profiles/input/manager.c +++ b/profiles/input/manager.c @@ -76,42 +76,6 @@ static void hid_device_remove(struct btd_device *device) input_remove(device, HID_UUID); } -static int headset_probe(struct btd_device *device, GSList *uuids) -{ - const gchar *path = device_get_path(device); - const sdp_record_t *record; - sdp_list_t *protos; - int ch; - - DBG("path %s", path); - - if (!g_slist_find_custom(uuids, HSP_HS_UUID, bt_uuid_strcmp)) - return -EINVAL; - - record = btd_device_get_record(device, uuids->data); - - if (!record || sdp_get_access_protos(record, &protos) < 0) { - error("Invalid record"); - return -EINVAL; - } - - ch = sdp_get_proto_port(protos, RFCOMM_UUID); - sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); - sdp_list_free(protos, NULL); - - if (ch <= 0) { - error("Invalid RFCOMM channel"); - return -EINVAL; - } - - return fake_input_register(connection, device, path, HSP_HS_UUID, ch); -} - -static void headset_remove(struct btd_device *device) -{ - input_remove(device, HSP_HS_UUID); -} - static int hid_server_probe(struct btd_adapter *adapter) { bdaddr_t src; @@ -151,14 +115,6 @@ static struct btd_profile input_profile = { .adapter_remove = hid_server_remove, }; -static struct btd_profile input_headset_profile = { - .name = "input-headset", - .remote_uuids = BTD_UUIDS(HSP_HS_UUID), - - .device_probe = headset_probe, - .device_remove = headset_remove, -}; - int input_manager_init(DBusConnection *conn, GKeyFile *config) { GError *err = NULL; @@ -175,7 +131,6 @@ int input_manager_init(DBusConnection *conn, GKeyFile *config) connection = dbus_connection_ref(conn); btd_profile_register(&input_profile); - btd_profile_register(&input_headset_profile); return 0; } @@ -183,7 +138,6 @@ int input_manager_init(DBusConnection *conn, GKeyFile *config) void input_manager_exit(void) { btd_profile_unregister(&input_profile); - btd_profile_unregister(&input_headset_profile); dbus_connection_unref(connection); connection = NULL; |