Wed Jul 27 10:25:09 2011 UTC ()
cleanup some DIAGNOSTIC and KASSERT code

- remove #ifdef DIAGNOSTIC, so that we won't act
  differently

- handle the cases where a Bluetooth adapter
  sends invalid packet data (I've not seen this,
  but it is not impossible)

- use KASSERT for actual impossible situations
  (to catch bad future development)


(plunky)
diff -r1.22 -r1.23 src/sys/netbt/hci_event.c
diff -r1.22 -r1.23 src/sys/netbt/hci_link.c
diff -r1.13 -r1.14 src/sys/netbt/l2cap_signal.c
diff -r1.17 -r1.18 src/sys/netbt/rfcomm_session.c

cvs diff -r1.22 -r1.23 src/sys/netbt/hci_event.c (expand / switch to unified diff)

--- src/sys/netbt/hci_event.c 2010/11/22 19:56:51 1.22
+++ src/sys/netbt/hci_event.c 2011/07/27 10:25:09 1.23
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: hci_event.c,v 1.22 2010/11/22 19:56:51 plunky Exp $ */ 1/* $NetBSD: hci_event.c,v 1.23 2011/07/27 10:25:09 plunky Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2005 Iain Hibbert. 4 * Copyright (c) 2005 Iain Hibbert.
5 * Copyright (c) 2006 Itronix Inc. 5 * Copyright (c) 2006 Itronix Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN 27 * ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.22 2010/11/22 19:56:51 plunky Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.23 2011/07/27 10:25:09 plunky Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/malloc.h> 38#include <sys/malloc.h>
39#include <sys/mbuf.h> 39#include <sys/mbuf.h>
40#include <sys/proc.h> 40#include <sys/proc.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42 42
43#include <netbt/bluetooth.h> 43#include <netbt/bluetooth.h>
44#include <netbt/hci.h> 44#include <netbt/hci.h>
45#include <netbt/sco.h> 45#include <netbt/sco.h>
46 46
47static void hci_event_inquiry_result(struct hci_unit *, struct mbuf *); 47static void hci_event_inquiry_result(struct hci_unit *, struct mbuf *);
@@ -147,41 +147,44 @@ hci_eventstr(unsigned int event) @@ -147,41 +147,44 @@ hci_eventstr(unsigned int event)
147 147
148 case HCI_EVENT_VENDOR: /* 0xff */ 148 case HCI_EVENT_VENDOR: /* 0xff */
149 return "VENDOR"; 149 return "VENDOR";
150 } 150 }
151 151
152 return "UNKNOWN"; 152 return "UNKNOWN";
153} 153}
154#endif /* BLUETOOTH_DEBUG */ 154#endif /* BLUETOOTH_DEBUG */
155 155
156/* 156/*
157 * process HCI Events 157 * process HCI Events
158 * 158 *
159 * We will free the mbuf at the end, no need for any sub 159 * We will free the mbuf at the end, no need for any sub
160 * functions to handle that. We kind of assume that the 160 * functions to handle that.
161 * device sends us valid events. 
162 */ 161 */
163void 162void
164hci_event(struct mbuf *m, struct hci_unit *unit) 163hci_event(struct mbuf *m, struct hci_unit *unit)
165{ 164{
166 hci_event_hdr_t hdr; 165 hci_event_hdr_t hdr;
167 166
168 KASSERT(m->m_flags & M_PKTHDR); 167 KASSERT(m->m_flags & M_PKTHDR);
169 168
170 KASSERT(m->m_pkthdr.len >= sizeof(hdr)); 169 if (m->m_pkthdr.len < sizeof(hdr))
 170 goto done;
 171
171 m_copydata(m, 0, sizeof(hdr), &hdr); 172 m_copydata(m, 0, sizeof(hdr), &hdr);
172 m_adj(m, sizeof(hdr)); 173 m_adj(m, sizeof(hdr));
173 174
174 KASSERT(hdr.type == HCI_EVENT_PKT); 175 KASSERT(hdr.type == HCI_EVENT_PKT);
 176 if (m->m_pkthdr.len != hdr.length)
 177 goto done;
175 178
176 DPRINTFN(1, "(%s) event %s\n", 179 DPRINTFN(1, "(%s) event %s\n",
177 device_xname(unit->hci_dev), hci_eventstr(hdr.event)); 180 device_xname(unit->hci_dev), hci_eventstr(hdr.event));
178 181
179 switch(hdr.event) { 182 switch(hdr.event) {
180 case HCI_EVENT_COMMAND_STATUS: 183 case HCI_EVENT_COMMAND_STATUS:
181 hci_event_command_status(unit, m); 184 hci_event_command_status(unit, m);
182 break; 185 break;
183 186
184 case HCI_EVENT_COMMAND_COMPL: 187 case HCI_EVENT_COMMAND_COMPL:
185 hci_event_command_compl(unit, m); 188 hci_event_command_compl(unit, m);
186 break; 189 break;
187 190
@@ -223,40 +226,43 @@ hci_event(struct mbuf *m, struct hci_uni @@ -223,40 +226,43 @@ hci_event(struct mbuf *m, struct hci_uni
223 226
224 case HCI_EVENT_CHANGE_CON_LINK_KEY_COMPL: 227 case HCI_EVENT_CHANGE_CON_LINK_KEY_COMPL:
225 hci_event_change_con_link_key_compl(unit, m); 228 hci_event_change_con_link_key_compl(unit, m);
226 break; 229 break;
227 230
228 case HCI_EVENT_READ_CLOCK_OFFSET_COMPL: 231 case HCI_EVENT_READ_CLOCK_OFFSET_COMPL:
229 hci_event_read_clock_offset_compl(unit, m); 232 hci_event_read_clock_offset_compl(unit, m);
230 break; 233 break;
231 234
232 default: 235 default:
233 break; 236 break;
234 } 237 }
235 238
 239done:
236 m_freem(m); 240 m_freem(m);
237} 241}
238 242
239/* 243/*
240 * Command Status 244 * Command Status
241 * 245 *
242 * Restart command queue and post-process any pending commands 246 * Restart command queue and post-process any pending commands
243 */ 247 */
244static void 248static void
245hci_event_command_status(struct hci_unit *unit, struct mbuf *m) 249hci_event_command_status(struct hci_unit *unit, struct mbuf *m)
246{ 250{
247 hci_command_status_ep ep; 251 hci_command_status_ep ep;
248 252
249 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 253 if (m->m_pkthdr.len < sizeof(ep))
 254 return;
 255
250 m_copydata(m, 0, sizeof(ep), &ep); 256 m_copydata(m, 0, sizeof(ep), &ep);
251 m_adj(m, sizeof(ep)); 257 m_adj(m, sizeof(ep));
252 258
253 ep.opcode = le16toh(ep.opcode); 259 ep.opcode = le16toh(ep.opcode);
254 260
255 DPRINTFN(1, "(%s) opcode (%03x|%04x) status = 0x%x num_cmd_pkts = %d\n", 261 DPRINTFN(1, "(%s) opcode (%03x|%04x) status = 0x%x num_cmd_pkts = %d\n",
256 device_xname(unit->hci_dev), 262 device_xname(unit->hci_dev),
257 HCI_OGF(ep.opcode), HCI_OCF(ep.opcode), 263 HCI_OGF(ep.opcode), HCI_OCF(ep.opcode),
258 ep.status, 264 ep.status,
259 ep.num_cmd_pkts); 265 ep.num_cmd_pkts);
260 266
261 hci_num_cmds(unit, ep.num_cmd_pkts); 267 hci_num_cmds(unit, ep.num_cmd_pkts);
262 268
@@ -282,27 +288,29 @@ hci_event_command_status(struct hci_unit @@ -282,27 +288,29 @@ hci_event_command_status(struct hci_unit
282} 288}
283 289
284/* 290/*
285 * Command Complete 291 * Command Complete
286 * 292 *
287 * Restart command queue and handle the completed command 293 * Restart command queue and handle the completed command
288 */ 294 */
289static void 295static void
290hci_event_command_compl(struct hci_unit *unit, struct mbuf *m) 296hci_event_command_compl(struct hci_unit *unit, struct mbuf *m)
291{ 297{
292 hci_command_compl_ep ep; 298 hci_command_compl_ep ep;
293 hci_status_rp rp; 299 hci_status_rp rp;
294 300
295 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 301 if (m->m_pkthdr.len < sizeof(ep))
 302 return;
 303
296 m_copydata(m, 0, sizeof(ep), &ep); 304 m_copydata(m, 0, sizeof(ep), &ep);
297 m_adj(m, sizeof(ep)); 305 m_adj(m, sizeof(ep));
298 306
299 DPRINTFN(1, "(%s) opcode (%03x|%04x) num_cmd_pkts = %d\n", 307 DPRINTFN(1, "(%s) opcode (%03x|%04x) num_cmd_pkts = %d\n",
300 device_xname(unit->hci_dev), 308 device_xname(unit->hci_dev),
301 HCI_OGF(le16toh(ep.opcode)), HCI_OCF(le16toh(ep.opcode)), 309 HCI_OGF(le16toh(ep.opcode)), HCI_OCF(le16toh(ep.opcode)),
302 ep.num_cmd_pkts); 310 ep.num_cmd_pkts);
303 311
304 hci_num_cmds(unit, ep.num_cmd_pkts); 312 hci_num_cmds(unit, ep.num_cmd_pkts);
305 313
306 /* 314 /*
307 * I am not sure if this is completely correct, it is not guaranteed 315 * I am not sure if this is completely correct, it is not guaranteed
308 * that a command_complete packet will contain the status though most 316 * that a command_complete packet will contain the status though most
@@ -359,27 +367,29 @@ hci_event_command_compl(struct hci_unit  @@ -359,27 +367,29 @@ hci_event_command_compl(struct hci_unit
359 * buffers are now freed up and which handle was using them. From 367 * buffers are now freed up and which handle was using them. From
360 * this we determine which type of buffer it was and add the qty 368 * this we determine which type of buffer it was and add the qty
361 * back into the relevant packet counter, then restart output on 369 * back into the relevant packet counter, then restart output on
362 * links that have halted. 370 * links that have halted.
363 */ 371 */
364static void 372static void
365hci_event_num_compl_pkts(struct hci_unit *unit, struct mbuf *m) 373hci_event_num_compl_pkts(struct hci_unit *unit, struct mbuf *m)
366{ 374{
367 hci_num_compl_pkts_ep ep; 375 hci_num_compl_pkts_ep ep;
368 struct hci_link *link, *next; 376 struct hci_link *link, *next;
369 uint16_t handle, num; 377 uint16_t handle, num;
370 int num_acl = 0, num_sco = 0; 378 int num_acl = 0, num_sco = 0;
371 379
372 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 380 if (m->m_pkthdr.len < sizeof(ep))
 381 return;
 382
373 m_copydata(m, 0, sizeof(ep), &ep); 383 m_copydata(m, 0, sizeof(ep), &ep);
374 m_adj(m, sizeof(ep)); 384 m_adj(m, sizeof(ep));
375 385
376 while (ep.num_con_handles--) { 386 while (ep.num_con_handles--) {
377 m_copydata(m, 0, sizeof(handle), &handle); 387 m_copydata(m, 0, sizeof(handle), &handle);
378 m_adj(m, sizeof(handle)); 388 m_adj(m, sizeof(handle));
379 handle = le16toh(handle); 389 handle = le16toh(handle);
380 390
381 m_copydata(m, 0, sizeof(num), &num); 391 m_copydata(m, 0, sizeof(num), &num);
382 m_adj(m, sizeof(num)); 392 m_adj(m, sizeof(num));
383 num = le16toh(num); 393 num = le16toh(num);
384 394
385 link = hci_link_lookup_handle(unit, handle); 395 link = hci_link_lookup_handle(unit, handle);
@@ -429,35 +439,39 @@ hci_event_num_compl_pkts(struct hci_unit @@ -429,35 +439,39 @@ hci_event_num_compl_pkts(struct hci_unit
429/* 439/*
430 * Inquiry Result 440 * Inquiry Result
431 * 441 *
432 * keep a note of devices seen, so we know which unit to use 442 * keep a note of devices seen, so we know which unit to use
433 * on outgoing connections 443 * on outgoing connections
434 */ 444 */
435static void 445static void
436hci_event_inquiry_result(struct hci_unit *unit, struct mbuf *m) 446hci_event_inquiry_result(struct hci_unit *unit, struct mbuf *m)
437{ 447{
438 hci_inquiry_result_ep ep; 448 hci_inquiry_result_ep ep;
439 hci_inquiry_response ir; 449 hci_inquiry_response ir;
440 struct hci_memo *memo; 450 struct hci_memo *memo;
441 451
442 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 452 if (m->m_pkthdr.len < sizeof(ep))
 453 return;
 454
443 m_copydata(m, 0, sizeof(ep), &ep); 455 m_copydata(m, 0, sizeof(ep), &ep);
444 m_adj(m, sizeof(ep)); 456 m_adj(m, sizeof(ep));
445 457
446 DPRINTFN(1, "%d response%s\n", ep.num_responses, 458 DPRINTFN(1, "%d response%s\n", ep.num_responses,
447 (ep.num_responses == 1 ? "" : "s")); 459 (ep.num_responses == 1 ? "" : "s"));
448 460
449 while(ep.num_responses--) { 461 while(ep.num_responses--) {
450 KASSERT(m->m_pkthdr.len >= sizeof(ir)); 462 if (m->m_pkthdr.len < sizeof(ir))
 463 return;
 464
451 m_copydata(m, 0, sizeof(ir), &ir); 465 m_copydata(m, 0, sizeof(ir), &ir);
452 m_adj(m, sizeof(ir)); 466 m_adj(m, sizeof(ir));
453 467
454 DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n", 468 DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n",
455 ir.bdaddr.b[5], ir.bdaddr.b[4], ir.bdaddr.b[3], 469 ir.bdaddr.b[5], ir.bdaddr.b[4], ir.bdaddr.b[3],
456 ir.bdaddr.b[2], ir.bdaddr.b[1], ir.bdaddr.b[0]); 470 ir.bdaddr.b[2], ir.bdaddr.b[1], ir.bdaddr.b[0]);
457 471
458 memo = hci_memo_new(unit, &ir.bdaddr); 472 memo = hci_memo_new(unit, &ir.bdaddr);
459 if (memo != NULL) { 473 if (memo != NULL) {
460 memo->page_scan_rep_mode = ir.page_scan_rep_mode; 474 memo->page_scan_rep_mode = ir.page_scan_rep_mode;
461 memo->page_scan_mode = ir.page_scan_mode; 475 memo->page_scan_mode = ir.page_scan_mode;
462 memo->clock_offset = ir.clock_offset; 476 memo->clock_offset = ir.clock_offset;
463 } 477 }
@@ -466,35 +480,39 @@ hci_event_inquiry_result(struct hci_unit @@ -466,35 +480,39 @@ hci_event_inquiry_result(struct hci_unit
466 480
467/* 481/*
468 * Inquiry Result with RSSI 482 * Inquiry Result with RSSI
469 * 483 *
470 * as above but different packet when RSSI result is enabled 484 * as above but different packet when RSSI result is enabled
471 */ 485 */
472static void 486static void
473hci_event_rssi_result(struct hci_unit *unit, struct mbuf *m) 487hci_event_rssi_result(struct hci_unit *unit, struct mbuf *m)
474{ 488{
475 hci_rssi_result_ep ep; 489 hci_rssi_result_ep ep;
476 hci_rssi_response rr; 490 hci_rssi_response rr;
477 struct hci_memo *memo; 491 struct hci_memo *memo;
478 492
479 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 493 if (m->m_pkthdr.len < sizeof(ep))
 494 return;
 495
480 m_copydata(m, 0, sizeof(ep), &ep); 496 m_copydata(m, 0, sizeof(ep), &ep);
481 m_adj(m, sizeof(ep)); 497 m_adj(m, sizeof(ep));
482 498
483 DPRINTFN(1, "%d response%s\n", ep.num_responses, 499 DPRINTFN(1, "%d response%s\n", ep.num_responses,
484 (ep.num_responses == 1 ? "" : "s")); 500 (ep.num_responses == 1 ? "" : "s"));
485 501
486 while(ep.num_responses--) { 502 while(ep.num_responses--) {
487 KASSERT(m->m_pkthdr.len >= sizeof(rr)); 503 if (m->m_pkthdr.len < sizeof(rr))
 504 return;
 505
488 m_copydata(m, 0, sizeof(rr), &rr); 506 m_copydata(m, 0, sizeof(rr), &rr);
489 m_adj(m, sizeof(rr)); 507 m_adj(m, sizeof(rr));
490 508
491 DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n", 509 DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n",
492 rr.bdaddr.b[5], rr.bdaddr.b[4], rr.bdaddr.b[3], 510 rr.bdaddr.b[5], rr.bdaddr.b[4], rr.bdaddr.b[3],
493 rr.bdaddr.b[2], rr.bdaddr.b[1], rr.bdaddr.b[0]); 511 rr.bdaddr.b[2], rr.bdaddr.b[1], rr.bdaddr.b[0]);
494 512
495 memo = hci_memo_new(unit, &rr.bdaddr); 513 memo = hci_memo_new(unit, &rr.bdaddr);
496 if (memo != NULL) { 514 if (memo != NULL) {
497 memo->page_scan_rep_mode = rr.page_scan_rep_mode; 515 memo->page_scan_rep_mode = rr.page_scan_rep_mode;
498 memo->page_scan_mode = 0; 516 memo->page_scan_mode = 0;
499 memo->clock_offset = rr.clock_offset; 517 memo->clock_offset = rr.clock_offset;
500 } 518 }
@@ -502,27 +520,29 @@ hci_event_rssi_result(struct hci_unit *u @@ -502,27 +520,29 @@ hci_event_rssi_result(struct hci_unit *u
502} 520}
503 521
504/* 522/*
505 * Extended Inquiry Result 523 * Extended Inquiry Result
506 * 524 *
507 * as above but provides only one response and extended service info 525 * as above but provides only one response and extended service info
508 */ 526 */
509static void 527static void
510hci_event_extended_result(struct hci_unit *unit, struct mbuf *m) 528hci_event_extended_result(struct hci_unit *unit, struct mbuf *m)
511{ 529{
512 hci_extended_result_ep ep; 530 hci_extended_result_ep ep;
513 struct hci_memo *memo; 531 struct hci_memo *memo;
514 532
515 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 533 if (m->m_pkthdr.len < sizeof(ep))
 534 return;
 535
516 m_copydata(m, 0, sizeof(ep), &ep); 536 m_copydata(m, 0, sizeof(ep), &ep);
517 m_adj(m, sizeof(ep)); 537 m_adj(m, sizeof(ep));
518 538
519 if (ep.num_responses != 1) 539 if (ep.num_responses != 1)
520 return; 540 return;
521 541
522 DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n", 542 DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n",
523 ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3], 543 ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3],
524 ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0]); 544 ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0]);
525 545
526 memo = hci_memo_new(unit, &ep.bdaddr); 546 memo = hci_memo_new(unit, &ep.bdaddr);
527 if (memo != NULL) { 547 if (memo != NULL) {
528 memo->page_scan_rep_mode = ep.page_scan_rep_mode; 548 memo->page_scan_rep_mode = ep.page_scan_rep_mode;
@@ -536,27 +556,29 @@ hci_event_extended_result(struct hci_uni @@ -536,27 +556,29 @@ hci_event_extended_result(struct hci_uni
536 * 556 *
537 * Sent to us when a connection is made. If there is no link 557 * Sent to us when a connection is made. If there is no link
538 * structure already allocated for this, we must have changed 558 * structure already allocated for this, we must have changed
539 * our mind, so just disconnect. 559 * our mind, so just disconnect.
540 */ 560 */
541static void 561static void
542hci_event_con_compl(struct hci_unit *unit, struct mbuf *m) 562hci_event_con_compl(struct hci_unit *unit, struct mbuf *m)
543{ 563{
544 hci_con_compl_ep ep; 564 hci_con_compl_ep ep;
545 hci_write_link_policy_settings_cp cp; 565 hci_write_link_policy_settings_cp cp;
546 struct hci_link *link; 566 struct hci_link *link;
547 int err; 567 int err;
548 568
549 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 569 if (m->m_pkthdr.len < sizeof(ep))
 570 return;
 571
550 m_copydata(m, 0, sizeof(ep), &ep); 572 m_copydata(m, 0, sizeof(ep), &ep);
551 m_adj(m, sizeof(ep)); 573 m_adj(m, sizeof(ep));
552 574
553 DPRINTFN(1, "(%s) %s connection complete for " 575 DPRINTFN(1, "(%s) %s connection complete for "
554 "%02x:%02x:%02x:%02x:%02x:%02x status %#x\n", 576 "%02x:%02x:%02x:%02x:%02x:%02x status %#x\n",
555 device_xname(unit->hci_dev), 577 device_xname(unit->hci_dev),
556 (ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO"), 578 (ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO"),
557 ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3], 579 ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3],
558 ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0], 580 ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0],
559 ep.status); 581 ep.status);
560 582
561 link = hci_link_lookup_bdaddr(unit, &ep.bdaddr, ep.link_type); 583 link = hci_link_lookup_bdaddr(unit, &ep.bdaddr, ep.link_type);
562 584
@@ -631,54 +653,58 @@ hci_event_con_compl(struct hci_unit *uni @@ -631,54 +653,58 @@ hci_event_con_compl(struct hci_unit *uni
631 653
632/* 654/*
633 * Disconnection Complete 655 * Disconnection Complete
634 * 656 *
635 * This is sent in response to a disconnection request, but also if 657 * This is sent in response to a disconnection request, but also if
636 * the remote device goes out of range. 658 * the remote device goes out of range.
637 */ 659 */
638static void 660static void
639hci_event_discon_compl(struct hci_unit *unit, struct mbuf *m) 661hci_event_discon_compl(struct hci_unit *unit, struct mbuf *m)
640{ 662{
641 hci_discon_compl_ep ep; 663 hci_discon_compl_ep ep;
642 struct hci_link *link; 664 struct hci_link *link;
643 665
644 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 666 if (m->m_pkthdr.len < sizeof(ep))
 667 return;
 668
645 m_copydata(m, 0, sizeof(ep), &ep); 669 m_copydata(m, 0, sizeof(ep), &ep);
646 m_adj(m, sizeof(ep)); 670 m_adj(m, sizeof(ep));
647 671
648 ep.con_handle = le16toh(ep.con_handle); 672 ep.con_handle = le16toh(ep.con_handle);
649 673
650 DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status); 674 DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status);
651 675
652 link = hci_link_lookup_handle(unit, HCI_CON_HANDLE(ep.con_handle)); 676 link = hci_link_lookup_handle(unit, HCI_CON_HANDLE(ep.con_handle));
653 if (link) 677 if (link)
654 hci_link_free(link, ENOLINK); 678 hci_link_free(link, ENOLINK);
655} 679}
656 680
657/* 681/*
658 * Connect Request 682 * Connect Request
659 * 683 *
660 * We check upstream for appropriate listeners and accept connections 684 * We check upstream for appropriate listeners and accept connections
661 * that are wanted. 685 * that are wanted.
662 */ 686 */
663static void 687static void
664hci_event_con_req(struct hci_unit *unit, struct mbuf *m) 688hci_event_con_req(struct hci_unit *unit, struct mbuf *m)
665{ 689{
666 hci_con_req_ep ep; 690 hci_con_req_ep ep;
667 hci_accept_con_cp ap; 691 hci_accept_con_cp ap;
668 hci_reject_con_cp rp; 692 hci_reject_con_cp rp;
669 struct hci_link *link; 693 struct hci_link *link;
670 694
671 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 695 if (m->m_pkthdr.len < sizeof(ep))
 696 return;
 697
672 m_copydata(m, 0, sizeof(ep), &ep); 698 m_copydata(m, 0, sizeof(ep), &ep);
673 m_adj(m, sizeof(ep)); 699 m_adj(m, sizeof(ep));
674 700
675 DPRINTFN(1, "bdaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " 701 DPRINTFN(1, "bdaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
676 "class %2.2x%2.2x%2.2x type %s\n", 702 "class %2.2x%2.2x%2.2x type %s\n",
677 ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3], 703 ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3],
678 ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0], 704 ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0],
679 ep.uclass[0], ep.uclass[1], ep.uclass[2], 705 ep.uclass[0], ep.uclass[1], ep.uclass[2],
680 ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO"); 706 ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO");
681 707
682 if (ep.link_type == HCI_LINK_ACL) 708 if (ep.link_type == HCI_LINK_ACL)
683 link = hci_acl_newconn(unit, &ep.bdaddr); 709 link = hci_acl_newconn(unit, &ep.bdaddr);
684 else 710 else
@@ -705,27 +731,29 @@ hci_event_con_req(struct hci_unit *unit, @@ -705,27 +731,29 @@ hci_event_con_req(struct hci_unit *unit,
705/* 731/*
706 * Auth Complete 732 * Auth Complete
707 * 733 *
708 * Authentication has been completed on an ACL link. We can notify the 734 * Authentication has been completed on an ACL link. We can notify the
709 * upper layer protocols unless further mode changes are pending. 735 * upper layer protocols unless further mode changes are pending.
710 */ 736 */
711static void 737static void
712hci_event_auth_compl(struct hci_unit *unit, struct mbuf *m) 738hci_event_auth_compl(struct hci_unit *unit, struct mbuf *m)
713{ 739{
714 hci_auth_compl_ep ep; 740 hci_auth_compl_ep ep;
715 struct hci_link *link; 741 struct hci_link *link;
716 int err; 742 int err;
717 743
718 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 744 if (m->m_pkthdr.len < sizeof(ep))
 745 return;
 746
719 m_copydata(m, 0, sizeof(ep), &ep); 747 m_copydata(m, 0, sizeof(ep), &ep);
720 m_adj(m, sizeof(ep)); 748 m_adj(m, sizeof(ep));
721 749
722 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle)); 750 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle));
723 751
724 DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status); 752 DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status);
725 753
726 link = hci_link_lookup_handle(unit, ep.con_handle); 754 link = hci_link_lookup_handle(unit, ep.con_handle);
727 if (link == NULL || link->hl_type != HCI_LINK_ACL) 755 if (link == NULL || link->hl_type != HCI_LINK_ACL)
728 return; 756 return;
729 757
730 if (ep.status == 0) { 758 if (ep.status == 0) {
731 link->hl_flags |= HCI_LINK_AUTH; 759 link->hl_flags |= HCI_LINK_AUTH;
@@ -747,27 +775,29 @@ hci_event_auth_compl(struct hci_unit *un @@ -747,27 +775,29 @@ hci_event_auth_compl(struct hci_unit *un
747 * The encryption status has changed. Basically, we note the change 775 * The encryption status has changed. Basically, we note the change
748 * then notify the upper layer protocol unless further mode changes 776 * then notify the upper layer protocol unless further mode changes
749 * are pending. 777 * are pending.
750 * Note that if encryption gets disabled when it has been requested, 778 * Note that if encryption gets disabled when it has been requested,
751 * we will attempt to enable it again.. (its a feature not a bug :) 779 * we will attempt to enable it again.. (its a feature not a bug :)
752 */ 780 */
753static void 781static void
754hci_event_encryption_change(struct hci_unit *unit, struct mbuf *m) 782hci_event_encryption_change(struct hci_unit *unit, struct mbuf *m)
755{ 783{
756 hci_encryption_change_ep ep; 784 hci_encryption_change_ep ep;
757 struct hci_link *link; 785 struct hci_link *link;
758 int err; 786 int err;
759 787
760 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 788 if (m->m_pkthdr.len < sizeof(ep))
 789 return;
 790
761 m_copydata(m, 0, sizeof(ep), &ep); 791 m_copydata(m, 0, sizeof(ep), &ep);
762 m_adj(m, sizeof(ep)); 792 m_adj(m, sizeof(ep));
763 793
764 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle)); 794 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle));
765 795
766 DPRINTFN(1, "handle #%d, status=0x%x, encryption_enable=0x%x\n", 796 DPRINTFN(1, "handle #%d, status=0x%x, encryption_enable=0x%x\n",
767 ep.con_handle, ep.status, ep.encryption_enable); 797 ep.con_handle, ep.status, ep.encryption_enable);
768 798
769 link = hci_link_lookup_handle(unit, ep.con_handle); 799 link = hci_link_lookup_handle(unit, ep.con_handle);
770 if (link == NULL || link->hl_type != HCI_LINK_ACL) 800 if (link == NULL || link->hl_type != HCI_LINK_ACL)
771 return; 801 return;
772 802
773 if (ep.status == 0) { 803 if (ep.status == 0) {
@@ -791,27 +821,29 @@ hci_event_encryption_change(struct hci_u @@ -791,27 +821,29 @@ hci_event_encryption_change(struct hci_u
791 * Change Connection Link Key Complete 821 * Change Connection Link Key Complete
792 * 822 *
793 * Link keys are handled in userland but if we are waiting to secure 823 * Link keys are handled in userland but if we are waiting to secure
794 * this link, we should notify the upper protocols. A SECURE request 824 * this link, we should notify the upper protocols. A SECURE request
795 * only needs a single key change, so we can cancel the request. 825 * only needs a single key change, so we can cancel the request.
796 */ 826 */
797static void 827static void
798hci_event_change_con_link_key_compl(struct hci_unit *unit, struct mbuf *m) 828hci_event_change_con_link_key_compl(struct hci_unit *unit, struct mbuf *m)
799{ 829{
800 hci_change_con_link_key_compl_ep ep; 830 hci_change_con_link_key_compl_ep ep;
801 struct hci_link *link; 831 struct hci_link *link;
802 int err; 832 int err;
803 833
804 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 834 if (m->m_pkthdr.len < sizeof(ep))
 835 return;
 836
805 m_copydata(m, 0, sizeof(ep), &ep); 837 m_copydata(m, 0, sizeof(ep), &ep);
806 m_adj(m, sizeof(ep)); 838 m_adj(m, sizeof(ep));
807 839
808 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle)); 840 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle));
809 841
810 DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status); 842 DPRINTFN(1, "handle #%d, status=0x%x\n", ep.con_handle, ep.status);
811 843
812 link = hci_link_lookup_handle(unit, ep.con_handle); 844 link = hci_link_lookup_handle(unit, ep.con_handle);
813 if (link == NULL || link->hl_type != HCI_LINK_ACL) 845 if (link == NULL || link->hl_type != HCI_LINK_ACL)
814 return; 846 return;
815 847
816 link->hl_flags &= ~HCI_LINK_SECURE_REQ; 848 link->hl_flags &= ~HCI_LINK_SECURE_REQ;
817 849
@@ -831,76 +863,82 @@ hci_event_change_con_link_key_compl(stru @@ -831,76 +863,82 @@ hci_event_change_con_link_key_compl(stru
831 863
832/* 864/*
833 * Read Clock Offset Complete 865 * Read Clock Offset Complete
834 * 866 *
835 * We keep a note of the clock offset of remote devices when a 867 * We keep a note of the clock offset of remote devices when a
836 * link is made, in order to facilitate reconnections to the device 868 * link is made, in order to facilitate reconnections to the device
837 */ 869 */
838static void 870static void
839hci_event_read_clock_offset_compl(struct hci_unit *unit, struct mbuf *m) 871hci_event_read_clock_offset_compl(struct hci_unit *unit, struct mbuf *m)
840{ 872{
841 hci_read_clock_offset_compl_ep ep; 873 hci_read_clock_offset_compl_ep ep;
842 struct hci_link *link; 874 struct hci_link *link;
843 875
844 KASSERT(m->m_pkthdr.len >= sizeof(ep)); 876 if (m->m_pkthdr.len < sizeof(ep))
 877 return;
 878
845 m_copydata(m, 0, sizeof(ep), &ep); 879 m_copydata(m, 0, sizeof(ep), &ep);
846 m_adj(m, sizeof(ep)); 880 m_adj(m, sizeof(ep));
847 881
848 DPRINTFN(1, "handle #%d, offset=%u, status=0x%x\n", 882 DPRINTFN(1, "handle #%d, offset=%u, status=0x%x\n",
849 le16toh(ep.con_handle), le16toh(ep.clock_offset), ep.status); 883 le16toh(ep.con_handle), le16toh(ep.clock_offset), ep.status);
850 884
851 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle)); 885 ep.con_handle = HCI_CON_HANDLE(le16toh(ep.con_handle));
852 link = hci_link_lookup_handle(unit, ep.con_handle); 886 link = hci_link_lookup_handle(unit, ep.con_handle);
853 if (link == NULL || link->hl_type != HCI_LINK_ACL) 887 if (link == NULL || link->hl_type != HCI_LINK_ACL)
854 return; 888 return;
855 889
856 if (ep.status == 0) 890 if (ep.status == 0)
857 link->hl_clock = ep.clock_offset; 891 link->hl_clock = ep.clock_offset;
858} 892}
859 893
860/* 894/*
861 * process results of read_bdaddr command_complete event 895 * process results of read_bdaddr command_complete event
862 */ 896 */
863static void 897static void
864hci_cmd_read_bdaddr(struct hci_unit *unit, struct mbuf *m) 898hci_cmd_read_bdaddr(struct hci_unit *unit, struct mbuf *m)
865{ 899{
866 hci_read_bdaddr_rp rp; 900 hci_read_bdaddr_rp rp;
867 901
868 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 902 if (m->m_pkthdr.len < sizeof(rp))
 903 return;
 904
869 m_copydata(m, 0, sizeof(rp), &rp); 905 m_copydata(m, 0, sizeof(rp), &rp);
870 m_adj(m, sizeof(rp)); 906 m_adj(m, sizeof(rp));
871 907
872 if (rp.status > 0) 908 if (rp.status > 0)
873 return; 909 return;
874 910
875 if ((unit->hci_flags & BTF_INIT_BDADDR) == 0) 911 if ((unit->hci_flags & BTF_INIT_BDADDR) == 0)
876 return; 912 return;
877 913
878 bdaddr_copy(&unit->hci_bdaddr, &rp.bdaddr); 914 bdaddr_copy(&unit->hci_bdaddr, &rp.bdaddr);
879 915
880 unit->hci_flags &= ~BTF_INIT_BDADDR; 916 unit->hci_flags &= ~BTF_INIT_BDADDR;
881 917
882 cv_broadcast(&unit->hci_init); 918 cv_broadcast(&unit->hci_init);
883} 919}
884 920
885/* 921/*
886 * process results of read_buffer_size command_complete event 922 * process results of read_buffer_size command_complete event
887 */ 923 */
888static void 924static void
889hci_cmd_read_buffer_size(struct hci_unit *unit, struct mbuf *m) 925hci_cmd_read_buffer_size(struct hci_unit *unit, struct mbuf *m)
890{ 926{
891 hci_read_buffer_size_rp rp; 927 hci_read_buffer_size_rp rp;
892 928
893 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 929 if (m->m_pkthdr.len < sizeof(rp))
 930 return;
 931
894 m_copydata(m, 0, sizeof(rp), &rp); 932 m_copydata(m, 0, sizeof(rp), &rp);
895 m_adj(m, sizeof(rp)); 933 m_adj(m, sizeof(rp));
896 934
897 if (rp.status > 0) 935 if (rp.status > 0)
898 return; 936 return;
899 937
900 if ((unit->hci_flags & BTF_INIT_BUFFER_SIZE) == 0) 938 if ((unit->hci_flags & BTF_INIT_BUFFER_SIZE) == 0)
901 return; 939 return;
902 940
903 unit->hci_max_acl_size = le16toh(rp.max_acl_size); 941 unit->hci_max_acl_size = le16toh(rp.max_acl_size);
904 unit->hci_num_acl_pkts = le16toh(rp.num_acl_pkts); 942 unit->hci_num_acl_pkts = le16toh(rp.num_acl_pkts);
905 unit->hci_max_acl_pkts = le16toh(rp.num_acl_pkts); 943 unit->hci_max_acl_pkts = le16toh(rp.num_acl_pkts);
906 unit->hci_max_sco_size = rp.max_sco_size; 944 unit->hci_max_sco_size = rp.max_sco_size;
@@ -910,27 +948,29 @@ hci_cmd_read_buffer_size(struct hci_unit @@ -910,27 +948,29 @@ hci_cmd_read_buffer_size(struct hci_unit
910 unit->hci_flags &= ~BTF_INIT_BUFFER_SIZE; 948 unit->hci_flags &= ~BTF_INIT_BUFFER_SIZE;
911 949
912 cv_broadcast(&unit->hci_init); 950 cv_broadcast(&unit->hci_init);
913} 951}
914 952
915/* 953/*
916 * process results of read_local_features command_complete event 954 * process results of read_local_features command_complete event
917 */ 955 */
918static void 956static void
919hci_cmd_read_local_features(struct hci_unit *unit, struct mbuf *m) 957hci_cmd_read_local_features(struct hci_unit *unit, struct mbuf *m)
920{ 958{
921 hci_read_local_features_rp rp; 959 hci_read_local_features_rp rp;
922 960
923 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 961 if (m->m_pkthdr.len < sizeof(rp))
 962 return;
 963
924 m_copydata(m, 0, sizeof(rp), &rp); 964 m_copydata(m, 0, sizeof(rp), &rp);
925 m_adj(m, sizeof(rp)); 965 m_adj(m, sizeof(rp));
926 966
927 if (rp.status > 0) 967 if (rp.status > 0)
928 return; 968 return;
929 969
930 if ((unit->hci_flags & BTF_INIT_FEATURES) == 0) 970 if ((unit->hci_flags & BTF_INIT_FEATURES) == 0)
931 return; 971 return;
932 972
933 memcpy(unit->hci_feat0, rp.features, HCI_FEATURES_SIZE); 973 memcpy(unit->hci_feat0, rp.features, HCI_FEATURES_SIZE);
934 974
935 unit->hci_lmp_mask = 0; 975 unit->hci_lmp_mask = 0;
936 976
@@ -1019,27 +1059,29 @@ hci_cmd_read_local_features(struct hci_u @@ -1019,27 +1059,29 @@ hci_cmd_read_local_features(struct hci_u
1019 1059
1020 unit->hci_flags &= ~BTF_INIT_FEATURES; 1060 unit->hci_flags &= ~BTF_INIT_FEATURES;
1021 cv_broadcast(&unit->hci_init); 1061 cv_broadcast(&unit->hci_init);
1022} 1062}
1023 1063
1024/* 1064/*
1025 * process results of read_local_extended_features command_complete event 1065 * process results of read_local_extended_features command_complete event
1026 */ 1066 */
1027static void 1067static void
1028hci_cmd_read_local_extended_features(struct hci_unit *unit, struct mbuf *m) 1068hci_cmd_read_local_extended_features(struct hci_unit *unit, struct mbuf *m)
1029{ 1069{
1030 hci_read_local_extended_features_rp rp; 1070 hci_read_local_extended_features_rp rp;
1031 1071
1032 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 1072 if (m->m_pkthdr.len < sizeof(rp))
 1073 return;
 1074
1033 m_copydata(m, 0, sizeof(rp), &rp); 1075 m_copydata(m, 0, sizeof(rp), &rp);
1034 m_adj(m, sizeof(rp)); 1076 m_adj(m, sizeof(rp));
1035 1077
1036 if (rp.status > 0) 1078 if (rp.status > 0)
1037 return; 1079 return;
1038 1080
1039 if ((unit->hci_flags & BTF_INIT_FEATURES) == 0) 1081 if ((unit->hci_flags & BTF_INIT_FEATURES) == 0)
1040 return; 1082 return;
1041 1083
1042 DPRINTFN(1, "%s: page %d of %d\n", device_xname(unit->hci_dev), 1084 DPRINTFN(1, "%s: page %d of %d\n", device_xname(unit->hci_dev),
1043 rp.page, rp.max_page); 1085 rp.page, rp.max_page);
1044 1086
1045 switch (rp.page) { 1087 switch (rp.page) {
@@ -1066,54 +1108,58 @@ hci_cmd_read_local_extended_features(str @@ -1066,54 +1108,58 @@ hci_cmd_read_local_extended_features(str
1066 cv_broadcast(&unit->hci_init); 1108 cv_broadcast(&unit->hci_init);
1067} 1109}
1068 1110
1069/* 1111/*
1070 * process results of read_local_ver command_complete event 1112 * process results of read_local_ver command_complete event
1071 * 1113 *
1072 * reading local supported commands is only supported from 1.2 spec 1114 * reading local supported commands is only supported from 1.2 spec
1073 */ 1115 */
1074static void 1116static void
1075hci_cmd_read_local_ver(struct hci_unit *unit, struct mbuf *m) 1117hci_cmd_read_local_ver(struct hci_unit *unit, struct mbuf *m)
1076{ 1118{
1077 hci_read_local_ver_rp rp; 1119 hci_read_local_ver_rp rp;
1078 1120
1079 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 1121 if (m->m_pkthdr.len < sizeof(rp))
 1122 return;
 1123
1080 m_copydata(m, 0, sizeof(rp), &rp); 1124 m_copydata(m, 0, sizeof(rp), &rp);
1081 m_adj(m, sizeof(rp)); 1125 m_adj(m, sizeof(rp));
1082 1126
1083 if (rp.status != 0) 1127 if (rp.status != 0)
1084 return; 1128 return;
1085 1129
1086 if ((unit->hci_flags & BTF_INIT_COMMANDS) == 0) 1130 if ((unit->hci_flags & BTF_INIT_COMMANDS) == 0)
1087 return; 1131 return;
1088 1132
1089 if (rp.hci_version < HCI_SPEC_V12) { 1133 if (rp.hci_version < HCI_SPEC_V12) {
1090 unit->hci_flags &= ~BTF_INIT_COMMANDS; 1134 unit->hci_flags &= ~BTF_INIT_COMMANDS;
1091 cv_broadcast(&unit->hci_init); 1135 cv_broadcast(&unit->hci_init);
1092 return; 1136 return;
1093 } 1137 }
1094 1138
1095 hci_send_cmd(unit, HCI_CMD_READ_LOCAL_COMMANDS, NULL, 0); 1139 hci_send_cmd(unit, HCI_CMD_READ_LOCAL_COMMANDS, NULL, 0);
1096} 1140}
1097 1141
1098/* 1142/*
1099 * process results of read_local_commands command_complete event 1143 * process results of read_local_commands command_complete event
1100 */ 1144 */
1101static void 1145static void
1102hci_cmd_read_local_commands(struct hci_unit *unit, struct mbuf *m) 1146hci_cmd_read_local_commands(struct hci_unit *unit, struct mbuf *m)
1103{ 1147{
1104 hci_read_local_commands_rp rp; 1148 hci_read_local_commands_rp rp;
1105 1149
1106 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 1150 if (m->m_pkthdr.len < sizeof(rp))
 1151 return;
 1152
1107 m_copydata(m, 0, sizeof(rp), &rp); 1153 m_copydata(m, 0, sizeof(rp), &rp);
1108 m_adj(m, sizeof(rp)); 1154 m_adj(m, sizeof(rp));
1109 1155
1110 if (rp.status != 0) 1156 if (rp.status != 0)
1111 return; 1157 return;
1112 1158
1113 if ((unit->hci_flags & BTF_INIT_COMMANDS) == 0) 1159 if ((unit->hci_flags & BTF_INIT_COMMANDS) == 0)
1114 return; 1160 return;
1115 1161
1116 unit->hci_flags &= ~BTF_INIT_COMMANDS; 1162 unit->hci_flags &= ~BTF_INIT_COMMANDS;
1117 memcpy(unit->hci_cmds, rp.commands, HCI_COMMANDS_SIZE); 1163 memcpy(unit->hci_cmds, rp.commands, HCI_COMMANDS_SIZE);
1118 1164
1119 cv_broadcast(&unit->hci_init); 1165 cv_broadcast(&unit->hci_init);
@@ -1122,27 +1168,29 @@ hci_cmd_read_local_commands(struct hci_u @@ -1122,27 +1168,29 @@ hci_cmd_read_local_commands(struct hci_u
1122/* 1168/*
1123 * process results of reset command_complete event 1169 * process results of reset command_complete event
1124 * 1170 *
1125 * This has killed all the connections, so close down anything we have left, 1171 * This has killed all the connections, so close down anything we have left,
1126 * and reinitialise the unit. 1172 * and reinitialise the unit.
1127 */ 1173 */
1128static void 1174static void
1129hci_cmd_reset(struct hci_unit *unit, struct mbuf *m) 1175hci_cmd_reset(struct hci_unit *unit, struct mbuf *m)
1130{ 1176{
1131 hci_reset_rp rp; 1177 hci_reset_rp rp;
1132 struct hci_link *link, *next; 1178 struct hci_link *link, *next;
1133 int acl; 1179 int acl;
1134 1180
1135 KASSERT(m->m_pkthdr.len >= sizeof(rp)); 1181 if (m->m_pkthdr.len < sizeof(rp))
 1182 return;
 1183
1136 m_copydata(m, 0, sizeof(rp), &rp); 1184 m_copydata(m, 0, sizeof(rp), &rp);
1137 m_adj(m, sizeof(rp)); 1185 m_adj(m, sizeof(rp));
1138 1186
1139 if (rp.status != 0) 1187 if (rp.status != 0)
1140 return; 1188 return;
1141 1189
1142 /* 1190 /*
1143 * release SCO links first, since they may be holding 1191 * release SCO links first, since they may be holding
1144 * an ACL link reference. 1192 * an ACL link reference.
1145 */ 1193 */
1146 for (acl = 0 ; acl < 2 ; acl++) { 1194 for (acl = 0 ; acl < 2 ; acl++) {
1147 next = TAILQ_FIRST(&unit->hci_links); 1195 next = TAILQ_FIRST(&unit->hci_links);
1148 while ((link = next) != NULL) { 1196 while ((link = next) != NULL) {

cvs diff -r1.22 -r1.23 src/sys/netbt/hci_link.c (expand / switch to unified diff)

--- src/sys/netbt/hci_link.c 2010/10/14 07:05:03 1.22
+++ src/sys/netbt/hci_link.c 2011/07/27 10:25:09 1.23
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: hci_link.c,v 1.22 2010/10/14 07:05:03 plunky Exp $ */ 1/* $NetBSD: hci_link.c,v 1.23 2011/07/27 10:25:09 plunky Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2005 Iain Hibbert. 4 * Copyright (c) 2005 Iain Hibbert.
5 * Copyright (c) 2006 Itronix Inc. 5 * Copyright (c) 2006 Itronix Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN 27 * ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.22 2010/10/14 07:05:03 plunky Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.23 2011/07/27 10:25:09 plunky Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/malloc.h> 38#include <sys/malloc.h>
39#include <sys/mbuf.h> 39#include <sys/mbuf.h>
40#include <sys/proc.h> 40#include <sys/proc.h>
41#include <sys/queue.h> 41#include <sys/queue.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43 43
44#include <netbt/bluetooth.h> 44#include <netbt/bluetooth.h>
45#include <netbt/hci.h> 45#include <netbt/hci.h>
46#include <netbt/l2cap.h> 46#include <netbt/l2cap.h>
47#include <netbt/sco.h> 47#include <netbt/sco.h>
@@ -422,49 +422,42 @@ hci_acl_linkmode(struct hci_link *link) @@ -422,49 +422,42 @@ hci_acl_linkmode(struct hci_link *link)
422 * until a full L2CAP frame is ready, then send it on. 422 * until a full L2CAP frame is ready, then send it on.
423 */ 423 */
424void 424void
425hci_acl_recv(struct mbuf *m, struct hci_unit *unit) 425hci_acl_recv(struct mbuf *m, struct hci_unit *unit)
426{ 426{
427 struct hci_link *link; 427 struct hci_link *link;
428 hci_acldata_hdr_t hdr; 428 hci_acldata_hdr_t hdr;
429 uint16_t handle, want; 429 uint16_t handle, want;
430 int pb, got; 430 int pb, got;
431 431
432 KASSERT(m != NULL); 432 KASSERT(m != NULL);
433 KASSERT(unit != NULL); 433 KASSERT(unit != NULL);
434 434
435 KASSERT(m->m_pkthdr.len >= sizeof(hdr)); 435 if (m->m_pkthdr.len < sizeof(hdr))
 436 goto bad;
 437
436 m_copydata(m, 0, sizeof(hdr), &hdr); 438 m_copydata(m, 0, sizeof(hdr), &hdr);
437 m_adj(m, sizeof(hdr)); 439 m_adj(m, sizeof(hdr));
438 440
439#ifdef DIAGNOSTIC 441 KASSERT(hdr.type == HCI_ACL_DATA_PKT);
440 if (hdr.type != HCI_ACL_DATA_PKT) { 
441 aprint_error_dev(unit->hci_dev, "bad ACL packet type\n"); 
442 goto bad; 
443 } 
444 
445 if (m->m_pkthdr.len != le16toh(hdr.length)) { 
446 aprint_error_dev(unit->hci_dev, 
447 "bad ACL packet length (%d != %d)\n", 
448 m->m_pkthdr.len, le16toh(hdr.length)); 
449 goto bad; 
450 } 
451#endif 
452 442
453 hdr.length = le16toh(hdr.length); 443 hdr.length = le16toh(hdr.length);
454 hdr.con_handle = le16toh(hdr.con_handle); 444 hdr.con_handle = le16toh(hdr.con_handle);
455 handle = HCI_CON_HANDLE(hdr.con_handle); 445 handle = HCI_CON_HANDLE(hdr.con_handle);
456 pb = HCI_PB_FLAG(hdr.con_handle); 446 pb = HCI_PB_FLAG(hdr.con_handle);
457 447
 448 if (m->m_pkthdr.len != hdr.length)
 449 goto bad;
 450
458 link = hci_link_lookup_handle(unit, handle); 451 link = hci_link_lookup_handle(unit, handle);
459 if (link == NULL) { 452 if (link == NULL) {
460 hci_discon_cp cp; 453 hci_discon_cp cp;
461 454
462 DPRINTF("%s: dumping packet for unknown handle #%d\n", 455 DPRINTF("%s: dumping packet for unknown handle #%d\n",
463 device_xname(unit->hci_dev), handle); 456 device_xname(unit->hci_dev), handle);
464 457
465 /* 458 /*
466 * There is no way to find out what this connection handle is 459 * There is no way to find out what this connection handle is
467 * for, just get rid of it. This may happen, if a USB dongle 460 * for, just get rid of it. This may happen, if a USB dongle
468 * is plugged into a self powered hub and does not reset when 461 * is plugged into a self powered hub and does not reset when
469 * the system is shut down. 462 * the system is shut down.
470 * 463 *
@@ -476,51 +469,51 @@ hci_acl_recv(struct mbuf *m, struct hci_ @@ -476,51 +469,51 @@ hci_acl_recv(struct mbuf *m, struct hci_
476 cp.con_handle = htole16(handle); 469 cp.con_handle = htole16(handle);
477 cp.reason = 0x13;/*"Remote User Terminated Connection"*/ 470 cp.reason = 0x13;/*"Remote User Terminated Connection"*/
478 hci_send_cmd(unit, HCI_CMD_DISCONNECT, &cp, sizeof(cp)); 471 hci_send_cmd(unit, HCI_CMD_DISCONNECT, &cp, sizeof(cp));
479 } 472 }
480 goto bad; 473 goto bad;
481 } 474 }
482 475
483 switch (pb) { 476 switch (pb) {
484 case HCI_PACKET_START: 477 case HCI_PACKET_START:
485 if (link->hl_rxp != NULL) 478 if (link->hl_rxp != NULL)
486 aprint_error_dev(unit->hci_dev, 479 aprint_error_dev(unit->hci_dev,
487 "dropped incomplete ACL packet\n"); 480 "dropped incomplete ACL packet\n");
488 481
489 if (m->m_pkthdr.len < sizeof(l2cap_hdr_t)) { 482 if (m->m_pkthdr.len < sizeof(l2cap_hdr_t))
490 aprint_error_dev(unit->hci_dev, "short ACL packet\n"); 
491 goto bad; 483 goto bad;
492 } 
493 484
494 link->hl_rxp = m; 485 link->hl_rxp = m;
495 got = m->m_pkthdr.len; 486 got = m->m_pkthdr.len;
496 break; 487 break;
497 488
498 case HCI_PACKET_FRAGMENT: 489 case HCI_PACKET_FRAGMENT:
499 if (link->hl_rxp == NULL) { 490 if (link->hl_rxp == NULL) {
500 aprint_error_dev(unit->hci_dev, 491 aprint_error_dev(unit->hci_dev,
501 "unexpected packet fragment\n"); 492 "unexpected packet fragment\n");
502 493
503 goto bad; 494 goto bad;
504 } 495 }
505 496
506 got = m->m_pkthdr.len + link->hl_rxp->m_pkthdr.len; 497 got = m->m_pkthdr.len + link->hl_rxp->m_pkthdr.len;
507 m_cat(link->hl_rxp, m); 498 m_cat(link->hl_rxp, m);
508 m = link->hl_rxp; 499 m = link->hl_rxp;
509 m->m_pkthdr.len = got; 500 m->m_pkthdr.len = got;
510 break; 501 break;
511 502
512 default: 503 default:
513 aprint_error_dev(unit->hci_dev, "unknown packet type\n"); 504 DPRINTF("%s: unknown packet type\n",
 505 device_xname(unit->hci_dev));
 506
514 goto bad; 507 goto bad;
515 } 508 }
516 509
517 m_copydata(m, 0, sizeof(want), &want); 510 m_copydata(m, 0, sizeof(want), &want);
518 want = le16toh(want) + sizeof(l2cap_hdr_t) - got; 511 want = le16toh(want) + sizeof(l2cap_hdr_t) - got;
519 512
520 if (want > 0) 513 if (want > 0)
521 return; 514 return;
522 515
523 link->hl_rxp = NULL; 516 link->hl_rxp = NULL;
524 517
525 if (want == 0) { 518 if (want == 0) {
526 l2cap_recv_frame(m, link); 519 l2cap_recv_frame(m, link);
@@ -827,48 +820,40 @@ hci_sco_newconn(struct hci_unit *unit, b @@ -827,48 +820,40 @@ hci_sco_newconn(struct hci_unit *unit, b
827 * receive SCO packet, we only need to strip the header and send 820 * receive SCO packet, we only need to strip the header and send
828 * it to the right handler 821 * it to the right handler
829 */ 822 */
830void 823void
831hci_sco_recv(struct mbuf *m, struct hci_unit *unit) 824hci_sco_recv(struct mbuf *m, struct hci_unit *unit)
832{ 825{
833 struct hci_link *link; 826 struct hci_link *link;
834 hci_scodata_hdr_t hdr; 827 hci_scodata_hdr_t hdr;
835 uint16_t handle; 828 uint16_t handle;
836 829
837 KASSERT(m != NULL); 830 KASSERT(m != NULL);
838 KASSERT(unit != NULL); 831 KASSERT(unit != NULL);
839 832
840 KASSERT(m->m_pkthdr.len >= sizeof(hdr)); 833 if (m->m_pkthdr.len < sizeof(hdr))
841 m_copydata(m, 0, sizeof(hdr), &hdr); 
842 m_adj(m, sizeof(hdr)); 
843 
844#ifdef DIAGNOSTIC 
845 if (hdr.type != HCI_SCO_DATA_PKT) { 
846 aprint_error_dev(unit->hci_dev, "bad SCO packet type\n"); 
847 goto bad; 834 goto bad;
848 } 
849 835
850 if (m->m_pkthdr.len != hdr.length) { 836 m_copydata(m, 0, sizeof(hdr), &hdr);
851 aprint_error_dev(unit->hci_dev, 837 m_adj(m, sizeof(hdr));
852 "bad SCO packet length (%d != %d)\n", 
853 m->m_pkthdr.len, hdr.length); 
854 838
855 goto bad; 839 KASSERT(hdr.type == HCI_SCO_DATA_PKT);
856 } 
857#endif 
858 840
859 hdr.con_handle = le16toh(hdr.con_handle); 841 hdr.con_handle = le16toh(hdr.con_handle);
860 handle = HCI_CON_HANDLE(hdr.con_handle); 842 handle = HCI_CON_HANDLE(hdr.con_handle);
861 843
 844 if (m->m_pkthdr.len != hdr.length)
 845 goto bad;
 846
862 link = hci_link_lookup_handle(unit, handle); 847 link = hci_link_lookup_handle(unit, handle);
863 if (link == NULL || link->hl_type == HCI_LINK_ACL) { 848 if (link == NULL || link->hl_type == HCI_LINK_ACL) {
864 DPRINTF("%s: dumping packet for unknown handle #%d\n", 849 DPRINTF("%s: dumping packet for unknown handle #%d\n",
865 device_xname(unit->hci_dev), handle); 850 device_xname(unit->hci_dev), handle);
866 851
867 goto bad; 852 goto bad;
868 } 853 }
869 854
870 (*link->hl_sco->sp_proto->input)(link->hl_sco->sp_upper, m); 855 (*link->hl_sco->sp_proto->input)(link->hl_sco->sp_upper, m);
871 return; 856 return;
872 857
873bad: 858bad:
874 m_freem(m); 859 m_freem(m);

cvs diff -r1.13 -r1.14 src/sys/netbt/l2cap_signal.c (expand / switch to unified diff)

--- src/sys/netbt/l2cap_signal.c 2011/07/17 20:54:53 1.13
+++ src/sys/netbt/l2cap_signal.c 2011/07/27 10:25:09 1.14
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: l2cap_signal.c,v 1.13 2011/07/17 20:54:53 joerg Exp $ */ 1/* $NetBSD: l2cap_signal.c,v 1.14 2011/07/27 10:25:09 plunky Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2005 Iain Hibbert. 4 * Copyright (c) 2005 Iain Hibbert.
5 * Copyright (c) 2006 Itronix Inc. 5 * Copyright (c) 2006 Itronix Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN 27 * ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: l2cap_signal.c,v 1.13 2011/07/17 20:54:53 joerg Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: l2cap_signal.c,v 1.14 2011/07/27 10:25:09 plunky Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/mbuf.h> 38#include <sys/mbuf.h>
39#include <sys/proc.h> 39#include <sys/proc.h>
40#include <sys/queue.h> 40#include <sys/queue.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42 42
43#include <netbt/bluetooth.h> 43#include <netbt/bluetooth.h>
44#include <netbt/hci.h> 44#include <netbt/hci.h>
45#include <netbt/l2cap.h> 45#include <netbt/l2cap.h>
46 46
47/******************************************************************************* 47/*******************************************************************************
@@ -145,30 +145,27 @@ l2cap_recv_signal(struct mbuf *m, struct @@ -145,30 +145,27 @@ l2cap_recv_signal(struct mbuf *m, struct
145 goto reject; 145 goto reject;
146 146
147 l2cap_recv_info_req(m, link); 147 l2cap_recv_info_req(m, link);
148 break; 148 break;
149 149
150 case L2CAP_INFO_RSP: 150 case L2CAP_INFO_RSP:
151 m_adj(m, sizeof(cmd) + cmd.length); 151 m_adj(m, sizeof(cmd) + cmd.length);
152 break; 152 break;
153 153
154 default: 154 default:
155 goto reject; 155 goto reject;
156 } 156 }
157 } 157 }
158 
159#ifdef DIAGNOSTIC 
160 panic("impossible!"); 158 panic("impossible!");
161#endif 
162 159
163reject: 160reject:
164 l2cap_send_command_rej(link, cmd.ident, L2CAP_REJ_NOT_UNDERSTOOD); 161 l2cap_send_command_rej(link, cmd.ident, L2CAP_REJ_NOT_UNDERSTOOD);
165finish: 162finish:
166 m_freem(m); 163 m_freem(m);
167} 164}
168 165
169/* 166/*
170 * Process Received Command Reject. For now we dont try to recover gracefully 167 * Process Received Command Reject. For now we dont try to recover gracefully
171 * from this, it probably means that the link is garbled or the other end is 168 * from this, it probably means that the link is garbled or the other end is
172 * insufficiently capable of handling normal traffic. (not *my* fault, no way!) 169 * insufficiently capable of handling normal traffic. (not *my* fault, no way!)
173 */ 170 */
174static void 171static void
@@ -920,34 +917,28 @@ l2cap_recv_info_req(struct mbuf *m, stru @@ -920,34 +917,28 @@ l2cap_recv_info_req(struct mbuf *m, stru
920} 917}
921 918
922/* 919/*
923 * Construct signal and wrap in C-Frame for link. 920 * Construct signal and wrap in C-Frame for link.
924 */ 921 */
925static int 922static int
926l2cap_send_signal(struct hci_link *link, uint8_t code, uint8_t ident, 923l2cap_send_signal(struct hci_link *link, uint8_t code, uint8_t ident,
927 uint16_t length, void *data) 924 uint16_t length, void *data)
928{ 925{
929 struct mbuf *m; 926 struct mbuf *m;
930 l2cap_hdr_t *hdr; 927 l2cap_hdr_t *hdr;
931 l2cap_cmd_hdr_t *cmd; 928 l2cap_cmd_hdr_t *cmd;
932 929
933#ifdef DIAGNOSTIC 930 KASSERT(link != NULL);
934 if (link == NULL) 931 KASSERT(sizeof(l2cap_cmd_hdr_t) + length <= link->hl_mtu);
935 return ENETDOWN; 
936 
937 if (sizeof(l2cap_cmd_hdr_t) + length > link->hl_mtu) 
938 aprint_error_dev(link->hl_unit->hci_dev, 
939 "exceeding L2CAP Signal MTU for link!\n"); 
940#endif 
941 932
942 m = m_gethdr(M_DONTWAIT, MT_DATA); 933 m = m_gethdr(M_DONTWAIT, MT_DATA);
943 if (m == NULL) 934 if (m == NULL)
944 return ENOMEM; 935 return ENOMEM;
945 936
946 hdr = mtod(m, l2cap_hdr_t *); 937 hdr = mtod(m, l2cap_hdr_t *);
947 cmd = (l2cap_cmd_hdr_t *)(hdr + 1); 938 cmd = (l2cap_cmd_hdr_t *)(hdr + 1);
948 939
949 m->m_len = m->m_pkthdr.len = MHLEN; 940 m->m_len = m->m_pkthdr.len = MHLEN;
950 941
951 /* Command Data */ 942 /* Command Data */
952 if (length > 0) 943 if (length > 0)
953 m_copyback(m, sizeof(*hdr) + sizeof(*cmd), length, data); 944 m_copyback(m, sizeof(*hdr) + sizeof(*cmd), length, data);

cvs diff -r1.17 -r1.18 src/sys/netbt/rfcomm_session.c (expand / switch to unified diff)

--- src/sys/netbt/rfcomm_session.c 2010/11/17 20:19:25 1.17
+++ src/sys/netbt/rfcomm_session.c 2011/07/27 10:25:09 1.18
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rfcomm_session.c,v 1.17 2010/11/17 20:19:25 plunky Exp $ */ 1/* $NetBSD: rfcomm_session.c,v 1.18 2011/07/27 10:25:09 plunky Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2006 Itronix Inc. 4 * Copyright (c) 2006 Itronix Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Iain Hibbert for Itronix Inc. 7 * Written by Iain Hibbert for Itronix Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN 28 * ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.17 2010/11/17 20:19:25 plunky Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.18 2011/07/27 10:25:09 plunky Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/kernel.h> 38#include <sys/kernel.h>
39#include <sys/mbuf.h> 39#include <sys/mbuf.h>
40#include <sys/proc.h> 40#include <sys/proc.h>
41#include <sys/socketvar.h> 41#include <sys/socketvar.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/types.h> 43#include <sys/types.h>
44 44
45#include <netbt/bluetooth.h> 45#include <netbt/bluetooth.h>
46#include <netbt/hci.h> 46#include <netbt/hci.h>
47#include <netbt/l2cap.h> 47#include <netbt/l2cap.h>
48#include <netbt/rfcomm.h> 48#include <netbt/rfcomm.h>
@@ -446,32 +446,31 @@ rfcomm_session_complete(void *arg, int c @@ -446,32 +446,31 @@ rfcomm_session_complete(void *arg, int c
446{ 446{
447 struct rfcomm_session *rs = arg; 447 struct rfcomm_session *rs = arg;
448 struct rfcomm_credit *credit; 448 struct rfcomm_credit *credit;
449 struct rfcomm_dlc *dlc; 449 struct rfcomm_dlc *dlc;
450 450
451 /* 451 /*
452 * count L2CAP packets are 'complete', meaning that they are cleared 452 * count L2CAP packets are 'complete', meaning that they are cleared
453 * our buffers (for best effort) or arrived safe (for guaranteed) so 453 * our buffers (for best effort) or arrived safe (for guaranteed) so
454 * we can take it off our list and pass the message on, so that 454 * we can take it off our list and pass the message on, so that
455 * eventually the data can be removed from the sockbuf 455 * eventually the data can be removed from the sockbuf
456 */ 456 */
457 while (count-- > 0) { 457 while (count-- > 0) {
458 credit = SIMPLEQ_FIRST(&rs->rs_credits); 458 credit = SIMPLEQ_FIRST(&rs->rs_credits);
459#ifdef DIAGNOSTIC 
460 if (credit == NULL) { 459 if (credit == NULL) {
461 printf("%s: too many packets completed!\n", __func__); 460 printf("%s: too many packets completed!\n", __func__);
462 break; 461 break;
463 } 462 }
464#endif 463
465 dlc = credit->rc_dlc; 464 dlc = credit->rc_dlc;
466 if (dlc != NULL) { 465 if (dlc != NULL) {
467 dlc->rd_pending--; 466 dlc->rd_pending--;
468 (*dlc->rd_proto->complete) 467 (*dlc->rd_proto->complete)
469 (dlc->rd_upper, credit->rc_len); 468 (dlc->rd_upper, credit->rc_len);
470 469
471 /* 470 /*
472 * if not using credit flow control, we may push 471 * if not using credit flow control, we may push
473 * more data now 472 * more data now
474 */ 473 */
475 if ((rs->rs_flags & RFCOMM_SESSION_CFC) == 0 474 if ((rs->rs_flags & RFCOMM_SESSION_CFC) == 0
476 && dlc->rd_state == RFCOMM_DLC_OPEN) { 475 && dlc->rd_state == RFCOMM_DLC_OPEN) {
477 rfcomm_dlc_start(dlc); 476 rfcomm_dlc_start(dlc);