Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/bluetooth/hccontrol/link_policy.c
107607 views
1
/*-
2
* link_policy.c
3
*
4
* SPDX-License-Identifier: BSD-2-Clause
5
*
6
* Copyright (c) 2001-2002 Maksim Yevmenkin <[email protected]>
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: link_policy.c,v 1.3 2003/08/18 19:19:54 max Exp $
31
*/
32
33
#define L2CAP_SOCKET_CHECKED
34
#include <bluetooth.h>
35
#include <errno.h>
36
#include <stdio.h>
37
#include <string.h>
38
#include "hccontrol.h"
39
40
/* Send Role Discovery to the unit */
41
static int
42
hci_role_discovery(int s, int argc, char **argv)
43
{
44
ng_hci_role_discovery_cp cp;
45
ng_hci_role_discovery_rp rp;
46
int n;
47
48
/* parse command parameters */
49
switch (argc) {
50
case 1:
51
/* connection handle */
52
if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
53
return (USAGE);
54
55
cp.con_handle = (uint16_t) (n & 0x0fff);
56
cp.con_handle = htole16(cp.con_handle);
57
break;
58
59
default:
60
return (USAGE);
61
}
62
63
/* send request */
64
n = sizeof(rp);
65
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_POLICY,
66
NG_HCI_OCF_ROLE_DISCOVERY),
67
(char const *) &cp, sizeof(cp),
68
(char *) &rp, &n) == ERROR)
69
return (ERROR);
70
71
if (rp.status != 0x00) {
72
fprintf(stdout, "Status: %s [%#02x]\n",
73
hci_status2str(rp.status), rp.status);
74
return (FAILED);
75
}
76
77
fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
78
fprintf(stdout, "Role: %s [%#x]\n",
79
(rp.role == NG_HCI_ROLE_MASTER)? "Master" : "Slave", rp.role);
80
81
return (OK);
82
} /* hci_role_discovery */
83
84
/* Send Switch Role to the unit */
85
static int
86
hci_switch_role(int s, int argc, char **argv)
87
{
88
int n0;
89
char b[512];
90
ng_hci_switch_role_cp cp;
91
ng_hci_event_pkt_t *e = (ng_hci_event_pkt_t *) b;
92
93
/* parse command parameters */
94
switch (argc) {
95
case 2:
96
/* bdaddr */
97
if (!bt_aton(argv[0], &cp.bdaddr)) {
98
struct hostent *he = NULL;
99
100
if ((he = bt_gethostbyname(argv[0])) == NULL)
101
return (USAGE);
102
103
memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
104
}
105
106
/* role */
107
if (sscanf(argv[1], "%d", &n0) != 1)
108
return (USAGE);
109
110
cp.role = n0? NG_HCI_ROLE_SLAVE : NG_HCI_ROLE_MASTER;
111
break;
112
113
default:
114
return (USAGE);
115
}
116
117
/* send request and expect status response */
118
n0 = sizeof(b);
119
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_POLICY,
120
NG_HCI_OCF_SWITCH_ROLE),
121
(char const *) &cp, sizeof(cp), b, &n0) == ERROR)
122
return (ERROR);
123
124
if (*b != 0x00)
125
return (FAILED);
126
127
/* wait for event */
128
again:
129
n0 = sizeof(b);
130
if (hci_recv(s, b, &n0) == ERROR)
131
return (ERROR);
132
if (n0 < sizeof(*e)) {
133
errno = EIO;
134
return (ERROR);
135
}
136
137
if (e->event == NG_HCI_EVENT_ROLE_CHANGE) {
138
ng_hci_role_change_ep *ep = (ng_hci_role_change_ep *)(e + 1);
139
140
if (ep->status != 0x00) {
141
fprintf(stdout, "Status: %s [%#02x]\n",
142
hci_status2str(ep->status), ep->status);
143
return (FAILED);
144
}
145
146
fprintf(stdout, "BD_ADDR: %s\n", hci_bdaddr2str(&ep->bdaddr));
147
fprintf(stdout, "Role: %s [%#x]\n",
148
(ep->role == NG_HCI_ROLE_MASTER)? "Master" : "Slave",
149
ep->role);
150
} else
151
goto again;
152
153
return (OK);
154
} /* hci_switch_role */
155
156
/* Send Read_Link_Policy_Settings command to the unit */
157
static int
158
hci_read_link_policy_settings(int s, int argc, char **argv)
159
{
160
ng_hci_read_link_policy_settings_cp cp;
161
ng_hci_read_link_policy_settings_rp rp;
162
int n;
163
164
/* parse command parameters */
165
switch (argc) {
166
case 1:
167
/* connection handle */
168
if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
169
return (USAGE);
170
171
cp.con_handle = (uint16_t) (n & 0x0fff);
172
cp.con_handle = htole16(cp.con_handle);
173
break;
174
175
default:
176
return (USAGE);
177
}
178
179
/* send request */
180
n = sizeof(rp);
181
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_POLICY,
182
NG_HCI_OCF_READ_LINK_POLICY_SETTINGS),
183
(char const *) &cp, sizeof(cp),
184
(char *) &rp, &n) == ERROR)
185
return (ERROR);
186
187
if (rp.status != 0x00) {
188
fprintf(stdout, "Status: %s [%#02x]\n",
189
hci_status2str(rp.status), rp.status);
190
return (FAILED);
191
}
192
193
fprintf(stdout, "Connection handle: %d\n", le16toh(rp.con_handle));
194
fprintf(stdout, "Link policy settings: %#x\n", le16toh(rp.settings));
195
196
return (OK);
197
} /* hci_read_link_policy_settings */
198
199
/* Send Write_Link_Policy_Settings command to the unit */
200
static int
201
hci_write_link_policy_settings(int s, int argc, char **argv)
202
{
203
ng_hci_write_link_policy_settings_cp cp;
204
ng_hci_write_link_policy_settings_rp rp;
205
int n;
206
207
/* parse command parameters */
208
switch (argc) {
209
case 2:
210
/* connection handle */
211
if (sscanf(argv[0], "%d", &n) != 1 || n <= 0 || n > 0x0eff)
212
return (USAGE);
213
214
cp.con_handle = (uint16_t) (n & 0x0fff);
215
cp.con_handle = htole16(cp.con_handle);
216
217
/* link policy settings */
218
if (sscanf(argv[1], "%x", &n) != 1)
219
return (USAGE);
220
221
cp.settings = (uint16_t) (n & 0x0ffff);
222
cp.settings = htole16(cp.settings);
223
break;
224
225
default:
226
return (USAGE);
227
}
228
229
/* send request */
230
n = sizeof(rp);
231
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LINK_POLICY,
232
NG_HCI_OCF_WRITE_LINK_POLICY_SETTINGS),
233
(char const *) &cp, sizeof(cp),
234
(char *) &rp, &n) == ERROR)
235
return (ERROR);
236
237
if (rp.status != 0x00) {
238
fprintf(stdout, "Status: %s [%#02x]\n",
239
hci_status2str(rp.status), rp.status);
240
return (FAILED);
241
}
242
243
return (OK);
244
} /* hci_write_link_policy_settings */
245
246
struct hci_command link_policy_commands[] = {
247
{
248
"role_discovery <connection_handle>",
249
"\nThe Role_Discovery command is used for a Bluetooth device to determine\n" \
250
"which role the device is performing for a particular Connection Handle.\n" \
251
"The connection handle must be a connection handle for an ACL connection.\n\n" \
252
"\t<connection_handle> - dddd; connection handle",
253
&hci_role_discovery
254
},
255
{
256
"switch_role <BD_ADDR> <role>",
257
"\nThe Switch_Role command is used for a Bluetooth device to switch the\n" \
258
"current role the device is performing for a particular connection with\n" \
259
"another specified Bluetooth device. The BD_ADDR command parameter indicates\n"\
260
"for which connection the role switch is to be performed. The Role indicates\n"\
261
"the requested new role that the local device performs. Note: the BD_ADDR\n" \
262
"command parameter must specify a Bluetooth device for which a connection\n"
263
"already exists.\n\n" \
264
"\t<BD_ADDR> - xx:xx:xx:xx:xx:xx BD_ADDR or name\n" \
265
"\t<role> - dd; role; 0 - Master, 1 - Slave",
266
&hci_switch_role
267
},
268
{
269
"read_link_policy_settings <connection_handle>",
270
"\nThis command will read the Link Policy setting for the specified connection\n"\
271
"handle. The link policy settings parameter determines the behavior of the\n" \
272
"local Link Manager when it receives a request from a remote device or it\n" \
273
"determines itself to change the master-slave role or to enter the hold,\n" \
274
"sniff, or park mode. The local Link Manager will automatically accept or\n" \
275
"reject such a request from the remote device, and may even autonomously\n" \
276
"request itself, depending on the value of the link policy settings parameter\n"\
277
"for the corresponding connection handle. The connection handle must be a\n" \
278
"connection handle for an ACL connection.\n\n" \
279
"\t<connection_handle> - dddd; connection handle",
280
&hci_read_link_policy_settings
281
},
282
{
283
"write_link_policy_settings <connection_handle> <settings>",
284
"\nThis command will write the Link Policy setting for the specified connection\n"\
285
"handle. The link policy settings parameter determines the behavior of the\n" \
286
"local Link Manager when it receives a request from a remote device or it\n" \
287
"determines itself to change the master-slave role or to enter the hold,\n" \
288
"sniff, or park mode. The local Link Manager will automatically accept or\n" \
289
"reject such a request from the remote device, and may even autonomously\n" \
290
"request itself, depending on the value of the link policy settings parameter\n"\
291
"for the corresponding connection handle. The connection handle must be a\n" \
292
"connection handle for an ACL connection. Multiple Link Manager policies may\n"\
293
"be specified for the link policy settings parameter by performing a bitwise\n"\
294
"OR operation of the different activity types.\n\n" \
295
"\t<connection_handle> - dddd; connection handle\n" \
296
"\t<settings> - xxxx; settings\n" \
297
"\t\t0x0000 - Disable All LM Modes (Default)\n" \
298
"\t\t0x0001 - Enable Master Slave Switch\n" \
299
"\t\t0x0002 - Enable Hold Mode\n" \
300
"\t\t0x0004 - Enable Sniff Mode\n" \
301
"\t\t0x0008 - Enable Park Mode\n",
302
&hci_write_link_policy_settings
303
},
304
{
305
NULL,
306
}};
307
308
309