This source file includes following definitions.
- hci_dump
- hci_ioctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <sys/cdefs.h>
35
36 #include <sys/param.h>
37 #include <sys/domain.h>
38 #include <sys/ioctl.h>
39 #include <sys/kernel.h>
40 #include <sys/mbuf.h>
41 #include <sys/proc.h>
42 #include <sys/systm.h>
43
44 #include <netbt/bluetooth.h>
45 #include <netbt/hci.h>
46 #include <netbt/l2cap.h>
47 #include <netbt/rfcomm.h>
48
49 #ifdef BLUETOOTH_DEBUG
50 #define BDADDR(bd) (bd).b[5], (bd).b[4], (bd).b[3], \
51 (bd).b[2], (bd).b[1], (bd).b[0]
52
53 static void
54 hci_dump(void)
55 {
56 struct hci_unit *unit;
57 struct hci_link *link;
58 struct l2cap_channel *chan;
59 struct rfcomm_session *rs;
60 struct rfcomm_dlc *dlc;
61
62 printf("HCI:\n");
63 TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
64 printf("UNIT %s: flags 0x%4.4x, "
65 "num_cmd=%d, num_acl=%d, num_sco=%d\n",
66 unit->hci_devname, unit->hci_flags,
67 unit->hci_num_cmd_pkts,
68 unit->hci_num_acl_pkts,
69 unit->hci_num_sco_pkts);
70 TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
71 printf("+HANDLE #%d: %s "
72 "raddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
73 "state %d, refcnt %d\n",
74 link->hl_handle,
75 (link->hl_type == HCI_LINK_ACL ? "ACL":"SCO"),
76 BDADDR(link->hl_bdaddr),
77 link->hl_state, link->hl_refcnt);
78 }
79 }
80
81 printf("L2CAP:\n");
82 LIST_FOREACH(chan, &l2cap_active_list, lc_ncid) {
83 printf("CID #%d state %d, psm=0x%4.4x, "
84 "laddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
85 "raddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
86 chan->lc_lcid, chan->lc_state, chan->lc_raddr.bt_psm,
87 BDADDR(chan->lc_laddr.bt_bdaddr),
88 BDADDR(chan->lc_raddr.bt_bdaddr));
89 }
90
91 LIST_FOREACH(chan, &l2cap_listen_list, lc_ncid) {
92 printf("LISTEN psm=0x%4.4x, "
93 "laddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
94 chan->lc_laddr.bt_psm,
95 BDADDR(chan->lc_laddr.bt_bdaddr));
96 }
97
98 printf("RFCOMM:\n");
99 LIST_FOREACH(rs, &rfcomm_session_active, rs_next) {
100 chan = rs->rs_l2cap;
101 printf("SESSION: state=%d, flags=0x%4.4x, psm 0x%4.4x "
102 "laddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
103 "raddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
104 rs->rs_state, rs->rs_flags, chan->lc_raddr.bt_psm,
105 BDADDR(chan->lc_laddr.bt_bdaddr),
106 BDADDR(chan->lc_raddr.bt_bdaddr));
107 LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
108 printf("+DLC channel=%d, dlci=%d, "
109 "state=%d, flags=0x%4.4x, rxcred=%d, rxsize=%ld, "
110 "txcred=%d, pending=%d, txqlen=%d\n",
111 dlc->rd_raddr.bt_channel, dlc->rd_dlci,
112 dlc->rd_state, dlc->rd_flags,
113 dlc->rd_rxcred, (unsigned long)dlc->rd_rxsize,
114 dlc->rd_txcred, dlc->rd_pending,
115 (dlc->rd_txbuf ? dlc->rd_txbuf->m_pkthdr.len : 0));
116 }
117 }
118
119 LIST_FOREACH(rs, &rfcomm_session_listen, rs_next) {
120 chan = rs->rs_l2cap;
121 printf("LISTEN: psm 0x%4.4x, "
122 "laddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
123 chan->lc_laddr.bt_psm,
124 BDADDR(chan->lc_laddr.bt_bdaddr));
125 LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next)
126 printf("+DLC channel=%d\n", dlc->rd_laddr.bt_channel);
127 }
128 }
129
130 #undef BDADDR
131 #endif
132
133 int
134 hci_ioctl(unsigned long cmd, void *data, struct proc *p)
135 {
136 struct btreq *btr = data;
137 struct hci_unit *unit;
138 int s, err = 0;
139
140 DPRINTFN(1, "cmd %#lx\n", cmd);
141
142 switch(cmd) {
143 #ifdef BLUETOOTH_DEBUG
144 case SIOCBTDUMP:
145 hci_dump();
146 return 0;
147 #endif
148
149
150
151 case SIOCGBTINFOA:
152 unit = hci_unit_lookup(&btr->btr_bdaddr);
153 if (unit == NULL)
154 return ENXIO;
155
156 break;
157
158
159
160
161
162 case SIOCNBTINFO:
163
164 if (btr->btr_name[0] == '\0') {
165 unit = NULL;
166 break;
167 }
168
169
170 case SIOCGBTINFO:
171 case SIOCSBTFLAGS:
172 case SIOCSBTPOLICY:
173 case SIOCSBTPTYPE:
174 case SIOCGBTSTATS:
175 case SIOCZBTSTATS:
176 case SIOCSBTSCOMTU:
177 TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
178 if (strncmp(unit->hci_devname, btr->btr_name,
179 HCI_DEVNAME_SIZE) == 0)
180 break;
181 }
182
183 if (unit == NULL)
184 return ENXIO;
185
186 break;
187
188 default:
189 return EPASSTHROUGH;
190 }
191
192 switch(cmd) {
193 case SIOCNBTINFO:
194 if (unit)
195 unit = TAILQ_NEXT(unit, hci_next);
196 else
197 unit = TAILQ_FIRST(&hci_unit_list);
198
199 if (unit == NULL) {
200 err = ENXIO;
201 break;
202 }
203
204
205 case SIOCGBTINFO:
206 case SIOCGBTINFOA:
207 memset(btr, 0, sizeof(struct btreq));
208 strlcpy(btr->btr_name, unit->hci_devname, HCI_DEVNAME_SIZE);
209 bdaddr_copy(&btr->btr_bdaddr, &unit->hci_bdaddr);
210
211 btr->btr_flags = unit->hci_flags;
212
213 btr->btr_num_cmd = unit->hci_num_cmd_pkts;
214 btr->btr_num_acl = unit->hci_num_acl_pkts;
215 btr->btr_num_sco = unit->hci_num_sco_pkts;
216 btr->btr_acl_mtu = unit->hci_max_acl_size;
217 btr->btr_sco_mtu = unit->hci_max_sco_size;
218
219 btr->btr_packet_type = unit->hci_packet_type;
220 btr->btr_link_policy = unit->hci_link_policy;
221 break;
222
223 case SIOCSBTFLAGS:
224 err = suser(p, 0);
225 if (err)
226 break;
227
228 if ((unit->hci_flags & BTF_UP)
229 && (btr->btr_flags & BTF_UP) == 0) {
230 hci_disable(unit);
231 unit->hci_flags &= ~BTF_UP;
232 }
233
234 s = splraiseipl(unit->hci_ipl);
235 unit->hci_flags |= (btr->btr_flags & BTF_INIT);
236 splx(s);
237
238 if ((unit->hci_flags & BTF_UP) == 0
239 && (btr->btr_flags & BTF_UP)) {
240 err = hci_enable(unit);
241 if (err)
242 break;
243
244 s = splraiseipl(unit->hci_ipl);
245 unit->hci_flags |= BTF_UP;
246 splx(s);
247 }
248
249 btr->btr_flags = unit->hci_flags;
250 break;
251
252 case SIOCSBTPOLICY:
253 err = suser(p, 0);
254 if (err)
255 break;
256
257 unit->hci_link_policy = btr->btr_link_policy;
258 unit->hci_link_policy &= unit->hci_lmp_mask;
259 btr->btr_link_policy = unit->hci_link_policy;
260 break;
261
262 case SIOCSBTPTYPE:
263 err = suser(p, 0);
264 if (err)
265 break;
266
267 unit->hci_packet_type = btr->btr_packet_type;
268 unit->hci_packet_type &= unit->hci_acl_mask;
269 btr->btr_packet_type = unit->hci_packet_type;
270 break;
271
272 case SIOCGBTSTATS:
273 s = splraiseipl(unit->hci_ipl);
274 memcpy(&btr->btr_stats, &unit->hci_stats,
275 sizeof(struct bt_stats));
276 splx(s);
277 break;
278
279 case SIOCZBTSTATS:
280 err = suser(p, 0);
281 if (err)
282 break;
283
284 s = splraiseipl(unit->hci_ipl);
285 memcpy(&btr->btr_stats, &unit->hci_stats,
286 sizeof(struct bt_stats));
287 memset(&unit->hci_stats, 0, sizeof(struct bt_stats));
288 splx(s);
289
290 break;
291
292 case SIOCSBTSCOMTU:
293
294
295
296
297
298
299 err = suser(p, 0);
300 if (err)
301 break;
302
303 unit->hci_max_sco_size = btr->btr_sco_mtu;
304 break;
305
306 default:
307 err = EFAULT;
308 break;
309 }
310
311 return err;
312 }