int manager_update_adapter(uint16_t dev_id, uint8_t svc) { struct btd_adapter *adapter; adapter = manager_find_adapter_by_id(dev_id); if (!adapter) return -EINVAL; return adapter_update(adapter, svc); }
int manager_get_adapter_class(uint16_t dev_id, uint8_t *cls) { struct btd_adapter *adapter; adapter = manager_find_adapter_by_id(dev_id); if (!adapter) return -EINVAL; return adapter_get_class(adapter, cls); }
int manager_idle_adapter(int id) { struct btd_adapter *adapter; adapter = manager_find_adapter_by_id(id); if (!adapter) { error("Getting device data failed: hci%d", id); return -EINVAL; } return adapter_idle(adapter); }
int btd_manager_unregister_adapter(int id) { struct btd_adapter *adapter; const gchar *path; adapter = manager_find_adapter_by_id(id); if (!adapter) return -1; path = adapter_get_path(adapter); info("Unregister path: %s", path); manager_remove_adapter(adapter); return 0; }
static void read_local_oob_data_failed(int sk, uint16_t index) { struct btd_adapter *adapter; if (index > max_index) { error("Unexpected index %u in read_local_oob_data_failed", index); return; } DBG("hci%u", index); adapter = manager_find_adapter_by_id(index); if (adapter) oob_read_local_data_complete(adapter, NULL, NULL); }
struct btd_adapter *btd_manager_register_adapter(int id, gboolean up) { struct btd_adapter *adapter; const char *path; adapter = manager_find_adapter_by_id(id); if (adapter) { error("Unable to register adapter: hci%d already exist", id); return NULL; } adapter = adapter_create(connection, id); if (!adapter) return NULL; adapters = g_slist_append(adapters, adapter); if (!adapter_init(adapter, up)) { adapters = g_slist_remove(adapters, adapter); btd_adapter_unref(adapter); return NULL; } path = adapter_get_path(adapter); g_dbus_emit_signal(connection, "/", MANAGER_INTERFACE, "AdapterAdded", DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); manager_update_adapters(); btd_stop_exit_timer(); if (default_adapter_id < 0) manager_set_default_adapter(id); if (main_opts.did_source) btd_adapter_set_did(adapter, main_opts.did_vendor, main_opts.did_product, main_opts.did_version, main_opts.did_source); DBG("Adapter %s registered", path); return btd_adapter_ref(adapter); }
static DBusMessage *find_adapter(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; struct adapter *adapter; char *path; struct hci_dev_info di; const char *pattern; int dev_id; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_INVALID)) return NULL; /* hci_devid() would make sense to use here, except it is restricted to devices which are up */ if (!strncmp(pattern, "hci", 3) && strlen(pattern) >= 4) dev_id = atoi(pattern + 3); else dev_id = find_by_address(pattern); if (dev_id < 0) return no_such_adapter(msg); if (hci_devinfo(dev_id, &di) < 0) return no_such_adapter(msg); if (hci_test_bit(HCI_RAW, &di.flags)) return no_such_adapter(msg); adapter = manager_find_adapter_by_id(dev_id); if (!adapter) return no_such_adapter(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; path = adapter->path + ADAPTER_PATH_INDEX; dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); return reply; }
int manager_register_adapter(int id, gboolean devup) { struct btd_adapter *adapter; adapter = manager_find_adapter_by_id(id); if (adapter) { error("Unable to register adapter: hci%d already exist", id); return -1; } adapter = adapter_create(connection, id, devup); if (!adapter) return -1; adapters = g_slist_append(adapters, adapter); return 0; }
static DBusMessage *find_adapter(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; struct btd_adapter *adapter; const char *pattern; int dev_id; const gchar *path; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_INVALID)) return NULL; /* hci_devid() would make sense to use here, except it is * restricted to devices which are up */ if (!strcmp(pattern, "any") || !strcmp(pattern, "00:00:00:00:00:00")) { path = adapter_any_get_path(); if (path != NULL) goto done; return btd_error_no_such_adapter(msg); } else if (!strncmp(pattern, "hci", 3) && strlen(pattern) >= 4) { dev_id = atoi(pattern + 3); adapter = manager_find_adapter_by_id(dev_id); } else { bdaddr_t bdaddr; str2ba(pattern, &bdaddr); adapter = manager_find_adapter(&bdaddr); } if (!adapter) return btd_error_no_such_adapter(msg); path = adapter_get_path(adapter); done: reply = dbus_message_new_method_return(msg); if (!reply) return NULL; dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); return reply; }
static void manager_set_default_adapter(int id) { struct btd_adapter *adapter; const gchar *path; default_adapter_id = id; adapter = manager_find_adapter_by_id(id); if (!adapter) return; path = adapter_get_path(adapter); g_dbus_emit_signal(connection, "/", MANAGER_INTERFACE, "DefaultAdapterChanged", DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); }
void manager_set_default_adapter(int id) { struct adapter *adapter = manager_find_adapter_by_id(id); const char *ptr = adapter->path + ADAPTER_PATH_INDEX; default_adapter_id = id; if (hcid_dbus_use_experimental()) g_dbus_emit_signal(connection, "/", MANAGER_INTERFACE, "DefaultAdapterChanged", DBUS_TYPE_OBJECT_PATH, &ptr, DBUS_TYPE_INVALID); g_dbus_emit_signal(connection, BASE_PATH, MANAGER_INTERFACE, "DefaultAdapterChanged", DBUS_TYPE_STRING, &adapter->path, DBUS_TYPE_INVALID); }
int manager_start_adapter(int id) { struct btd_adapter* adapter; int ret; adapter = manager_find_adapter_by_id(id); if (!adapter) { error("Getting device data failed: hci%d", id); return -EINVAL; } ret = adapter_start(adapter); if (ret < 0) return ret; if (default_adapter_id < 0) manager_set_default_adapter(id); return ret; }
static DBusMessage *default_adapter(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; struct adapter *adapter; char *path; adapter = manager_find_adapter_by_id(default_adapter_id); if (!adapter) return no_such_adapter(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; path = adapter->path + ADAPTER_PATH_INDEX; dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); return reply; }
static void read_local_oob_data_complete(int sk, uint16_t index, void *buf, size_t len) { struct mgmt_rp_read_local_oob_data *rp = buf; struct btd_adapter *adapter; if (len != sizeof(*rp)) { error("Wrong read_local_oob_data_complete event size"); return; } if (index > max_index) { error("Unexpected index %u in read_local_oob_data_complete", index); return; } DBG("hci%u", index); adapter = manager_find_adapter_by_id(index); if (adapter) oob_read_local_data_complete(adapter, rp->hash, rp->randomizer); }
static gboolean rfkill_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[32]; struct rfkill_event *event = (void *) buf; struct btd_adapter *adapter; char sysname[PATH_MAX]; ssize_t len; int fd, id; if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) return FALSE; fd = g_io_channel_unix_get_fd(chan); memset(buf, 0, sizeof(buf)); len = read(fd, buf, sizeof(buf)); if (len < 0) { if (errno == EAGAIN) return TRUE; return FALSE; } if (len != sizeof(struct rfkill_event)) return TRUE; DBG("RFKILL event idx %u type %u op %u soft %u hard %u", event->idx, event->type, event->op, event->soft, event->hard); if (event->soft || event->hard) return TRUE; if (event->op != RFKILL_OP_CHANGE) return TRUE; if (event->type != RFKILL_TYPE_BLUETOOTH && event->type != RFKILL_TYPE_ALL) return TRUE; snprintf(sysname, sizeof(sysname) - 1, "/sys/class/rfkill/rfkill%u/name", event->idx); fd = open(sysname, O_RDONLY); if (fd < 0) return TRUE; memset(sysname, 0, sizeof(sysname)); if (read(fd, sysname, sizeof(sysname)) < 4) { close(fd); return TRUE; } close(fd); if (g_str_has_prefix(sysname, "hci") == FALSE) return TRUE; id = atoi(sysname + 3); if (id < 0) return TRUE; adapter = manager_find_adapter_by_id(id); if (!adapter) return TRUE; DBG("RFKILL unblock for hci%d", id); btd_adapter_restore_powered(adapter); return TRUE; }
struct btd_adapter *manager_get_default_adapter(void) { return manager_find_adapter_by_id(default_adapter_id); }