Пример #1
0
/* Send Read_Connection_List command to the node */
static int
hci_read_connection_list(int s, int argc, char **argv)
{
	struct ng_btsocket_hci_raw_con_list	r;
	int					n, error = OK;

	memset(&r, 0, sizeof(r));
	r.num_connections = NG_HCI_MAX_CON_NUM;
	r.connections = calloc(NG_HCI_MAX_CON_NUM, sizeof(ng_hci_node_con_ep));
	if (r.connections == NULL) {
		errno = ENOMEM;
		return (ERROR);
	}

	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_CON_LIST, &r, sizeof(r)) < 0) {
		error = ERROR;
		goto out;
	}

	fprintf(stdout,
"Remote BD_ADDR    " \
"Handle " \
"Type " \
"Mode " \
"Role " \
"Encrypt " \
"Pending " \
"Queue " \
"State\n");

	for (n = 0; n < r.num_connections; n++) {
		fprintf(stdout,
"%-17.17s " \
"%6d " \
"%4.4s " \
"%4d " \
"%4.4s " \
"%7.7s " \
"%7d " \
"%5d " \
"%s\n",
			hci_bdaddr2str(&r.connections[n].bdaddr),
			r.connections[n].con_handle,
			(r.connections[n].link_type == NG_HCI_LINK_ACL)?
				"ACL" : "SCO",
			r.connections[n].mode,
			(r.connections[n].role == NG_HCI_ROLE_MASTER)?
				"MAST" : "SLAV",
			hci_encrypt2str(r.connections[n].encryption_mode, 1),
			r.connections[n].pending,
			r.connections[n].queue_len,
			hci_con_state2str(r.connections[n].state));
	}
out:
	free(r.connections);

	return (error);
} /* hci_read_connection_list */
Пример #2
0
/* Send Read_Neighbor_Cache command to the node */
static int
hci_read_neighbor_cache(int s, int argc, char **argv)
{
	struct ng_btsocket_hci_raw_node_neighbor_cache	r;
	int						n, error = OK;

	memset(&r, 0, sizeof(r));
	r.num_entries = NG_HCI_MAX_NEIGHBOR_NUM;
	r.entries = calloc(NG_HCI_MAX_NEIGHBOR_NUM,
				sizeof(ng_hci_node_neighbor_cache_entry_ep));
	if (r.entries == NULL) {
		errno = ENOMEM;
		return (ERROR);
	}

	if (ioctl(s, SIOC_HCI_RAW_NODE_GET_NEIGHBOR_CACHE, &r,
			sizeof(r)) < 0) {
		error = ERROR;
		goto out;
	}

	fprintf(stdout,
"BD_ADDR           " \
"Features                " \
"Clock offset " \
"Page scan " \
"Rep. scan\n");

	for (n = 0; n < r.num_entries; n++) {
		fprintf(stdout, 
"%-17.17s " \
"%02x %02x %02x %02x %02x %02x %02x %02x " \
"%#12x " \
"%#9x " \
"%#9x\n",
			hci_bdaddr2str(&r.entries[n].bdaddr),
			r.entries[n].features[0], r.entries[n].features[1],
			r.entries[n].features[2], r.entries[n].features[3],
			r.entries[n].features[4], r.entries[n].features[5],
			r.entries[n].features[6], r.entries[n].features[7],
			r.entries[n].clock_offset, r.entries[n].page_scan_mode,
			r.entries[n].page_scan_rep_mode);
	}
out:
	free(r.entries);

	return (error);
} /* hci_read_neightbor_cache */
Пример #3
0
/* Print Inquiry_Result event */
static void
hci_inquiry_response(int n, uint8_t **b)
{
	ng_hci_inquiry_response	*ir = (ng_hci_inquiry_response *)(*b);

	fprintf(stdout, "Inquiry result #%d\n", n);
	fprintf(stdout, "\tBD_ADDR: %s\n", hci_bdaddr2str(&ir->bdaddr));
	fprintf(stdout, "\tPage Scan Rep. Mode: %#02x\n",
		ir->page_scan_rep_mode);
	fprintf(stdout, "\tPage Scan Period Mode: %#02x\n",
		ir->page_scan_period_mode);
	fprintf(stdout, "\tPage Scan Mode: %#02x\n",
		ir->page_scan_mode);
	fprintf(stdout, "\tClass: %02x:%02x:%02x\n",
		ir->uclass[2], ir->uclass[1], ir->uclass[0]);
	fprintf(stdout, "\tClock offset: %#04x\n",
		le16toh(ir->clock_offset));

	*b += sizeof(*ir);
} /* hci_inquiry_response */
Пример #4
0
/* Send Swith Role to the unit */
static int
hci_switch_role(int s, int argc, char **argv)
{
	int			 n0;
	char			 b[512];
	ng_hci_switch_role_cp	 cp;
	ng_hci_event_pkt_t	*e = (ng_hci_event_pkt_t *) b; 

	/* parse command parameters */
	switch (argc) {
	case 2:
		/* bdaddr */
		if (!bt_aton(argv[0], &cp.bdaddr)) {
			struct hostent	*he = NULL;

			if ((he = bt_gethostbyname(argv[0])) == NULL)
				return (USAGE);

			memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
		}

		/* role */
		if (sscanf(argv[1], "%d", &n0) != 1)
			return (USAGE);

		cp.role = n0? NG_HCI_ROLE_SLAVE : NG_HCI_ROLE_MASTER;
		break;

	default:
		return (USAGE);
	}

	/* send request and expect status response */
	n0 = sizeof(b);
	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_POLICY,
			NG_HCI_OCF_SWITCH_ROLE),
			(char const *) &cp, sizeof(cp), b, &n0) == ERROR)
		return (ERROR);

	if (*b != 0x00)
		return (FAILED);

	/* wait for event */
