static void mgmt_discovering(int sk, uint16_t index, void *buf, size_t len) { struct mgmt_mode *ev = buf; struct controller_info *info; struct btd_adapter *adapter; int state; if (len < sizeof(*ev)) { error("Too small discovering event"); return; } DBG("Controller %u discovering %u", index, ev->val); if (index > max_index) { error("Unexpected index %u in discovering event", index); return; } info = &controllers[index]; adapter = manager_find_adapter(&info->bdaddr); if (!adapter) return; if (ev->val) state = STATE_DISCOV; else state = STATE_IDLE; adapter_set_state(adapter, state); }
static struct btd_device *device_for_connection(const bdaddr_t *src, const bdaddr_t *dst) { struct btd_adapter *adapter; struct btd_device *device; char sstr[18]; char dstr[18]; ba2str(src, sstr); ba2str(dst, dstr); adapter = manager_find_adapter(src); if (adapter == NULL) { DBG("No adapter for address %s.", sstr); return NULL; } DBG("Adapter found."); device = adapter_find_device(adapter, dstr); if (device == NULL) { DBG("No device for address %s.", dstr); return NULL; } return device; }
static void mgmt_pairable(int sk, uint16_t index, void *buf, size_t len) { struct mgmt_mode *ev = buf; struct controller_info *info; struct btd_adapter *adapter; if (len < sizeof(*ev)) { error("Too small pairable event"); return; } DBG("Controller %u pairable %u", index, ev->val); if (index > max_index) { error("Unexpected index %u in pairable event", index); return; } info = &controllers[index]; info->pairable = ev->val ? TRUE : FALSE; adapter = manager_find_adapter(&info->bdaddr); if (!adapter) return; btd_adapter_pairable_changed(adapter, info->pairable); }
static void set_local_name_complete(int sk, uint16_t index, void *buf, size_t len) { struct mgmt_cp_set_local_name *rp = buf; struct controller_info *info; struct btd_adapter *adapter; if (len < sizeof(*rp)) { error("Too small set_local_name complete event"); return; } DBG("hci%d name %s", index, (char *) rp->name); if (index > max_index) { error("Unexpected index %u in set_local_name complete", index); return; } info = &controllers[index]; adapter = manager_find_adapter(&info->bdaddr); if (adapter == NULL) { DBG("Adapter not found"); return; } adapter_update_local_name(adapter, (char *) rp->name); }
static gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst, struct btd_adapter **adapter, struct btd_device **device, gboolean create) { char peer_addr[18]; *adapter = manager_find_adapter(src); if (!*adapter) { error("Unable to find matching adapter"); return FALSE; } ba2str(dst, peer_addr); if (create) *device = adapter_get_device(connection, *adapter, peer_addr); else *device = adapter_find_device(*adapter, peer_addr); if (create && !*device) { error("Unable to get device object!"); return FALSE; } return TRUE; }
void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info) { struct btd_adapter *adapter; struct eir_data eir_data; int8_t rssi; int err; adapter = manager_find_adapter(local); if (adapter == NULL) { error("No matching adapter found"); return; } memset(&eir_data, 0, sizeof(eir_data)); err = parse_eir_data(&eir_data, info->data, info->length); if (err < 0) error("Error parsing advertising data: %s (%d)", strerror(-err), -err); rssi = *(info->data + info->length); adapter_update_device_from_info(adapter, info->bdaddr, rssi, info->evt_type, eir_data.name, eir_data.services, eir_data.flags); free_eir_data(&eir_data); }
static void set_pairable_complete(int sk, void *buf, size_t len) { struct mgmt_mode *rp = buf; struct controller_info *info; struct btd_adapter *adapter; uint16_t index; if (len < sizeof(*rp)) { error("Too small set pairable complete event"); return; } index = btohs(bt_get_unaligned(&rp->index)); DBG("hci%d pairable %u", index, rp->val); if (index > max_index) { error("Unexpected index %u in pairable complete", index); return; } info = &controllers[index]; info->pairable = rp->val ? TRUE : FALSE; adapter = manager_find_adapter(&info->bdaddr); if (!adapter) return; btd_adapter_pairable_changed(adapter, info->pairable); }
static void set_connectable_complete(int sk, uint16_t index, void *buf, size_t len) { struct mgmt_mode *rp = buf; struct controller_info *info; struct btd_adapter *adapter; if (len < sizeof(*rp)) { error("Too small set connectable complete event"); return; } DBG("hci%d connectable %u", index, rp->val); if (index > max_index) { error("Unexpected index %u in connectable complete", index); return; } info = &controllers[index]; info->connectable = rp->val ? TRUE : FALSE; adapter = manager_find_adapter(&info->bdaddr); if (adapter) adapter_mode_changed(adapter, rp->val ? SCAN_PAGE : 0); }
static int mgmt_update_powered(int index, uint8_t powered) { struct controller_info *info; struct btd_adapter *adapter; gboolean pairable, discoverable; uint8_t on_mode; if (index > max_index) { error("Unexpected index %u", index); return -ENODEV; } info = &controllers[index]; info->enabled = powered; adapter = manager_find_adapter(&info->bdaddr); if (adapter == NULL) { DBG("Adapter not found"); return -ENODEV; } if (!powered) { info->connectable = FALSE; info->pairable = FALSE; info->discoverable = FALSE; btd_adapter_stop(adapter); return 0; } btd_adapter_start(adapter); btd_adapter_get_mode(adapter, NULL, &on_mode, &pairable); discoverable = (on_mode == MODE_DISCOVERABLE); if (on_mode == MODE_DISCOVERABLE && !info->discoverable) mgmt_set_discoverable(index, TRUE); else if (on_mode == MODE_CONNECTABLE && !info->connectable) mgmt_set_connectable(index, TRUE); else { uint8_t mode = 0; if (info->connectable) mode |= SCAN_PAGE; if (info->discoverable) mode |= SCAN_INQUIRY; adapter_mode_changed(adapter, mode); } if (info->pairable != pairable) mgmt_set_pairable(index, pairable); return 0; }
static struct btd_device *get_btd_dev(bdaddr_t *src, const char *addr) { struct btd_adapter *adapter; adapter = manager_find_adapter(src); if (!adapter) return NULL; return adapter_get_device(adapter, addr); }
void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer, gboolean legacy) { struct btd_adapter *adapter; struct remote_dev_info *dev; adapter = manager_find_adapter(local); if (!adapter) { error("No matching adapter found"); return; } dev = adapter_search_found_devices(adapter, peer); if (dev) dev->legacy = legacy; }
/* 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 = manager_find_adapter(&mcl->mi->src); if (!adapter) return FALSE; if (btd_adapter_read_clock(adapter, &mcl->addr, which, 1000, btclock, btaccuracy) < 0) return FALSE; return TRUE; }
struct audio_device *manager_get_device(const bdaddr_t *src, const bdaddr_t *dst, gboolean create) { struct audio_device *dev; struct btd_adapter *adapter; struct btd_device *device; char addr[18]; const char *path; dev = manager_find_device(NULL, src, dst, NULL, FALSE); if (dev) return dev; if (!create) return NULL; ba2str(src, addr); adapter = manager_find_adapter(src); if (!adapter) { error("Unable to get a btd_adapter object for %s", addr); return NULL; } ba2str(dst, addr); device = adapter_get_device(connection, adapter, addr); if (!device) { error("Unable to get btd_device object for %s", addr); return NULL; } path = device_get_path(device); dev = audio_device_register(connection, device, path, src, dst); if (!dev) return NULL; devices = g_slist_append(devices, dev); return dev; }
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; }
void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type, int8_t rssi, uint8_t confirm_name, uint8_t *data, uint8_t data_len) { struct btd_adapter *adapter; adapter = manager_find_adapter(local); if (!adapter) { error("No matching adapter found"); return; } update_lastseen(local, peer); if (data) write_remote_eir(local, peer, data, data_len); adapter_update_found_devices(adapter, peer, bdaddr_type, rssi, confirm_name, data, data_len); }
static void mgmt_connectable(int sk, void *buf, size_t len) { struct mgmt_mode *ev = buf; struct controller_info *info; struct btd_adapter *adapter; uint16_t index; uint8_t mode; if (len < sizeof(*ev)) { error("Too small connectable event"); return; } index = btohs(bt_get_unaligned(&ev->index)); DBG("Controller %u connectable %u", index, ev->val); if (index > max_index) { error("Unexpected index %u in connectable event", index); return; } info = &controllers[index]; info->connectable = ev->val ? TRUE : FALSE; adapter = manager_find_adapter(&info->bdaddr); if (!adapter) return; if (info->discoverable) mode = SCAN_INQUIRY; else mode = 0; if (info->connectable) mode |= SCAN_PAGE; adapter_mode_changed(adapter, mode); }
static void set_discoverable_complete(int sk, void *buf, size_t len) { struct mgmt_mode *rp = buf; struct controller_info *info; struct btd_adapter *adapter; uint16_t index; uint8_t mode; if (len < sizeof(*rp)) { error("Too small set discoverable complete event"); return; } index = btohs(bt_get_unaligned(&rp->index)); DBG("hci%d discoverable %u", index, rp->val); if (index > max_index) { error("Unexpected index %u in discoverable complete", index); return; } info = &controllers[index]; info->discoverable = rp->val ? TRUE : FALSE; adapter = manager_find_adapter(&info->bdaddr); if (!adapter) return; /* set_discoverable will always also change page scanning */ mode = SCAN_PAGE; if (info->discoverable) mode |= SCAN_INQUIRY; adapter_mode_changed(adapter, mode); }
static void mgmt_local_name_changed(int sk, uint16_t index, void *buf, size_t len) { struct mgmt_cp_set_local_name *ev = buf; struct controller_info *info; struct btd_adapter *adapter; if (len < sizeof(*ev)) { error("Too small mgmt_local_name_changed event packet"); return; } DBG("hci%u local name changed: %s", index, (char *) ev->name); if (index > max_index) { error("Unexpected index %u in name_changed event", index); return; } info = &controllers[index]; adapter = manager_find_adapter(&info->bdaddr); if (adapter) adapter_update_local_name(adapter, (char *) ev->name); }
{ time_t t; struct tm *tm; t = time(NULL); tm = gmtime(&t); write_lastused_info(sba, dba, tm); } void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi, uint8_t *data) { struct btd_adapter *adapter; adapter = manager_find_adapter(local); if (!adapter) { error("No matching adapter found"); return; } update_lastseen(local, peer); write_remote_class(local, peer, class); if (data) write_remote_eir(local, peer, data); adapter_update_found_devices(adapter, peer, class, rssi, data); } void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer,