static bool setup_device(int fd, int index, struct btd_adapter *adapter) { char device_addr[18], master_addr[18], adapter_addr[18]; bdaddr_t device_bdaddr, master_bdaddr; const bdaddr_t *adapter_bdaddr; struct btd_device *device; if (get_device_bdaddr(fd, &device_bdaddr) < 0) return false; if (get_master_bdaddr(fd, &master_bdaddr) < 0) 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 */ device = btd_adapter_find_device(adapter, &device_bdaddr, BDADDR_BREDR); if (device && btd_device_is_connected(device)) return false; adapter_bdaddr = btd_adapter_get_address(adapter); if (bacmp(adapter_bdaddr, &master_bdaddr)) { if (set_master_bdaddr(fd, adapter_bdaddr) < 0) return false; } ba2str(&device_bdaddr, device_addr); ba2str(&master_bdaddr, master_addr); ba2str(adapter_bdaddr, adapter_addr); DBG("remote %s old_master %s new_master %s", device_addr, master_addr, adapter_addr); device = btd_adapter_get_device(adapter, &device_bdaddr, BDADDR_BREDR); if (g_slist_find_custom(btd_device_get_uuids(device), HID_UUID, (GCompareFunc)strcasecmp)) { DBG("device %s already known, skipping", device_addr); return true; } info("sixaxis: setting up new device"); btd_device_device_set_name(device, devices[index].name); btd_device_set_pnpid(device, devices[index].source, devices[index].vid, devices[index].pid, devices[index].version); btd_device_set_temporary(device, FALSE); return true; }
static void avctp_confirm_cb(GIOChannel *chan, gpointer data) { struct avctp *session; char address[18]; bdaddr_t src, dst; GError *err = NULL; uint16_t psm; struct btd_device *device; bt_io_get(chan, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_DEST, address, BT_IO_OPT_PSM, &psm, BT_IO_OPT_INVALID); if (err) { error("%s", err->message); g_error_free(err); g_io_channel_shutdown(chan, TRUE, NULL); return; } DBG("AVCTP: incoming connect from %s", address); device = btd_adapter_find_device(adapter_find(&src), &dst, BDADDR_BREDR); if (!device) return; session = avctp_get_internal(device); if (session == NULL) return; if (btd_device_get_service(device, AVRCP_REMOTE_UUID) == NULL) btd_device_add_uuid(device, AVRCP_REMOTE_UUID); if (btd_device_get_service(device, AVRCP_TARGET_UUID) == NULL) btd_device_add_uuid(device, AVRCP_TARGET_UUID); switch (psm) { case AVCTP_CONTROL_PSM: avctp_control_confirm(session, chan, device); break; case AVCTP_BROWSING_PSM: avctp_browsing_confirm(session, chan, device); break; } return; }
static struct input_device *find_device(const bdaddr_t *src, const bdaddr_t *dst) { struct btd_device *device; struct btd_service *service; device = btd_adapter_find_device(adapter_find(src), dst); if (device == NULL) return NULL; service = btd_device_get_service(device, HID_UUID); if (service == NULL) return NULL; return btd_service_get_user_data(service); }
static void sixaxis_browse_sdp(const bdaddr_t *src, const bdaddr_t *dst, GIOChannel *chan, uint16_t psm) { struct btd_device *device; struct sixaxis_data *data; device = btd_adapter_find_device(adapter_find(src), dst); if (!device) return; data = g_new0(struct sixaxis_data, 1); data->chan = g_io_channel_ref(chan); data->psm = psm; if (psm == L2CAP_PSM_HIDP_CTRL) device_discover_services(device); device_wait_for_svc_complete(device, sixaxis_sdp_cb, data); }
static bool dev_is_sixaxis(const bdaddr_t *src, const bdaddr_t *dst) { struct btd_device *device; uint16_t vid, pid; device = btd_adapter_find_device(adapter_find(src), dst); if (!device) return false; vid = btd_device_get_vendor(device); pid = btd_device_get_product(device); /* DualShock 3 */ if (vid == 0x054c && pid == 0x0268) return true; /* DualShock 4 */ if (vid == 0x054c && pid == 0x05c4) return true; return false; }