again:
	n0 = sizeof(b);
	if (hci_recv(s, b, &n0) == ERROR)
		return (ERROR);
	if (n0 < sizeof(*e)) {
		errno = EIO;
		return (ERROR);
	}

	if (e->event == NG_HCI_EVENT_ROLE_CHANGE) {
		ng_hci_role_change_ep	*ep = (ng_hci_role_change_ep *)(e + 1);

		if (ep->status != 0x00) {
			fprintf(stdout, "Status: %s [%#02x]\n", 
				hci_status2str(ep->status), ep->status);
			return (FAILED);
		}

		fprintf(stdout, "BD_ADDR: %s\n", hci_bdaddr2str(&ep->bdaddr));
		fprintf(stdout, "Role: %s [%#x]\n",
			(ep->role == NG_HCI_ROLE_MASTER)? "Master" : "Slave",
			ep->role);
	} else
		goto again;

	return (OK);
} /* hci_switch_role */
Пример #5
0
/* Send Remote_Name_Request command to the unit */
static int
hci_remote_name_request(int s, int argc, char **argv)
{
	int				 n0;
	char				 b[512];
	ng_hci_remote_name_req_cp	 cp;
	ng_hci_event_pkt_t		*e = (ng_hci_event_pkt_t *) b; 

	memset(&cp, 0, sizeof(cp));
	cp.page_scan_rep_mode = NG_HCI_SCAN_REP_MODE0;
	cp.page_scan_mode = NG_HCI_MANDATORY_PAGE_SCAN_MODE;

	/* parse command parameters */
	switch (argc) {
	case 4:
		/* clock_offset */
		if (sscanf(argv[3], "%x", &n0) != 1)
			return (USAGE);

		cp.clock_offset = (n0 & 0xffff);
		cp.clock_offset = htole16(cp.clock_offset);

	case 3:
		/* page_scan_mode */
		if (sscanf(argv[2], "%d", &n0) != 1 || n0 < 0x00 || n0 > 0x03)
			return (USAGE);

		cp.page_scan_mode = (n0 & 0xff);

	case 2:
		/* page_scan_rep_mode */
		if (sscanf(argv[1], "%d", &n0) != 1 || n0 < 0x00 || n0 > 0x02)
			return (USAGE);

		cp.page_scan_rep_mode = (n0 & 0xff);

	case 1:
		/* BD_ADDR */
		if (!bt_aton(argv[0], &cp.bdaddr)) {
			struct hostent	*he = NULL;

			if ((he = bt_gethostbyname(argv[0])) == NULL)
				return (USAGE);

			memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
		}
		break;

	default:
		return (USAGE);
	}

	/* send request and expect status response */
	n0 = sizeof(b);
	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
			NG_HCI_OCF_REMOTE_NAME_REQ),
			(char const *) &cp, sizeof(cp), b, &n0) == ERROR)
		return (ERROR);

	if (*b != 0x00)
		return (FAILED);

	/* wait for event */
