/* * Given a service record handle, remove its record from the repository */ int sdp_record_remove(uint32_t handle) { sdp_list_t *p = record_locate(handle); sdp_record_t *r; sdp_access_t *a; if (!p) { error("Remove : Couldn't find record for : 0x%x", handle); return -1; } r = p->data; if (r) service_db = sdp_list_remove(service_db, r); p = access_locate(handle); if (p == NULL || p->data == NULL) return 0; a = p->data; if (bacmp(&a->device, BDADDR_ANY) != 0) { struct btd_adapter *adapter = adapter_find(&a->device); if (adapter) adapter_service_remove(adapter, r); } else adapter_foreach(adapter_service_remove, r); access_db = sdp_list_remove(access_db, a); access_free(a); return 0; }
/* * Add a service record to the repository */ void sdp_record_add(const bdaddr_t *device, sdp_record_t *rec) { struct btd_adapter *adapter; sdp_access_t *dev; SDPDBG("Adding rec : 0x%lx", (long) rec); SDPDBG("with handle : 0x%x", rec->handle); service_db = sdp_list_insert_sorted(service_db, rec, record_sort); dev = malloc(sizeof(*dev)); if (!dev) return; bacpy(&dev->device, device); dev->handle = rec->handle; access_db = sdp_list_insert_sorted(access_db, dev, access_sort); if (bacmp(device, BDADDR_ANY) == 0) { adapter_foreach(adapter_service_insert, rec); return; } adapter = adapter_find(device); if (adapter) adapter_service_insert(adapter, rec); }
static void avctp_confirm_cb(GIOChannel *chan, gpointer data) { struct avctp *session; struct audio_device *dev; 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 = adapter_find_device(adapter_find(&src), &dst); if (!device) return; session = avctp_get_internal(device); if (session == NULL) return; dev = manager_get_audio_device(device, TRUE); if (!dev) { error("Unable to get audio device object for %s", address); goto drop; } if (dev->control == NULL) { btd_device_add_uuid(dev->btd_dev, AVRCP_REMOTE_UUID); if (dev->control == NULL) goto drop; } switch (psm) { case AVCTP_CONTROL_PSM: avctp_control_confirm(session, chan, dev); break; case AVCTP_BROWSING_PSM: avctp_browsing_confirm(session, chan, dev); break; } return; drop: if (psm == AVCTP_CONTROL_PSM) avctp_set_state(session, AVCTP_STATE_DISCONNECTED); }
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); }
/* This call may fail; either deal with retry or use read_btclock_retry */ static gboolean read_btclock(struct mcap_mcl *mcl, uint32_t *btclock, uint16_t *btaccuracy) { int which = 1; struct btd_adapter *adapter; adapter = adapter_find(&mcl->mi->src); if (!adapter) return FALSE; if (btd_adapter_read_clock(adapter, &mcl->addr, which, 1000, btclock, btaccuracy) < 0) return FALSE; return TRUE; }
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; }