summaryrefslogtreecommitdiff
path: root/plugins/sixaxis.c
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2017-09-04 20:12:04 +0200
committerSzymon Janc <szymon.janc@codecoup.pl>2017-09-27 11:04:20 +0200
commitefe53dc46f0ebcfbe7d03f21fe52b5720f39ec59 (patch)
tree4f890e23a813c57cca2768783e9116a319e48472 /plugins/sixaxis.c
parent41d7520120301b7b73fe306eabacc62867f4f1fe (diff)
downloadbluez-efe53dc46f0ebcfbe7d03f21fe52b5720f39ec59.tar.gz
plugins/sixaxis: Remove LEDs handling
It's done in the kernel since 2014 in linux kernel commit 8025087acf9d2b941bae93b3e0967560e7e03e87
Diffstat (limited to 'plugins/sixaxis.c')
-rw-r--r--plugins/sixaxis.c295
1 files changed, 5 insertions, 290 deletions
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index 7e3c950b4..7d3a8f3ac 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -71,17 +71,6 @@ static const struct {
},
};
-struct leds_data {
- char *syspath_prefix;
- uint8_t bitmap;
-};
-
-static void leds_data_destroy(struct leds_data *data)
-{
- free(data->syspath_prefix);
- free(data);
-}
-
static struct udev *ctx = NULL;
static struct udev_monitor *monitor = NULL;
static guint watch_id = 0;
@@ -146,115 +135,6 @@ static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr)
return ret;
}
-static uint8_t calc_leds_bitmap(int number)
-{
- uint8_t bitmap = 0;
-
- /* TODO we could support up to 10 (1 + 2 + 3 + 4) */
- if (number > 7)
- return bitmap;
-
- if (number > 4) {
- bitmap |= 0x10;
- number -= 4;
- }
-
- bitmap |= 0x01 << number;
-
- return bitmap;
-}
-
-static void set_leds_hidraw(int fd, uint8_t leds_bitmap)
-{
- /*
- * the total time the led is active (0xff means forever)
- * | duty_length: cycle time in deciseconds (0 - "blink very fast")
- * | | ??? (Maybe a phase shift or duty_length multiplier?)
- * | | | % of duty_length led is off (0xff means 100%)
- * | | | | % of duty_length led is on (0xff means 100%)
- * | | | | |
- * 0xff, 0x27, 0x10, 0x00, 0x32,
- */
- uint8_t leds_report[] = {
- 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, /* rumble values TBD */
- 0x00, 0x00, 0x00, 0x00, 0x00, /* LED_1=0x02, LED_2=0x04 ... */
- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_4 */
- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_3 */
- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_2 */
- 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_1 */
- 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- int ret;
-
- leds_report[10] = leds_bitmap;
-
- ret = write(fd, leds_report, sizeof(leds_report));
- if (ret == sizeof(leds_report))
- return;
-
- if (ret < 0)
- error("sixaxis: failed to set LEDS (%s)", strerror(errno));
- else
- error("sixaxis: failed to set LEDS (%d bytes written)", ret);
-}
-
-static bool set_leds_sysfs(struct leds_data *data)
-{
- int i;
-
- if (!data->syspath_prefix)
- return false;
-
- /* start from 1, LED0 is never used */
- for (i = 1; i <= 4; i++) {
- char path[PATH_MAX] = { 0 };
- char buf[2] = { 0 };
- int fd;
- int ret;
-
- snprintf(path, PATH_MAX, "%s%d/brightness",
- data->syspath_prefix, i);
-
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- error("sixaxis: cannot open %s (%s)", path,
- strerror(errno));
- return false;
- }
-
- buf[0] = '0' + !!(data->bitmap & (1 << i));
- ret = write(fd, buf, sizeof(buf));
- close(fd);
- if (ret != sizeof(buf))
- return false;
- }
-
- return true;
-}
-
-static gboolean setup_leds(GIOChannel *channel, GIOCondition cond,
- gpointer user_data)
-{
- struct leds_data *data = user_data;
-
- if (!data)
- return FALSE;
-
- if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
- goto out;
-
- if(!set_leds_sysfs(data)) {
- int fd = g_io_channel_unix_get_fd(channel);
- set_leds_hidraw(fd, data->bitmap);
- }
-
-out:
- leds_data_destroy(data);
-
- return FALSE;
-}
-
static bool setup_device(int fd, int index, struct btd_adapter *adapter)
{
char device_addr[18], master_addr[18], adapter_addr[18];
@@ -269,8 +149,7 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
return false;
/* This can happen if controller was plugged while already connected
- * eg. to charge up battery.
- * Don't set LEDs in that case, hence return false */
+ * eg. to charge up battery. */
device = btd_adapter_find_device(adapter, &device_bdaddr,
BDADDR_BREDR);
if (device && btd_device_is_connected(device))
@@ -307,152 +186,6 @@ static bool setup_device(int fd, int index, struct btd_adapter *adapter)
return true;
}
-static int get_js_number(struct udev_device *udevice)
-{
- struct udev_list_entry *devices, *dev_list_entry;
- struct udev_enumerate *enumerate;
- struct udev_device *hid_parent;
- const char *hidraw_node;
- const char *hid_id;
- int number = 0;
-
- hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
- "hid", NULL);
-
- /*
- * Look for HID_UNIQ first for the correct behavior via BT, if
- * HID_UNIQ is not available it means the USB bus is being used and we
- * can rely on HID_PHYS.
- */
- hid_id = udev_device_get_property_value(hid_parent, "HID_UNIQ");
- if (!hid_id)
- hid_id = udev_device_get_property_value(hid_parent,
- "HID_PHYS");
-
- hidraw_node = udev_device_get_devnode(udevice);
- if (!hid_id || !hidraw_node)
- return 0;
-
- enumerate = udev_enumerate_new(udev_device_get_udev(udevice));
- udev_enumerate_add_match_sysname(enumerate, "js*");
- udev_enumerate_scan_devices(enumerate);
- devices = udev_enumerate_get_list_entry(enumerate);
-
- udev_list_entry_foreach(dev_list_entry, devices) {
- struct udev_device *input_parent;
- struct udev_device *js_dev;
- const char *input_id;
- const char *devname;
-
- devname = udev_list_entry_get_name(dev_list_entry);
- js_dev = udev_device_new_from_syspath(
- udev_device_get_udev(udevice),
- devname);
-
- input_parent = udev_device_get_parent_with_subsystem_devtype(
- js_dev, "input", NULL);
- if (!input_parent)
- goto next;
-
- /* check if this is the joystick relative to the hidraw device
- * above */
- input_id = udev_device_get_sysattr_value(input_parent, "uniq");
-
- /*
- * A strlen() check is needed because input device over USB
- * have the UNIQ attribute defined but with an empty value.
- */
- if (!input_id || strlen(input_id) == 0)
- input_id = udev_device_get_sysattr_value(input_parent,
- "phys");
-
- if (!input_id)
- goto next;
-
- if (!strcmp(input_id, hid_id)) {
- number = atoi(udev_device_get_sysnum(js_dev));
-
- /* joystick numbers start from 0, leds from 1 */
- number++;
-
- udev_device_unref(js_dev);
- break;
- }
-next:
- udev_device_unref(js_dev);
- }
-
- udev_enumerate_unref(enumerate);
-
- return number;
-}
-
-static char *get_leds_syspath_prefix(struct udev_device *udevice)
-{
- struct udev_list_entry *dev_list_entry;
- struct udev_enumerate *enumerate;
- struct udev_device *hid_parent;
- const char *syspath;
- char *syspath_prefix;
-
- hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
- "hid", NULL);
-
- enumerate = udev_enumerate_new(udev_device_get_udev(udevice));
- udev_enumerate_add_match_parent(enumerate, hid_parent);
- udev_enumerate_add_match_subsystem(enumerate, "leds");
- udev_enumerate_scan_devices(enumerate);
-
- dev_list_entry = udev_enumerate_get_list_entry(enumerate);
- if (!dev_list_entry) {
- syspath_prefix = NULL;
- goto out;
- }
-
- syspath = udev_list_entry_get_name(dev_list_entry);
-
- /*
- * All the sysfs paths of the LEDs have the same structure, just the
- * number changes, so strip it and store only the common prefix.
- *
- * Subtracting 1 here means assuming that the LED number is a single
- * digit, this is safe as the kernel driver only exposes 4 LEDs.
- */
- syspath_prefix = strndup(syspath, strlen(syspath) - 1);
-
-out:
- udev_enumerate_unref(enumerate);
-
- return syspath_prefix;
-}
-
-static struct leds_data *get_leds_data(struct udev_device *udevice)
-{
- struct leds_data *data;
- int number;
-
- number = get_js_number(udevice);
- DBG("number %d", number);
-
- data = malloc0(sizeof(*data));
- if (!data)
- return NULL;
-
- data->bitmap = calc_leds_bitmap(number);
- if (data->bitmap == 0) {
- leds_data_destroy(data);
- return NULL;
- }
-
- /*
- * It's OK if this fails, set_leds_hidraw() will be used in
- * case data->syspath_prefix is NULL.
- */
- data->syspath_prefix = get_leds_syspath_prefix(udevice);
-
- return data;
-}
-
static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
{
struct udev_device *hid_parent;
@@ -481,7 +214,6 @@ static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
static void device_added(struct udev_device *udevice)
{
struct btd_adapter *adapter;
- GIOChannel *io;
uint16_t bus;
int index;
int fd;
@@ -493,6 +225,8 @@ static void device_added(struct udev_device *udevice)
index = get_supported_device(udevice, &bus);
if (index < 0)
return;
+ if (bus != BUS_USB)
+ return;
info("sixaxis: compatible device connected: %s (%04X:%04X)",
devices[index].name, devices[index].vid,
@@ -502,27 +236,8 @@ static void device_added(struct udev_device *udevice)
if (fd < 0)
return;
- io = g_io_channel_unix_new(fd);
-
- switch (bus) {
- case BUS_USB:
- if (!setup_device(fd, index, adapter))
- break;
-
- /* fall through */
- case BUS_BLUETOOTH:
- /* wait for events before setting leds */
- g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- setup_leds, get_leds_data(udevice));
-
- break;
- default:
- DBG("uknown bus type (%u)", bus);
- break;
- }
-
- g_io_channel_set_close_on_unref(io, TRUE);
- g_io_channel_unref(io);
+ setup_device(fd, index, adapter);
+ close(fd);
}
static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,