again:
	n0 = sizeof(b);
	if (hci_recv(s, b, &n0) == ERROR)
		return (ERROR);
	if (n0 < sizeof(*e)) {
		errno = EIO;
		return (ERROR);
	}

	if (e->event == NG_HCI_EVENT_REMOTE_NAME_REQ_COMPL) {
		ng_hci_remote_name_req_compl_ep	*ep = 
				(ng_hci_remote_name_req_compl_ep *)(e + 1);

		if (ep->status != 0x00) {
			fprintf(stdout, "Status: %s [%#02x]\n", 
				hci_status2str(ep->status), ep->status);
			return (FAILED);
		}

		fprintf(stdout, "BD_ADDR: %s\n", hci_bdaddr2str(&ep->bdaddr));
		fprintf(stdout, "Name: %s\n", ep->name);
	} else 
		goto again;

	return (OK);
} /* hci_remote_name_request */
Пример #6
0
/* Send Add_SCO_Connection command to the unit */
static int
hci_add_sco_connection(int s, int argc, char **argv)
{
	int			 n;
	char			 b[512];
	ng_hci_add_sco_con_cp	 cp;
	ng_hci_event_pkt_t	*e = (ng_hci_event_pkt_t *) b; 

	/* Set defaults */
	memset(&cp, 0, sizeof(cp));
	cp.pkt_type = htole16(NG_HCI_PKT_HV1 | NG_HCI_PKT_HV2 | NG_HCI_PKT_HV3);

	/* parse command parameters */
	switch (argc) {
	case 2:
		/* packet type */
		if (sscanf(argv[1], "%x", &n) != 1)
			return (USAGE);

		n &= (NG_HCI_PKT_HV1 | NG_HCI_PKT_HV2 | NG_HCI_PKT_HV3);
		if (n == 0)
			return (USAGE);

		cp.pkt_type = (uint16_t) (n & 0x0fff);
		cp.pkt_type = htole16(cp.pkt_type);

	case 1:
		/* acl connection handle */
		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
			return (USAGE);

		cp.con_handle = (uint16_t) (n & 0x0fff);
		cp.con_handle = htole16(cp.con_handle);
		break;

	default:
		return (USAGE);
	}

	/* send request and expect status response */
	n = sizeof(b);
	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
			NG_HCI_OCF_ADD_SCO_CON),
			(char const *) &cp, sizeof(cp), b, &n) == ERROR)
		return (ERROR);

	if (*b != 0x00)
		return (FAILED);

	/* wait for event */
