xref: /netbsd-src/sys/netbt/hci_event.c (revision 1ad9454efb13a65cd7535ccf867508cb14d9d30e)
1 /*	$NetBSD: hci_event.c,v 1.2 2006/09/11 22:12:39 plunky Exp $	*/
2 
3 /*-
4  * Copyright (c) 2005 Iain Hibbert.
5  * Copyright (c) 2006 Itronix Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of Itronix Inc. may not be used to endorse
17  *    or promote products derived from this software without specific
18  *    prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
24  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27  * ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.2 2006/09/11 22:12:39 plunky Exp $");
35 
36 #include <sys/param.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/mbuf.h>
40 #include <sys/proc.h>
41 #include <sys/systm.h>
42 
43 #include <netbt/bluetooth.h>
44 #include <netbt/hci.h>
45 #include <netbt/sco.h>
46 
47 static void hci_event_inquiry_result(struct hci_unit *, struct mbuf *);
48 static void hci_event_command_status(struct hci_unit *, struct mbuf *);
49 static void hci_event_command_compl(struct hci_unit *, struct mbuf *);
50 static void hci_event_con_compl(struct hci_unit *, struct mbuf *);
51 static void hci_event_discon_compl(struct hci_unit *, struct mbuf *);
52 static void hci_event_con_req(struct hci_unit *, struct mbuf *);
53 static void hci_event_num_compl_pkts(struct hci_unit *, struct mbuf *);
54 static void hci_cmd_read_bdaddr(struct hci_unit *, struct mbuf *);
55 static void hci_cmd_read_buffer_size(struct hci_unit *, struct mbuf *);
56 static void hci_cmd_read_local_features(struct hci_unit *, struct mbuf *);
57 static void hci_cmd_reset(struct hci_unit *, struct mbuf *);
58 
59 #ifdef BLUETOOTH_DEBUG
60 int bluetooth_debug = BLUETOOTH_DEBUG;
61 
62 static const char *hci_eventnames[] = {
63 /* 0x00 */ "NULL",
64 /* 0x01 */ "INQUIRY COMPLETE",
65 /* 0x02 */ "INQUIRY RESULT",
66 /* 0x03 */ "CONN COMPLETE",
67 /* 0x04 */ "CONN REQ",
68 /* 0x05 */ "DISCONN COMPLETE",
69 /* 0x06 */ "AUTH COMPLETE",
70 /* 0x07 */ "REMOTE NAME REQ COMPLETE",
71 /* 0x08 */ "ENCRYPTION CHANGE",
72 /* 0x09 */ "CHANGE CONN LINK KEY COMPLETE",
73 /* 0x0a */ "MASTER LINK KEY COMPLETE",
74 /* 0x0b */ "READ REMOTE FEATURES COMPLETE",
75 /* 0x0c */ "READ REMOTE VERSION INFO COMPLETE",
76 /* 0x0d */ "QoS SETUP COMPLETE",
77 /* 0x0e */ "COMMAND COMPLETE",
78 /* 0x0f */ "COMMAND STATUS",
79 /* 0x10 */ "HARDWARE ERROR",
80 /* 0x11 */ "FLUSH OCCUR",
81 /* 0x12 */ "ROLE CHANGE",
82 /* 0x13 */ "NUM COMPLETED PACKETS",
83 /* 0x14 */ "MODE CHANGE",
84 /* 0x15 */ "RETURN LINK KEYS",
85 /* 0x16 */ "PIN CODE REQ",
86 /* 0x17 */ "LINK KEY REQ",
87 /* 0x18 */ "LINK KEY NOTIFICATION",
88 /* 0x19 */ "LOOPBACK COMMAND",
89 /* 0x1a */ "DATA BUFFER OVERFLOW",
90 /* 0x1b */ "MAX SLOT CHANGE",
91 /* 0x1c */ "READ CLOCK OFFSET COMPLETE",
92 /* 0x1d */ "CONN PKT TYPE CHANGED",
93 /* 0x1e */ "QOS VIOLATION",
94 /* 0x1f */ "PAGE SCAN MODE CHANGE",
95 /* 0x20 */ "PAGE SCAN REP MODE CHANGE",
96 /* 0x21 */ "FLOW SPECIFICATION COMPLETE",
97 /* 0x22 */ "RSSI RESULT",
98 /* 0x23 */ "READ REMOTE EXT FEATURES"
99 };
100 
101 static const char *
102 hci_eventstr(unsigned int event)
103 {
104 
105 	if (event < (sizeof(hci_eventnames) / sizeof(*hci_eventnames)))
106 		return hci_eventnames[event];
107 
108 	switch (event) {
109 	case HCI_EVENT_SCO_CON_COMPL:	/* 0x2c */
110 		return "SCO CON COMPLETE";
111 
112 	case HCI_EVENT_SCO_CON_CHANGED:	/* 0x2d */
113 		return "SCO CON CHANGED";
114 
115 	case HCI_EVENT_BT_LOGO:		/* 0xfe */
116 		return "BT_LOGO";
117 
118 	case HCI_EVENT_VENDOR:		/* 0xff */
119 		return "VENDOR";
120 	}
121 
122 	return "UNRECOGNISED";
123 }
124 #endif	/* BLUETOOTH_DEBUG */
125 
126 /*
127  * process HCI Events
128  *
129  * We will free the mbuf at the end, no need for any sub
130  * functions to handle that. We kind of assume that the
131  * device sends us valid events.
132  */
133 void
134 hci_event(struct mbuf *m, struct hci_unit *unit)
135 {
136 	hci_event_hdr_t hdr;
137 
138 	KASSERT(m->m_flags & M_PKTHDR);
139 
140 	KASSERT(m->m_pkthdr.len >= sizeof(hdr));
141 	m_copydata(m, 0, sizeof(hdr), &hdr);
142 	m_adj(m, sizeof(hdr));
143 
144 	KASSERT(hdr.type == HCI_EVENT_PKT);
145 
146 	DPRINTFN(1, "(%s) event %s\n", unit->hci_devname, hci_eventstr(hdr.event));
147 
148 	switch(hdr.event) {
149 	case HCI_EVENT_COMMAND_STATUS:
150 		hci_event_command_status(unit, m);
151 		break;
152 
153 	case HCI_EVENT_COMMAND_COMPL:
154 		hci_event_command_compl(unit, m);
155 		break;
156 
157 	case HCI_EVENT_NUM_COMPL_PKTS:
158 		hci_event_num_compl_pkts(unit, m);
159 		break;
160 
161 	case HCI_EVENT_INQUIRY_RESULT:
162 		hci_event_inquiry_result(unit, m);
163 		break;
164 
165 	case HCI_EVENT_CON_COMPL:
166 		hci_event_con_compl(unit, m);
167 		break;
168 
169 	case HCI_EVENT_DISCON_COMPL:
170 		hci_event_discon_compl(unit, m);
171 		break;
172 
173 	case HCI_EVENT_CON_REQ:
174 		hci_event_con_req(unit, m);
175 		break;
176 
177 	case HCI_EVENT_SCO_CON_COMPL:
178 	case HCI_EVENT_INQUIRY_COMPL:
179 	case HCI_EVENT_AUTH_COMPL:
180 	case HCI_EVENT_REMOTE_NAME_REQ_COMPL:
181 	case HCI_EVENT_ENCRYPTION_CHANGE:
182 	case HCI_EVENT_CHANGE_CON_LINK_KEY_COMPL:
183 	case HCI_EVENT_MASTER_LINK_KEY_COMPL:
184 	case HCI_EVENT_READ_REMOTE_FEATURES_COMPL:
185 	case HCI_EVENT_READ_REMOTE_VER_INFO_COMPL:
186 	case HCI_EVENT_QOS_SETUP_COMPL:
187 	case HCI_EVENT_HARDWARE_ERROR:
188 	case HCI_EVENT_FLUSH_OCCUR:
189 	case HCI_EVENT_ROLE_CHANGE:
190 	case HCI_EVENT_MODE_CHANGE:
191 	case HCI_EVENT_RETURN_LINK_KEYS:
192 	case HCI_EVENT_PIN_CODE_REQ:
193 	case HCI_EVENT_LINK_KEY_REQ:
194 	case HCI_EVENT_LINK_KEY_NOTIFICATION:
195 	case HCI_EVENT_LOOPBACK_COMMAND:
196 	case HCI_EVENT_DATA_BUFFER_OVERFLOW:
197 	case HCI_EVENT_MAX_SLOT_CHANGE:
198 	case HCI_EVENT_READ_CLOCK_OFFSET_COMPL:
199 	case HCI_EVENT_CON_PKT_TYPE_CHANGED:
200 	case HCI_EVENT_QOS_VIOLATION:
201 	case HCI_EVENT_PAGE_SCAN_MODE_CHANGE:
202 	case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE:
203 	case HCI_EVENT_FLOW_SPECIFICATION_COMPL:
204 	case HCI_EVENT_RSSI_RESULT:
205 	case HCI_EVENT_READ_REMOTE_EXTENDED_FEATURES:
206 	case HCI_EVENT_SCO_CON_CHANGED:
207 	case HCI_EVENT_BT_LOGO:
208 	case HCI_EVENT_VENDOR:
209 		break;
210 
211 	default:
212 		UNKNOWN(hdr.event);
213 		break;
214 	}
215 
216 	m_freem(m);
217 }
218 
219 /*
220  * Command Status
221  *
222  * Update our record of num_cmd_pkts then post-process any pending commands
223  * and optionally restart cmd output on the unit.
224  */
225 static void
226 hci_event_command_status(struct hci_unit *unit, struct mbuf *m)
227 {
228 	hci_command_status_ep ep;
229 
230 	KASSERT(m->m_pkthdr.len >= sizeof(ep));
231 	m_copydata(m, 0, sizeof(ep), &ep);
232 	m_adj(m, sizeof(ep));
233 
234 	DPRINTFN(1, "(%s) opcode (%03x|%04x) num_cmd_pkts = %d\n",
235 		unit->hci_devname,
236 		HCI_OGF(le16toh(ep.opcode)), HCI_OCF(le16toh(ep.opcode)),
237 		ep.num_cmd_pkts);
238 
239 	unit->hci_num_cmd_pkts = ep.num_cmd_pkts;
240 
241 	/*
242 	 * post processing of pending commands
243 	 */
244 	switch(le16toh(ep.opcode)) {
245 	default:
246 		break;
247 	}
248 
249 	while (unit->hci_num_cmd_pkts > 0 && MBUFQ_FIRST(&unit->hci_cmdwait)) {
250 		MBUFQ_DEQUEUE(&unit->hci_cmdwait, m);
251 		hci_output_cmd(unit, m);
252 	}
253 }
254 
255 /*
256  * Command Complete
257  *
258  * Update our record of num_cmd_pkts then handle the completed command,
259  * and optionally restart cmd output on the unit.
260  */
261 static void
262 hci_event_command_compl(struct hci_unit *unit, struct mbuf *m)
263 {
264 	hci_command_compl_ep ep;
265 
266 	KASSERT(m->m_pkthdr.len >= sizeof(ep));
267 	m_copydata(m, 0, sizeof(ep), &ep);
268 	m_adj(m, sizeof(ep));
269 
270 	DPRINTFN(1, "(%s) opcode (%03x|%04x) num_cmd_pkts = %d\n",
271 		unit->hci_devname,
272 		HCI_OGF(le16toh(ep.opcode)), HCI_OCF(le16toh(ep.opcode)),
273 		ep.num_cmd_pkts);
274 
275 	unit->hci_num_cmd_pkts = ep.num_cmd_pkts;
276 
277 	/*
278 	 * post processing of completed commands
279 	 */
280 	switch(le16toh(ep.opcode)) {
281 	case HCI_CMD_READ_BDADDR:
282 		hci_cmd_read_bdaddr(unit, m);
283 		break;
284 
285 	case HCI_CMD_READ_BUFFER_SIZE:
286 		hci_cmd_read_buffer_size(unit, m);
287 		break;
288 
289 	case HCI_CMD_READ_LOCAL_FEATURES:
290 		hci_cmd_read_local_features(unit, m);
291 		break;
292 
293 	case HCI_CMD_RESET:
294 		hci_cmd_reset(unit, m);
295 		break;
296 
297 	default:
298 		break;
299 	}
300 
301 	while (unit->hci_num_cmd_pkts > 0 && MBUFQ_FIRST(&unit->hci_cmdwait)) {
302 		MBUFQ_DEQUEUE(&unit->hci_cmdwait, m);
303 		hci_output_cmd(unit, m);
304 	}
305 }
306 
307 /*
308  * Number of Completed Packets
309  *
310  * This is sent periodically by the Controller telling us how many
311  * buffers are now freed up and which handle was using them. From
312  * this we determine which type of buffer it was and add the qty
313  * back into the relevant packet counter, then restart output on
314  * links that have halted.
315  */
316 static void
317 hci_event_num_compl_pkts(struct hci_unit *unit, struct mbuf *m)
318 {
319 	hci_num_compl_pkts_ep ep;
320 	struct hci_link *link, *next;
321 	uint16_t handle, num;
322 	int num_acl = 0, num_sco = 0;
323 
324 	KASSERT(m->m_pkthdr.len >= sizeof(ep));
325 	m_copydata(m, 0, sizeof(ep), &ep);
326 	m_adj(m, sizeof(ep));
327 
328 	while (ep.num_con_handles--) {
329 		m_copydata(m, 0, sizeof(handle), (caddr_t)&handle);
330 		m_adj(m, sizeof(handle));
331 		handle = le16toh(handle);
332 
333 		m_copydata(m, 0, sizeof(num), (caddr_t)&num);
334 		m_adj(m, sizeof(num));
335 		num = le16toh(num);
336 
337 		link = hci_link_lookup_handle(unit, handle);
338 		if (link) {
339 			if (link->hl_type == HCI_LINK_ACL) {
340 				num_acl += num;
341 				hci_acl_complete(link, num);
342 			} else {
343 				num_sco += num;
344 				hci_sco_complete(link, num);
345 			}
346 		} else {
347 			// XXX need to issue Read_Buffer_Size or Reset?
348 			printf("%s: unknown handle %d! "
349 				"(losing track of %d packet buffer%s)\n",
350 				unit->hci_devname, handle,
351 				num, (num == 1 ? "" : "s"));
352 		}
353 	}
354 
355 	/*
356 	 * Move up any queued packets. When a link has sent data, it will move
357 	 * to the back of the queue - technically then if a link had something
358 	 * to send and there were still buffers available it could get started
359 	 * twice but it seemed more important to to handle higher loads fairly
360 	 * than worry about wasting cycles when we are not busy.
361 	 */
362 
363 	unit->hci_num_acl_pkts += num_acl;
364 	unit->hci_num_sco_pkts += num_sco;
365 
366 	link = TAILQ_FIRST(&unit->hci_links);
367 	while (link && (unit->hci_num_acl_pkts > 0 || unit->hci_num_sco_pkts > 0)) {
368 		next = TAILQ_NEXT(link, hl_next);
369 
370 		if (link->hl_type == HCI_LINK_ACL) {
371 			if (unit->hci_num_acl_pkts > 0 && link->hl_txqlen > 0)
372 				hci_acl_start(link);
373 		} else {
374 			if (unit->hci_num_sco_pkts > 0 && link->hl_txqlen > 0)
375 				hci_sco_start(link);
376 		}
377 
378 		link = next;
379 	}
380 }
381 
382 /*
383  * Inquiry Result
384  *
385  * keep a note of devices seen, so we know which unit to use
386  * on outgoing connections
387  */
388 static void
389 hci_event_inquiry_result(struct hci_unit *unit, struct mbuf *m)
390 {
391 	hci_inquiry_result_ep ep;
392 	struct hci_memo *memo;
393 	bdaddr_t bdaddr;
394 
395 	KASSERT(m->m_pkthdr.len >= sizeof(ep));
396 	m_copydata(m, 0, sizeof(ep), &ep);
397 	m_adj(m, sizeof(ep));
398 
399 	DPRINTFN(1, "%d response%s\n", ep.num_responses,
400 				(ep.num_responses == 1 ? "" : "s"));
401 
402 	while(ep.num_responses--) {
403 		m_copydata(m, 0, sizeof(bdaddr_t), (caddr_t)&bdaddr);
404 
405 		DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n",
406 			bdaddr.b[5], bdaddr.b[4], bdaddr.b[3],
407 			bdaddr.b[2], bdaddr.b[1], bdaddr.b[0]);
408 
409 		memo = hci_memo_find(unit, &bdaddr);
410 		if (memo == NULL) {
411 			memo = malloc(sizeof(struct hci_memo),
412 				M_BLUETOOTH, M_NOWAIT | M_ZERO);
413 			if (memo == NULL) {
414 				DPRINTFN(0, "out of memo memory!\n");
415 				break;
416 			}
417 
418 			LIST_INSERT_HEAD(&unit->hci_memos, memo, next);
419 		}
420 
421 		microtime(&memo->time);
422 		m_copydata(m, 0, sizeof(hci_inquiry_response),
423 			(caddr_t)&memo->response);
424 		m_adj(m, sizeof(hci_inquiry_response));
425 
426 		memo->response.clock_offset =
427 		    le16toh(memo->response.clock_offset);
428 	}
429 }
430 
431 /*
432  * Connection Complete
433  *
434  * Sent to us when a connection is made. If there is no link
435  * structure already allocated for this, we must have changed
436  * our mind, so just disconnect.
437  */
438 static void
439 hci_event_con_compl(struct hci_unit *unit, struct mbuf *m)
440 {
441 	hci_con_compl_ep ep;
442 	hci_write_link_policy_settings_cp cp;
443 	struct hci_link *link;
444 	int err;
445 
446 	KASSERT(m->m_pkthdr.len >= sizeof(ep));
447 	m_copydata(m, 0, sizeof(ep), &ep);
448 	m_adj(m, sizeof(ep));
449 
450 	DPRINTFN(1, "(%s) %s connection complete for "
451 		"%02x:%02x:%02x:%02x:%02x:%02x status %#x\n",
452 		unit->hci_devname,
453 		(ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO"),
454 		ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3],
455 		ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0],
456 		ep.status);
457 
458 	link = hci_link_lookup_bdaddr(unit, &ep.bdaddr, ep.link_type);
459 
460 	if (ep.status) {
461 		if (link != NULL) {
462 			switch (ep.status) {
463 			case 0x04: /* "Page Timeout" */
464 				err = EHOSTDOWN;
465 				break;
466 
467 			case 0x08: /* "Connection Timed Out" */
468 				err = ETIMEDOUT;
469 				break;
470 
471 			case 0x16: /* "Connection Terminated by Local Host" */
472 				err = 0;
473 				break;
474 
475 			default:
476 				err = ECONNREFUSED;
477 				break;
478 			}
479 
480 			hci_link_free(link, err);
481 		}
482 
483 		return;
484 	}
485 
486 	if (link == NULL) {
487 		hci_discon_cp dp;
488 
489 		dp.con_handle = ep.con_handle;
490 		dp.reason = 0x13; /* "Remote User Terminated Connection" */
491 
492 		hci_send_cmd(unit, HCI_CMD_DISCONNECT, &dp, sizeof(dp));
493 		return;
494 	}
495 
496 	link->hl_state = HCI_LINK_OPEN;
497 	link->hl_handle = HCI_CON_HANDLE(le16toh(ep.con_handle));
498 
499 	if (ep.link_type == HCI_LINK_ACL) {
500 		cp.con_handle = ep.con_handle;
501 		cp.settings = htole16(unit->hci_link_policy);
502 		err = hci_send_cmd(unit, HCI_CMD_WRITE_LINK_POLICY_SETTINGS,
503 						&cp, sizeof(cp));
504 		if (err)
505 			printf("%s: Warning, could not write link policy\n",
506 				unit->hci_devname);
507 
508 		hci_acl_start(link);
509 	} else {
510 		(*link->hl_sco->sp_proto->connected)(link->hl_sco->sp_upper);
511 	}
512 }
513 
514 /*
515  * Disconnection Complete
516  *
517  * This is sent in response to a disconnection request, but also if
518  * the remote device goes out of range.
519  */
520 static void
521 hci_event_discon_compl(struct hci_unit *unit, struct mbuf *m)
522 {
523 	hci_discon_compl_ep ep;
524 	struct hci_link *link;
525 
526 	KASSERT(m->m_pkthdr.len >= sizeof(ep));
527 	m_copydata(m, 0, sizeof(ep), &ep);
528 	m_adj(m, sizeof(ep));
529 
530 	ep.con_handle = le16toh(ep.con_handle);
531 
532 	DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status);
533 
534 	link = hci_link_lookup_handle(unit, HCI_CON_HANDLE(ep.con_handle));
535 	if (link)
536 		hci_link_free(link, ENOLINK);
537 }
538 
539 /*
540  * Connect Request
541  *
542  * We check upstream for appropriate listeners and accept connections
543  * that are wanted.
544  */
545 static void
546 hci_event_con_req(struct hci_unit *unit, struct mbuf *m)
547 {
548 	hci_con_req_ep ep;
549 	hci_accept_con_cp ap;
550 	hci_reject_con_cp rp;
551 	struct hci_link *link;
552 
553 	KASSERT(m->m_pkthdr.len >= sizeof(ep));
554 	m_copydata(m, 0, sizeof(ep), &ep);
555 	m_adj(m, sizeof(ep));
556 
557 	DPRINTFN(1, "bdaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
558 		"class %2.2x%2.2x%2.2x type %s\n",
559 		ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3],
560 		ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0],
561 		ep.uclass[0], ep.uclass[1], ep.uclass[2],
562 		ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO");
563 
564 	if (ep.link_type == HCI_LINK_ACL)
565 		link = hci_acl_newconn(unit, &ep.bdaddr);
566 	else
567 		link = hci_sco_newconn(unit, &ep.bdaddr);
568 
569 	if (link == NULL) {
570 		memset(&rp, 0, sizeof(rp));
571 		bdaddr_copy(&rp.bdaddr, &ep.bdaddr);
572 		rp.reason = 0x0f;	/* Unacceptable BD_ADDR */
573 
574 		hci_send_cmd(unit, HCI_CMD_REJECT_CON, &rp, sizeof(rp));
575 	} else {
576 		memset(&ap, 0, sizeof(ap));
577 		bdaddr_copy(&ap.bdaddr, &ep.bdaddr);
578 		if (unit->hci_link_policy & HCI_LINK_POLICY_ENABLE_ROLE_SWITCH)
579 			ap.role = HCI_ROLE_MASTER;
580 		else
581 			ap.role = HCI_ROLE_SLAVE;
582 
583 		hci_send_cmd(unit, HCI_CMD_ACCEPT_CON, &ap, sizeof(ap));
584 	}
585 }
586 
587 /*
588  * process results of read_bdaddr command_complete event
589  */
590 static void
591 hci_cmd_read_bdaddr(struct hci_unit *unit, struct mbuf *m)
592 {
593 	hci_read_bdaddr_rp rp;
594 	int s;
595 
596 	KASSERT(m->m_pkthdr.len >= sizeof(rp));
597 	m_copydata(m, 0, sizeof(rp), &rp);
598 	m_adj(m, sizeof(rp));
599 
600 	if (rp.status > 0)
601 		return;
602 
603 	if ((unit->hci_flags & BTF_INIT_BDADDR) == 0)
604 		return;
605 
606 	bdaddr_copy(&unit->hci_bdaddr, &rp.bdaddr);
607 
608 	s = splraiseipl(unit->hci_ipl);
609 	unit->hci_flags &= ~BTF_INIT_BDADDR;
610 	splx(s);
611 
612 	wakeup(unit);
613 }
614 
615 /*
616  * process results of read_buffer_size command_complete event
617  */
618 static void
619 hci_cmd_read_buffer_size(struct hci_unit *unit, struct mbuf *m)
620 {
621 	hci_read_buffer_size_rp rp;
622 	int s;
623 
624 	KASSERT(m->m_pkthdr.len >= sizeof(rp));
625 	m_copydata(m, 0, sizeof(rp), &rp);
626 	m_adj(m, sizeof(rp));
627 
628 	if (rp.status > 0)
629 		return;
630 
631 	if ((unit->hci_flags & BTF_INIT_BUFFER_SIZE) == 0)
632 		return;
633 
634 	unit->hci_max_acl_size = le16toh(rp.max_acl_size);
635 	unit->hci_num_acl_pkts = le16toh(rp.num_acl_pkts);
636 	unit->hci_max_sco_size = rp.max_sco_size;
637 	unit->hci_num_sco_pkts = le16toh(rp.num_sco_pkts);
638 
639 	s = splraiseipl(unit->hci_ipl);
640 	unit->hci_flags &= ~BTF_INIT_BUFFER_SIZE;
641 	splx(s);
642 
643 	wakeup(unit);
644 }
645 
646 /*
647  * process results of read_local_features command_complete event
648  */
649 static void
650 hci_cmd_read_local_features(struct hci_unit *unit, struct mbuf *m)
651 {
652 	hci_read_local_features_rp rp;
653 	int s;
654 
655 	KASSERT(m->m_pkthdr.len >= sizeof(rp));
656 	m_copydata(m, 0, sizeof(rp), &rp);
657 	m_adj(m, sizeof(rp));
658 
659 	if (rp.status > 0)
660 		return;
661 
662 	if ((unit->hci_flags & BTF_INIT_FEATURES) == 0)
663 		return;
664 
665 	unit->hci_lmp_mask = 0;
666 
667 	if (rp.features[0] & HCI_LMP_ROLE_SWITCH)
668 		unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_ROLE_SWITCH;
669 
670 	if (rp.features[0] & HCI_LMP_HOLD_MODE)
671 		unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_HOLD_MODE;
672 
673 	if (rp.features[0] & HCI_LMP_SNIFF_MODE)
674 		unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_SNIFF_MODE;
675 
676 	if (rp.features[1] & HCI_LMP_PARK_MODE)
677 		unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_PARK_MODE;
678 
679 	/* ACL packet mask */
680 	unit->hci_acl_mask = HCI_PKT_DM1 | HCI_PKT_DH1;
681 
682 	if (rp.features[0] & HCI_LMP_3SLOT)
683 		unit->hci_acl_mask |= HCI_PKT_DM3 | HCI_PKT_DH3;
684 
685 	if (rp.features[0] & HCI_LMP_5SLOT)
686 		unit->hci_acl_mask |= HCI_PKT_DM5 | HCI_PKT_DH5;
687 
688 	if ((rp.features[3] & HCI_LMP_EDR_ACL_2MBPS) == 0)
689 		unit->hci_acl_mask |= HCI_PKT_2MBPS_DH1
690 				    | HCI_PKT_2MBPS_DH3
691 				    | HCI_PKT_2MBPS_DH5;
692 
693 	if ((rp.features[3] & HCI_LMP_EDR_ACL_3MBPS) == 0)
694 		unit->hci_acl_mask |= HCI_PKT_3MBPS_DH1
695 				    | HCI_PKT_3MBPS_DH3
696 				    | HCI_PKT_3MBPS_DH5;
697 
698 	if ((rp.features[4] & HCI_LMP_3SLOT_EDR_ACL) == 0)
699 		unit->hci_acl_mask |= HCI_PKT_2MBPS_DH3
700 				    | HCI_PKT_3MBPS_DH3;
701 
702 	if ((rp.features[5] & HCI_LMP_5SLOT_EDR_ACL) == 0)
703 		unit->hci_acl_mask |= HCI_PKT_2MBPS_DH5
704 				    | HCI_PKT_3MBPS_DH5;
705 
706 	unit->hci_packet_type = unit->hci_acl_mask;
707 
708 	/* SCO packet mask */
709 	unit->hci_sco_mask = 0;
710 	if (rp.features[1] & HCI_LMP_SCO_LINK)
711 		unit->hci_sco_mask |= HCI_PKT_HV1;
712 
713 	if (rp.features[1] & HCI_LMP_HV2_PKT)
714 		unit->hci_sco_mask |= HCI_PKT_HV2;
715 
716 	if (rp.features[1] & HCI_LMP_HV3_PKT)
717 		unit->hci_sco_mask |= HCI_PKT_HV3;
718 
719 	if (rp.features[3] & HCI_LMP_EV3_PKT)
720 		unit->hci_sco_mask |= HCI_PKT_EV3;
721 
722 	if (rp.features[4] & HCI_LMP_EV4_PKT)
723 		unit->hci_sco_mask |= HCI_PKT_EV4;
724 
725 	if (rp.features[4] & HCI_LMP_EV5_PKT)
726 		unit->hci_sco_mask |= HCI_PKT_EV5;
727 
728 	// XXX what do 2MBPS/3MBPS/3SLOT eSCO mean?
729 
730 	s = splraiseipl(unit->hci_ipl);
731 	unit->hci_flags &= ~BTF_INIT_FEATURES;
732 	splx(s);
733 
734 	wakeup(unit);
735 
736 	DPRINTFN(1, "%s: lmp_mask %4.4x, acl_mask %4.4x, sco_mask %4.4x\n",
737 		unit->hci_devname, unit->hci_lmp_mask,
738 		unit->hci_acl_mask, unit->hci_sco_mask);
739 }
740 
741 /*
742  * process results of reset command_complete event
743  *
744  * This has killed all the connections, so close down anything we have left,
745  * and reinitialise the unit.
746  */
747 static void
748 hci_cmd_reset(struct hci_unit *unit, struct mbuf *m)
749 {
750 	hci_reset_rp rp;
751 	struct hci_link *link, *next;
752 	int acl;
753 
754 	KASSERT(m->m_pkthdr.len >= sizeof(rp));
755 	m_copydata(m, 0, sizeof(rp), &rp);
756 	m_adj(m, sizeof(rp));
757 
758 	if (rp.status != 0)
759 		return;
760 
761 	/*
762 	 * release SCO links first, since they may be holding
763 	 * an ACL link reference.
764 	 */
765 	for (acl = 0 ; acl < 2 ; acl++) {
766 		next = TAILQ_FIRST(&unit->hci_links);
767 		while ((link = next) != NULL) {
768 			next = TAILQ_NEXT(link, hl_next);
769 			if (acl || link->hl_type != HCI_LINK_ACL)
770 				hci_link_free(link, ECONNABORTED);
771 		}
772 	}
773 
774 	unit->hci_num_acl_pkts = 0;
775 	unit->hci_num_sco_pkts = 0;
776 
777 	if (hci_send_cmd(unit, HCI_CMD_READ_BDADDR, NULL, 0))
778 		return;
779 
780 	if (hci_send_cmd(unit, HCI_CMD_READ_BUFFER_SIZE, NULL, 0))
781 		return;
782 
783 	if (hci_send_cmd(unit, HCI_CMD_READ_LOCAL_FEATURES, NULL, 0))
784 		return;
785 }
786