1107120Sjulian/*
2107120Sjulian * status.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: status.c,v 1.2 2003/05/21 22:40:30 max Exp $
29107120Sjulian * $FreeBSD$
30107120Sjulian */
31107120Sjulian
32107120Sjulian#include <sys/types.h>
33107120Sjulian#include <sys/endian.h>
34107120Sjulian#include <errno.h>
35121054Semax#include <netgraph/bluetooth/include/ng_hci.h>
36107120Sjulian#include <stdio.h>
37107120Sjulian#include "hccontrol.h"
38107120Sjulian
39107120Sjulian/* Send Read_Failed_Contact_Counter command to the unit */
40107120Sjulianstatic int
41107120Sjulianhci_read_failed_contact_counter(int s, int argc, char **argv)
42107120Sjulian{
43107120Sjulian	ng_hci_read_failed_contact_cntr_cp	cp;
44107120Sjulian	ng_hci_read_failed_contact_cntr_rp	rp;
45107120Sjulian	int					n;
46107120Sjulian
47107120Sjulian	switch (argc) {
48107120Sjulian	case 1:
49107120Sjulian		/* connection handle */
50107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
51107120Sjulian			return (USAGE);
52107120Sjulian
53128079Semax		cp.con_handle = (uint16_t) (n & 0x0fff);
54107120Sjulian		cp.con_handle = htole16(cp.con_handle);
55107120Sjulian		break;
56107120Sjulian
57107120Sjulian	default:
58107120Sjulian		return (USAGE);
59107120Sjulian	}
60107120Sjulian
61107120Sjulian	/* send command */
62107120Sjulian	n = sizeof(rp);
63107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_STATUS,
64107120Sjulian			NG_HCI_OCF_READ_FAILED_CONTACT_CNTR),
65107120Sjulian			(char const *) &cp, sizeof(cp),
66107120Sjulian			(char *) &rp, &n) == ERROR)
67107120Sjulian		return (ERROR);
68107120Sjulian
69107120Sjulian	if (rp.status != 0x00) {
70107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
71107120Sjulian			hci_status2str(rp.status), rp.status);
72107120Sjulian		return (FAILED);
73107120Sjulian	}
74107120Sjulian
75107120Sjulian	fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
76107120Sjulian	fprintf(stdout, "Failed contact counter: %d\n", le16toh(rp.counter));
77107120Sjulian
78107120Sjulian	return (OK);
79107120Sjulian} /* hci_read_failed_contact_counter */
80107120Sjulian
81107120Sjulian/* Send Reset_Failed_Contact_Counter command to the unit */
82107120Sjulianstatic int
83107120Sjulianhci_reset_failed_contact_counter(int s, int argc, char **argv)
84107120Sjulian{
85107120Sjulian	ng_hci_reset_failed_contact_cntr_cp	cp;
86107120Sjulian	ng_hci_reset_failed_contact_cntr_rp	rp;
87107120Sjulian	int					n;
88107120Sjulian
89107120Sjulian	switch (argc) {
90107120Sjulian	case 1:
91107120Sjulian		/* connection handle */
92107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
93107120Sjulian			return (USAGE);
94107120Sjulian
95128079Semax		cp.con_handle = (uint16_t) (n & 0x0fff);
96107120Sjulian		cp.con_handle = htole16(cp.con_handle);
97107120Sjulian		break;
98107120Sjulian
99107120Sjulian	default:
100107120Sjulian		return (USAGE);
101107120Sjulian	}
102107120Sjulian
103107120Sjulian	/* send command */
104107120Sjulian	n = sizeof(rp);
105107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_STATUS,
106107120Sjulian			NG_HCI_OCF_RESET_FAILED_CONTACT_CNTR),
107107120Sjulian			(char const *) &cp, sizeof(cp),
108107120Sjulian			(char *) &rp, &n) == ERROR)
109107120Sjulian		return (ERROR);
110107120Sjulian
111107120Sjulian	if (rp.status != 0x00) {
112107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
113107120Sjulian			hci_status2str(rp.status), rp.status);
114107120Sjulian		return (FAILED);
115107120Sjulian	}
116107120Sjulian
117107120Sjulian	return (OK);
118107120Sjulian} /* hci_reset_failed_contact_counter */
119107120Sjulian
120107120Sjulian/* Sent Get_Link_Quality command to the unit */
121107120Sjulianstatic int
122107120Sjulianhci_get_link_quality(int s, int argc, char **argv)
123107120Sjulian{
124107120Sjulian	ng_hci_get_link_quality_cp	cp;
125107120Sjulian	ng_hci_get_link_quality_rp	rp;
126107120Sjulian	int				n;
127107120Sjulian
128107120Sjulian	switch (argc) {
129107120Sjulian	case 1:
130107120Sjulian		/* connection handle */
131107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
132107120Sjulian			return (USAGE);
133107120Sjulian
134128079Semax		cp.con_handle = (uint16_t) (n & 0x0fff);
135107120Sjulian		cp.con_handle = htole16(cp.con_handle);
136107120Sjulian		break;
137107120Sjulian
138107120Sjulian	default:
139107120Sjulian		return (USAGE);
140107120Sjulian	}
141107120Sjulian
142107120Sjulian	/* send command */
143107120Sjulian	n = sizeof(rp);
144107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_STATUS,
145107120Sjulian			NG_HCI_OCF_GET_LINK_QUALITY),
146107120Sjulian			(char const *) &cp, sizeof(cp),
147107120Sjulian			(char *) &rp, &n) == ERROR)
148107120Sjulian		return (ERROR);
149107120Sjulian
150107120Sjulian	if (rp.status != 0x00) {
151107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
152107120Sjulian			hci_status2str(rp.status), rp.status);
153107120Sjulian		return (FAILED);
154107120Sjulian	}
155107120Sjulian
156107120Sjulian	fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
157107120Sjulian	fprintf(stdout, "Link quality: %d\n", le16toh(rp.quality));
158107120Sjulian
159107120Sjulian	return (OK);
160107120Sjulian} /* hci_get_link_quality */
161107120Sjulian
162107120Sjulian/* Send Read_RSSI command to the unit */
163107120Sjulianstatic int
164107120Sjulianhci_read_rssi(int s, int argc, char **argv)
165107120Sjulian{
166107120Sjulian	ng_hci_read_rssi_cp	cp;
167107120Sjulian	ng_hci_read_rssi_rp	rp;
168107120Sjulian	int			n;
169107120Sjulian
170107120Sjulian	switch (argc) {
171107120Sjulian	case 1:
172107120Sjulian		/* connection handle */
173107120Sjulian		if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
174107120Sjulian			return (USAGE);
175107120Sjulian
176128079Semax		cp.con_handle = (uint16_t) (n & 0x0fff);
177107120Sjulian		cp.con_handle = htole16(cp.con_handle);
178107120Sjulian		break;
179107120Sjulian
180107120Sjulian	default:
181107120Sjulian		return (USAGE);
182107120Sjulian	}
183107120Sjulian
184107120Sjulian	/* send command */
185107120Sjulian	n = sizeof(rp);
186107120Sjulian	if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_STATUS,
187107120Sjulian			NG_HCI_OCF_READ_RSSI),
188107120Sjulian			(char const *) &cp, sizeof(cp),
189107120Sjulian			(char *) &rp, &n) == ERROR)
190107120Sjulian		return (ERROR);
191107120Sjulian
192107120Sjulian	if (rp.status != 0x00) {
193107120Sjulian		fprintf(stdout, "Status: %s [%#02x]\n",
194107120Sjulian			hci_status2str(rp.status), rp.status);
195107120Sjulian		return (FAILED);
196107120Sjulian	}
197107120Sjulian
198107120Sjulian	fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
199107120Sjulian	fprintf(stdout, "RSSI: %d dB\n", (int) rp.rssi);
200107120Sjulian
201107120Sjulian	return (OK);
202107120Sjulian} /* hci_read_rssi */
203107120Sjulian
204107120Sjulianstruct hci_command	status_commands[] = {
205107120Sjulian{
206107120Sjulian"read_failed_contact_counter <connection_handle>",
207107120Sjulian"\nThis command will read the value for the Failed_Contact_Counter\n" \
208107120Sjulian"parameter for a particular ACL connection to another device.\n\n" \
209107120Sjulian"\t<connection_handle> - dddd; ACL connection handle\n",
210107120Sjulian&hci_read_failed_contact_counter
211107120Sjulian},
212107120Sjulian{
213107120Sjulian"reset_failed_contact_counter <connection_handle>",
214107120Sjulian"\nThis command will reset the value for the Failed_Contact_Counter\n" \
215107120Sjulian"parameter for a particular ACL connection to another device.\n\n" \
216107120Sjulian"\t<connection_handle> - dddd; ACL connection handle\n",
217107120Sjulian&hci_reset_failed_contact_counter
218107120Sjulian},
219107120Sjulian{
220107120Sjulian"get_link_quality <connection_handle>",
221107120Sjulian"\nThis command will return the value for the Link_Quality for the\n" \
222107120Sjulian"specified ACL connection handle. This command will return a Link_Quality\n" \
223107120Sjulian"value from 0-255, which represents the quality of the link between two\n" \
224107120Sjulian"Bluetooth devices. The higher the value, the better the link quality is.\n" \
225107120Sjulian"Each Bluetooth module vendor will determine how to measure the link quality." \
226107120Sjulian"\n\n" \
227107120Sjulian"\t<connection_handle> - dddd; ACL connection handle\n",
228107120Sjulian&hci_get_link_quality
229107120Sjulian},
230107120Sjulian{
231107120Sjulian"read_rssi <connection_handle>",
232107120Sjulian"\nThis command will read the value for the difference between the\n" \
233107120Sjulian"measured Received Signal Strength Indication (RSSI) and the limits of\n" \
234114879Sjulian"the Golden Receive Power Range for a ACL connection handle to another\n" \
235107120Sjulian"Bluetooth device. Any positive RSSI value returned by the Host Controller\n" \
236107120Sjulian"indicates how many dB the RSSI is above the upper limit, any negative\n" \
237107120Sjulian"value indicates how many dB the RSSI is below the lower limit. The value\n" \
238107120Sjulian"zero indicates that the RSSI is inside the Golden Receive Power Range.\n\n" \
239107120Sjulian"\t<connection_handle> - dddd; ACL connection handle\n",
240107120Sjulian&hci_read_rssi
241107120Sjulian},
242107120Sjulian{
243107120SjulianNULL,
244107120Sjulian}};
245107120Sjulian
246