FreeBSD/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c
/* Send Read_Stored_Link_Key command to the unit */
Send Read_Stored_Link_Key command to the unit
Send Read_Stored_Link_Key command to the unit
static int
hci_read_stored_link_key(int s, int argc, char **argv)
{
	struct {
		ng_hci_cmd_pkt_t			hdr;
		ng_hci_read_stored_link_key_cp		cp;
	} __attribute__ ((packed))			cmd;
	struct {
		ng_hci_event_pkt_t			hdr;
		union {
			ng_hci_command_compl_ep		cc;
			ng_hci_return_link_keys_ep	key;
			uint8_t				b[NG_HCI_EVENT_PKT_SIZE];
		}					ep;
	} __attribute__ ((packed))			event;
	int						n, n1;
	memset(&cmd, 0, sizeof(cmd));
	cmd.hdr.type = NG_HCI_CMD_PKT;
	cmd.hdr.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
				NG_HCI_OCF_READ_STORED_LINK_KEY));
	cmd.hdr.length = sizeof(cmd.cp);
	switch (argc) {
	case 1:
		if (!bt_aton(argv[0], &cmd.cp.bdaddr)) {
			struct hostent	*he = NULL;
			if ((he = bt_gethostbyname(argv[0])) == NULL)
				return (USAGE);
			memcpy(&cmd.cp.bdaddr, he->h_addr, sizeof(cmd.cp.bdaddr));
		}
		break;
	default:
		cmd.cp.read_all = 1;
		break;
	}
	if (hci_send(s, (char const *) &cmd, sizeof(cmd)) != OK)
		return (ERROR);
again:
	memset(&event, 0, sizeof(event));
	n = sizeof(event);
	if (hci_recv(s, (char *) &event, &n) != OK)
		return (ERROR);
	if (n <= sizeof(event.hdr)) {
		errno = EMSGSIZE;
		return (ERROR);
	}
	if (event.hdr.type != NG_HCI_EVENT_PKT) {
		errno = EIO;
		return (ERROR);
	}
	switch (event.hdr.event) {
	case NG_HCI_EVENT_COMMAND_COMPL: {
		ng_hci_read_stored_link_key_rp	*rp = NULL;
		if (event.ep.cc.opcode == 0x0000 ||
		    event.ep.cc.opcode != cmd.hdr.opcode)
			goto again;
		rp = (ng_hci_read_stored_link_key_rp *)(event.ep.b + 
				sizeof(event.ep.cc));
		fprintf(stdout, "Complete: Status: %s [%#x]\n", 
				hci_status2str(rp->status), rp->status);
		fprintf(stdout, "Maximum Number of keys: %d\n",
				le16toh(rp->max_num_keys));
		fprintf(stdout, "Number of keys read: %d\n",
				le16toh(rp->num_keys_read));
		} break;
	case NG_HCI_EVENT_RETURN_LINK_KEYS: {
		struct _key {
			bdaddr_t	bdaddr;
			uint8_t		key[NG_HCI_KEY_SIZE];
		} __attribute__ ((packed))	*k = NULL;
		fprintf(stdout, "Event: Number of keys: %d\n",
			event.ep.key.num_keys);
		k = (struct _key *)(event.ep.b + sizeof(event.ep.key));
		for (n = 0; n < event.ep.key.num_keys; n++) {
			fprintf(stdout, "\t%d: %s ",
				n + 1, hci_bdaddr2str(&k->bdaddr));
			for (n1 = 0; n1 < sizeof(k->key); n1++)
				fprintf(stdout, "%02x", k->key[n1]);
			fprintf(stdout, "\n");
			k ++;
		}
		goto again;
		} break;
	default:
		goto again;
	}
	return (OK);
}
static int hci_read_stored_link_key ( int s , int argc , char * * argv ) { struct { ng_hci_cmd_pkt_t hdr ; ng_hci_read_stored_link_key_cp cp ; } __attribute__ ( ( packed ) ) cmd ; struct { ng_hci_event_pkt_t hdr ; union { ng_hci_command_compl_ep cc ; ng_hci_return_link_keys_ep key ; uint8_t b [ NG_HCI_EVENT_PKT_SIZE ] ; } ep ; } __attribute__ ( ( packed ) ) event ; int n , n1 ; memset ( & cmd , 0 , sizeof ( cmd ) ) ; cmd . hdr . type = NG_HCI_CMD_PKT ; cmd . hdr . opcode = htole16 ( NG_HCI_OPCODE ( NG_HCI_OGF_HC_BASEBAND , NG_HCI_OCF_READ_STORED_LINK_KEY ) ) ; cmd . hdr . length = sizeof ( cmd . cp ) ; switch ( argc ) { case 1 : if ( ! bt_aton ( argv [ 0 ] , & cmd . cp . bdaddr ) ) { struct hostent * he = NULL ; if ( ( he = bt_gethostbyname ( argv [ 0 ] ) ) == NULL ) return ( USAGE ) ; memcpy ( & cmd . cp . bdaddr , he -> h_addr , sizeof ( cmd . cp . bdaddr ) ) ; } break ; default : cmd . cp . read_all = 1 ; break ; } if ( hci_send ( s , ( char const * ) & cmd , sizeof ( cmd ) ) != OK ) return ( ERROR ) ; again : memset ( & event , 0 , sizeof ( event ) ) ; n = sizeof ( event ) ; if ( hci_recv ( s , ( char * ) & event , & n ) != OK ) return ( ERROR ) ; if ( n <= sizeof ( event . hdr ) ) { errno = EMSGSIZE ; return ( ERROR ) ; } if ( event . hdr . type != NG_HCI_EVENT_PKT ) { errno = EIO ; return ( ERROR ) ; } switch ( event . hdr . event ) { case NG_HCI_EVENT_COMMAND_COMPL : { ng_hci_read_stored_link_key_rp * rp = NULL ; if ( event . ep . cc . opcode == 0x0000 || event . ep . cc . opcode != cmd . hdr . opcode ) goto again ; rp = ( ng_hci_read_stored_link_key_rp * ) ( event . ep . b + sizeof ( event . ep . cc ) ) ; fprintf ( stdout , " \n " , hci_status2str ( rp -> status ) , rp -> status ) ; fprintf ( stdout , " \n " , le16toh ( rp -> max_num_keys ) ) ; fprintf ( stdout , " \n " , le16toh ( rp -> num_keys_read ) ) ; } break ; case NG_HCI_EVENT_RETURN_LINK_KEYS : { struct _key { bdaddr_t bdaddr ; uint8_t key [ NG_HCI_KEY_SIZE ] ; } __attribute__ ( ( packed ) ) * k = NULL ; fprintf ( stdout , " \n " , event . ep . key . num_keys ) ; k = ( struct _key * ) ( event . ep . b + sizeof ( event . ep . key ) ) ; for ( n = 0 ; n < event . ep . key . num_keys ; n ++ ) { fprintf ( stdout , " \t " , n + 1 , hci_bdaddr2str ( & k -> bdaddr ) ) ; for ( n1 = 0 ; n1 < sizeof ( k -> key ) ; n1 ++ ) fprintf ( stdout , " " , k -> key [ n1 ] ) ; fprintf ( stdout , " \n " ) ; k ++ ; } goto again ; } break ; default : goto again ; } return ( OK ) ; }
Send Read_Stored_Link_Key command to the unit
Send Read_Stored_Link_Key command to the unit
/* Send command */ /* parse BD_ADDR */ /* Receive events */ /* Parse event */