again:
	n = sizeof(b);
	if (hci_recv(s, b, &n) == ERROR)
		return (ERROR);
	if (n < sizeof(*e)) {
		errno = EIO;
		return (ERROR);
	}

	if (e->event == NG_HCI_EVENT_CON_COMPL) {
		ng_hci_con_compl_ep	*ep = (ng_hci_con_compl_ep *)(e + 1);

		if (ep->status != 0x00) {
			fprintf(stdout, "Status: %s [%#02x]\n", 
				hci_status2str(ep->status), ep->status);
			return (FAILED);
		}

		fprintf(stdout, "BD_ADDR: %s\n", hci_bdaddr2str(&ep->bdaddr));
		fprintf(stdout, "Connection handle: %d\n",
			le16toh(ep->con_handle));
		fprintf(stdout, "Encryption mode: %s [%d]\n",
			hci_encrypt2str(ep->encryption_mode, 0),
			ep->encryption_mode);
	} else
		goto again;

	return (OK);
} /* Add_SCO_Connection */
Пример #7
0
/* Send Create_Connection command to the unit */
static int
hci_create_connection(int s, int argc, char **argv)
{
	int			 n0;
	char			 b[512];
	ng_hci_create_con_cp	 cp;
	ng_hci_event_pkt_t	*e = (ng_hci_event_pkt_t *) b; 

	/* Set defaults */
	memset(&cp, 0, sizeof(cp));
	cp.pkt_type = htole16(	NG_HCI_PKT_DM1 | NG_HCI_PKT_DH1 |
				NG_HCI_PKT_DM3 | NG_HCI_PKT_DH3 |
				NG_HCI_PKT_DM5);
	cp.page_scan_rep_mode = NG_HCI_SCAN_REP_MODE0;
	cp.page_scan_mode = NG_HCI_MANDATORY_PAGE_SCAN_MODE;
	cp.clock_offset = 0;
	cp.accept_role_switch = 1;

	/* parse command parameters */
	switch (argc) {
	case 6:
		/* accept role switch */
		if (sscanf(argv[5], "%d", &n0) != 1)
			return (USAGE);

		cp.accept_role_switch = n0 ? 1 : 0;

	case 5:
		/* clock offset */
		if (sscanf(argv[4], "%d", &n0) != 1)
			return (USAGE);

		cp.clock_offset = (n0 & 0xffff);
		cp.clock_offset = htole16(cp.clock_offset);

	case 4:
		/* page scan mode */
		if (sscanf(argv[3], "%d", &n0) != 1 || n0 < 0 || n0 > 3)
			return (USAGE);

		cp.page_scan_mode = (n0 & 0xff);

	case 3:
		/* page scan rep mode */
		if (sscanf(argv[2], "%d", &n0) != 1 || n0 < 0 || n0 > 2)
			return (USAGE);

		cp.page_scan_rep_mode = (n0 & 0xff);

	case 2:
		/* packet type */
		if (sscanf(argv[1], "%x", &n0) != 1)
			return (USAGE);

		n0 &= (	NG_HCI_PKT_DM1 | NG_HCI_PKT_DH1 |
			NG_HCI_PKT_DM3 | NG_HCI_PKT_DH3 |
			NG_HCI_PKT_DM5);
		if (n0 == 0)
			return (USAGE);

		cp.pkt_type = (n0 & 0xffff);
		cp.pkt_type = htole16(cp.pkt_type);

	case 1:
		/* BD_ADDR */
		if (!bt_aton(argv[0], &cp.bdaddr)) {
			struct hostent	*he = NULL;

			if ((he = bt_gethostbyname(argv[0])) == NULL)
				return (USAGE);

			memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
		}
		break;

	default:
		return (USAGE);
	}

	/* send request and expect status response */
	n0 = sizeof(b);
	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_CONTROL,
			NG_HCI_OCF_CREATE_CON),
			(char const *) &cp, sizeof(cp), b, &n0) == ERROR)
		return (ERROR);

	if (*b != 0x00)
		return (FAILED);

	/* wait for event */
again:
	n0 = sizeof(b);
	if (hci_recv(s, b, &n0) == ERROR)
		return (ERROR);
	if (n0 < sizeof(*e)) {
		errno = EIO;
		return (ERROR);
	}

	if (e->event == NG_HCI_EVENT_CON_COMPL) {
		ng_hci_con_compl_ep	*ep = (ng_hci_con_compl_ep *)(e + 1);

		if (ep->status != 0x00) {
			fprintf(stdout, "Status: %s [%#02x]\n", 
				hci_status2str(ep->status), ep->status);
			return (FAILED);
		}

		fprintf(stdout, "BD_ADDR: %s\n", hci_bdaddr2str(&ep->bdaddr));
		fprintf(stdout, "Connection handle: %d\n",
			le16toh(ep->con_handle));
		fprintf(stdout, "Encryption mode: %s [%d]\n",
			hci_encrypt2str(ep->encryption_mode, 0),
			ep->encryption_mode);
	} else
		goto again;

	return (OK);
} /* hci_create_connection */