static int device_cmp(gconstpointer s, gconstpointer user_data) { const struct a2dp_device *dev = s; const bdaddr_t *dst = user_data; return bacmp(&dev->dst, dst); }
static void rewrite_bdaddr(unsigned char *buf, int len, bdaddr_t *bdaddr) { hci_event_hdr *eh; unsigned char *ptr = buf; int type; if (!bdaddr) return; if (!bacmp(bdaddr, BDADDR_ANY)) return; type = *ptr++; switch (type) { case HCI_EVENT_PKT: eh = (hci_event_hdr *) ptr; ptr += HCI_EVENT_HDR_SIZE; if (eh->evt == EVT_CMD_COMPLETE) { evt_cmd_complete *cc = (void *) ptr; ptr += EVT_CMD_COMPLETE_SIZE; if (cc->opcode == htobs(cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BD_ADDR))) { bacpy((bdaddr_t *) (ptr + 1), bdaddr); } } break; } }
static bool match_dev_by_addr(const void *data, const void *user_data) { const struct health_device *dev = data; const bdaddr_t *addr = user_data; return !bacmp(&dev->dst, addr); }
void manager_update_svc(const bdaddr_t *bdaddr, uint8_t svc) { GSList *l; bdaddr_t src; for (l = adapters; l != NULL; l = l->next) { struct btd_adapter *adapter = l->data; adapter_get_address(adapter, &src); if (bacmp(bdaddr, BDADDR_ANY) != 0 && bacmp(bdaddr, &src) != 0) continue; adapter_update(adapter, svc); } }
HCI::optional HCI::getConnHandle(device &dev) { conn_info info; info.req.conn_num = 1; info.req.dev_id = _dev_id; if(ioctl(_hci_sock, HCIGETCONNLIST, &info) < 0) { err::code = err::LIB_SYS; return optional(); } uint16_t handle; for(hci_conn_info &x: info.info) { if(bacmp(&x.bdaddr, &dev.bdaddr) == 0) { handle = x.handle; return optional(handle); } } return optional(); }
static gint server_cmp(gconstpointer a, gconstpointer b) { const struct dun_server *server = a; const bdaddr_t *src = b; return bacmp(src, &server->bda); }
gboolean manager_allow_headset_connection(struct audio_device *device) { GSList *l; int connected = 0; for (l = devices; l != NULL; l = l->next) { struct audio_device *dev = l->data; struct headset *hs = dev->headset; if (dev == device) continue; if (bacmp(&dev->src, &device->src)) continue; if (!hs) continue; if (headset_get_state(dev) > HEADSET_STATE_DISCONNECTED) connected++; if (connected >= max_connected_headsets) return FALSE; } return TRUE; }
int find_conn(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; int i; int ret = 0; if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) goto out; cl->dev_id = dev_id; cl->conn_num = 10; ci = cl->conn_info; if (ioctl(s, HCIGETCONNLIST, (void *) cl)) goto out; for (i = 0; i < cl->conn_num; i++, ci++) if (!bacmp((bdaddr_t *) arg, &ci->bdaddr)) { ret = 1; goto out; } out: free(cl); return ret; }
static int server_cmp(gconstpointer s, gconstpointer user_data) { const struct input_server *server = s; const bdaddr_t *src = user_data; return bacmp(&server->src, src); }
static int find_conn(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; int i; if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { perror("Can't allocate memory\n"); exit(1); } cl->dev_id = dev_id; cl->conn_num = 10; ci = cl->conn_info; if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { perror("Can't get connection list\n"); exit(1); } for (i=0; i < cl->conn_num; i++, ci++) { if (!bacmp((bdaddr_t *)arg, &ci->bdaddr)) { return 1; } } return 0; }
int handle_confirm_request(DBusConnection *conn, int dev, const char *path, bdaddr_t *sba, bdaddr_t *dba, const char *pin) { struct passkey_agent *agent = default_agent; struct adapter *adapter = NULL; GSList *l; char addr[18]; void *data; dbus_connection_get_object_user_data(conn, path, &data); if (!data) goto done; adapter = data; if (!bacmp(&adapter->agents_disabled, dba)) goto done; ba2str(dba, addr); for (l = adapter->passkey_agents; l != NULL; l = l->next) { struct passkey_agent *a = l->data; if (a != default_agent && g_slist_length(a->pending_requests) >= 1) continue; if (!strcmp(a->addr, addr)) { agent = a; break; } } done: return call_confirm_agent(conn, agent, dev, path, sba, dba, pin); }
int btbcm_check_bdaddr(struct hci_dev *hdev) { struct hci_rp_read_bd_addr *bda; struct sk_buff *skb; skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { int err = PTR_ERR(skb); BT_ERR("%s: BCM: Reading device address failed (%d)", hdev->name, err); return err; } if (skb->len != sizeof(*bda)) { BT_ERR("%s: BCM: Device address length mismatch", hdev->name); kfree_skb(skb); return -EIO; } bda = (struct hci_rp_read_bd_addr *)skb->data; /* Check if the address indicates a controller with either an * invalid or default address. In both cases the device needs * to be marked as not having a valid address. * * The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller * with no configured address. * * The address 43:24:B3:00:00:00 indicates a BCM4324B3 controller * with waiting for configuration state. * * The address 43:30:B1:00:00:00 indicates a BCM4330B1 controller * with waiting for configuration state. */ if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) || !bacmp(&bda->bdaddr, BDADDR_BCM4324B3) || !bacmp(&bda->bdaddr, BDADDR_BCM4330B1)) { BT_INFO("%s: BCM: Using default device address (%pMR)", hdev->name, &bda->bdaddr); set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); } kfree_skb(skb); return 0; }
/* -------- Socket interface ---------- */ static struct sock *__l2cap_get_sock_by_addr(__u16 psm, bdaddr_t *src) { struct sock *sk; for (sk = l2cap_sk_list.head; sk; sk = sk->next) { if (sk->sport == psm && !bacmp(&bluez_pi(sk)->src, src)) break; } return sk; }
/* * Add entry to the new inq. If it is not also * in the old inq, report adds. */ void reporter_add(inquiry_info* newthingy) { char ieeeaddr[18]; int i; inquiry_info *rstore; /* make storage bigger for bluetooth object if needed */ entries1++; if ((entries1 * INQUIRY_INFO_SIZE) > capacity1) { capacity1 = entries1 * INQUIRY_INFO_SIZE; rstore = realloc(store1, capacity1); if (rstore == NULL) { perror("I cannot allocate any more memory for new device, but continuing anyways... :-/"); return; } store1 = rstore; } /* store in the array */ *(store1+(entries1-1)) = *newthingy; /* find out if new object is in the old array... C cannot compare structures on its own... */ for (i = 0; i < entries2; i++) { if (0 == bacmp(&((store2+i)->bdaddr),&(newthingy->bdaddr))) { if (debug) { ba2str(&(newthingy->bdaddr), ieeeaddr); printf("= %s %02x %02x %04x ", ieeeaddr, newthingy->pscan_rep_mode, newthingy->pscan_mode, newthingy->clock_offset); classinfo(newthingy->dev_class); printf("\n"); } return; } } /* it isn't ... report it to chatbot... * we report the clock offset as it is used to quickly home in on the radio frequency (in the channel hopping sequence) * that the target is operating on, when we want to send a command to a device. * * just for fun when you are running this program in debug mode, you may see the clock offset drift up and down * slightly, maybe due to doppler effect, interference, etc. * * Time ---> (clock offset) * +---+---+---+---+---+---+---+---+ * R |\ | |/---\ | | /---\ | * F | \ | / | \---\ | /| |\--| * | \---/| | | \--/ | | | * +---+---+---+---+---+---+---+---+ * */ ba2str(&(newthingy->bdaddr), ieeeaddr); printf("+ %s %02x %02x %04x ", ieeeaddr, newthingy->pscan_rep_mode, newthingy->pscan_mode, newthingy->clock_offset); classinfo(newthingy->dev_class); printf("\n"); }
static struct vhci_conn *conn_get_by_bdaddr(bdaddr_t *ba) { register int i; for (i = 0; i < VHCI_MAX_CONN; i++) if (!bacmp(&vconn[i]->dest, ba)) return vconn[i]; return NULL; }
static gint adapter_cmp(gconstpointer a, gconstpointer b) { struct btd_adapter *adapter = (struct btd_adapter *) a; const bdaddr_t *bdaddr = b; bdaddr_t src; adapter_get_address(adapter, &src); return bacmp(&src, bdaddr); }
int sdp_check_access(uint32_t handle, bdaddr_t *device) { sdp_list_t *p = access_locate(handle); sdp_access_t *a; if (!p) return 1; a = p->data; if (!a) return 1; if (bacmp(&a->device, device) && bacmp(&a->device, BDADDR_ANY) && bacmp(device, BDADDR_ANY)) return 0; return 1; }
static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) { struct sock *sk; sk_for_each(sk, &l2cap_sk_list.head) if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src)) goto found; sk = NULL; found: return sk; }
static struct avctp_server *find_server(GSList *list, const bdaddr_t *src) { for (; list; list = list->next) { struct avctp_server *server = list->data; if (bacmp(&server->src, src) == 0) return server; } return NULL; }
/* Find socket with psm and source bdaddr. * Returns closest match. */ static struct sock *__l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src) { struct sock *sk, *sk1 = NULL; for (sk = l2cap_sk_list.head; sk; sk = sk->next) { if (state && sk->state != state) continue; if (l2cap_pi(sk)->psm == psm) { /* Exact match. */ if (!bacmp(&bluez_pi(sk)->src, src)) break; /* Closest match */ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY)) sk1 = sk; } } return sk ? sk : sk1; }
/* -------- Socket interface ---------- */ static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba) { struct sock *sk; for (sk = sco_sk_list.head; sk; sk = sk->next) { if (!bacmp(&bluez_pi(sk)->src, ba)) break; } return sk; }
/* This function is not reentrable */ static struct link_key *__get_link_key(int f, bdaddr_t *sba, bdaddr_t *dba) { static struct link_key k; struct link_key *key = NULL; int r; while ((r = read_n(f, &k, sizeof(k)))) { if (r < 0) { syslog(LOG_ERR, "Link key database read failed: %s (%d)", strerror(errno), errno); break; } if (!bacmp(&k.sba, sba) && !bacmp(&k.dba, dba)) { key = &k; break; } } return key; }
static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr) { struct cmtp_session *session; BT_DBG(""); list_for_each_entry(session, &cmtp_session_list, list) if (!bacmp(bdaddr, &session->bdaddr)) return session; return NULL; }
static struct a2dp_server *find_server(GSList *list, const bdaddr_t *src) { GSList *l; for (l = list; l; l = l->next) { struct a2dp_server *server = l->data; if (bacmp(&server->src, src) == 0) return server; } return NULL; }
static struct mcap_mcl *find_mcl(GSList *list, const bdaddr_t *addr) { struct mcap_mcl *mcl; for (; list; list = list->next) { mcl = list->data; if (!bacmp(&mcl->addr, addr)) return mcl; } return NULL; }
static struct avctp *find_session(GSList *list, const bdaddr_t *dst) { for (; list != NULL; list = g_slist_next(list)) { struct avctp *s = list->data; if (bacmp(dst, &s->dst)) continue; return s; } return NULL; }
static bool setup_device(int fd, int index, struct btd_adapter *adapter) { char device_addr[18], master_addr[18], adapter_addr[18]; bdaddr_t device_bdaddr, master_bdaddr; const bdaddr_t *adapter_bdaddr; struct btd_device *device; if (get_device_bdaddr(fd, &device_bdaddr) < 0) return false; if (get_master_bdaddr(fd, &master_bdaddr) < 0) return false; /* This can happen if controller was plugged while already connected * eg. to charge up battery. * Don't set LEDs in that case, hence return false */ device = btd_adapter_find_device(adapter, &device_bdaddr, BDADDR_BREDR); if (device && btd_device_is_connected(device)) return false; adapter_bdaddr = btd_adapter_get_address(adapter); if (bacmp(adapter_bdaddr, &master_bdaddr)) { if (set_master_bdaddr(fd, adapter_bdaddr) < 0) return false; } ba2str(&device_bdaddr, device_addr); ba2str(&master_bdaddr, master_addr); ba2str(adapter_bdaddr, adapter_addr); DBG("remote %s old_master %s new_master %s", device_addr, master_addr, adapter_addr); device = btd_adapter_get_device(adapter, &device_bdaddr, BDADDR_BREDR); if (g_slist_find_custom(btd_device_get_uuids(device), HID_UUID, (GCompareFunc)strcasecmp)) { DBG("device %s already known, skipping", device_addr); return true; } info("sixaxis: setting up new device"); btd_device_device_set_name(device, devices[index].name); btd_device_set_pnpid(device, devices[index].source, devices[index].vid, devices[index].pid, devices[index].version); btd_device_set_temporary(device, FALSE); return true; }
/* Find socket listening on source bdaddr. * Returns closest match. */ static struct sock *sco_get_sock_listen(bdaddr_t *src) { struct sock *sk, *sk1 = NULL; read_lock(&sco_sk_list.lock); for (sk = sco_sk_list.head; sk; sk = sk->next) { if (sk->state != BT_LISTEN) continue; /* Exact match. */ if (!bacmp(&bluez_pi(sk)->src, src)) break; /* Closest match */ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY)) sk1 = sk; } read_unlock(&sco_sk_list.lock); return sk ? sk : sk1; }
static sdp_session_t *get_sdp_session(const bdaddr_t *src, const bdaddr_t *dst) { GSList *l; for (l = cached_sdp_sessions; l != NULL; l = l->next) { struct cached_sdp_session *c = l->data; sdp_session_t *session; if (bacmp(&c->src, src) || bacmp(&c->dst, dst)) continue; g_source_remove(c->timer); session = c->session; cached_sdp_sessions = g_slist_remove(cached_sdp_sessions, c); g_free(c); return session; } return sdp_connect(src, dst, SDP_NON_BLOCKING); }
static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, struct sk_buff *skb) { struct smp_cmd_ident_addr_info *info = (void *) skb->data; struct smp_chan *smp = conn->smp_chan; struct hci_conn *hcon = conn->hcon; bdaddr_t rpa; BT_DBG(""); if (skb->len < sizeof(*info)) return SMP_UNSPECIFIED; /* Ignore this PDU if it wasn't requested */ if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) return 0; /* Mark the information as received */ smp->remote_key_dist &= ~SMP_DIST_ID_KEY; skb_pull(skb, sizeof(*info)); /* Strictly speaking the Core Specification (4.1) allows sending * an empty address which would force us to rely on just the IRK * as "identity information". However, since such * implementations are not known of and in order to not over * complicate our implementation, simply pretend that we never * received an IRK for such a device. */ if (!bacmp(&info->bdaddr, BDADDR_ANY)) { BT_ERR("Ignoring IRK with no identity address"); smp_distribute_keys(conn); return 0; } bacpy(&smp->id_addr, &info->bdaddr); smp->id_addr_type = info->addr_type; if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type)) bacpy(&rpa, &hcon->dst); else bacpy(&rpa, BDADDR_ANY); smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, smp->id_addr_type, smp->irk, &rpa); smp_distribute_keys(conn); return 0; }