Esempio n. 1
0
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;
}
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 3
0
/*
 * Returns true if \a event was successfully enabled
 */
bool HciManager::monitorEvent(HciManager::HciEvent event)
{
    if (!isValid())
        return false;

    // this event is already enabled
    // TODO runningEvents does not seem to be used
    if (runningEvents.contains(event))
        return true;

    hci_filter filter;
    socklen_t length = sizeof(hci_filter);
    if (getsockopt(hciSocket, SOL_HCI, HCI_FILTER, &filter, &length) < 0) {
        qCWarning(QT_BT_BLUEZ) << "Cannot retrieve HCI filter settings";
        return false;
    }

    hci_filter_set_ptype(HCI_EVENT_PKT, &filter);
    hci_filter_set_event(event, &filter);
    //hci_filter_all_events(&filter);

    if (setsockopt(hciSocket, SOL_HCI, HCI_FILTER, &filter, sizeof(hci_filter)) < 0) {
        qCWarning(QT_BT_BLUEZ) << "Could not set HCI socket options:" << strerror(errno);
        return false;
    }

    return true;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
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, &current_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;
}
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;
}
Esempio n. 9
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);
}
Esempio n. 10
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;
}
Esempio n. 11
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;
}
Esempio n. 12
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;
}
Esempio n. 13
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;
}
Esempio n. 14
0
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;
}