sixaxis.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2009 Bastien Nocera <hadess@hadess.net>
  7. * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it>
  8. * Copyright (C) 2013 Szymon Janc <szymon.janc@gmail.com>
  9. *
  10. *
  11. */
  12. #ifdef HAVE_CONFIG_H
  13. #include <config.h>
  14. #endif
  15. #define _GNU_SOURCE
  16. #include <stddef.h>
  17. #include <errno.h>
  18. #include <fcntl.h>
  19. #include <unistd.h>
  20. #include <stdlib.h>
  21. #include <sys/ioctl.h>
  22. #include <linux/hidraw.h>
  23. #include <linux/input.h>
  24. #include <glib.h>
  25. #include <libudev.h>
  26. #include "lib/bluetooth.h"
  27. #include "lib/sdp.h"
  28. #include "lib/uuid.h"
  29. #include "src/adapter.h"
  30. #include "src/device.h"
  31. #include "src/agent.h"
  32. #include "src/plugin.h"
  33. #include "src/log.h"
  34. #include "src/shared/util.h"
  35. #include "profiles/input/sixaxis.h"
  36. struct authentication_closure {
  37. guint auth_id;
  38. char *sysfs_path;
  39. struct btd_adapter *adapter;
  40. struct btd_device *device;
  41. int fd;
  42. bdaddr_t bdaddr; /* device bdaddr */
  43. CablePairingType type;
  44. };
  45. struct authentication_destroy_closure {
  46. struct authentication_closure *closure;
  47. bool remove_device;
  48. };
  49. static struct udev *ctx = NULL;
  50. static struct udev_monitor *monitor = NULL;
  51. static guint watch_id = 0;
  52. /* key = sysfs_path (const str), value = auth_closure */
  53. static GHashTable *pending_auths = NULL;
  54. #define SIXAXIS_HID_SDP_RECORD "3601920900000A000100000900013503191124090004"\
  55. "350D35061901000900113503190011090006350909656E09006A090100090009350"\
  56. "8350619112409010009000D350F350D350619010009001335031900110901002513"\
  57. "576972656C65737320436F6E74726F6C6C65720901012513576972656C657373204"\
  58. "36F6E74726F6C6C6572090102251B536F6E7920436F6D707574657220456E746572"\
  59. "7461696E6D656E74090200090100090201090100090202080009020308210902042"\
  60. "8010902052801090206359A35980822259405010904A101A1028501750895011500"\
  61. "26FF00810375019513150025013500450105091901291381027501950D0600FF810"\
  62. "3150026FF0005010901A10075089504350046FF0009300931093209358102C00501"\
  63. "75089527090181027508953009019102750895300901B102C0A1028502750895300"\
  64. "901B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C00902"\
  65. "07350835060904090901000902082800090209280109020A280109020B090100090"\
  66. "20C093E8009020D280009020E2800"
  67. /* Make sure to unset auth_id if already handled */
  68. static void auth_closure_destroy(struct authentication_closure *closure,
  69. bool remove_device)
  70. {
  71. if (closure->auth_id)
  72. btd_cancel_authorization(closure->auth_id);
  73. if (remove_device)
  74. btd_adapter_remove_device(closure->adapter, closure->device);
  75. close(closure->fd);
  76. g_free(closure->sysfs_path);
  77. g_free(closure);
  78. }
  79. static int sixaxis_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
  80. {
  81. uint8_t buf[18];
  82. int ret;
  83. memset(buf, 0, sizeof(buf));
  84. buf[0] = 0xf2;
  85. ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
  86. if (ret < 0) {
  87. error("sixaxis: failed to read device address (%s)",
  88. strerror(errno));
  89. return ret;
  90. }
  91. baswap(bdaddr, (bdaddr_t *) (buf + 4));
  92. return 0;
  93. }
  94. static int ds4_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
  95. {
  96. uint8_t buf[7];
  97. int ret;
  98. memset(buf, 0, sizeof(buf));
  99. buf[0] = 0x81;
  100. ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
  101. if (ret < 0) {
  102. error("sixaxis: failed to read DS4 device address (%s)",
  103. strerror(errno));
  104. return ret;
  105. }
  106. /* address is little-endian on DS4 */
  107. bacpy(bdaddr, (bdaddr_t*) (buf + 1));
  108. return 0;
  109. }
  110. static int get_device_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
  111. {
  112. if (type == CABLE_PAIRING_SIXAXIS)
  113. return sixaxis_get_device_bdaddr(fd, bdaddr);
  114. else if (type == CABLE_PAIRING_DS4)
  115. return ds4_get_device_bdaddr(fd, bdaddr);
  116. return -1;
  117. }
  118. static int sixaxis_get_central_bdaddr(int fd, bdaddr_t *bdaddr)
  119. {
  120. uint8_t buf[8];
  121. int ret;
  122. memset(buf, 0, sizeof(buf));
  123. buf[0] = 0xf5;
  124. ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
  125. if (ret < 0) {
  126. error("sixaxis: failed to read central address (%s)",
  127. strerror(errno));
  128. return ret;
  129. }
  130. baswap(bdaddr, (bdaddr_t *) (buf + 2));
  131. return 0;
  132. }
  133. static int ds4_get_central_bdaddr(int fd, bdaddr_t *bdaddr)
  134. {
  135. uint8_t buf[16];
  136. int ret;
  137. memset(buf, 0, sizeof(buf));
  138. buf[0] = 0x12;
  139. ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
  140. if (ret < 0) {
  141. error("sixaxis: failed to read DS4 central address (%s)",
  142. strerror(errno));
  143. return ret;
  144. }
  145. /* address is little-endian on DS4 */
  146. bacpy(bdaddr, (bdaddr_t*) (buf + 10));
  147. return 0;
  148. }
  149. static int get_central_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
  150. {
  151. if (type == CABLE_PAIRING_SIXAXIS)
  152. return sixaxis_get_central_bdaddr(fd, bdaddr);
  153. else if (type == CABLE_PAIRING_DS4)
  154. return ds4_get_central_bdaddr(fd, bdaddr);
  155. return -1;
  156. }
  157. static int sixaxis_set_central_bdaddr(int fd, const bdaddr_t *bdaddr)
  158. {
  159. uint8_t buf[8];
  160. int ret;
  161. buf[0] = 0xf5;
  162. buf[1] = 0x01;
  163. baswap((bdaddr_t *) (buf + 2), bdaddr);
  164. ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
  165. if (ret < 0)
  166. error("sixaxis: failed to write central address (%s)",
  167. strerror(errno));
  168. return ret;
  169. }
  170. static int ds4_set_central_bdaddr(int fd, const bdaddr_t *bdaddr)
  171. {
  172. uint8_t buf[23];
  173. int ret;
  174. buf[0] = 0x13;
  175. bacpy((bdaddr_t*) (buf + 1), bdaddr);
  176. /* TODO: we could put the key here but
  177. there is no way to force a re-loading
  178. of link keys to the kernel from here. */
  179. memset(buf + 7, 0, 16);
  180. ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
  181. if (ret < 0)
  182. error("sixaxis: failed to write DS4 central address (%s)",
  183. strerror(errno));
  184. return ret;
  185. }
  186. static int set_central_bdaddr(int fd, const bdaddr_t *bdaddr,
  187. CablePairingType type)
  188. {
  189. if (type == CABLE_PAIRING_SIXAXIS)
  190. return sixaxis_set_central_bdaddr(fd, bdaddr);
  191. else if (type == CABLE_PAIRING_DS4)
  192. return ds4_set_central_bdaddr(fd, bdaddr);
  193. return -1;
  194. }
  195. static bool is_auth_pending(struct authentication_closure *closure)
  196. {
  197. GHashTableIter iter;
  198. gpointer value;
  199. g_hash_table_iter_init(&iter, pending_auths);
  200. while (g_hash_table_iter_next(&iter, NULL, &value)) {
  201. struct authentication_closure *c = value;
  202. if (c == closure)
  203. return true;
  204. }
  205. return false;
  206. }
  207. static gboolean auth_closure_destroy_idle(gpointer user_data)
  208. {
  209. struct authentication_destroy_closure *destroy = user_data;
  210. auth_closure_destroy(destroy->closure, destroy->remove_device);
  211. g_free(destroy);
  212. return false;
  213. }
  214. static void agent_auth_cb(DBusError *derr, void *user_data)
  215. {
  216. struct authentication_closure *closure = user_data;
  217. struct authentication_destroy_closure *destroy;
  218. char central_addr[18], adapter_addr[18], device_addr[18];
  219. bdaddr_t central_bdaddr;
  220. const bdaddr_t *adapter_bdaddr;
  221. bool remove_device = true;
  222. if (!is_auth_pending(closure))
  223. return;
  224. /* Don't try to remove this auth, we're handling it already */
  225. closure->auth_id = 0;
  226. if (derr != NULL) {
  227. DBG("Agent replied negatively, removing temporary device");
  228. goto out;
  229. }
  230. if (get_central_bdaddr(closure->fd, &central_bdaddr, closure->type) < 0)
  231. goto out;
  232. adapter_bdaddr = btd_adapter_get_address(closure->adapter);
  233. if (bacmp(adapter_bdaddr, &central_bdaddr)) {
  234. if (set_central_bdaddr(closure->fd, adapter_bdaddr,
  235. closure->type) < 0)
  236. goto out;
  237. }
  238. remove_device = false;
  239. btd_device_set_trusted(closure->device, true);
  240. btd_device_set_temporary(closure->device, false);
  241. if (closure->type == CABLE_PAIRING_SIXAXIS)
  242. btd_device_set_record(closure->device, HID_UUID,
  243. SIXAXIS_HID_SDP_RECORD);
  244. ba2str(&closure->bdaddr, device_addr);
  245. ba2str(&central_bdaddr, central_addr);
  246. ba2str(adapter_bdaddr, adapter_addr);
  247. DBG("remote %s old_central %s new_central %s",
  248. device_addr, central_addr, adapter_addr);
  249. out:
  250. g_hash_table_steal(pending_auths, closure->sysfs_path);
  251. /* btd_adapter_remove_device() cannot be called in this
  252. * callback or it would lead to a double-free in while
  253. * trying to cancel the authentication that's being processed,
  254. * so clean up in an idle */
  255. destroy = g_new0(struct authentication_destroy_closure, 1);
  256. destroy->closure = closure;
  257. destroy->remove_device = remove_device;
  258. g_idle_add(auth_closure_destroy_idle, destroy);
  259. }
  260. static bool setup_device(int fd, const char *sysfs_path,
  261. const struct cable_pairing *cp,
  262. struct btd_adapter *adapter)
  263. {
  264. bdaddr_t device_bdaddr;
  265. const bdaddr_t *adapter_bdaddr;
  266. struct btd_device *device;
  267. struct authentication_closure *closure;
  268. if (get_device_bdaddr(fd, &device_bdaddr, cp->type) < 0)
  269. return false;
  270. /* This can happen if controller was plugged while already setup and
  271. * connected eg. to charge up battery. */
  272. device = btd_adapter_find_device(adapter, &device_bdaddr,
  273. BDADDR_BREDR);
  274. if (device != NULL &&
  275. btd_device_is_connected(device) &&
  276. g_slist_find_custom(btd_device_get_uuids(device), HID_UUID,
  277. (GCompareFunc)strcasecmp)) {
  278. char device_addr[18];
  279. ba2str(&device_bdaddr, device_addr);
  280. DBG("device %s already known, skipping", device_addr);
  281. return false;
  282. }
  283. device = btd_adapter_get_device(adapter, &device_bdaddr, BDADDR_BREDR);
  284. info("sixaxis: setting up new device");
  285. btd_device_device_set_name(device, cp->name);
  286. btd_device_set_pnpid(device, cp->source, cp->vid, cp->pid, cp->version);
  287. btd_device_set_trusted(device, false);
  288. btd_device_set_temporary(device, true);
  289. closure = g_new0(struct authentication_closure, 1);
  290. if (!closure) {
  291. btd_adapter_remove_device(adapter, device);
  292. return false;
  293. }
  294. closure->adapter = adapter;
  295. closure->device = device;
  296. closure->sysfs_path = g_strdup(sysfs_path);
  297. closure->fd = fd;
  298. bacpy(&closure->bdaddr, &device_bdaddr);
  299. closure->type = cp->type;
  300. adapter_bdaddr = btd_adapter_get_address(adapter);
  301. closure->auth_id = btd_request_authorization_cable_configured(
  302. adapter_bdaddr, &device_bdaddr,
  303. HID_UUID, agent_auth_cb, closure);
  304. if (closure->auth_id == 0) {
  305. error("sixaxis: could not request cable authorization");
  306. auth_closure_destroy(closure, true);
  307. return false;
  308. }
  309. g_hash_table_insert(pending_auths, closure->sysfs_path, closure);
  310. return true;
  311. }
  312. static const struct cable_pairing *
  313. get_pairing_type_for_device(struct udev_device *udevice, uint16_t *bus,
  314. char **sysfs_path)
  315. {
  316. struct udev_device *hid_parent;
  317. const char *hid_name;
  318. const char *hid_id;
  319. const struct cable_pairing *cp;
  320. uint16_t vid, pid;
  321. hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
  322. "hid", NULL);
  323. if (!hid_parent)
  324. return NULL;
  325. hid_id = udev_device_get_property_value(hid_parent, "HID_ID");
  326. if (!hid_id || sscanf(hid_id, "%hx:%hx:%hx", bus, &vid, &pid) != 3)
  327. return NULL;
  328. hid_name = udev_device_get_property_value(hid_parent, "HID_NAME");
  329. cp = get_pairing(vid, pid, hid_name);
  330. *sysfs_path = g_strdup(udev_device_get_syspath(udevice));
  331. return cp;
  332. }
  333. static void device_added(struct udev_device *udevice)
  334. {
  335. struct btd_adapter *adapter;
  336. uint16_t bus;
  337. char *sysfs_path = NULL;
  338. const struct cable_pairing *cp;
  339. int fd;
  340. adapter = btd_adapter_get_default();
  341. if (!adapter)
  342. return;
  343. cp = get_pairing_type_for_device(udevice, &bus, &sysfs_path);
  344. if (!cp || (cp->type != CABLE_PAIRING_SIXAXIS &&
  345. cp->type != CABLE_PAIRING_DS4))
  346. return;
  347. if (bus != BUS_USB)
  348. return;
  349. info("sixaxis: compatible device connected: %s (%04X:%04X %s)",
  350. cp->name, cp->vid, cp->pid, sysfs_path);
  351. fd = open(udev_device_get_devnode(udevice), O_RDWR);
  352. if (fd < 0) {
  353. g_free(sysfs_path);
  354. return;
  355. }
  356. /* Only close the fd if an authentication is not pending */
  357. if (!setup_device(fd, sysfs_path, cp, adapter))
  358. close(fd);
  359. g_free(sysfs_path);
  360. }
  361. static void device_removed(struct udev_device *udevice)
  362. {
  363. struct authentication_closure *closure;
  364. const char *sysfs_path;
  365. sysfs_path = udev_device_get_syspath(udevice);
  366. if (!sysfs_path)
  367. return;
  368. closure = g_hash_table_lookup(pending_auths, sysfs_path);
  369. if (!closure)
  370. return;
  371. g_hash_table_steal(pending_auths, sysfs_path);
  372. auth_closure_destroy(closure, true);
  373. }
  374. static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,
  375. gpointer data)
  376. {
  377. struct udev_device *udevice;
  378. udevice = udev_monitor_receive_device(monitor);
  379. if (!udevice)
  380. return TRUE;
  381. if (!g_strcmp0(udev_device_get_action(udevice), "add"))
  382. device_added(udevice);
  383. else if (!g_strcmp0(udev_device_get_action(udevice), "remove"))
  384. device_removed(udevice);
  385. udev_device_unref(udevice);
  386. return TRUE;
  387. }
  388. static int sixaxis_init(void)
  389. {
  390. GIOChannel *channel;
  391. DBG("");
  392. ctx = udev_new();
  393. if (!ctx)
  394. return -EIO;
  395. monitor = udev_monitor_new_from_netlink(ctx, "udev");
  396. if (!monitor) {
  397. udev_unref(ctx);
  398. ctx = NULL;
  399. return -EIO;
  400. }
  401. /* Listen for newly connected hidraw interfaces */
  402. udev_monitor_filter_add_match_subsystem_devtype(monitor, "hidraw",
  403. NULL);
  404. udev_monitor_enable_receiving(monitor);
  405. channel = g_io_channel_unix_new(udev_monitor_get_fd(monitor));
  406. watch_id = g_io_add_watch(channel, G_IO_IN, monitor_watch, NULL);
  407. g_io_channel_unref(channel);
  408. pending_auths = g_hash_table_new(g_str_hash,
  409. g_str_equal);
  410. return 0;
  411. }
  412. static void sixaxis_exit(void)
  413. {
  414. GHashTableIter iter;
  415. gpointer value;
  416. DBG("");
  417. g_hash_table_iter_init(&iter, pending_auths);
  418. while (g_hash_table_iter_next(&iter, NULL, &value)) {
  419. struct authentication_closure *closure = value;
  420. auth_closure_destroy(closure, true);
  421. }
  422. g_hash_table_destroy(pending_auths);
  423. pending_auths = NULL;
  424. g_source_remove(watch_id);
  425. watch_id = 0;
  426. udev_monitor_unref(monitor);
  427. monitor = NULL;
  428. udev_unref(ctx);
  429. ctx = NULL;
  430. }
  431. BLUETOOTH_PLUGIN_DEFINE(sixaxis, VERSION, BLUETOOTH_PLUGIN_PRIORITY_LOW,
  432. sixaxis_init, sixaxis_exit)