static int write_inquiry_mode(int dev_id, int sock) { struct hci_filter flt; write_inquiry_mode_cp cp; hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("Can't set HCI filter"); return 1; } memset(&cp, 0, sizeof(cp)); cp.mode = 0x01; //cp.mode = 0x00; if (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE,WRITE_INQUIRY_MODE_RP_SIZE, &cp) < 0) { perror("Can't set write inquiry mode"); return 1; } return 0; }
/** send_hciCmd Function * This function takes the hci commands for the BT chip configurations, creates * a hci channel to send the commadns through UART to configure BT chip * * Parameters : * @ dev_id : HCI device ID * @ command_length : Number of arguments of the command * @ command : Pointer to command list * Returns 0 upon success * , different error messages depending upon the error. */ static void send_hciCmd(int dev_id, int command_length, char **command) { unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; int i, opt, len, dd; uint16_t ocf; uint8_t ogf; if (dev_id < 0) dev_id = hci_get_route(NULL); errno = 0; ogf = strtol(command[0], NULL, 16); ocf = strtol(command[1], NULL, 16); for (i = 2, len = 0; i < command_length && len < sizeof(buf); i++, len++) *ptr++ = (uint8_t) strtol(command[i], NULL, 16); dd = hci_open_dev(dev_id); if (dd < 0) { perror("Device open failed"); return; } /* Setup filter */ hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_all_events(&flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("HCI filter setup failed"); return; } /* Send the BT chip configuration commands */ if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { perror("Send failed"); return; } /* Wait for the command completion event */ len = read(dd, buf, sizeof(buf)); if (len < 0) { perror("Read failed"); return; } hdr = (void *)(buf + 1); ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); hci_close_dev(dd); }
VALUE method_scan(int argc, VALUE *argv, VALUE klass) { VALUE rb_device_id; int device_id; int device_handle; uint8_t scan_type = 0x01; //passive uint8_t own_type = 0x00; // I think this specifies not to use a random MAC uint8_t filter_dups = 0x00; uint8_t filter_policy = 0x00; // ? uint16_t interval = htobs(0x0005); uint16_t window = htobs(0x0005); struct hci_filter new_filter; socklen_t filter_size; // which device was specified? rb_scan_args(argc, argv, "01", &rb_device_id); if (rb_device_id == Qnil) { device_id = hci_get_route(NULL); } else { device_id = NUM2INT(rb_device_id); } // open the device if ( (device_handle = hci_open_dev(device_id)) < 0) { rb_raise(rb_eException, "Could not open device"); } device_handles[device_id] = device_handle; // save the old filter so we can restore it later filter_size = sizeof(stored_filters[0]); if (getsockopt(device_handle, SOL_HCI, HCI_FILTER, &stored_filters[device_id], &filter_size) < 0) { rb_raise(rb_eException, "Could not get socket options"); } // new filter to only look for event packets hci_filter_clear(&new_filter); hci_filter_set_ptype(HCI_EVENT_PKT, &new_filter); hci_filter_set_event(EVT_LE_META_EVENT, &new_filter); if (setsockopt(device_handle, SOL_HCI, HCI_FILTER, &new_filter, sizeof(new_filter)) < 0) { rb_raise(rb_eException, "Could not set socket options"); } // set the params hci_le_set_scan_parameters(device_handle, scan_type, interval, window, own_type, filter_policy, 1000); hci_le_set_scan_enable(device_handle, 0x01, filter_dups, 1000); // perform the scan and make sure device gets put back into a proper state // even in the case of being interrupted by a ruby exception rb_ensure(perform_scan, INT2FIX(device_id), stop_scan, INT2FIX(device_id)); return Qnil; }
/** * Set up the socket so that we get the message that we are interested in, and * put the device into periodic inquiry mode. */ static int start_scan(int dev_sd, int scan_length) { int opt; struct hci_filter flt; periodic_inquiry_cp info_data; periodic_inquiry_cp *info = &info_data; opt = 1; if (setsockopt(dev_sd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "failed to request data timestamps: %m"); return EXIT_FAILURE; } hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); if (setsockopt(dev_sd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { syslog(LOG_ERR, "failed to set hci filter: %m"); return EXIT_FAILURE; } /* no limit on number of responses per scan */ info->num_rsp = 0x00; /* use the global inquiry access code (GIAC), which has 0x338b9e as its lower * address part (LAP) */ info->lap[0] = 0x33; info->lap[1] = 0x8b; info->lap[2] = 0x9e; /* note: according to [BTSPEC, volume 2, section 7.1.3], we must have * max_period > min_period > length * so we set these values to give us the shortest random delay between scans * that is permitted by the specification */ info->length = scan_length; info->min_period = info->length + 1; info->max_period = info->min_period + 1; if (hci_send_cmd(dev_sd, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, PERIODIC_INQUIRY_CP_SIZE, info) < 0) { syslog(LOG_ERR, "failed to request periodic inquiry: %m"); return EXIT_FAILURE; } return EXIT_SUCCESS; }
/* * Unsubscribe from all events */ void HciManager::stopEvents() { if (!isValid()) return; hci_filter filter; hci_filter_clear(&filter); if (setsockopt(hciSocket, SOL_HCI, HCI_FILTER, &filter, sizeof(hci_filter)) < 0) { qCWarning(QT_BT_BLUEZ) << "Could not clear HCI socket options:" << strerror(errno); return; } runningEvents.clear(); }
static int open_hci_dev(uint16_t index) { struct sockaddr_hci addr; struct hci_filter flt; int fd, opt = 1; fd = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI); if (fd < 0) { perror("Failed to open channel"); return -1; } /* Setup filter */ hci_filter_clear(&flt); hci_filter_all_ptypes(&flt); hci_filter_all_events(&flt); if (setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("Failed to set HCI filter"); close(fd); return -1; } if (setsockopt(fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) { perror("Failed to enable HCI data direction info"); close(fd); return -1; } if (setsockopt(fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) { perror("Failed to enable HCI time stamps"); close(fd); return -1; } memset(&addr, 0, sizeof(addr)); addr.hci_family = AF_BLUETOOTH; addr.hci_dev = index; addr.hci_channel = HCI_CHANNEL_RAW; if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("Failed to bind channel"); close(fd); return -1; } return fd; }
struct HCIInfo *bt_host_hci(const char *id) { struct bt_host_hci_s *s; int fd = -1; # ifdef CONFIG_BLUEZ int dev_id = hci_devid(id); struct hci_filter flt; if (dev_id < 0) { fprintf(stderr, "qemu: `%s' not available\n", id); return 0; } fd = hci_open_dev(dev_id); /* XXX: can we ensure nobody else has the device opened? */ # endif if (fd < 0) { fprintf(stderr, "qemu: Can't open `%s': %s (%i)\n", id, strerror(errno), errno); return NULL; } # ifdef CONFIG_BLUEZ hci_filter_clear(&flt); hci_filter_all_ptypes(&flt); hci_filter_all_events(&flt); if (setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { fprintf(stderr, "qemu: Can't set HCI filter on socket (%i)\n", errno); return 0; } # endif s = g_malloc0(sizeof(struct bt_host_hci_s)); s->fd = fd; s->hci.cmd_send = bt_host_cmd; s->hci.sco_send = bt_host_sco; s->hci.acl_send = bt_host_acl; s->hci.bdaddr_set = bt_host_bdaddr_set; qemu_set_fd_handler(s->fd, bt_host_read, NULL, s); return &s->hci; }
static int open_stack_internal(void) { struct sockaddr_hci addr; struct hci_filter flt; int fd, opt = 1; fd = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI); if (fd < 0) { perror("Failed to open channel"); return -1; } /* Setup filter */ hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_STACK_INTERNAL, &flt); if (setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("Failed to set HCI filter"); close(fd); return -1; } if (setsockopt(fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) { perror("Failed to enable HCI time stamps"); close(fd); return -1; } memset(&addr, 0, sizeof(addr)); addr.hci_family = AF_BLUETOOTH; addr.hci_dev = HCI_DEV_NONE; addr.hci_channel = HCI_CHANNEL_RAW; if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("Failed to bind channel"); close(fd); return -1; } device_list(fd, HCI_MAX_DEV); return fd; }
void start_hci_scan(struct hci_state current_hci_state) { if(hci_le_set_scan_parameters(current_hci_state.device_handle, 0x01, htobs(0x0010), htobs(0x0010), 0x00, 0x00, 1000) < 0) { current_hci_state.has_error = TRUE; snprintf(current_hci_state.error_message, sizeof(current_hci_state.error_message), "Failed to set scan parameters: %s", strerror(errno)); return; } if(hci_le_set_scan_enable(current_hci_state.device_handle, 0x01, 1, 1000) < 0) { current_hci_state.has_error = TRUE; snprintf(current_hci_state.error_message, sizeof(current_hci_state.error_message), "Failed to enable scan: %s", strerror(errno)); return; } current_hci_state.state = HCI_STATE_SCANNING; // Save the current HCI filter socklen_t olen = sizeof(current_hci_state.original_filter); if(getsockopt(current_hci_state.device_handle, SOL_HCI, HCI_FILTER, ¤t_hci_state.original_filter, &olen) < 0) { current_hci_state.has_error = TRUE; snprintf(current_hci_state.error_message, sizeof(current_hci_state.error_message), "Could not get socket options: %s", strerror(errno)); return; } // Create and set the new filter struct hci_filter new_filter; hci_filter_clear(&new_filter); hci_filter_set_ptype(HCI_EVENT_PKT, &new_filter); hci_filter_set_event(EVT_LE_META_EVENT, &new_filter); if(setsockopt(current_hci_state.device_handle, SOL_HCI, HCI_FILTER, &new_filter, sizeof(new_filter)) < 0) { current_hci_state.has_error = TRUE; snprintf(current_hci_state.error_message, sizeof(current_hci_state.error_message), "Could not set socket options: %s", strerror(errno)); return; } current_hci_state.state = HCI_STATE_FILTERING; }
CBlueZStack::CBlueZStack(): CGenericBluetoothStack(), m_fd(-1) { if (g_devId < 0) { // retrieve local bluetooth address from environment variable const char *addr = getenv("JSR82BTADDR"); if (addr != NULL) { g_devId = hci_devid(addr); } else { g_devId = hci_get_route(NULL); } if (g_devId < 0) { return; } hci_dev_info di; hci_devinfo(g_devId, &di); } m_fd = hci_open_dev(g_devId); if (m_fd < 0) { return; } fcntl(m_fd, F_SETFL, O_NONBLOCK); hci_filter flt; hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_CMD_COMPLETE, &flt); hci_filter_set_event(EVT_CMD_STATUS, &flt); hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); hci_filter_set_event(EVT_AUTH_COMPLETE, &flt); hci_filter_set_event(EVT_ENCRYPT_CHANGE, &flt); if (setsockopt(m_fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { return; } m_poll.fd = m_fd; m_poll.events = POLLIN | POLLHUP | POLLERR; m_poll.revents = 0; m_bInitialized = true; }
static int print_advertising_devices(int dd, uint8_t filter_type) { unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr; struct hci_filter nf, of; struct sigaction sa; socklen_t olen; int len; int8_t rssi; olen = sizeof(of); if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &olen) < 0) { printf("Could not get socket options\n"); return -1; } hci_filter_clear(&nf); hci_filter_set_ptype(HCI_EVENT_PKT, &nf); hci_filter_set_event(EVT_LE_META_EVENT, &nf); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) { printf("Could not set socket options\n"); return -1; } memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = sigint_handler; sigaction(SIGINT, &sa, NULL); while (1) { evt_le_meta_event *meta; le_advertising_info *info; char addr[18]; while ((len = read(dd, buf, sizeof(buf))) < 0) { if (errno == EINTR && signal_received == SIGINT) { len = 0; goto done; } if (errno == EAGAIN || errno == EINTR) continue; goto done; } ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); meta = (void *) ptr; if (meta->subevent != 0x02) goto done; /* Ignoring multiple reports */ info = (le_advertising_info *) (meta->data + 1); if (check_report_filter(filter_type, info)) { // Jeff's comment // typedef struct { // uint8_t evt_type; // uint8_t bdaddr_type; // bdaddr_t bdaddr; // uint8_t length; // uint8_t data[0]; // } __attribute__ ((packed)) le_advertising_info; char name[30]; memset(name, 0, sizeof(name)); ba2str(&info->bdaddr, addr); eir_parse_name(info->data, info->length, name, sizeof(name) - 1); rssi = *(info->data + info->length); printf("%s %s %d\n", addr, name, rssi); fflush(stdout); // see: http://stackoverflow.com/questions/20503671/python-c-program-subprocess-hangs-at-for-line-in-iter } } done: setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of)); if (len < 0) return -1; return 0; }
static int run_proxy(int fd, int dev, bdaddr_t *bdaddr) { unsigned char buf[HCI_MAX_FRAME_SIZE + 1]; struct hci_dev_info di; struct hci_filter flt; struct pollfd p[2]; int dd, err, len, need_raw; dd = hci_open_dev(dev); if (dd < 0) { syslog(LOG_ERR, "Can't open device hci%d: %s (%d)", dev, strerror(errno), errno); return 1; } if (hci_devinfo(dev, &di) < 0) { syslog(LOG_ERR, "Can't get device info for hci%d: %s (%d)", dev, strerror(errno), errno); hci_close_dev(dd); return 1; } need_raw = !hci_test_bit(HCI_RAW, &di.flags); hci_filter_clear(&flt); hci_filter_all_ptypes(&flt); hci_filter_all_events(&flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { syslog(LOG_ERR, "Can't set filter for hci%d: %s (%d)", dev, strerror(errno), errno); hci_close_dev(dd); return 1; } if (need_raw) { if (ioctl(dd, HCISETRAW, 1) < 0) { syslog(LOG_ERR, "Can't set raw mode on hci%d: %s (%d)", dev, strerror(errno), errno); hci_close_dev(dd); return 1; } } p[0].fd = fd; p[0].events = POLLIN; p[1].fd = dd; p[1].events = POLLIN; while (!__io_canceled) { p[0].revents = 0; p[1].revents = 0; err = poll(p, 2, 500); if (err < 0) break; if (!err) continue; if (p[0].revents & POLLIN) { len = read(fd, buf, sizeof(buf)); if (len > 0) { rewrite_bdaddr(buf, len, bdaddr); err = write(dd, buf, len); } } if (p[1].revents & POLLIN) { len = read(dd, buf, sizeof(buf)); if (len > 0) { rewrite_bdaddr(buf, len, bdaddr); err = write(fd, buf, len); } } } if (need_raw) { if (ioctl(dd, HCISETRAW, 0) < 0) syslog(LOG_ERR, "Can't clear raw mode on hci%d: %s (%d)", dev, strerror(errno), errno); } hci_close_dev(dd); syslog(LOG_INFO, "Exit"); return 0; }
static int hciops_setup(void) { struct sockaddr_hci addr; struct hci_filter flt; GIOChannel *ctl_io, *child_io; int sock, err; if (child_pipe[0] != -1) return -EALREADY; if (pipe(child_pipe) < 0) { err = errno; error("pipe(): %s (%d)", strerror(err), err); return -err; } child_io = g_io_channel_unix_new(child_pipe[0]); g_io_channel_set_close_on_unref(child_io, TRUE); child_io_id = g_io_add_watch(child_io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, child_exit, NULL); g_io_channel_unref(child_io); /* Create and bind HCI socket */ sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sock < 0) { err = errno; error("Can't open HCI socket: %s (%d)", strerror(err), err); return -err; } /* Set filter */ hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_STACK_INTERNAL, &flt); if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { err = errno; error("Can't set filter: %s (%d)", strerror(err), err); return -err; } memset(&addr, 0, sizeof(addr)); addr.hci_family = AF_BLUETOOTH; addr.hci_dev = HCI_DEV_NONE; if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { err = errno; error("Can't bind HCI socket: %s (%d)", strerror(err), err); return -err; } ctl_io = g_io_channel_unix_new(sock); g_io_channel_set_close_on_unref(ctl_io, TRUE); ctl_io_id = g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL); g_io_channel_unref(ctl_io); /* Initialize already connected devices */ return init_known_adapters(sock); }
/** voiceCallSendHciCmd Function * This function takes the hci commands for the BT chip configurations, creates * a hci channel to send the commands through UART to configure BT chip * * Parameters : * @ commandLlength : Number of arguments of the command * @ command : Pointer to command list * Returns NO_ERROR upon success * , different error messages depending upon the error. */ static int voiceCallSendHciCmd(int commandLength, const char **command) { unsigned char messageBuffer[HCI_MAX_EVENT_SIZE]; unsigned char *ptr = messageBuffer; struct hci_filter hciFilter; hci_event_hdr *hciEventHandler; uint16_t ocf, ogf; int deviceDescriptor, error, i, messageLength, deviceId; deviceId = hci_get_route(NULL); if (deviceId < 0) { LOGE("hci_get_route failed: %s(%d)", strerror(deviceId), deviceId); return deviceId; } LOGV("Bluetooth Device Id: %d", deviceId); ogf = (uint16_t)strtol(command[0], NULL, 16); ocf = (uint16_t)strtol(command[1], NULL, 16); for (i = 2, messageLength = 0; i < commandLength && messageLength < (int)sizeof(messageBuffer); i++, messageLength++) *ptr++ = (uint8_t) strtol(command[i], NULL, 16); deviceDescriptor = hci_open_dev(deviceId); if (deviceDescriptor < 0) { LOGE("hci_open_dev failed: %s(%d)", strerror(deviceDescriptor), deviceDescriptor); return deviceDescriptor; } LOGV("Bluetooth Device Descriptor: %d", deviceDescriptor); // Setup filter hci_filter_clear(&hciFilter); hci_filter_set_ptype(HCI_EVENT_PKT, &hciFilter); hci_filter_all_events(&hciFilter); error = setsockopt(deviceDescriptor, SOL_HCI, HCI_FILTER, &hciFilter, sizeof(hciFilter)); if (error < 0) { LOGE("HCI filter setup failed: %s(%d)", strerror(error), error); hci_close_dev(deviceDescriptor); return error; } // Send the BT chip configuration commands error = hci_send_cmd(deviceDescriptor, ogf, ocf, messageLength, messageBuffer); if (error < 0) { LOGE("hci_send_cmd failed: %s(%d)", strerror(error), error); hci_close_dev(deviceDescriptor); return error; } // Wait for the command completion event messageLength = read(deviceDescriptor, messageBuffer, sizeof(messageBuffer)); if (messageLength < 0) { LOGE("HCI message completion failed: %s(%d)", strerror(messageLength), messageLength); hci_close_dev(deviceDescriptor); return error; } hci_close_dev(deviceDescriptor); return 0; }
static int print_advertising_devices(int dd, uint8_t filter_type) { unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr; struct hci_filter nf, of; struct sigaction sa; socklen_t olen; int len; olen = sizeof(of); if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &olen) < 0) { printf("Could not get socket options\n"); return -1; } hci_filter_clear(&nf); hci_filter_set_ptype(HCI_EVENT_PKT, &nf); hci_filter_set_event(EVT_LE_META_EVENT, &nf); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) { printf("Could not set socket options\n"); return -1; } memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = sigint_handler; sigaction(SIGINT, &sa, NULL); while (1) { evt_le_meta_event *meta; le_advertising_info *info; char addr[18]; while ((len = read(dd, buf, sizeof(buf))) < 0) { if (errno == EINTR && signal_received == SIGINT) { len = 0; goto done; } if (errno == EAGAIN || errno == EINTR) continue; goto done; } ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); meta = (void *) ptr; if (meta->subevent != 0x02) goto done; /* Ignoring multiple reports */ info = (le_advertising_info *) (meta->data + 1); if (check_report_filter(filter_type, info)) { char name[30]; char uuid[16*2 + 1]; memset(name, 0, sizeof(name)); ba2str(&info->bdaddr, addr); eir_parse_name(info->data, info->length, name, sizeof(name) - 1); eir_parse_uuid(info->data, info->length, uuid, sizeof(uuid) - 1); printf("%s %s %s\n", addr, name, uuid); } } done: setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of)); if (len < 0) return -1; return 0; }
int main(int argc, const char* argv[]) { char *hciDeviceIdOverride = NULL; int hciDeviceId = 0; int hciSocket; struct hci_dev_info hciDevInfo; struct hci_filter oldHciFilter; struct hci_filter newHciFilter; socklen_t oldHciFilterLen; int previousAdapterState = -1; int currentAdapterState; const char* adapterState = NULL; fd_set rfds; struct timeval tv; int selectRetval; unsigned char hciEventBuf[HCI_MAX_EVENT_SIZE]; int hciEventLen; evt_le_meta_event *leMetaEvent; le_advertising_info *leAdvertisingInfo; char btAddress[18]; int i; int scanning = 0; int8_t rssi; memset(&hciDevInfo, 0x00, sizeof(hciDevInfo)); // setup signal handlers signal(SIGINT, signalHandler); signal(SIGKILL, signalHandler); signal(SIGUSR1, signalHandler); signal(SIGUSR2, signalHandler); signal(SIGHUP, signalHandler); prctl(PR_SET_PDEATHSIG, SIGKILL); // remove buffering setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); hciDeviceIdOverride = getenv("NOBLE_HCI_DEVICE_ID"); if (hciDeviceIdOverride != NULL) { hciDeviceId = atoi(hciDeviceIdOverride); } else { // if no env variable given, use the first available device hciDeviceId = hci_get_route(NULL); } if (hciDeviceId < 0) { hciDeviceId = 0; // use device 0, if device id is invalid } // setup HCI socket hciSocket = hci_open_dev(hciDeviceId); if (hciSocket == -1) { printf("adapterState unsupported\n"); return -1; } hciDevInfo.dev_id = hciDeviceId; // get old HCI filter oldHciFilterLen = sizeof(oldHciFilter); getsockopt(hciSocket, SOL_HCI, HCI_FILTER, &oldHciFilter, &oldHciFilterLen); // setup new HCI filter hci_filter_clear(&newHciFilter); hci_filter_set_ptype(HCI_EVENT_PKT, &newHciFilter); hci_filter_set_event(EVT_LE_META_EVENT, &newHciFilter); setsockopt(hciSocket, SOL_HCI, HCI_FILTER, &newHciFilter, sizeof(newHciFilter)); while(1) { FD_ZERO(&rfds); FD_SET(hciSocket, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; // get HCI dev info for adapter state ioctl(hciSocket, HCIGETDEVINFO, (void *)&hciDevInfo); currentAdapterState = hci_test_bit(HCI_UP, &hciDevInfo.flags); if (previousAdapterState != currentAdapterState) { previousAdapterState = currentAdapterState; if (!currentAdapterState) { adapterState = "poweredOff"; } else if (hci_le_set_scan_parameters(hciSocket, 0x01, htobs(0x0010), htobs(0x0010), 0x00, 0, 1000) < 0) { if (EPERM == errno) { adapterState = "unauthorized"; } else if (EIO == errno) { adapterState = "unsupported"; } else { adapterState = "unknown"; } } else { adapterState = "poweredOn"; } printf("adapterState %s\n", adapterState); } selectRetval = select(hciSocket + 1, &rfds, NULL, NULL, &tv); if (-1 == selectRetval) { if (SIGINT == lastSignal || SIGKILL == lastSignal) { // done break; } else if (SIGUSR1 == lastSignal) { // start scan, filter scanning = 1; hci_le_set_scan_enable(hciSocket, 0x00, 1, 1000); hci_le_set_scan_enable(hciSocket, 0x01, 1, 1000); } else if (SIGUSR2 == lastSignal) { // start scan, no filter scanning = 1; hci_le_set_scan_enable(hciSocket, 0x00, 0, 1000); hci_le_set_scan_enable(hciSocket, 0x01, 0, 1000); } else if (SIGHUP == lastSignal) { // stop scan scanning = 0; hci_le_set_scan_enable(hciSocket, 0x00, 0, 1000); } } else if (selectRetval) { // read event hciEventLen = read(hciSocket, hciEventBuf, sizeof(hciEventBuf)); leMetaEvent = (evt_le_meta_event *)(hciEventBuf + (1 + HCI_EVENT_HDR_SIZE)); hciEventLen -= (1 + HCI_EVENT_HDR_SIZE); if (!scanning) { // ignore, not scanning continue; } if (leMetaEvent->subevent != 0x02) { continue; } leAdvertisingInfo = (le_advertising_info *)(leMetaEvent->data + 1); ba2str(&leAdvertisingInfo->bdaddr, btAddress); printf("event %s,%s,", btAddress, (leAdvertisingInfo->bdaddr_type == LE_PUBLIC_ADDRESS) ? "public" : "random"); for (i = 0; i < leAdvertisingInfo->length; i++) { printf("%02x", leAdvertisingInfo->data[i]); } rssi = *(leAdvertisingInfo->data + leAdvertisingInfo->length); printf(",%d\n", rssi); } } // restore original filter setsockopt(hciSocket, SOL_HCI, HCI_FILTER, &oldHciFilter, sizeof(oldHciFilter)); // disable LE scan hci_le_set_scan_enable(hciSocket, 0x00, 0, 1000); close(hciSocket); return 0; }
int main(int argc, char *argv[]) { int dev_id = -1; unsigned char buf[HCI_MAX_EVENT_SIZE]; struct hci_filter flt; int len = 0; int dd = -1; uint16_t ocf; uint8_t ogf; int i = 0; hci_event_hdr *hdr; char* ptr; LOGE("[GABT] %s :: before : getuid=%d",__FUNCTION__, getuid()); android_set_aid_and_cap_k(); LOGE("[GABT] %s :: after : getuid=%d",__FUNCTION__, getuid()); if (dev_id < 0) dev_id = hci_get_route(NULL); errno = 0; dd = hci_open_dev(dev_id); if (dd < 0) { LOGE("[GABT] %s :: Hci Device open failed :: dev_id=%d, dd=%d",__FUNCTION__, dev_id, dd); perror("Hci Device open failed"); exit(EXIT_FAILURE); } /* Setup filter */ hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_all_events(&flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { LOGE("[GABT] %s :: HCI filter setup failed ",__FUNCTION__); perror("HCI filter setup failed"); exit(EXIT_FAILURE); } #if 0 /* sleep mode disable */ ogf = 0x3f; ocf = 0x0027; memset(buf, 0, sizeof(buf)); buf[0] = 0x00; buf[1] = 0x00; buf[2] = 0x00; buf[3] = 0x00; buf[4] = 0x00; buf[5] = 0x00; buf[6] = 0x00; buf[7] = 0x00; buf[8] = 0x00; buf[9] = 0x00; buf[10] = 0x00; buf[11] = 0x00; len = 12; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { LOGE("[GABT] %s :: Send failed 1",__FUNCTION__); perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { LOGE("[GABT] %s :: Read failed 1",__FUNCTION__); perror("Read failed"); exit(EXIT_FAILURE); } LOGE("[GABT] sleep mode disable -"); /* Set Event Filter */ ogf = 0x03; ocf = 0x0005; memset(buf, 0, sizeof(buf)); buf[0] = 0x02; //Filter_Type , 0x02 : Connection Setup. buf[1] = 0x00; //Filter_Condition_Type, 0x00 : Allow Connections from all devices. buf[2] = 0x02; //Condition len = 3; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { LOGE("[GABT] %s :: Send failed 2 ",__FUNCTION__); perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { LOGE("[GABT] %s :: Read failed 2 ",__FUNCTION__); perror("Read failed"); exit(EXIT_FAILURE); } LOGE("[GABT] Set Event Filter -"); /* Write Scan Enable */ ogf = 0x03; ocf = 0x001a; memset(buf, 0, sizeof(buf)); buf[0] = 0x03; //Scan_Enable, 0x03 : Inquiry Scan enabled. // Page Scan enabled. len = 1; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { LOGE("[GABT] %s :: Send failed 3 ",__FUNCTION__); perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { LOGE("[GABT] %s :: Read failed 3 ",__FUNCTION__); perror("Read failed"); exit(EXIT_FAILURE); } LOGE("[GABT] Write Scan Enable -"); #endif /* Enable Device Under Test Mode */ ogf = 0x06; ocf = 0x0003; memset(buf, 0, sizeof(buf)); buf[0] = 0x00; len = 0; LOGE("< HCI Command: ogf 0x%02x, ocf 0x%04x, plen %d\n", ogf, ocf, len); if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { LOGE("[GABT] %s :: Send failed 4 ",__FUNCTION__); perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { LOGE("[GABT] %s :: Read failed 4 ",__FUNCTION__); perror("Read failed"); exit(EXIT_FAILURE); } hdr = (void *)(buf + 1); ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); LOGE("> HCI Event: 0x%02x plen %d\n", hdr->evt, hdr->plen); hex_dump(" ", 20, ptr, len); LOGE("[GABT] Enable Device Under Test Mode -"); //////////////////////////////////////////////////////////////////// /* Set Event Filter */ ogf = 0x03; ocf = 0x0005; memset(buf, 0, sizeof(buf)); buf[0] = 0x02; //Filter_Type , 0x02 : Connection Setup. buf[1] = 0x00; //Filter_Condition_Type, 0x00 : Allow Connections from all devices. buf[2] = 0x02; //Condition len = 3; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { perror("Read failed"); exit(EXIT_FAILURE); } /* Write Scan Enable */ ogf = 0x03; ocf = 0x001a; memset(buf, 0, sizeof(buf)); buf[0] = 0x03; //Scan_Enable, 0x03 : Inquiry Scan enabled. // Page Scan enabled. len = 1; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { perror("Read failed"); exit(EXIT_FAILURE); } /* Write Authentication Enable*/ ogf = 0x03; ocf = 0x0020; memset(buf, 0, sizeof(buf)); buf[0] = 0x00; //Authentication_Enable, 0x00: Authentication not required. Default. len = 1; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { perror("Read failed"); exit(EXIT_FAILURE); } /* Write Encrytion Mode*/ ogf = 0x03; ocf = 0x0022; memset(buf, 0, sizeof(buf)); buf[0] = 0x00; //Encryption_Mode, 0x00 : Encryption not required. len = 1; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { perror("Read failed"); exit(EXIT_FAILURE); } ///////////////////////////////////////////////////////////////////////// hci_close_dev(dd); LOGE("[GABT] %s :: EXIT ",__FUNCTION__); return 0; }
/** * @brief Open Socket * * @param dev Device handle * * @return */ static int open_socket(int dev) { struct sockaddr_hci addr; struct hci_filter flt; struct hci_dev_info di; int sk, opt; if (dev != HCI_DEV_NONE) { int dd = hci_open_dev(dev); if (dd < 0) { perror("Can't open device"); return -1; } if (hci_devinfo(dev, &di) < 0) { perror("Can't get device info"); return -1; } if (hci_read_bd_addr(dd, &g_mac_address, 1000) < 0 ) { perror("Can't get device mac address"); return -1; } opt = hci_test_bit(HCI_RAW, &di.flags); if (ioctl(dd, HCISETRAW, opt) < 0) { if (errno == EACCES) { perror("Can't access device"); return -1; } } hci_close_dev(dd); } /* Create HCI socket */ sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) { perror("Can't create raw socket"); return -1; } opt = 1; if (setsockopt(sk, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) { perror("Can't enable data direction info"); return -1; } opt = 1; if (setsockopt(sk, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) { perror("Can't enable time stamp"); return -1; } /* Setup filter */ hci_filter_clear(&flt); hci_filter_all_ptypes(&flt); hci_filter_all_events(&flt); if (setsockopt(sk, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("Can't set filter"); return -1; } /* Bind socket to the HCI device */ memset(&addr, 0, sizeof(addr)); addr.hci_family = AF_BLUETOOTH; addr.hci_dev = dev; if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { fprintf(stderr, "Can't attach to device hci%d. %s(%d)\n", dev, strerror(errno), errno); return -1; } return sk; }
static int cmd_lescan(int dev_id) { int hci_dev = 0; int err = 0, opt = 0, dd = 0; uint8_t own_type = 0x00; uint8_t scan_type = 0x01; uint8_t filter_type = 0; uint8_t filter_policy = 0x00; uint8_t filter_dup = 1; uint16_t interval = htobs(0x0010); uint16_t window = htobs(0x0010); if (dev_id < 0) { dev_id = hci_get_route(NULL); } if (dev_id < 0) { return -1; } if((hci_dev = hci_open_dev(dev_id)) < 0) { printf("Opening hci device failed\n"); return -2; } err = hci_le_set_scan_parameters(hci_dev, scan_type, interval, window, own_type, filter_policy, 2000); if (err < 0) { printf("Setting scan parameters failed %d\n", err); return -3; } err = hci_le_set_scan_enable(hci_dev, 0x01, filter_dup, 1000); if (err < 0) { printf("Enabling the scan failed\n"); return -4; } struct sigaction sa; sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = signal_handler; sigaction(SIGINT, &sa, NULL); unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr; int len, sl_no = 0; socklen_t olen = sizeof(old_filter); if (getsockopt(hci_dev, SOL_HCI, HCI_FILTER, &old_filter, &olen) < 0) { printf("getsockopt failed\n"); btcmd_stop_scanning(hci_dev); return -5; } struct hci_filter filter; hci_filter_clear(&filter); hci_filter_set_ptype(HCI_EVENT_PKT, &filter); hci_filter_set_event(EVT_LE_META_EVENT, &filter); if (setsockopt(hci_dev, SOL_HCI, HCI_FILTER, &filter, sizeof(filter)) < 0) { printf("setsockopt failed\n"); btcmd_stop_scanning(hci_dev); return -6; } finish_scanning = 0; while(1) { le_advertising_info *info; evt_le_meta_event *meta; char addr[20]; while ((len = read(hci_dev, buf, sizeof(buf))) < 0) { set_state(STATE_SCANNING); if (errno == EINTR && finish_scanning) { len = 0; goto done; } if (errno == EAGAIN) { continue; } /* anything else, just end the loop */ goto done; } ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); meta = (void *) ptr; if (meta->subevent != 0x02) { goto done; } info = (le_advertising_info *) (meta->data + 1); memset(addr, 0, sizeof(addr)); address2string(&info->bdaddr, addr); /* Socket gives same BT address twice, and we need to eliminate * duplicate entries */ static int duplicate = 0; if (duplicate == 0) { printf("%s\n", addr); duplicate = 1; } else if (duplicate) { duplicate = 0; } } /* while (1) */ done: btcmd_stop_scanning(hci_dev); set_state(STATE_DISCONNECTED); return 0; }
int main() { int btSocket; int optionValue; struct hci_filter eventFilter; struct iovec iov; //I/O Vector, a scatter-gather array for sockets struct msghdr msgFromBTSocket; struct cmsghdr * cmsgFromBTSocket; //A pointer to the control messages struct timeval timeStamp; int msgLengthFromBTSocket; periodic_inquiry_cp hciCmdParamInfo; periodic_inquiry_cp * hciCmdParam = &hciCmdParamInfo; int inquiryLength = 21; //File Descriptor fd_set readSet; fd_set writeSet; fd_set exceptSet; //Program begin //Database connection conn = mysql_init(NULL); if (conn == NULL){ printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn)); exit(1); } //mysql_real_connect( ..., database name, port number, unix socket, client flag) if (mysql_real_connect(conn, "localhost", "multipleBT", "multipleBT", NULL, 0, NULL, 0) == NULL ){ printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn)); exit(1); } if (mysql_query( conn, "USE BTSignalRecords")){ printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn)); exit(1); } //initialize msgFromBTSocket //assign msgBuffer to be the space for btSocket to send and receive message iov.iov_base = &msgBuffer; iov.iov_len = sizeof(msgBuffer); msgFromBTSocket.msg_iov = &iov; //scatter-gatther array //struct iovec msgFromBTSocket.msg_iovlen = 1; // # elements in msg_iov msgFromBTSocket.msg_control = &controlBuffer; msgFromBTSocket.msg_controllen = sizeof(controlBuffer); //Open a bluetooth adaptor and connect it to a socket //int hci_open_dev(int dev_id); btSocket = hci_open_dev(0); /*Set HCI_DATA_DIR to true, the msg return will include data direction*/ //int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len); optionValue = 1; setsockopt(btSocket, SOL_HCI, HCI_DATA_DIR, &optionValue, sizeof(optionValue)); /*Set HCI_TIME_STAMP*/ optionValue = 1; setsockopt(btSocket, SOL_HCI, HCI_TIME_STAMP, &optionValue, sizeof(optionValue)); hci_filter_clear(&eventFilter); //Set the filter to only receive HCI_EVENT_PKT //This specifies what events we want on our socket. hci_filter_set_ptype(HCI_EVENT_PKT, &eventFilter); //We want all the events related to HCI hci_filter_all_events(&eventFilter); //Set HCI_FILTER setsockopt(btSocket, SOL_HCI, HCI_FILTER, &eventFilter, sizeof(eventFilter)); //Set Periodic Inquiry Parameters hciCmdParam->num_rsp = 0x00; //Unlimited number of responses hciCmdParam->lap[0] = 0x33; //Bluetooth's magic number hciCmdParam->lap[1] = 0x8b; hciCmdParam->lap[2] = 0x9e; hciCmdParam->length = inquiryLength; hciCmdParam->min_period = hciCmdParam->length + 1; hciCmdParam->max_period = hciCmdParam->min_period + 1; //Begin Periodic Inquiry hci_send_cmd(btSocket, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, PERIODIC_INQUIRY_CP_SIZE, hciCmdParam); while (1){ //Listen the responses from the HCI socket FD_ZERO(&readSet); //Set btSocket to the file descriptor set we read FD_SET(btSocket, &readSet); //int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); select(btSocket+1, &readSet, NULL, NULL, NULL); if(FD_ISSET(btSocket, &readSet)) { debug && printf("btSocket receives a message.\n"); msgLengthFromBTSocket = recvmsg(btSocket, &msgFromBTSocket, 0 ); // 0 = no flags debug && printf("msgLengthFromBTSocket = %d\n", msgLengthFromBTSocket); if(msgLengthFromBTSocket < 0){ //put how to exit the program here debug && printf("msgLengthFromBTSocket < 0, exit program\n"); } else { debug && printf("msgLengthFromBTSocket >= 0:\n"); if( msgLengthFromBTSocket >= 0){ cmsgFromBTSocket = CMSG_FIRSTHDR( &msgFromBTSocket ); //cmsg = control messages while (cmsgFromBTSocket) { switch (cmsgFromBTSocket->cmsg_type){ case HCI_CMSG_DIR: //Do something ... debug && printf("Receive HCI_CMSG_DIR\n"); break; case HCI_CMSG_TSTAMP: debug && printf("Receove HCI_CMSG_TSTAMP\n"); //CMSG_DATA returns a pointer to the data portion of the cmsg //Here, it returns a pointer to the the time stamp data //So we point to this time stamp data, and dereference it. timeStamp = *( (struct timeval *) CMSG_DATA(cmsgFromBTSocket) ); break; } //Look at next cmsghdr cmsgFromBTSocket = CMSG_NXTHDR( &msgFromBTSocket, cmsgFromBTSocket); } //Begin decode the packets (messages) debug && printf("Get into decode()\n"); decode( msgLengthFromBTSocket, timeStamp); } } } }//end while() mysql_close(conn); return 0; }
int main(int argc, char *argv[]) { struct sigaction sa; struct hci_dev_info di; struct hci_version ver; struct hci_filter flt; bdaddr_t bdaddr, master, slave; int need_raw; int dd, opt, dev = 0; bacpy(&slave, BDADDR_ANY); while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); if (dev < 0) { perror("Invalid device"); exit(1); } break; case 'h': default: usage(); exit(0); } } argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); exit(1); } str2ba(argv[0], &master); if (argc > 1) str2ba(argv[1], &slave); dd = hci_open_dev(dev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", dev, strerror(errno), errno); exit(1); } if (hci_devinfo(dev, &di) < 0) { fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } if (hci_read_local_version(dd, &ver, 1000) < 0) { fprintf(stderr, "Can't read version for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } if (ver.manufacturer != 10 || id2ver(ver.hci_rev) < 0) { fprintf(stderr, "Can't find sniffer at hci%d: %s (%d)\n", dev, strerror(ENOSYS), ENOSYS); hci_close_dev(dd); exit(1); } if (!bacmp(&di.bdaddr, BDADDR_ANY)) { if (hci_read_bd_addr(dd, &bdaddr, 1000) < 0) { fprintf(stderr, "Can't read address for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } } else bacpy(&bdaddr, &di.bdaddr); need_raw = !hci_test_bit(HCI_RAW, &di.flags); hci_filter_clear(&flt); hci_filter_set_ptype(HCI_ACLDATA_PKT, &flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_VENDOR, &flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { fprintf(stderr, "Can't set filter for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); if (need_raw) { if (ioctl(dd, HCISETRAW, 1) < 0) { fprintf(stderr, "Can't set raw mode on hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } } printf("CSR sniffer - Bluetooth packet analyzer ver %s\n", VERSION); if (need_raw) { if (ioctl(dd, HCISETRAW, 0) < 0) fprintf(stderr, "Can't clear raw mode on hci%d: %s (%d)\n", dev, strerror(errno), errno); } hci_close_dev(dd); return 0; }
static int ble_scan(int device_desc, ble_discovered_device_t discovered_device_cb, int timeout) { struct hci_filter old_options; socklen_t slen = sizeof(old_options); struct hci_filter new_options; int len; unsigned char buffer[HCI_MAX_EVENT_SIZE]; evt_le_meta_event* meta = (evt_le_meta_event*)(buffer + HCI_EVENT_HDR_SIZE + 1); le_advertising_info* info; struct timeval wait; fd_set read_set; char addr[18]; if (getsockopt(device_desc, SOL_HCI, HCI_FILTER, &old_options, &slen) < 0) { fprintf(stderr, "ERROR: Could not get socket options.\n"); return 1; } hci_filter_clear(&new_options); hci_filter_set_ptype(HCI_EVENT_PKT, &new_options); hci_filter_set_event(EVT_LE_META_EVENT, &new_options); if (setsockopt(device_desc, SOL_HCI, HCI_FILTER, &new_options, sizeof(new_options)) < 0) { fprintf(stderr, "ERROR: Could not set socket options.\n"); return 1; } wait.tv_sec = timeout; int ts = time(NULL); while(1) { FD_ZERO(&read_set); FD_SET(device_desc, &read_set); int err = select(FD_SETSIZE, &read_set, NULL, NULL, &wait); if (err <= 0) break; len = read(device_desc, buffer, sizeof(buffer)); if (meta->subevent != 0x02 || (uint8_t)buffer[BLE_EVENT_TYPE] != BLE_SCAN_RESPONSE) continue; info = (le_advertising_info*) (meta->data + 1); ba2str(&info->bdaddr, addr); char* name = parse_name(info->data, info->length); discovered_device_cb(addr, name); if (name) { free(name); } int elapsed = time(NULL) - ts; if (elapsed >= timeout) break; wait.tv_sec = timeout - elapsed; } setsockopt(device_desc, SOL_HCI, HCI_FILTER, &old_options, sizeof(old_options)); return 0; }
void peisk_clUseBluetooth(char *device) { int opt,dd; char key[256], val[256]; PeisBluetoothAdaptor *adaptor = &peisk_bluetoothAdaptors[peisk_nBluetoothAdaptors]; adaptor->id = hci_devid(device); adaptor->outgoing.mode = 0; if(adaptor->id < 0) { perror(""); fprintf(stderr,"Warning, failed to open adaptor %s\n",device); return; } if(hci_devinfo(adaptor->id,&adaptor->info)) { perror(""); fprintf(stderr,"Failed to query adaptor %s\n",device); return; } printf("Current MTU ACL %d SCO %d\n",adaptor->info.acl_mtu,adaptor->info.sco_mtu); if(hci_devba(adaptor->id, &adaptor->addr) < 0) { perror(""); fprintf(stderr,"Failed to query address of %s\n",device); return; } dd = hci_open_dev(adaptor->id); opt = hci_test_bit(HCI_RAW,&adaptor->info.flags); /* Setting adaptor to RAW mode, needed for scanning (?) */ errno=0; if(ioctl(dd,HCISETRAW,opt) < 0) { if(errno == EACCES) { fprintf(stderr,"Warning, cannot gain RAW access to bluetooth device %s\n",device); /*return;*/ } } hci_close_dev(dd); adaptor->interfaceSocket = socket(AF_BLUETOOTH, SOCK_RAW,BTPROTO_HCI); if(adaptor->interfaceSocket < 0) { fprintf(stderr,"Error, cannot create RAW socket to bluetooth device %s, dropping it\n",device); return; } opt=1; if (setsockopt(adaptor->interfaceSocket, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) { perror("Can't enable data direction info"); return; } opt=1; if (setsockopt(adaptor->interfaceSocket, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) { perror("Can't enable time stamp"); return; } /* Setup filter */ struct hci_filter flt; hci_filter_clear(&flt); hci_filter_all_ptypes(&flt); hci_filter_all_events(&flt); if (setsockopt(adaptor->interfaceSocket, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("Can't set filter"); return; } /* Bind socket to the HCI device */ struct sockaddr_hci isock_addr; isock_addr.hci_family = AF_BLUETOOTH; isock_addr.hci_dev = adaptor->id; if (bind(adaptor->interfaceSocket, (struct sockaddr *) &isock_addr, sizeof(isock_addr)) < 0) { printf("Can't attach to device %s. %s(%d)\n", device, strerror(errno), errno); return; } printf("Successfully bound a RAW socket to %s\n",device); adaptor->name = strdup(device); adaptor->isScanning = 0; adaptor->nextScan = 0; peisk_nBluetoothAdaptors++; /* Give mac address of adaptor as value for the device tuple kernel.hciX */ sprintf(key,"kernel.%s",device); ba2str(&adaptor->addr, val); peisk_setStringTuple(key,val); /* Setup any L2CAP port for connections */ struct sockaddr_l2 listen_addr={0}; adaptor->listenSocket = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if(adaptor->listenSocket < 0) { fprintf(stderr,"peisk::warning - cannot create listening socket for %s\n",device); } else { adaptor->port = 1000; listen_addr.l2_family = AF_BLUETOOTH; listen_addr.l2_bdaddr = adaptor->addr; /* Brute force search until we find a free port we can use */ while(1) { listen_addr.l2_psm = adaptor->port; if(bind(adaptor->listenSocket, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) == 0) break; if(++adaptor->port > 32765) { adaptor->port=-1; close(adaptor->listenSocket); adaptor->listenSocket=-1; fprintf(stderr,"peisk::warning - cannot bind any port for %s\n",device); break; } } printf("Using bluetooth port %d\n",adaptor->port); if(adaptor->listenSocket != -1 && listen(adaptor->listenSocket, 1)) { adaptor->port=-1; close(adaptor->listenSocket); adaptor->listenSocket=-1; fprintf(stderr,"peisk::warning - cannot listen on %s\n",device); } if(adaptor->listenSocket != -1 && fcntl(adaptor->listenSocket,F_SETFL,O_NONBLOCK) == -1){ adaptor->port=-1; close(adaptor->listenSocket); adaptor->listenSocket=-1; fprintf(stderr,"peisk::warning - failed to set listening socket of %s non blocking\n",device); } /* if(adaptor->listenSocket != -1) { peisk_bluetooth_setMTU(adaptor->listenSocket); }*/ } /* Setup L2CAP port for hello messages */ struct sockaddr_l2 hello_addr={0}; adaptor->helloSocket = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); hello_addr.l2_family = AF_BLUETOOTH; hello_addr.l2_bdaddr = adaptor->addr; hello_addr.l2_psm = htobs(0x1001); if(adaptor->helloSocket != -1 && bind(adaptor->helloSocket, (struct sockaddr *)&hello_addr, sizeof(hello_addr))) { close(adaptor->helloSocket); adaptor->helloSocket = -1; printf("peisk::warning, could not bind L2CAP socket 0x7E15 on %s\nWe will not be bluetooth connectable\n",device); } if(adaptor->helloSocket != -1 && listen(adaptor->helloSocket, 1)) { printf("peisk::warning, failed to listen to L2CAP on %s\nWe will not be bluetooth connectable",device); close(adaptor->helloSocket); adaptor->helloSocket = -1; } if(adaptor->helloSocket != -1 && fcntl(adaptor->helloSocket,F_SETFL,O_NONBLOCK) == -1) { printf("peisk::warning, failed to set L2CAP socket on %s non blocking\nWe will not be bluetooth connectable",device); close(adaptor->helloSocket); adaptor->helloSocket = -1; } /* Mark adaptor as not having any pending hello's right now */ adaptor->pendingHelloFd = -1; printf("Listesting on %s: %02X:%02X:%02X:%02X:%02X:%02X;%d\n",device, adaptor->addr.b[5],adaptor->addr.b[4],adaptor->addr.b[3],adaptor->addr.b[2], adaptor->addr.b[1],adaptor->addr.b[0],adaptor->port); }
int main(int argc, char *argv[]) { int dev_id = -1; ALOGI("[GABT] %s :: before : getuid=%d",__FUNCTION__, getuid()); android_set_aid_and_cap_k(); ALOGI("[GABT] %s :: after : getuid=%d",__FUNCTION__, getuid()); unsigned char buf[HCI_MAX_EVENT_SIZE]; struct hci_filter flt; int len = 0; int dd = -1; uint16_t ocf; uint8_t ogf; if (dev_id < 0) dev_id = hci_get_route(NULL); errno = 0; dd = hci_open_dev(dev_id); if (dd < 0) { ALOGE("[GABT] %s :: Hci Device open failed :: dev_id=%d, dd=%d",__FUNCTION__, dev_id, dd); perror("Hci Device open failed"); exit(EXIT_FAILURE); } /* Setup filter */ hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_all_events(&flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { ALOGE("[GABT] %s :: HCI filter setup failed ",__FUNCTION__); perror("HCI filter setup failed"); exit(EXIT_FAILURE); } /* sleep mode disable */ ogf = 0x03; ocf = 0x0001; memset(buf, 0, sizeof(buf)); buf[0] = 0x3f; buf[1] = 0x27; buf[2] = 0x00; buf[3] = 0x00; buf[4] = 0x00; buf[5] = 0x00; buf[6] = 0x00; buf[7] = 0x00; buf[8] = 0x00; buf[9] = 0x00; buf[10] = 0x00; buf[11] = 0x00; buf[12] = 0x00; buf[13] = 0x00; len = 14; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { ALOGE("[GABT] %s :: Send failed 1",__FUNCTION__); perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { ALOGE("[GABT] %s :: Read failed 1",__FUNCTION__); perror("Read failed"); exit(EXIT_FAILURE); } ALOGI("[GABT] sleep mode disable -"); /* Set Event Filter */ ogf = 0x03; ocf = 0x0005; memset(buf, 0, sizeof(buf)); buf[0] = 0x02; //Filter_Type , 0x02 : Connection Setup. buf[1] = 0x00; //Filter_Condition_Type, 0x00 : Allow Connections from all devices. buf[2] = 0x02; //Condition len = 3; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { ALOGE("[GABT] %s :: Send failed 2 ",__FUNCTION__); perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { ALOGE("[GABT] %s :: Read failed 2 ",__FUNCTION__); perror("Read failed"); exit(EXIT_FAILURE); } ALOGI("[GABT] Set Event Filter -"); /* Write Scan Enable */ ogf = 0x03; ocf = 0x001a; memset(buf, 0, sizeof(buf)); buf[0] = 0x03; //Scan_Enable, 0x03 : Inquiry Scan enabled. // Page Scan enabled. len = 1; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { ALOGE("[GABT] %s :: Send failed 3 ",__FUNCTION__); perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { ALOGE("[GABT] %s :: Read failed 3 ",__FUNCTION__); perror("Read failed"); exit(EXIT_FAILURE); } ALOGI("[GABT] Write Scan Enable -"); /* Enable Device Under Test Mode */ ogf = 0x06; ocf = 0x0003; memset(buf, 0, sizeof(buf)); //buf[0] = 0x00; len = 0;//1; if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { ALOGE("[GABT] %s :: Send failed 4 ",__FUNCTION__); perror("Send failed"); exit(EXIT_FAILURE); } len = read(dd, buf, sizeof(buf)); if (len < 0) { ALOGE("[GABT] %s :: Read failed 4 ",__FUNCTION__); perror("Read failed"); exit(EXIT_FAILURE); } ALOGE("[GABT] Enable Device Under Test Mode -"); hci_close_dev(dd); ALOGE("[GABT] %s :: EXIT ",__FUNCTION__); return 0; }
int main(void) { struct sockaddr_hci addr; struct hci_filter filter; int sock, one = 1; char packet[HCI_MAX_FRAME_SIZE]; struct cmsghdr *cmsg; struct msghdr msg; struct iovec iv; struct dump_hdr *dh; struct frame frm; char *buf, *ctrl; if((sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { perror("socket"); exit(1); } if(setsockopt(sock, SOL_HCI, HCI_DATA_DIR, &one, sizeof(one)) < 0) { perror("Can't enable data direction info"); exit(1); } if(setsockopt(sock, SOL_HCI, HCI_TIME_STAMP, &one, sizeof(one)) < 0) { perror("Can't enable time stamp"); exit(1); } hci_filter_clear(&filter); hci_filter_all_ptypes(&filter); hci_filter_all_events(&filter); if(setsockopt(sock, SOL_HCI, HCI_FILTER, &filter, sizeof(filter)) < 0) { perror("Can't set HCI filter"); exit(1); } addr.hci_family = AF_BLUETOOTH; addr.hci_dev = 0; if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); exit(1); } if (!(buf = malloc(DUMP_HDR_SIZE))) { perror("Can't allocate data buffer"); exit(1); } dh = (void *) buf; frm.data = buf + DUMP_HDR_SIZE; if (!(ctrl = malloc(100))) { perror("Can't allocate control buffer"); exit(1); } memset(&msg, 0, sizeof(msg)); while (1) { iv.iov_base = frm.data; iv.iov_len = snap_len; msg.msg_iov = &iv; msg.msg_iovlen = 1; msg.msg_control = ctrl; msg.msg_controllen = 100; if ((frm.data_len = recvmsg(sock, &msg, 0)) < 0) { perror("Receive failed"); exit(1); } /* Process control message */ frm.in = 0; cmsg = CMSG_FIRSTHDR(&msg); while (cmsg) { switch (cmsg->cmsg_type) { case HCI_CMSG_DIR: frm.in = *((int *)CMSG_DATA(cmsg)); break; case HCI_CMSG_TSTAMP: frm.ts = *((struct timeval *)CMSG_DATA(cmsg)); break; } cmsg = CMSG_NXTHDR(&msg, cmsg); } frm.ptr = frm.data; frm.len = frm.data_len; /* Parse and print */ hci_dump(&frm); } close(sock); return 0; }