/* Connect and initiate BNEP session */ int connection_connect(struct btd_service *service) { struct network_conn *nc = btd_service_get_user_data(service); struct network_peer *peer = nc->peer; uint16_t id = get_service_id(service); GError *err = NULL; const bdaddr_t *src; const bdaddr_t *dst; DBG("id %u", id); if (nc->state != DISCONNECTED) return -EALREADY; src = btd_adapter_get_address(device_get_adapter(peer->device)); dst = device_get_address(peer->device); nc->io = bt_io_connect(connect_cb, nc, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, src, BT_IO_OPT_DEST_BDADDR, dst, BT_IO_OPT_PSM, BNEP_PSM, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, BT_IO_OPT_OMTU, BNEP_MTU, BT_IO_OPT_IMTU, BNEP_MTU, BT_IO_OPT_INVALID); if (!nc->io) return -EIO; nc->state = CONNECTING; return 0; }
static void csc_device_remove(struct btd_service *service) { struct btd_device *device = btd_service_get_device(service); struct btd_adapter *adapter; struct csc_adapter *cadapter; struct csc *csc; GSList *l; adapter = device_get_adapter(device); cadapter = find_csc_adapter(adapter); if (cadapter == NULL) return; l = g_slist_find_custom(cadapter->devices, device, cmp_device); if (l == NULL) return; csc = l->data; cadapter->devices = g_slist_remove(cadapter->devices, csc); g_dbus_unregister_interface(btd_get_dbus_connection(), device_get_path(device), CYCLINGSPEED_INTERFACE); }
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 serial_probe(struct btd_device *device, const char *uuid) { struct btd_adapter *adapter = device_get_adapter(device); const gchar *path = device_get_path(device); sdp_list_t *protos; int ch; bdaddr_t src, dst; const sdp_record_t *rec; DBG("path %s: %s", path, uuid); rec = btd_device_get_record(device, uuid); if (!rec) return -EINVAL; if (sdp_get_access_protos(rec, &protos) < 0) return -EINVAL; ch = sdp_get_proto_port(protos, RFCOMM_UUID); sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); sdp_list_free(protos, NULL); if (ch < 1 || ch > 30) { error("Channel out of range: %d", ch); return -EINVAL; } adapter_get_address(adapter, &src); device_get_address(device, &dst); return port_register(connection, path, &src, &dst, uuid, ch); }
static int hid_device_probe(struct btd_device *device, GSList *uuids) { struct btd_adapter *adapter = device_get_adapter(device); const gchar *path = device_get_path(device); const sdp_record_t *rec = btd_device_get_record(device, uuids->data); bdaddr_t src, dst; DBG("path %s", path); #ifndef BT_ALT_STACK if (!rec) return -1; #endif adapter_get_address(adapter, &src); device_get_address(device, &dst); #ifdef BT_ALT_STACK return input_device_register(connection, device, path, &src, &dst, HID_UUID, 0 /* rec->handle */, idle_timeout * 60); #else return input_device_register(connection, device, path, &src, &dst, HID_UUID, rec->handle, idle_timeout * 60); #endif }
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 void pincode_cb(struct agent *agent, DBusError *derr, const char *pincode, struct btd_device *device) { struct btd_adapter *adapter = device_get_adapter(device); bdaddr_t dba; int err; size_t len; char rawpin[16]; device_get_address(device, &dba); len = decode_pin(pincode, rawpin); if (derr || !len) { err = btd_adapter_pincode_reply(adapter, &dba, NULL, 0); if (err < 0) goto fail; return; } err = btd_adapter_pincode_reply(adapter, &dba, rawpin, len); if (err < 0) goto fail; return; fail: error("Sending PIN code reply failed: %s (%d)", strerror(-err), -err); }
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; }
static struct input_device *input_device_new(struct btd_service *service) { struct btd_device *device = btd_service_get_device(service); struct btd_profile *p = btd_service_get_profile(service); const char *path = device_get_path(device); const sdp_record_t *rec = btd_device_get_record(device, p->remote_uuid); struct btd_adapter *adapter = device_get_adapter(device); struct input_device *idev; char name[HCI_MAX_NAME_LENGTH + 1]; idev = g_new0(struct input_device, 1); bacpy(&idev->src, btd_adapter_get_address(adapter)); bacpy(&idev->dst, device_get_address(device)); idev->service = btd_service_ref(service); idev->device = btd_device_ref(device); idev->path = g_strdup(path); idev->handle = rec->handle; idev->disable_sdp = is_device_sdp_disable(rec); device_get_name(device, name, HCI_MAX_NAME_LENGTH); if (strlen(name) > 0) idev->name = g_strdup(name); /* Initialize device properties */ extract_hid_props(idev, rec); return idev; }
static void pincode_cb(struct agent *agent, DBusError *derr, const char *pincode, struct btd_device *device) { struct btd_adapter *adapter = device_get_adapter(device); bdaddr_t dba; int err; device_get_address(device, &dba, NULL); if (derr) { err = btd_adapter_pincode_reply(adapter, &dba, NULL, 0); if (err < 0) goto fail; return; } err = btd_adapter_pincode_reply(adapter, &dba, pincode, pincode ? strlen(pincode) : 0); if (err < 0) goto fail; return; fail: error("Sending PIN code reply failed: %s (%d)", strerror(-err), -err); }
static DBusMessage *set_link_loss_alert(DBusConnection *conn, DBusMessage *msg, const char *level, void *data) { struct monitor *monitor = data; struct btd_device *device = monitor->device; bdaddr_t sba, dba; if (!level_is_valid(level)) return btd_error_invalid_args(msg); if (g_strcmp0(monitor->linklosslevel, level) == 0) return dbus_message_new_method_return(msg); g_free(monitor->linklosslevel); monitor->linklosslevel = g_strdup(level); adapter_get_address(device_get_adapter(device), &sba); device_get_address(device, &dba); write_proximity_config(&sba, &dba, "LinkLossAlertLevel", level); if (monitor->attrib) write_alert_level(monitor); return dbus_message_new_method_return(msg); }
static int hid_device_probe(struct btd_device *device, GSList *uuids) { struct btd_adapter *adapter = device_get_adapter(device); const gchar *path = device_get_path(device); const sdp_record_t *rec = btd_device_get_record(device, uuids->data); bdaddr_t src, dst; sdp_data_t *pdlist; DBG("path %s", path); if (!rec) return -1; adapter_get_address(adapter, &src); device_get_address(device, &dst); if (rec) pdlist = sdp_data_get(rec, SDP_ATTR_HID_SDP_DISABLE); if (pdlist && pdlist->val.uint8) { DBG("cancel discovery is issued"); bt_cancel_discovery(&src, &dst); } return input_device_register(connection, device, path, &src, &dst, HID_UUID, rec->handle, idle_timeout * 60); }
static void avctp_control_confirm(struct avctp *session, GIOChannel *chan, struct btd_device *dev) { const bdaddr_t *src; const bdaddr_t *dst; if (session->control != NULL) { error("Control: Refusing unexpected connect"); g_io_channel_shutdown(chan, TRUE, NULL); return; } avctp_set_state(session, AVCTP_STATE_CONNECTING); session->control = avctp_channel_create(session, chan, NULL); src = adapter_get_address(device_get_adapter(dev)); dst = device_get_address(dev); session->auth_id = btd_request_authorization(src, dst, AVRCP_TARGET_UUID, auth_cb, session); if (session->auth_id == 0) goto drop; session->control->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL, session_cb, session); return; drop: avctp_set_state(session, AVCTP_STATE_DISCONNECTED); }
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 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; }
static void sixaxis_sdp_cb(struct btd_device *dev, int err, void *user_data) { struct sixaxis_data *data = user_data; const bdaddr_t *src; DBG("err %d (%s)", err, strerror(-err)); if (err < 0) goto fail; src = btd_adapter_get_address(device_get_adapter(dev)); if (input_device_set_channel(src, device_get_address(dev), data->psm, data->chan) < 0) goto fail; g_io_channel_unref(data->chan); g_free(data); return; fail: g_io_channel_shutdown(data->chan, TRUE, NULL); g_io_channel_unref(data->chan); g_free(data); }
static void confirm_cb(struct agent *agent, DBusError *err, void *user_data) { struct btd_device *device = user_data; struct btd_adapter *adapter = device_get_adapter(device); gboolean success = (err == NULL) ? TRUE : FALSE; confirm_reply(adapter, device, success); }
static void gatt_get_address(struct gatt_service *gatt, bdaddr_t *sba, bdaddr_t *dba) { struct btd_device *device = gatt->dev; struct btd_adapter *adapter; adapter = device_get_adapter(device); adapter_get_address(adapter, sba); device_get_address(device, dba, NULL); }
void reporter_device_remove(struct btd_profile *p, struct btd_device *device) { struct reporter_adapter *radapter; struct btd_adapter *adapter = device_get_adapter(device); radapter = find_reporter_adapter(adapter); if (!radapter) return; unregister_reporter_device(device, radapter); }
static int reporter_device_probe(struct btd_device *device, GSList *uuids) { struct reporter_adapter *radapter; struct btd_adapter *adapter = device_get_adapter(device); radapter = find_reporter_adapter(adapter); if (!radapter) return -1; register_reporter_device(device, radapter); return 0; }
static int network_probe(struct btd_device *device, GSList *uuids, uint16_t id) { struct btd_adapter *adapter = device_get_adapter(device); const gchar *path = device_get_path(device); bdaddr_t src, dst; DBG("path %s", path); adapter_get_address(adapter, &src); device_get_address(device, &dst); return connection_register(device, path, &src, &dst, id); }
static struct media_adapter *find_adapter(struct btd_device *device) { GSList *l; for (l = adapters; l; l = l->next) { struct media_adapter *adapter = l->data; if (adapter->btd_adapter == device_get_adapter(device)) return adapter; } return NULL; }
static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey, void *user_data) { struct btd_device *device = user_data; struct btd_adapter *adapter = device_get_adapter(device); bdaddr_t bdaddr; device_get_address(device, &bdaddr); if (err) passkey = INVALID_PASSKEY; btd_adapter_passkey_reply(adapter, &bdaddr, passkey); }
int reporter_device_probe(struct btd_service *service) { struct btd_device *device = btd_service_get_device(service); struct reporter_adapter *radapter; struct btd_adapter *adapter = device_get_adapter(device); radapter = find_reporter_adapter(adapter); if (!radapter) return -1; register_reporter_device(device, radapter); return 0; }
static int csc_device_probe(struct btd_service *service) { struct btd_device *device = btd_service_get_device(service); struct btd_adapter *adapter; struct csc_adapter *cadapter; struct csc *csc; struct gatt_primary *prim; prim = btd_device_get_primary(device, CYCLING_SC_UUID); if (prim == NULL) return -EINVAL; adapter = device_get_adapter(device); cadapter = find_csc_adapter(adapter); if (cadapter == NULL) return -1; csc = g_new0(struct csc, 1); csc->dev = btd_device_ref(device); csc->cadapter = cadapter; if (!g_dbus_register_interface(btd_get_dbus_connection(), device_get_path(device), CYCLINGSPEED_INTERFACE, cyclingspeed_device_methods, NULL, cyclingspeed_device_properties, csc, destroy_csc)) { error("D-Bus failed to register %s interface", CYCLINGSPEED_INTERFACE); destroy_csc(csc); return -EIO; } csc->svc_range = g_new0(struct att_range, 1); csc->svc_range->start = prim->range.start; csc->svc_range->end = prim->range.end; cadapter->devices = g_slist_prepend(cadapter->devices, csc); csc->attioid = btd_device_add_attio_callback(device, attio_connected_cb, attio_disconnected_cb, csc); return 0; }
const char *imm_alert_get_level(struct btd_device *device) { struct imm_alert_adapter *imadapter; struct connected_device *condev; if (!device) return get_alert_level_string(NO_ALERT); imadapter = find_imm_alert_adapter(device_get_adapter(device)); if (!imadapter) return get_alert_level_string(NO_ALERT); condev = find_connected_device(imadapter, device); if (!condev) return get_alert_level_string(NO_ALERT); return get_alert_level_string(condev->alert_level); }
static int hid_device_probe(struct btd_device *device, GSList *uuids) { struct btd_adapter *adapter = device_get_adapter(device); const gchar *path = device_get_path(device); const sdp_record_t *rec = btd_device_get_record(device, uuids->data); bdaddr_t src, dst; DBG("path %s", path); if (!rec) return -1; adapter_get_address(adapter, &src); device_get_address(device, &dst, NULL); return input_device_register(connection, device, path, &src, &dst, HID_UUID, rec, idle_timeout * 60); }
static int heartrate_device_register(struct btd_device *device, struct gatt_primary *prim) { struct btd_adapter *adapter; struct heartrate_adapter *hradapter; struct heartrate *hr; adapter = device_get_adapter(device); hradapter = find_heartrate_adapter(adapter); if (hradapter == NULL) return -1; hr = g_new0(struct heartrate, 1); hr->dev = btd_device_ref(device); hr->hradapter = hradapter; if (!g_dbus_register_interface(btd_get_dbus_connection(), device_get_path(device), HEART_RATE_INTERFACE, heartrate_device_methods, NULL, heartrate_device_properties, hr, destroy_heartrate)) { error("D-Bus failed to register %s interface", HEART_RATE_INTERFACE); destroy_heartrate(hr); return -EIO; } hr->svc_range = g_new0(struct att_range, 1); hr->svc_range->start = prim->range.start; hr->svc_range->end = prim->range.end; hradapter->devices = g_slist_prepend(hradapter->devices, hr); hr->attioid = btd_device_add_attio_callback(device, attio_connected_cb, attio_disconnected_cb, hr); return 0; }
static int audio_probe(struct btd_device *device, GSList *uuids) { struct btd_adapter *adapter = device_get_adapter(device); bdaddr_t src, dst; struct audio_device *audio_dev; adapter_get_address(adapter, &src); //device_get_address(device, &dst); device_get_address(device, &dst, NULL); audio_dev = manager_get_device(&src, &dst, TRUE); if (!audio_dev) { DBG("unable to get a device object"); return -1; } g_slist_foreach(uuids, (GFunc) handle_uuid, audio_dev); return 0; }
int monitor_register(DBusConnection *conn, struct btd_device *device, struct att_primary *linkloss, struct att_primary *txpower, struct att_primary *immediate, struct enabled *enabled) { const char *path = device_get_path(device); struct monitor *monitor; bdaddr_t sba, dba; char *level; adapter_get_address(device_get_adapter(device), &sba); device_get_address(device, &dba); level = read_proximity_config(&sba, &dba, "LinkLossAlertLevel"); monitor = g_new0(struct monitor, 1); monitor->device = btd_device_ref(device); monitor->conn = dbus_connection_ref(conn); monitor->linklosslevel = (level ? : g_strdup("high")); monitor->signallevel = g_strdup("unknown"); monitor->immediatelevel = g_strdup("none"); if (g_dbus_register_interface(conn, path, PROXIMITY_INTERFACE, monitor_methods, monitor_signals, NULL, monitor, monitor_destroy) == FALSE) { error("D-Bus failed to register %s interface", PROXIMITY_INTERFACE); monitor_destroy(monitor); return -1; } DBG("Registered interface %s on path %s", PROXIMITY_INTERFACE, path); if (linkloss && enabled->linkloss) { monitor->linkloss = g_new0(struct att_range, 1); monitor->linkloss->start = linkloss->start; monitor->linkloss->end = linkloss->end; monitor->enabled.linkloss = TRUE; }