1 /*-
2 * status.c
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
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: status.c,v 1.2 2003/05/21 22:40:30 max Exp $
31 */
32
33 #include <sys/types.h>
34 #include <sys/endian.h>
35 #include <errno.h>
36 #include <netgraph/bluetooth/include/ng_hci.h>
37 #include <stdio.h>
38 #include "hccontrol.h"
39
40 /* Send Read_Failed_Contact_Counter command to the unit */
41 static int
hci_read_failed_contact_counter(int s,int argc,char ** argv)42 hci_read_failed_contact_counter(int s, int argc, char **argv)
43 {
44 ng_hci_read_failed_contact_cntr_cp cp;
45 ng_hci_read_failed_contact_cntr_rp rp;
46 int n;
47
48 switch (argc) {
49 case 1:
50 /* connection handle */
51 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
52 return (USAGE);
53
54 cp.con_handle = (uint16_t) (n & 0x0fff);
55 cp.con_handle = htole16(cp.con_handle);
56 break;
57
58 default:
59 return (USAGE);
60 }
61
62 /* send command */
63 n = sizeof(rp);
64 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_STATUS,
65 NG_HCI_OCF_READ_FAILED_CONTACT_CNTR),
66 (char const *) &cp, sizeof(cp),
67 (char *) &rp, &n) == ERROR)
68 return (ERROR);
69
70 if (rp.status != 0x00) {
71 fprintf(stdout, "Status: %s [%#02x]\n",
72 hci_status2str(rp.status), rp.status);
73 return (FAILED);
74 }
75
76 fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
77 fprintf(stdout, "Failed contact counter: %d\n", le16toh(rp.counter));
78
79 return (OK);
80 } /* hci_read_failed_contact_counter */
81
82 /* Send Reset_Failed_Contact_Counter command to the unit */
83 static int
hci_reset_failed_contact_counter(int s,int argc,char ** argv)84 hci_reset_failed_contact_counter(int s, int argc, char **argv)
85 {
86 ng_hci_reset_failed_contact_cntr_cp cp;
87 ng_hci_reset_failed_contact_cntr_rp rp;
88 int n;
89
90 switch (argc) {
91 case 1:
92 /* connection handle */
93 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
94 return (USAGE);
95
96 cp.con_handle = (uint16_t) (n & 0x0fff);
97 cp.con_handle = htole16(cp.con_handle);
98 break;
99
100 default:
101 return (USAGE);
102 }
103
104 /* send command */
105 n = sizeof(rp);
106 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_STATUS,
107 NG_HCI_OCF_RESET_FAILED_CONTACT_CNTR),
108 (char const *) &cp, sizeof(cp),
109 (char *) &rp, &n) == ERROR)
110 return (ERROR);
111
112 if (rp.status != 0x00) {
113 fprintf(stdout, "Status: %s [%#02x]\n",
114 hci_status2str(rp.status), rp.status);
115 return (FAILED);
116 }
117
118 return (OK);
119 } /* hci_reset_failed_contact_counter */
120
121 /* Sent Get_Link_Quality command to the unit */
122 static int
hci_get_link_quality(int s,int argc,char ** argv)123 hci_get_link_quality(int s, int argc, char **argv)
124 {
125 ng_hci_get_link_quality_cp cp;
126 ng_hci_get_link_quality_rp rp;
127 int n;
128
129 switch (argc) {
130 case 1:
131 /* connection handle */
132 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
133 return (USAGE);
134
135 cp.con_handle = (uint16_t) (n & 0x0fff);
136 cp.con_handle = htole16(cp.con_handle);
137 break;
138
139 default:
140 return (USAGE);
141 }
142
143 /* send command */
144 n = sizeof(rp);
145 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_STATUS,
146 NG_HCI_OCF_GET_LINK_QUALITY),
147 (char const *) &cp, sizeof(cp),
148 (char *) &rp, &n) == ERROR)
149 return (ERROR);
150
151 if (rp.status != 0x00) {
152 fprintf(stdout, "Status: %s [%#02x]\n",
153 hci_status2str(rp.status), rp.status);
154 return (FAILED);
155 }
156
157 fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
158 fprintf(stdout, "Link quality: %d\n", le16toh(rp.quality));
159
160 return (OK);
161 } /* hci_get_link_quality */
162
163 /* Send Read_RSSI command to the unit */
164 static int
hci_read_rssi(int s,int argc,char ** argv)165 hci_read_rssi(int s, int argc, char **argv)
166 {
167 ng_hci_read_rssi_cp cp;
168 ng_hci_read_rssi_rp rp;
169 int n;
170
171 switch (argc) {
172 case 1:
173 /* connection handle */
174 if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
175 return (USAGE);
176
177 cp.con_handle = (uint16_t) (n & 0x0fff);
178 cp.con_handle = htole16(cp.con_handle);
179 break;
180
181 default:
182 return (USAGE);
183 }
184
185 /* send command */
186 n = sizeof(rp);
187 if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_STATUS,
188 NG_HCI_OCF_READ_RSSI),
189 (char const *) &cp, sizeof(cp),
190 (char *) &rp, &n) == ERROR)
191 return (ERROR);
192
193 if (rp.status != 0x00) {
194 fprintf(stdout, "Status: %s [%#02x]\n",
195 hci_status2str(rp.status), rp.status);
196 return (FAILED);
197 }
198
199 fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
200 fprintf(stdout, "RSSI: %d dB\n", (int) rp.rssi);
201
202 return (OK);
203 } /* hci_read_rssi */
204
205 struct hci_command status_commands[] = {
206 {
207 "read_failed_contact_counter <connection_handle>",
208 "\nThis command will read the value for the Failed_Contact_Counter\n" \
209 "parameter for a particular ACL connection to another device.\n\n" \
210 "\t<connection_handle> - dddd; ACL connection handle\n",
211 &hci_read_failed_contact_counter
212 },
213 {
214 "reset_failed_contact_counter <connection_handle>",
215 "\nThis command will reset the value for the Failed_Contact_Counter\n" \
216 "parameter for a particular ACL connection to another device.\n\n" \
217 "\t<connection_handle> - dddd; ACL connection handle\n",
218 &hci_reset_failed_contact_counter
219 },
220 {
221 "get_link_quality <connection_handle>",
222 "\nThis command will return the value for the Link_Quality for the\n" \
223 "specified ACL connection handle. This command will return a Link_Quality\n" \
224 "value from 0-255, which represents the quality of the link between two\n" \
225 "Bluetooth devices. The higher the value, the better the link quality is.\n" \
226 "Each Bluetooth module vendor will determine how to measure the link quality." \
227 "\n\n" \
228 "\t<connection_handle> - dddd; ACL connection handle\n",
229 &hci_get_link_quality
230 },
231 {
232 "read_rssi <connection_handle>",
233 "\nThis command will read the value for the difference between the\n" \
234 "measured Received Signal Strength Indication (RSSI) and the limits of\n" \
235 "the Golden Receive Power Range for a ACL connection handle to another\n" \
236 "Bluetooth device. Any positive RSSI value returned by the Host Controller\n" \
237 "indicates how many dB the RSSI is above the upper limit, any negative\n" \
238 "value indicates how many dB the RSSI is below the lower limit. The value\n" \
239 "zero indicates that the RSSI is inside the Golden Receive Power Range.\n\n" \
240 "\t<connection_handle> - dddd; ACL connection handle\n",
241 &hci_read_rssi
242 },
243 {
244 NULL,
245 }};
246
247