Example #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;
}
Example #2
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);
}
Example #3
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;
}
Example #4
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;
}
Example #5
0
/*
 * 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();
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
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;
}
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;
}
Example #10
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;
}
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;
}
Example #13
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;
}
Example #15
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;
}
Example #16
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;
}
Example #18
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;
}
Example #19
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;
}
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;
}
Example #21
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;
}
Example #22
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;
}
Example #23
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;
}
Example #25
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;
}