gboolean mcap_get_mdep(struct mcap_device *device, struct mcap_application *app, mcap_continue_mdep_f func, gpointer data, GDestroyNotify destroy, GError **err) { DBG(""); struct get_mdep_data *mdep_data; bdaddr_t dst, src; uuid_t uuid; device_get_address(device->dev, &dst,NULL); adapter_get_address(device_get_adapter(device->dev), &src); mdep_data = g_new0(struct get_mdep_data, 1); mdep_data->app = mcap_application_ref(app); mdep_data->func = func; mdep_data->data = data; mdep_data->destroy = destroy; char dd[100] = {}; ba2str(&dst,dd); DBG("dst device = %s",dd); sdp_uuid32_create(&uuid, 0x1400); // bt_string2uuid(&uuid, 0x1400); if (bt_search_service(&src, &dst, &uuid, get_mdep_cb, mdep_data, free_mdep_data)) { g_set_error(err, MCAP_ERROR, MCAP_CONNECTION_ERROR, "Can't get remote SDP record"); g_free(mdep_data); return FALSE; } return TRUE; }
static int connect_port(struct serial_port *port) { struct serial_device *device = port->device; uuid_t uuid; int err; if (!port->uuid) goto connect; err = bt_string2uuid(&uuid, port->uuid); if (err < 0) return err; sdp_uuid128_to_uuid(&uuid); return bt_search_service(&device->src, &device->dst, &uuid, get_record_cb, port, NULL); connect: port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port, NULL, NULL, BT_IO_OPT_SOURCE_BDADDR, &device->src, BT_IO_OPT_DEST_BDADDR, &device->dst, BT_IO_OPT_CHANNEL, port->channel, BT_IO_OPT_INVALID); if (port->io) return 0; return -errno; }
gboolean hdp_get_dcpsm(struct hdp_device *device, hdp_continue_dcpsm_f func, gpointer data, GDestroyNotify destroy, GError **err) { struct get_dcpsm_data *dcpsm_data; bdaddr_t dst, src; uuid_t uuid; device_get_address(device->dev, &dst, NULL); adapter_get_address(device_get_adapter(device->dev), &src); dcpsm_data = g_new0(struct get_dcpsm_data, 1); dcpsm_data->func = func; dcpsm_data->data = data; dcpsm_data->destroy = destroy; bt_string2uuid(&uuid, HDP_UUID); if (bt_search_service(&src, &dst, &uuid, get_dcpsm_cb, dcpsm_data, free_dcpsm_data)) { g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR, "Can't get remote SDP record"); g_free(dcpsm_data); return FALSE; } return TRUE; }
gboolean hdp_establish_mcl(struct hdp_device *device, hdp_continue_proc_f func, gpointer data, GDestroyNotify destroy, GError **err) { struct conn_mcl_data *conn_data; const bdaddr_t *src; const bdaddr_t *dst; uuid_t uuid; src = btd_adapter_get_address(device_get_adapter(device->dev)); dst = device_get_address(device->dev); conn_data = g_new0(struct conn_mcl_data, 1); conn_data->refs = 1; conn_data->func = func; conn_data->data = data; conn_data->destroy = destroy; conn_data->dev = health_device_ref(device); bt_string2uuid(&uuid, HDP_UUID); if (bt_search_service(src, dst, &uuid, search_cb, conn_data, destroy_con_mcl_data, 0) < 0) { g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR, "Can't get remote SDP record"); g_free(conn_data); return FALSE; } return TRUE; }
gboolean mcap_establish_mcl(struct mcap_device *device, mcap_continue_proc_f func, gpointer data, GDestroyNotify destroy, GError **err) { DBG(""); DBG(""); struct conn_mcl_data *conn_data; bdaddr_t dst, src; uuid_t uuid; device_get_address(device->dev, &dst,NULL); adapter_get_address(device_get_adapter(device->dev), &src); conn_data = g_new0(struct conn_mcl_data, 1); conn_data->refs = 1; conn_data->func = func; conn_data->data = data; conn_data->destroy = destroy; conn_data->dev = mcap_device_ref(device); sdp_uuid32_create(&uuid, 0x001e); //bt_string2uuid(&uuid, 0x001e); if (bt_search_service(&src, &dst, &uuid, search_cb, conn_data, destroy_con_mcl_data)) { g_set_error(err, MCAP_ERROR, MCAP_CONNECTION_ERROR, "Can't get remote SDP record"); g_free(conn_data); return FALSE; } return TRUE; }
gboolean hdp_get_mdep(struct hdp_device *device, struct hdp_application *app, hdp_continue_mdep_f func, gpointer data, GDestroyNotify destroy, GError **err) { struct get_mdep_data *mdep_data; const bdaddr_t *src; const bdaddr_t *dst; uuid_t uuid; src = btd_adapter_get_address(device_get_adapter(device->dev)); dst = device_get_address(device->dev); mdep_data = g_new0(struct get_mdep_data, 1); mdep_data->app = hdp_application_ref(app); mdep_data->func = func; mdep_data->data = data; mdep_data->destroy = destroy; bt_string2uuid(&uuid, HDP_UUID); if (bt_search_service(src, dst, &uuid, get_mdep_cb, mdep_data, free_mdep_data, 0) < 0) { g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR, "Can't get remote SDP record"); g_free(mdep_data); return FALSE; } return TRUE; }
static int get_records(struct audio_device *device) { uuid_t uuid; sdp_uuid16_create(&uuid, HANDSFREE_AGW_SVCLASS_ID); return bt_search_service(&device->src, &device->dst, &uuid, get_record_cb, device, NULL); }
int bt_discover_services(const bdaddr_t *src, const bdaddr_t *dst, bt_callback_t cb, void *user_data, bt_destroy_t destroy) { uuid_t uuid; sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); return bt_search_service(src, dst, &uuid, cb, user_data, destroy); }
static int avrcp_device_search(struct avrcp_device *dev) { uuid_t uuid; sdp_uuid16_create(&uuid, AV_REMOTE_SVCLASS_ID); return bt_search_service(&adapter_addr, &dev->dst, &uuid, search_cb, dev, NULL, 0); }
static void bt_hid_connect(const void *buf, uint16_t len) { const struct hal_cmd_hidhost_connect *cmd = buf; struct hid_device *dev; uint8_t status; char addr[18]; bdaddr_t dst; GSList *l; uuid_t uuid; DBG(""); android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (l) { status = HAL_STATUS_FAILED; goto failed; } dev = hid_device_new(&dst); ba2str(&dev->dst, addr); DBG("connecting to %s", addr); if (bt_is_device_le(&dst)) { if (!hog_connect(dev)) { status = HAL_STATUS_FAILED; hid_device_remove(dev); goto failed; } goto done; } sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID); if (bt_search_service(&adapter_addr, &dev->dst, &uuid, hid_sdp_did_search_cb, dev, NULL, 0) < 0) { error("hidhost: Failed to search DeviceID SDP details"); hid_device_remove(dev); status = HAL_STATUS_FAILED; goto failed; } done: if (dev->state == HAL_HIDHOST_STATE_DISCONNECTED) bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING); status = HAL_STATUS_SUCCESS; failed: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT, status); }
static void hid_sdp_did_search_cb(sdp_list_t *recs, int err, gpointer data) { struct hid_device *dev = data; sdp_list_t *list; uuid_t uuid; DBG(""); if (err < 0) { error("hidhost: Unable to get Device ID SDP record: %s", strerror(-err)); goto fail; } if (!recs || !recs->data) { error("hidhost: No Device ID SDP records found"); goto fail; } for (list = recs; list; list = list->next) { sdp_record_t *rec = list->data; sdp_data_t *data; data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID); if (data) dev->vendor = data->val.uint16; data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID); if (data) dev->product = data->val.uint16; data = sdp_data_get(rec, SDP_ATTR_VERSION); if (data) dev->version = data->val.uint16; } sdp_uuid16_create(&uuid, HID_SVCLASS_ID); if (bt_search_service(&adapter_addr, &dev->dst, &uuid, hid_sdp_search_cb, dev, NULL, 0) < 0) { error("hidhost: Failed to search SDP details"); goto fail; } return; fail: bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); hid_device_remove(dev); }
static int get_records(struct audio_device *device) { uuid_t uuid; int err; sdp_uuid16_create(&uuid, HANDSFREE_AGW_SVCLASS_ID); err = bt_search_service(&device->src, &device->dst, &uuid, get_record_cb, device, NULL); if (err < 0) return err; change_state(device, GATEWAY_STATE_CONNECTING); return 0; }
static void rfcomm_incoming_cb(GIOChannel *chan, GError *err, gpointer user_data) { struct audio_device *dev = user_data; struct gateway *gw = dev->gateway; uuid_t uuid; gw->incoming = g_io_channel_ref(chan); sdp_uuid16_create(&uuid, HANDSFREE_AGW_SVCLASS_ID); if (bt_search_service(&dev->src, &dev->dst, &uuid, get_incoming_record_cb, dev, unregister_incoming) == 0) return; unregister_incoming(dev); gateway_close(dev); }
static void bt_hid_connect(const void *buf, uint16_t len) { const struct hal_cmd_hidhost_connect *cmd = buf; struct hid_device *dev; uint8_t status; char addr[18]; bdaddr_t dst; GSList *l; uuid_t uuid; DBG(""); android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (l) { status = HAL_STATUS_FAILED; goto failed; } dev = g_new0(struct hid_device, 1); bacpy(&dev->dst, &dst); dev->uhid_fd = -1; ba2str(&dev->dst, addr); DBG("connecting to %s", addr); bt_string2uuid(&uuid, HID_UUID); if (bt_search_service(&adapter_addr, &dev->dst, &uuid, hid_sdp_search_cb, dev, NULL, 0) < 0) { error("Failed to search sdp details"); hid_device_free(dev); status = HAL_STATUS_FAILED; goto failed; } devices = g_slist_append(devices, dev); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING); status = HAL_STATUS_SUCCESS; failed: ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT, status); }
static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data) { struct hid_device *dev; bdaddr_t dst; char address[18]; uint16_t psm; GError *gerr = NULL; GSList *l; uuid_t uuid; if (err) { error("hidhost: Connect failed (%s)", err->message); return; } bt_io_get(chan, &gerr, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_PSM, &psm, BT_IO_OPT_INVALID); if (gerr) { error("hidhost: Failed to read remote address (%s)", gerr->message); g_io_channel_shutdown(chan, TRUE, NULL); g_error_free(gerr); return; } ba2str(&dst, address); DBG("Incoming connection from %s on PSM %d", address, psm); switch (psm) { case L2CAP_PSM_HIDP_CTRL: l = g_slist_find_custom(devices, &dst, device_cmp); if (l) return; dev = hid_device_new(&dst); dev->ctrl_io = g_io_channel_ref(chan); sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID); if (bt_search_service(&adapter_addr, &dev->dst, &uuid, hid_sdp_did_search_cb, dev, NULL, 0) < 0) { error("hidhost: Failed to search DID SDP details"); hid_device_remove(dev); return; } dev->ctrl_watch = g_io_add_watch(dev->ctrl_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL, ctrl_watch_cb, dev); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING); break; case L2CAP_PSM_HIDP_INTR: l = g_slist_find_custom(devices, &dst, device_cmp); if (!l) return; dev = l->data; dev->intr_io = g_io_channel_ref(chan); dev->intr_watch = g_io_add_watch(dev->intr_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, intr_watch_cb, dev); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED); break; } }
static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data) { struct hid_device *dev; bdaddr_t src, dst; char address[18]; uint16_t psm; GError *gerr = NULL; GSList *l; uuid_t uuid; if (err) { error("%s", err->message); return; } bt_io_get(chan, &gerr, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_PSM, &psm, BT_IO_OPT_INVALID); if (gerr) { error("%s", gerr->message); g_io_channel_shutdown(chan, TRUE, NULL); g_error_free(gerr); return; } ba2str(&dst, address); DBG("Incoming connection from %s on PSM %d", address, psm); switch (psm) { case L2CAP_PSM_HIDP_CTRL: l = g_slist_find_custom(devices, &dst, device_cmp); if (l) return; dev = g_new0(struct hid_device, 1); bacpy(&dev->dst, &dst); dev->ctrl_io = g_io_channel_ref(chan); dev->uhid_fd = -1; bt_string2uuid(&uuid, HID_UUID); if (bt_search_service(&src, &dev->dst, &uuid, hid_sdp_search_cb, dev, NULL, 0) < 0) { error("failed to search sdp details"); hid_device_free(dev); return; } devices = g_slist_append(devices, dev); dev->ctrl_watch = g_io_add_watch(dev->ctrl_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL, ctrl_watch_cb, dev); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING); break; case L2CAP_PSM_HIDP_INTR: l = g_slist_find_custom(devices, &dst, device_cmp); if (!l) return; dev = l->data; dev->intr_io = g_io_channel_ref(chan); dev->intr_watch = g_io_add_watch(dev->intr_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, intr_watch_cb, dev); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED); break; } }
static DBusMessage *create_connection(DBusConnection *conn, DBusMessage *msg, void *data) { struct pending_reply *pr; const char *addr; const char *str; bdaddr_t src; uint16_t id; int dev_id, err; char key[32]; GSList *l; uuid_t uuid; if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID) == FALSE) return NULL; id = bnep_service_id(str); if (id != BNEP_SVC_GN && id != BNEP_SVC_NAP && id != BNEP_SVC_PANU) return not_supported(msg); snprintf(key, 32, "%s#%s", addr, bnep_name(id)); /* Checks if the connection was already been made */ for (l = connection_paths; l; l = l->next) { if (connection_find_data(l->data, key) == 0) return already_exists(msg); } bacpy(&src, BDADDR_ANY); dev_id = hci_get_route(&src); if (dev_id < 0 || hci_devba(dev_id, &src) < 0) return adapter_not_available(msg); pr = g_new0(struct pending_reply, 1); /* FIXME just to maintain compatibility */ pr->adapter_path = g_strdup_printf("/org/bluez/hci%d", dev_id); if (!pr->adapter_path) { pending_reply_free (pr); return adapter_not_available(msg); } pr->conn = dbus_connection_ref(conn); pr->msg = dbus_message_ref(msg); bacpy(&pr->src, &src); str2ba(addr, &pr->dst); pr->addr = g_strdup(addr); pr->id = id; pr->path = g_new0(char, MAX_PATH_LENGTH); snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH "/connection%d", net_uid++); sdp_uuid16_create(&uuid, pr->id); err = bt_search_service(&pr->src, &pr->dst, &uuid, records_cb, pr, NULL); if (err < 0) { pending_reply_free(pr); return not_supported(msg); } return NULL; }