1107120Sjulian/*
2107120Sjulian * info.c
3107120Sjulian *
4107120Sjulian * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5107120Sjulian * All rights reserved.
6107120Sjulian *
7107120Sjulian * Redistribution and use in source and binary forms, with or without
8107120Sjulian * modification, are permitted provided that the following conditions
9107120Sjulian * are met:
10107120Sjulian * 1. Redistributions of source code must retain the above copyright
11107120Sjulian *    notice, this list of conditions and the following disclaimer.
12107120Sjulian * 2. Redistributions in binary form must reproduce the above copyright
13107120Sjulian *    notice, this list of conditions and the following disclaimer in the
14107120Sjulian *    documentation and/or other materials provided with the distribution.
15107120Sjulian *
16107120Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17107120Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18107120Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19107120Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20107120Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21107120Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22107120Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23107120Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24107120Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25107120Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26107120Sjulian * SUCH DAMAGE.
27107120Sjulian *
28121054Semax * $Id: info.c,v 1.3 2003/08/18 19:19:54 max Exp $
29107120Sjulian * $FreeBSD: stable/10/usr.sbin/bluetooth/hccontrol/info.c 361154 2020-05-18 08:43:05Z hselasky $
30107120Sjulian */
31107120Sjulian
32121054Semax#include <bluetooth.h>
33107120Sjulian#include <errno.h>
34107120Sjulian#include <stdio.h>
35107120Sjulian#include <string.h>
36107120Sjulian#include "hccontrol.h"
37107120Sjulian
38107120Sjulian/* Send Read_Local_Version_Information command to the unit */
39107120Sjulianstatic int
40107120Sjulianhci_read_local_version_information(int s, int argc, char **argv)
41107120Sjulian{
42107120Sjulian	ng_hci_read_local_ver_rp	rp;
43107120Sjulian	int				n;
44107120Sjulian
45107120Sjulian	n = sizeof(rp);
46107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
47107120Sjulian			NG_HCI_OCF_READ_LOCAL_VER), (char *) &rp, &n) == ERROR)
48107120Sjulian		return (ERROR);
49107120Sjulian
50107120Sjulian	if (rp.status != 0x00) {
51107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
52107120Sjulian			hci_status2str(rp.status), rp.status);
53107120Sjulian		return (FAILED);
54107120Sjulian	}
55107120Sjulian
56107120Sjulian	rp.manufacturer = le16toh(rp.manufacturer);
57107120Sjulian
58107120Sjulian	fprintf(stdout, "HCI version: %s [%#02x]\n",
59107120Sjulian		hci_ver2str(rp.hci_version), rp.hci_version);
60107120Sjulian	fprintf(stdout, "HCI revision: %#04x\n",
61107120Sjulian		le16toh(rp.hci_revision));
62155964Smarkus	fprintf(stdout, "LMP version: %s [%#02x]\n",
63155964Smarkus		hci_lmpver2str(rp.lmp_version), rp.lmp_version);
64107120Sjulian	fprintf(stdout, "LMP sub-version: %#04x\n",
65107120Sjulian		le16toh(rp.lmp_subversion));
66107120Sjulian	fprintf(stdout, "Manufacturer: %s [%#04x]\n",
67107120Sjulian		hci_manufacturer2str(rp.manufacturer), rp.manufacturer);
68107120Sjulian
69107120Sjulian	return (OK);
70107120Sjulian} /* hci_read_local_version_information */
71107120Sjulian
72107120Sjulian/* Send Read_Local_Supported_Features command to the unit */
73107120Sjulianstatic int
74107120Sjulianhci_read_local_supported_features(int s, int argc, char **argv)
75107120Sjulian{
76107120Sjulian	ng_hci_read_local_features_rp	rp;
77107120Sjulian	int				n;
78361154Shselasky	char				buffer[2048];
79107120Sjulian
80107120Sjulian	n = sizeof(rp);
81107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
82107120Sjulian			NG_HCI_OCF_READ_LOCAL_FEATURES),
83107120Sjulian			(char *) &rp, &n) == ERROR)
84107120Sjulian		return (ERROR);
85107120Sjulian
86107120Sjulian	if (rp.status != 0x00) {
87107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
88107120Sjulian			hci_status2str(rp.status), rp.status);
89107120Sjulian		return (FAILED);
90107120Sjulian	}
91107120Sjulian
92107120Sjulian	fprintf(stdout, "Features: ");
93107120Sjulian	for (n = 0; n < sizeof(rp.features); n++)
94107120Sjulian		fprintf(stdout, "%#02x ", rp.features[n]);
95107120Sjulian	fprintf(stdout, "\n%s\n", hci_features2str(rp.features,
96107120Sjulian		buffer, sizeof(buffer)));
97107120Sjulian
98107120Sjulian	return (OK);
99107120Sjulian} /* hci_read_local_supported_features */
100107120Sjulian
101107120Sjulian/* Sent Read_Buffer_Size command to the unit */
102107120Sjulianstatic int
103107120Sjulianhci_read_buffer_size(int s, int argc, char **argv)
104107120Sjulian{
105107120Sjulian	ng_hci_read_buffer_size_rp	rp;
106107120Sjulian	int				n;
107107120Sjulian
108107120Sjulian	n = sizeof(rp);
109107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
110107120Sjulian			NG_HCI_OCF_READ_BUFFER_SIZE),
111107120Sjulian			(char *) &rp, &n) == ERROR)
112107120Sjulian		return (ERROR);
113107120Sjulian
114107120Sjulian	if (rp.status != 0x00) {
115107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
116107120Sjulian			hci_status2str(rp.status), rp.status);
117107120Sjulian		return (FAILED);
118107120Sjulian	}
119107120Sjulian
120107120Sjulian	fprintf(stdout, "Max. ACL packet size: %d bytes\n",
121107120Sjulian		le16toh(rp.max_acl_size));
122107120Sjulian	fprintf(stdout, "Number of ACL packets: %d\n",
123107120Sjulian		le16toh(rp.num_acl_pkt));
124107120Sjulian	fprintf(stdout, "Max. SCO packet size: %d bytes\n",
125107120Sjulian		rp.max_sco_size);
126107120Sjulian	fprintf(stdout, "Number of SCO packets: %d\n",
127107120Sjulian		le16toh(rp.num_sco_pkt));
128107120Sjulian
129107120Sjulian	return (OK);
130107120Sjulian} /* hci_read_buffer_size */
131107120Sjulian
132107120Sjulian/* Send Read_Country_Code command to the unit */
133107120Sjulianstatic int
134107120Sjulianhci_read_country_code(int s, int argc, char **argv)
135107120Sjulian{
136107120Sjulian	ng_hci_read_country_code_rp	rp;
137107120Sjulian	int				n;
138107120Sjulian
139107120Sjulian	n = sizeof(rp);
140107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
141107120Sjulian			NG_HCI_OCF_READ_COUNTRY_CODE),
142107120Sjulian			(char *) &rp, &n) == ERROR)
143107120Sjulian		return (ERROR);
144107120Sjulian
145107120Sjulian	if (rp.status != 0x00) {
146107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
147107120Sjulian			hci_status2str(rp.status), rp.status);
148107120Sjulian		return (FAILED);
149107120Sjulian	}
150107120Sjulian
151107120Sjulian	fprintf(stdout, "Country code: %s [%#02x]\n",
152107120Sjulian			hci_cc2str(rp.country_code), rp.country_code);
153107120Sjulian
154107120Sjulian	return (OK);
155107120Sjulian} /* hci_read_country_code */
156107120Sjulian
157107120Sjulian/* Send Read_BD_ADDR command to the unit */
158107120Sjulianstatic int
159107120Sjulianhci_read_bd_addr(int s, int argc, char **argv)
160107120Sjulian{
161107120Sjulian	ng_hci_read_bdaddr_rp	rp;
162107120Sjulian	int			n;
163107120Sjulian
164107120Sjulian	n = sizeof(rp);
165107120Sjulian	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
166107120Sjulian			NG_HCI_OCF_READ_BDADDR), (char *) &rp, &n) == ERROR)
167107120Sjulian		return (ERROR);
168107120Sjulian
169107120Sjulian	if (rp.status != 0x00) {
170107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
171107120Sjulian			hci_status2str(rp.status), rp.status);
172107120Sjulian		return (FAILED);
173107120Sjulian	}
174107120Sjulian
175121054Semax	fprintf(stdout, "BD_ADDR: %s\n", bt_ntoa(&rp.bdaddr, NULL));
176107120Sjulian
177107120Sjulian	return (OK);
178107120Sjulian} /* hci_read_bd_addr */
179107120Sjulian
180107120Sjulianstruct hci_command	info_commands[] = {
181107120Sjulian{
182107120Sjulian"read_local_version_information",
183107120Sjulian"\nThis command will read the values for the version information for the\n" \
184107120Sjulian"local Bluetooth unit.",
185107120Sjulian&hci_read_local_version_information
186107120Sjulian},
187107120Sjulian{
188107120Sjulian"read_local_supported_features",
189107120Sjulian"\nThis command requests a list of the supported features for the local\n" \
190107120Sjulian"unit. This command will return a list of the LMP features.",
191107120Sjulian&hci_read_local_supported_features
192107120Sjulian},
193107120Sjulian{
194107120Sjulian"read_buffer_size",
195107120Sjulian"\nThe Read_Buffer_Size command is used to read the maximum size of the\n" \
196107120Sjulian"data portion of HCI ACL and SCO Data Packets sent from the Host to the\n" \
197107120Sjulian"Host Controller.",
198107120Sjulian&hci_read_buffer_size
199107120Sjulian},
200107120Sjulian{
201107120Sjulian"read_country_code",
202107120Sjulian"\nThis command will read the value for the Country_Code return parameter.\n" \
203107120Sjulian"The Country_Code defines which range of frequency band of the ISM 2.4 GHz\n" \
204107120Sjulian"band will be used by the unit.",
205107120Sjulian&hci_read_country_code
206107120Sjulian},
207107120Sjulian{
208107120Sjulian"read_bd_addr",
209107120Sjulian"\nThis command will read the value for the BD_ADDR parameter. The BD_ADDR\n" \
210107120Sjulian"is a 48-bit unique identifier for a Bluetooth unit.",
211107120Sjulian&hci_read_bd_addr
212107120Sjulian},
213107120Sjulian{
214107120SjulianNULL,
215107120Sjulian}};
216107120Sjulian
217