info.c revision 361169
1/*-
2 * info.c
3 *
4 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5 *
6 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $Id: info.c,v 1.3 2003/08/18 19:19:54 max Exp $
31 * $FreeBSD: stable/11/usr.sbin/bluetooth/hccontrol/info.c 361169 2020-05-18 09:01:18Z hselasky $
32 */
33
34#define L2CAP_SOCKET_CHECKED
35#include <bluetooth.h>
36#include <errno.h>
37#include <stdio.h>
38#include <string.h>
39#include "hccontrol.h"
40
41/* Send Read_Local_Version_Information command to the unit */
42static int
43hci_read_local_version_information(int s, int argc, char **argv)
44{
45	ng_hci_read_local_ver_rp	rp;
46	int				n;
47
48	n = sizeof(rp);
49	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
50			NG_HCI_OCF_READ_LOCAL_VER), (char *) &rp, &n) == ERROR)
51		return (ERROR);
52
53	if (rp.status != 0x00) {
54		fprintf(stdout, "Status: %s [%#02x]\n",
55			hci_status2str(rp.status), rp.status);
56		return (FAILED);
57	}
58
59	rp.manufacturer = le16toh(rp.manufacturer);
60
61	fprintf(stdout, "HCI version: %s [%#02x]\n",
62		hci_ver2str(rp.hci_version), rp.hci_version);
63	fprintf(stdout, "HCI revision: %#04x\n",
64		le16toh(rp.hci_revision));
65	fprintf(stdout, "LMP version: %s [%#02x]\n",
66		hci_lmpver2str(rp.lmp_version), rp.lmp_version);
67	fprintf(stdout, "LMP sub-version: %#04x\n",
68		le16toh(rp.lmp_subversion));
69	fprintf(stdout, "Manufacturer: %s [%#04x]\n",
70		hci_manufacturer2str(rp.manufacturer), rp.manufacturer);
71
72	return (OK);
73} /* hci_read_local_version_information */
74
75/* Send Read_Local_Supported_Commands command to the unit */
76static int
77hci_read_local_supported_commands(int s, int argc, char **argv)
78{
79	ng_hci_read_local_commands_rp	rp;
80	int				n;
81	char				buffer[16384];
82
83	n = sizeof(rp);
84	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
85			NG_HCI_OCF_READ_LOCAL_COMMANDS),
86			(char *) &rp, &n) == ERROR)
87		return (ERROR);
88
89	if (rp.status != 0x00) {
90		fprintf(stdout, "Status: %s [%#02x]\n",
91			hci_status2str(rp.status), rp.status);
92		return (FAILED);
93	}
94
95	fprintf(stdout, "Supported commands:");
96	for (n = 0; n < sizeof(rp.features); n++) {
97		if (n % 8 == 0)
98			fprintf(stdout, "\n");
99		fprintf(stdout, "%#02x ", rp.features[n]);
100	}
101	fprintf(stdout, "\n%s\n", hci_commands2str(rp.features,
102		buffer, sizeof(buffer)));
103
104	return (OK);
105} /* hci_read_local_supported_commands */
106
107/* Send Read_Local_Supported_Features command to the unit */
108static int
109hci_read_local_supported_features(int s, int argc, char **argv)
110{
111	ng_hci_read_local_features_rp	rp;
112	int				n;
113	char				buffer[2048];
114
115	n = sizeof(rp);
116	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
117			NG_HCI_OCF_READ_LOCAL_FEATURES),
118			(char *) &rp, &n) == ERROR)
119		return (ERROR);
120
121	if (rp.status != 0x00) {
122		fprintf(stdout, "Status: %s [%#02x]\n",
123			hci_status2str(rp.status), rp.status);
124		return (FAILED);
125	}
126
127	fprintf(stdout, "Features: ");
128	for (n = 0; n < sizeof(rp.features); n++)
129		fprintf(stdout, "%#02x ", rp.features[n]);
130	fprintf(stdout, "\n%s\n", hci_features2str(rp.features,
131		buffer, sizeof(buffer)));
132
133	return (OK);
134} /* hci_read_local_supported_features */
135
136/* Sent Read_Buffer_Size command to the unit */
137static int
138hci_read_buffer_size(int s, int argc, char **argv)
139{
140	ng_hci_read_buffer_size_rp	rp;
141	int				n;
142
143	n = sizeof(rp);
144	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
145			NG_HCI_OCF_READ_BUFFER_SIZE),
146			(char *) &rp, &n) == ERROR)
147		return (ERROR);
148
149	if (rp.status != 0x00) {
150		fprintf(stdout, "Status: %s [%#02x]\n",
151			hci_status2str(rp.status), rp.status);
152		return (FAILED);
153	}
154
155	fprintf(stdout, "Max. ACL packet size: %d bytes\n",
156		le16toh(rp.max_acl_size));
157	fprintf(stdout, "Number of ACL packets: %d\n",
158		le16toh(rp.num_acl_pkt));
159	fprintf(stdout, "Max. SCO packet size: %d bytes\n",
160		rp.max_sco_size);
161	fprintf(stdout, "Number of SCO packets: %d\n",
162		le16toh(rp.num_sco_pkt));
163
164	return (OK);
165} /* hci_read_buffer_size */
166
167/* Send Read_Country_Code command to the unit */
168static int
169hci_read_country_code(int s, int argc, char **argv)
170{
171	ng_hci_read_country_code_rp	rp;
172	int				n;
173
174	n = sizeof(rp);
175	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
176			NG_HCI_OCF_READ_COUNTRY_CODE),
177			(char *) &rp, &n) == ERROR)
178		return (ERROR);
179
180	if (rp.status != 0x00) {
181		fprintf(stdout, "Status: %s [%#02x]\n",
182			hci_status2str(rp.status), rp.status);
183		return (FAILED);
184	}
185
186	fprintf(stdout, "Country code: %s [%#02x]\n",
187			hci_cc2str(rp.country_code), rp.country_code);
188
189	return (OK);
190} /* hci_read_country_code */
191
192/* Send Read_BD_ADDR command to the unit */
193static int
194hci_read_bd_addr(int s, int argc, char **argv)
195{
196	ng_hci_read_bdaddr_rp	rp;
197	int			n;
198
199	n = sizeof(rp);
200	if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_INFO,
201			NG_HCI_OCF_READ_BDADDR), (char *) &rp, &n) == ERROR)
202		return (ERROR);
203
204	if (rp.status != 0x00) {
205		fprintf(stdout, "Status: %s [%#02x]\n",
206			hci_status2str(rp.status), rp.status);
207		return (FAILED);
208	}
209
210	fprintf(stdout, "BD_ADDR: %s\n", bt_ntoa(&rp.bdaddr, NULL));
211
212	return (OK);
213} /* hci_read_bd_addr */
214
215struct hci_command	info_commands[] = {
216{
217"read_local_version_information",
218"\nThis command will read the values for the version information for the\n" \
219"local Bluetooth unit.",
220&hci_read_local_version_information
221},
222{
223"read_local_supported_commands",
224"\nThis command will read the commands the local Bluetooth unit supports.\n",
225&hci_read_local_supported_commands
226},
227{
228"read_local_supported_features",
229"\nThis command requests a list of the supported features for the local\n" \
230"unit. This command will return a list of the LMP features.",
231&hci_read_local_supported_features
232},
233{
234"read_buffer_size",
235"\nThe Read_Buffer_Size command is used to read the maximum size of the\n" \
236"data portion of HCI ACL and SCO Data Packets sent from the Host to the\n" \
237"Host Controller.",
238&hci_read_buffer_size
239},
240{
241"read_country_code",
242"\nThis command will read the value for the Country_Code return parameter.\n" \
243"The Country_Code defines which range of frequency band of the ISM 2.4 GHz\n" \
244"band will be used by the unit.",
245&hci_read_country_code
246},
247{
248"read_bd_addr",
249"\nThis command will read the value for the BD_ADDR parameter. The BD_ADDR\n" \
250"is a 48-bit unique identifier for a Bluetooth unit.",
251&hci_read_bd_addr
252},
253{
254NULL,
255}};
256
257