summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2014-07-11 21:54:37 +0000
committertedu <tedu@openbsd.org>2014-07-11 21:54:37 +0000
commitb8042ed98e3e7a691133b4fd8e91f61ba15a83ba (patch)
treeb4210de9bc12a180e816fe8ce2bb3606f14cb4f4
parentsync (diff)
downloadwireguard-openbsd-b8042ed98e3e7a691133b4fd8e91f61ba15a83ba.tar.xz
wireguard-openbsd-b8042ed98e3e7a691133b4fd8e91f61ba15a83ba.zip
"It's not the years, honey; it's the mileage."
bluetooth support doesn't work and isn't going anywhere. the current design is a dead end, and should not be the basis for any future support. general consensus says to whack it so as to not mislead the unwary.
-rw-r--r--sys/arch/alpha/conf/files.alpha7
-rw-r--r--sys/arch/amd64/conf/files.amd647
-rw-r--r--sys/arch/armish/conf/files.armish5
-rw-r--r--sys/arch/armv7/conf/files.armv75
-rw-r--r--sys/arch/hppa/conf/files.hppa7
-rw-r--r--sys/arch/hppa64/conf/files.hppa647
-rw-r--r--sys/arch/i386/conf/files.i3867
-rw-r--r--sys/arch/landisk/conf/files.landisk7
-rw-r--r--sys/arch/loongson/conf/files.loongson3
-rw-r--r--sys/arch/macppc/conf/files.macppc7
-rw-r--r--sys/arch/octeon/conf/files.octeon3
-rw-r--r--sys/arch/socppc/conf/files.socppc7
-rw-r--r--sys/arch/sparc64/conf/files.sparc647
-rw-r--r--sys/arch/zaurus/conf/files.zaurus4
-rw-r--r--sys/conf/files22
-rw-r--r--sys/dev/bluetooth/btdev.h112
-rw-r--r--sys/dev/bluetooth/bthid.h90
-rw-r--r--sys/dev/bluetooth/bthidev.c903
-rw-r--r--sys/dev/bluetooth/bthidev.h79
-rw-r--r--sys/dev/bluetooth/bthub.c241
-rw-r--r--sys/dev/bluetooth/btkbd.c225
-rw-r--r--sys/dev/bluetooth/btms.c205
-rw-r--r--sys/dev/bluetooth/btsco.c1224
-rw-r--r--sys/dev/bluetooth/btsco.h61
-rw-r--r--sys/dev/bluetooth/files.bluetooth32
-rw-r--r--sys/dev/sdmmc/files.sdmmc7
-rw-r--r--sys/dev/sdmmc/sbt.c582
-rw-r--r--sys/dev/usb/files.usb7
-rw-r--r--sys/dev/usb/ubt.c1586
-rw-r--r--sys/kern/uipc_domain.c6
-rw-r--r--sys/net/if.c3
-rw-r--r--sys/net/netisr.c6
-rw-r--r--sys/netbt/bluetooth.h167
-rw-r--r--sys/netbt/bt_input.c34
-rw-r--r--sys/netbt/bt_proto.c86
-rw-r--r--sys/netbt/bt_var.h21
-rw-r--r--sys/netbt/hci.h2582
-rw-r--r--sys/netbt/hci_event.c1112
-rw-r--r--sys/netbt/hci_ioctl.c298
-rw-r--r--sys/netbt/hci_link.c1047
-rw-r--r--sys/netbt/hci_misc.c181
-rw-r--r--sys/netbt/hci_socket.c946
-rw-r--r--sys/netbt/hci_unit.c592
-rw-r--r--sys/netbt/l2cap.h490
-rw-r--r--sys/netbt/l2cap_lower.c203
-rw-r--r--sys/netbt/l2cap_misc.c262
-rw-r--r--sys/netbt/l2cap_signal.c1152
-rw-r--r--sys/netbt/l2cap_socket.c405
-rw-r--r--sys/netbt/l2cap_upper.c517
-rw-r--r--sys/netbt/rfcomm.h427
-rw-r--r--sys/netbt/rfcomm_dlc.c410
-rw-r--r--sys/netbt/rfcomm_session.c1686
-rw-r--r--sys/netbt/rfcomm_socket.c420
-rw-r--r--sys/netbt/rfcomm_upper.c524
-rw-r--r--sys/netbt/sco.h86
-rw-r--r--sys/netbt/sco_socket.c378
-rw-r--r--sys/netbt/sco_upper.c354
57 files changed, 19 insertions, 19835 deletions
diff --git a/sys/arch/alpha/conf/files.alpha b/sys/arch/alpha/conf/files.alpha
index 7182b685a10..306add1ac68 100644
--- a/sys/arch/alpha/conf/files.alpha
+++ b/sys/arch/alpha/conf/files.alpha
@@ -1,4 +1,4 @@
-# $OpenBSD: files.alpha,v 1.98 2014/01/26 17:40:11 miod Exp $
+# $OpenBSD: files.alpha,v 1.99 2014/07/11 21:54:37 tedu Exp $
# $NetBSD: files.alpha,v 1.32 1996/11/25 04:03:21 cgd Exp $
#
# alpha-specific configuration info
@@ -352,11 +352,6 @@ include "dev/i2c/files.i2c"
include "dev/usb/files.usb"
#
-# Bluetooth
-#
-include "dev/bluetooth/files.bluetooth"
-
-#
# Machine-independent 1-Wire drivers
#
include "dev/onewire/files.onewire"
diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64
index f283f4c50fc..e1cd6fa6d6b 100644
--- a/sys/arch/amd64/conf/files.amd64
+++ b/sys/arch/amd64/conf/files.amd64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.amd64,v 1.73 2013/12/19 21:30:02 deraadt Exp $
+# $OpenBSD: files.amd64,v 1.74 2014/07/11 21:54:37 tedu Exp $
maxpartitions 16
maxusers 2 16 128
@@ -205,11 +205,6 @@ file arch/amd64/amd64/nvram.c nvram needs-flag
include "dev/usb/files.usb"
#
-# Bluetooth
-#
-include "dev/bluetooth/files.bluetooth"
-
-#
# I2C
#
include "dev/i2c/files.i2c"
diff --git a/sys/arch/armish/conf/files.armish b/sys/arch/armish/conf/files.armish
index 186f47d5a31..539fd8f1a5d 100644
--- a/sys/arch/armish/conf/files.armish
+++ b/sys/arch/armish/conf/files.armish
@@ -1,4 +1,4 @@
-# $OpenBSD: files.armish,v 1.16 2013/11/04 14:07:15 deraadt Exp $
+# $OpenBSD: files.armish,v 1.17 2014/07/11 21:54:37 tedu Exp $
maxpartitions 16
maxusers 2 8 64
@@ -57,9 +57,6 @@ include "dev/rasops/files.rasops"
# Include USB stuff
include "dev/usb/files.usb"
-# Bluetooth
-include "dev/bluetooth/files.bluetooth"
-
# Media Independent Interface (mii)
include "dev/mii/files.mii"
diff --git a/sys/arch/armv7/conf/files.armv7 b/sys/arch/armv7/conf/files.armv7
index b379a4bebe7..acdea23b479 100644
--- a/sys/arch/armv7/conf/files.armv7
+++ b/sys/arch/armv7/conf/files.armv7
@@ -1,4 +1,4 @@
-# $OpenBSD: files.armv7,v 1.9 2013/11/06 19:03:07 syl Exp $
+# $OpenBSD: files.armv7,v 1.10 2014/07/11 21:54:37 tedu Exp $
maxpartitions 16
maxusers 2 8 64
@@ -49,9 +49,6 @@ include "dev/wsfont/files.wsfont"
# Include USB stuff
include "dev/usb/files.usb"
-# Bluetooth
-include "dev/bluetooth/files.bluetooth"
-
# Machine-independent GPIO drivers
include "dev/gpio/files.gpio"
diff --git a/sys/arch/hppa/conf/files.hppa b/sys/arch/hppa/conf/files.hppa
index cf2f13bc9aa..041bb7b97e8 100644
--- a/sys/arch/hppa/conf/files.hppa
+++ b/sys/arch/hppa/conf/files.hppa
@@ -1,4 +1,4 @@
-# $OpenBSD: files.hppa,v 1.91 2013/11/04 14:07:16 deraadt Exp $
+# $OpenBSD: files.hppa,v 1.92 2014/07/11 21:54:37 tedu Exp $
#
# hppa-specific configuration info
@@ -73,11 +73,6 @@ include "dev/pcmcia/files.pcmcia"
include "dev/usb/files.usb"
#
-# Bluetooth
-#
-include "dev/bluetooth/files.bluetooth"
-
-#
# HIL Human Interface Loop devices
#
include "dev/hil/files.hil"
diff --git a/sys/arch/hppa64/conf/files.hppa64 b/sys/arch/hppa64/conf/files.hppa64
index 14093cb1a41..a3454a97b04 100644
--- a/sys/arch/hppa64/conf/files.hppa64
+++ b/sys/arch/hppa64/conf/files.hppa64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.hppa64,v 1.17 2013/11/04 14:07:16 deraadt Exp $
+# $OpenBSD: files.hppa64,v 1.18 2014/07/11 21:54:37 tedu Exp $
#
# hppa64-specific configuration info
@@ -53,11 +53,6 @@ include "dev/pcmcia/files.pcmcia"
include "dev/usb/files.usb"
#
-# Bluetooth
-#
-include "dev/bluetooth/files.bluetooth"
-
-#
# Machine-independent 1-Wire drivers
#
include "dev/onewire/files.onewire"
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386
index 2f234fa0bc5..164bcf6081b 100644
--- a/sys/arch/i386/conf/files.i386
+++ b/sys/arch/i386/conf/files.i386
@@ -1,4 +1,4 @@
-# $OpenBSD: files.i386,v 1.216 2013/12/19 21:30:02 deraadt Exp $
+# $OpenBSD: files.i386,v 1.217 2014/07/11 21:54:37 tedu Exp $
#
# new style config file for i386 architecture
#
@@ -389,11 +389,6 @@ include "dev/onewire/files.onewire"
#
include "dev/sdmmc/files.sdmmc"
-#
-# Machine-independent Bluetooth drivers
-#
-include "dev/bluetooth/files.bluetooth"
-
include "dev/acpi/files.acpi"
file arch/i386/i386/acpi_machdep.c acpi
file arch/i386/i386/acpi_wakecode.S acpi & !small_kernel
diff --git a/sys/arch/landisk/conf/files.landisk b/sys/arch/landisk/conf/files.landisk
index 39f7754d9b8..dc862dfff19 100644
--- a/sys/arch/landisk/conf/files.landisk
+++ b/sys/arch/landisk/conf/files.landisk
@@ -1,4 +1,4 @@
-# $OpenBSD: files.landisk,v 1.9 2013/11/04 14:07:16 deraadt Exp $
+# $OpenBSD: files.landisk,v 1.10 2014/07/11 21:54:37 tedu Exp $
# $NetBSD: files.landisk,v 1.2 2006/09/07 01:55:02 uwe Exp $
# maxpartitions must be first item in files.${MACHINE}
@@ -66,11 +66,6 @@ include "dev/rasops/files.rasops"
include "dev/usb/files.usb"
#
-# Bluetooth
-#
-include "dev/bluetooth/files.bluetooth"
-
-#
# SH bus
#
include "arch/sh/conf/files.shb"
diff --git a/sys/arch/loongson/conf/files.loongson b/sys/arch/loongson/conf/files.loongson
index 46b668181c5..aca9bbb9611 100644
--- a/sys/arch/loongson/conf/files.loongson
+++ b/sys/arch/loongson/conf/files.loongson
@@ -1,4 +1,4 @@
-# $OpenBSD: files.loongson,v 1.17 2013/11/04 14:07:16 deraadt Exp $
+# $OpenBSD: files.loongson,v 1.18 2014/07/11 21:54:37 tedu Exp $
# Standard stanzas config(8) can't run without
maxpartitions 16
@@ -40,7 +40,6 @@ include "dev/mii/files.mii"
include "dev/pci/files.pci"
include "dev/pckbc/files.pckbc"
include "dev/usb/files.usb"
-include "dev/bluetooth/files.bluetooth"
include "dev/rasops/files.rasops"
include "dev/wscons/files.wscons"
include "dev/wsfont/files.wsfont"
diff --git a/sys/arch/macppc/conf/files.macppc b/sys/arch/macppc/conf/files.macppc
index 4cc93ec16e5..8ebb630cb96 100644
--- a/sys/arch/macppc/conf/files.macppc
+++ b/sys/arch/macppc/conf/files.macppc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.macppc,v 1.77 2013/11/04 14:07:16 deraadt Exp $
+# $OpenBSD: files.macppc,v 1.78 2014/07/11 21:54:37 tedu Exp $
#
# macppc-specific configuration info
@@ -270,11 +270,6 @@ include "dev/pcmcia/files.pcmcia"
include "dev/usb/files.usb"
#
-# Bluetooth
-#
-include "dev/bluetooth/files.bluetooth"
-
-#
# Machine-independent I2C drivers
#
include "dev/i2c/files.i2c"
diff --git a/sys/arch/octeon/conf/files.octeon b/sys/arch/octeon/conf/files.octeon
index 13de7f1a01d..d8b9ea68b5c 100644
--- a/sys/arch/octeon/conf/files.octeon
+++ b/sys/arch/octeon/conf/files.octeon
@@ -1,4 +1,4 @@
-# $OpenBSD: files.octeon,v 1.18 2014/07/09 23:03:22 pirofti Exp $
+# $OpenBSD: files.octeon,v 1.19 2014/07/11 21:54:38 tedu Exp $
# Standard stanzas config(8) can't run without
maxpartitions 16
@@ -31,7 +31,6 @@ include "dev/mii/files.mii"
include "dev/pci/files.pci"
include "dev/pckbc/files.pckbc"
include "dev/usb/files.usb"
-include "dev/bluetooth/files.bluetooth"
include "dev/rasops/files.rasops"
include "dev/wscons/files.wscons"
include "dev/wsfont/files.wsfont"
diff --git a/sys/arch/socppc/conf/files.socppc b/sys/arch/socppc/conf/files.socppc
index 6b462634a1e..b4a5739331a 100644
--- a/sys/arch/socppc/conf/files.socppc
+++ b/sys/arch/socppc/conf/files.socppc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.socppc,v 1.11 2013/11/04 14:07:16 deraadt Exp $
+# $OpenBSD: files.socppc,v 1.12 2014/07/11 21:54:38 tedu Exp $
#
# macppc-specific configuration info
@@ -101,11 +101,6 @@ attach ehci at obio with ehci_obio
file arch/socppc/dev/ehci_obio.c ehci
#
-# Bluetooth
-#
-include "dev/bluetooth/files.bluetooth"
-
-#
# Machine-independent I2C drivers
#
include "dev/i2c/files.i2c"
diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64
index 94f61781f63..bc0f1b287fc 100644
--- a/sys/arch/sparc64/conf/files.sparc64
+++ b/sys/arch/sparc64/conf/files.sparc64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc64,v 1.144 2013/11/04 14:07:16 deraadt Exp $
+# $OpenBSD: files.sparc64,v 1.145 2014/07/11 21:54:38 tedu Exp $
# $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $
# maxpartitions must be first item in files.${ARCH}
@@ -370,11 +370,6 @@ include "dev/sdmmc/files.sdmmc"
include "dev/usb/files.usb"
#
-# Bluetooth
-#
-include "dev/bluetooth/files.bluetooth"
-
-#
# Cardbus
#
include "dev/cardbus/files.cardbus"
diff --git a/sys/arch/zaurus/conf/files.zaurus b/sys/arch/zaurus/conf/files.zaurus
index d77cf92ce11..e58f21fb710 100644
--- a/sys/arch/zaurus/conf/files.zaurus
+++ b/sys/arch/zaurus/conf/files.zaurus
@@ -1,4 +1,4 @@
-# $OpenBSD: files.zaurus,v 1.28 2013/11/04 14:07:16 deraadt Exp $
+# $OpenBSD: files.zaurus,v 1.29 2014/07/11 21:54:38 tedu Exp $
#
# First try for arm-specific configuration info
#
@@ -100,8 +100,6 @@ include "dev/usb/files.usb"
attach pxaudc at pxaip with pxaudc_zaurus
file arch/zaurus/dev/zaurus_udc.c pxaudc_zaurus
-# Bluetooth
-include "dev/bluetooth/files.bluetooth"
# Media Independent Interface (mii)
include "dev/mii/files.mii"
diff --git a/sys/conf/files b/sys/conf/files
index e4771b9e4cb..ae98d65ba19 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.572 2014/04/19 12:27:06 henning Exp $
+# $OpenBSD: files,v 1.573 2014/07/11 21:54:38 tedu Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -67,7 +67,6 @@ define systrace
define ether
define sppp
define wlan
-define bluetooth
# "Chipset" attributes. These are the machine-independent portions
# of device drivers.
@@ -884,25 +883,6 @@ file crypto/hmac.c wlan | (softraid & crypto)
file crypto/gmac.c (inet & ipsec) | crypto
file crypto/key_wrap.c wlan
file crypto/idgen.c inet6 | nfsclient | nfsserver
-file netbt/bt_input.c bluetooth needs-flag
-file netbt/bt_proto.c bluetooth
-file netbt/hci_event.c bluetooth
-file netbt/hci_ioctl.c bluetooth
-file netbt/hci_link.c bluetooth
-file netbt/hci_misc.c bluetooth
-file netbt/hci_socket.c bluetooth
-file netbt/hci_unit.c bluetooth
-file netbt/l2cap_lower.c bluetooth
-file netbt/l2cap_misc.c bluetooth
-file netbt/l2cap_signal.c bluetooth
-file netbt/l2cap_socket.c bluetooth
-file netbt/l2cap_upper.c bluetooth
-file netbt/rfcomm_dlc.c bluetooth
-file netbt/rfcomm_session.c bluetooth
-file netbt/rfcomm_socket.c bluetooth
-file netbt/rfcomm_upper.c bluetooth
-file netbt/sco_socket.c bluetooth
-file netbt/sco_upper.c bluetooth
file netmpls/mpls_input.c mpls
file netmpls/mpls_output.c mpls
file netmpls/mpls_proto.c mpls
diff --git a/sys/dev/bluetooth/btdev.h b/sys/dev/bluetooth/btdev.h
deleted file mode 100644
index a559f30921f..00000000000
--- a/sys/dev/bluetooth/btdev.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* $OpenBSD: btdev.h,v 1.5 2008/11/24 23:54:03 uwe Exp $ */
-/* $NetBSD: btdev.h,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DEV_BLUETOOTH_BTDEV_H_
-#define _DEV_BLUETOOTH_BTDEV_H_
-
-#include <netbt/bluetooth.h>
-
-/*
- * Bluetooth Device attach arguments (from userland)
- */
-struct btdev_attach_args {
- bdaddr_t bd_laddr; /* local address */
- bdaddr_t bd_raddr; /* remote address */
- uint16_t bd_type; /* device type */
- int bd_mode; /* link mode */
-
- union {
- struct { /* HID arguments */
- uint16_t hid_flags;/* HID flags */
- uint16_t hid_ctl; /* control PSM */
- uint16_t hid_int; /* interrupt PSM */
- void *hid_desc; /* HID descriptor */
- uint16_t hid_dlen; /* descriptor length */
- } bdd_hid;
-
- struct { /* HSET arguments */
- uint8_t hset_channel; /* RFCOMM channel */
- uint8_t hset_mtu; /* SCO mtu */
- int hset_listen; /* connect or listen */
- } bdd_hset;
-
- struct { /* HF arguments */
- uint8_t hf_channel; /* RFCOMM channel */
- uint8_t hf_mtu; /* SCO mtu */
- int hf_listen; /* connect or listen */
- } bdd_hf;
- } bdd;
-};
-
-#define bd_hid bdd.bdd_hid
-#define bd_hset bdd.bdd_hset
-#define bd_hf bdd.bdd_hf
-
-/* btdev type */
-#define BTDEV_NONE 0x0000
-#define BTDEV_HID 0x0001
-#define BTDEV_HSET 0x0002
-#define BTDEV_HF 0x0003
-
-/* btdev link mode */
-#define BTDEV_MODE_NONE 0
-#define BTDEV_MODE_AUTH 1
-#define BTDEV_MODE_ENCRYPT 2
-#define BTDEV_MODE_SECURE 3
-
-/* bthid flags */
-#define BTHID_INITIATE (1 << 0) /* normally initiate */
-
-/* btdev attach/detach ioctl's */
-#define BTDEV_ATTACH _IOW('b', 14, struct btdev_attach_args)
-#define BTDEV_DETACH _IOW('b', 15, struct btdev_attach_args)
-
-#ifdef _KERNEL
-
-/*
- * Bluetooth device header
- */
-struct btdev {
- struct device sc_dev; /* system device */
- bdaddr_t sc_addr; /* device bdaddr */
- uint16_t sc_type; /* device type */
-
- LIST_ENTRY(btdev) sc_next;
-};
-
-#define btdev_name(d) (((struct btdev *)(d))->sc_dev.dv_xname)
-
-#endif /* _KERNEL */
-
-#endif /* _DEV_BLUETOOTH_BTDEV_H_ */
diff --git a/sys/dev/bluetooth/bthid.h b/sys/dev/bluetooth/bthid.h
deleted file mode 100644
index 0b0e2046280..00000000000
--- a/sys/dev/bluetooth/bthid.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* $OpenBSD: bthid.h,v 1.1 2007/07/27 16:52:24 gwk Exp $ */
-/* $NetBSD: bthid.h,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DEV_BLUETOOTH_BTHID_H_
-#define _DEV_BLUETOOTH_BTHID_H_
-
-/* Transaction Types */
-#define BTHID_HANDSHAKE 0x0
-#define BTHID_CONTROL 0x1
-#define BTHID_GET_REPORT 0x4
-#define BTHID_SET_REPORT 0x5
-#define BTHID_GET_PROTOCOL 0x6
-#define BTHID_SET_PROTOCOL 0x7
-#define BTHID_GET_IDLE 0x8
-#define BTHID_SET_IDLE 0x9
-#define BTHID_DATA 0xa
-#define BTHID_DATC 0xb
-
-#define BTHID_TYPE(b) (((b) & 0xf0) >> 4)
-
-/* HANDSHAKE Transaction Parameters */
-#define BTHID_HANDSHAKE_SUCCESS 0x0
-#define BTHID_HANDSHAKE_NOT_READY 0x1
-#define BTHID_HANDSHAKE_INVALID_ID 0x2
-#define BTHID_HANDSHAKE_UNSUPPORTED 0x3
-#define BTHID_HANDSHAKE_INVALID_PARAM 0x4
-#define BTHID_HANDSHAKE_UNKNOWN 0xe
-#define BTHID_HANDSHAKE_FATAL 0xf
-
-#define BTHID_HANDSHAKE_PARAM(b) ((b) & 0x0f)
-
-/* HID_CONTROL Transaction Parameters */
-#define BTHID_CONTROL_NOP 0x0
-#define BTHID_CONTROL_HARD_RESET 0x1
-#define BTHID_CONTROL_SOFT_RESET 0x2
-#define BTHID_CONTROL_SUSPEND 0x3
-#define BTHID_CONTROL_RESUME 0x4
-#define BTHID_CONTROL_UNPLUG 0x5
-
-#define BTHID_CONTROL_PARAM(b) ((b) & 0x0f)
-
-/* GET_REPORT Transaction Parameters */
-#define BTHID_CONTROL_SIZE 0x08
-
-/* GET_PROTOCOL Transaction Parameters */
-#define BTHID_PROTOCOL_REPORT 0
-#define BTHID_PROTOCOL_BOOT 1
-
-#define BTHID_PROTOCOL_PARAM(b) ((b) & 0x01)
-
-/* DATA, DATC Transaction Parameters */
-#define BTHID_DATA_OTHER 0
-#define BTHID_DATA_INPUT 1
-#define BTHID_DATA_OUTPUT 2
-#define BTHID_DATA_FEATURE 3
-
-#define BTHID_DATA_PARAM(b) ((b) & 0x03)
-
-#endif /* _DEV_BLUETOOTH_BTHID_H_ */
diff --git a/sys/dev/bluetooth/bthidev.c b/sys/dev/bluetooth/bthidev.c
deleted file mode 100644
index 11b3b277a6e..00000000000
--- a/sys/dev/bluetooth/bthidev.c
+++ /dev/null
@@ -1,903 +0,0 @@
-/* $OpenBSD: bthidev.c,v 1.9 2011/06/17 07:06:46 mk Exp $ */
-/* $NetBSD: bthidev.c,v 1.16 2008/08/06 15:01:23 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/device.h>
-#include <sys/fcntl.h>
-#include <sys/kernel.h>
-#include <sys/queue.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/l2cap.h>
-
-#include <dev/usb/hid.h>
-#include <dev/bluetooth/btdev.h>
-#include <dev/bluetooth/bthid.h>
-#include <dev/bluetooth/bthidev.h>
-
-#define MAX_DESCRIPTOR_LEN 1024 /* sanity check */
-
-/* bthidev softc */
-struct bthidev_softc {
- struct btdev sc_btdev; /* base device */
- uint16_t sc_state;
- uint16_t sc_flags;
-
- bdaddr_t sc_laddr; /* local address */
- bdaddr_t sc_raddr; /* remote address */
- int sc_mode; /* link mode */
- void *sc_desc; /* HID descriptor */
- int sc_dlen; /* descriptor length */
-
- uint16_t sc_ctlpsm; /* control PSM */
- struct l2cap_channel *sc_ctl; /* control channel */
- struct l2cap_channel *sc_ctl_l; /* control listen */
-
- uint16_t sc_intpsm; /* interrupt PSM */
- struct l2cap_channel *sc_int; /* interrupt channel */
- struct l2cap_channel *sc_int_l; /* interrupt listen */
-
- LIST_HEAD(,bthidev) sc_list; /* child list */
-
- struct timeout sc_reconnect;
- int sc_attempts; /* connection attempts */
-};
-
-/* sc_flags */
-#define BTHID_RECONNECT (1 << 0) /* reconnect on link loss */
-#define BTHID_CONNECTING (1 << 1) /* we are connecting */
-
-/* device state */
-#define BTHID_CLOSED 0
-#define BTHID_WAIT_CTL 1
-#define BTHID_WAIT_INT 2
-#define BTHID_OPEN 3
-
-#define BTHID_RETRY_INTERVAL 5 /* seconds between connection attempts */
-
-/* bthidev internals */
-void bthidev_timeout(void *);
-int bthidev_listen(struct bthidev_softc *);
-int bthidev_connect(struct bthidev_softc *);
-int bthidev_output(struct bthidev *, uint8_t *, int, int);
-void bthidev_null(struct bthidev *, uint8_t *, int);
-
-/* autoconf(9) glue */
-int bthidev_match(struct device *, void *, void *);
-void bthidev_attach(struct device *, struct device *, void *);
-int bthidev_detach(struct device *, int);
-int bthidev_print(void *, const char *);
-
-int bthidevsubmatch(struct device *parent, void *, void *);
-
-struct cfdriver bthidev_cd = {
- NULL, "bthidev", DV_DULL
-};
-
-const struct cfattach bthidev_ca = {
- sizeof(struct bthidev_softc),
- bthidev_match,
- bthidev_attach,
- bthidev_detach,
-};
-
-/* bluetooth(9) protocol methods for L2CAP */
-void bthidev_connecting(void *);
-void bthidev_ctl_connected(void *);
-void bthidev_int_connected(void *);
-void bthidev_ctl_disconnected(void *, int);
-void bthidev_int_disconnected(void *, int);
-void *bthidev_ctl_newconn(void *, struct sockaddr_bt *,
- struct sockaddr_bt *);
-void *bthidev_int_newconn(void *, struct sockaddr_bt *,
- struct sockaddr_bt *);
-void bthidev_complete(void *, int);
-void bthidev_linkmode(void *, int);
-void bthidev_input(void *, struct mbuf *);
-
-const struct btproto bthidev_ctl_proto = {
- bthidev_connecting,
- bthidev_ctl_connected,
- bthidev_ctl_disconnected,
- bthidev_ctl_newconn,
- bthidev_complete,
- bthidev_linkmode,
- bthidev_input,
-};
-
-const struct btproto bthidev_int_proto = {
- bthidev_connecting,
- bthidev_int_connected,
- bthidev_int_disconnected,
- bthidev_int_newconn,
- bthidev_complete,
- bthidev_linkmode,
- bthidev_input,
-};
-
-/*****************************************************************************
- *
- * bthidev autoconf(9) routines
- */
-
-int
-bthidev_match(struct device *self, void *match, void *aux)
-{
- struct btdev_attach_args *bda = (struct btdev_attach_args *)aux;
-
- if (bda->bd_type != BTDEV_HID)
- return 0;
-
- return 1;
-}
-
-void
-bthidev_attach(struct device *parent, struct device *self, void *aux)
-{
- struct bthidev_softc *sc = (struct bthidev_softc *)self;
- struct btdev_attach_args *bda = (struct btdev_attach_args *)aux;
- struct bthidev_attach_args bha;
- struct bthidev *hidev;
- struct hid_data *d;
- struct hid_item h;
- int maxid, rep;
-
- /*
- * Init softc
- */
- LIST_INIT(&sc->sc_list);
- timeout_set(&sc->sc_reconnect, bthidev_timeout, sc);
- sc->sc_state = BTHID_CLOSED;
- sc->sc_flags = BTHID_CONNECTING;
- sc->sc_ctlpsm = L2CAP_PSM_HID_CNTL;
- sc->sc_intpsm = L2CAP_PSM_HID_INTR;
-
- sc->sc_mode = 0;
-
- /*
- * copy in our configuration info
- */
- bdaddr_copy(&sc->sc_laddr, &bda->bd_laddr);
- bdaddr_copy(&sc->sc_raddr, &bda->bd_raddr);
-
- if (bda->bd_mode != BTDEV_MODE_NONE) {
- if (bda->bd_mode == BTDEV_MODE_AUTH) {
- sc->sc_mode = L2CAP_LM_AUTH;
- printf(" auth");
- } else if (bda->bd_mode == BTDEV_MODE_ENCRYPT) {
- sc->sc_mode = L2CAP_LM_ENCRYPT;
- printf(" encrypt");
- } else if (bda->bd_mode == BTDEV_MODE_SECURE) {
- sc->sc_mode = L2CAP_LM_SECURE;
- printf(" secure");
- } else {
- printf(" unknown link-mode: %d\n", bda->bd_mode);
- return;
- }
- }
-
- if (!L2CAP_PSM_INVALID(bda->bd_hid.hid_ctl))
- sc->sc_ctlpsm = bda->bd_hid.hid_ctl;
-
- if (!L2CAP_PSM_INVALID(bda->bd_hid.hid_int))
- sc->sc_intpsm = bda->bd_hid.hid_int;
-
- if (bda->bd_hid.hid_flags & BTHID_INITIATE)
- sc->sc_flags |= BTHID_RECONNECT;
-
- if (bda->bd_hid.hid_desc == NULL ||
- bda->bd_hid.hid_dlen == 0 ||
- bda->bd_hid.hid_dlen > MAX_DESCRIPTOR_LEN) {
- printf(": no descriptor\n");
- return;
- }
- sc->sc_dlen = bda->bd_hid.hid_dlen;
- sc->sc_desc = malloc(bda->bd_hid.hid_dlen, M_BTHIDEV,
- M_WAITOK | M_CANFAIL);
- if (sc->sc_desc == NULL) {
- printf(": no memory\n");
- return;
- }
- if (copyin(bda->bd_hid.hid_desc, sc->sc_desc, bda->bd_hid.hid_dlen)) {
- free(sc->sc_desc, M_BTHIDEV);
- printf(": no descriptor");
- return;
- }
-
- /*
- * Parse the descriptor and attach child devices, one per report.
- */
- maxid = -1;
- h.report_ID = 0;
- d = hid_start_parse(sc->sc_desc, sc->sc_dlen, hid_none);
- while (hid_get_item(d, &h)) {
- if (h.report_ID > maxid)
- maxid = h.report_ID;
- }
- hid_end_parse(d);
-
- if (maxid < 0) {
- printf(": no reports found\n");
- return;
- }
-
- printf("\n");
-
- for (rep = 0 ; rep <= maxid ; rep++) {
- if (hid_report_size(sc->sc_desc, sc->sc_dlen, hid_feature, rep) == 0
- && hid_report_size(sc->sc_desc, sc->sc_dlen, hid_input, rep) == 0
- && hid_report_size(sc->sc_desc, sc->sc_dlen, hid_output, rep) == 0)
- continue;
-
- bha.ba_desc = sc->sc_desc;
- bha.ba_dlen = sc->sc_dlen;
- bha.ba_input = bthidev_null;
- bha.ba_feature = bthidev_null;
- bha.ba_output = bthidev_output;
- bha.ba_id = rep;
-
- hidev = (struct bthidev *)config_found_sm(self, &bha,
- bthidev_print, bthidevsubmatch);
- if (hidev != NULL) {
- hidev->sc_parent = &sc->sc_btdev;
- hidev->sc_id = rep;
- hidev->sc_input = bha.ba_input;
- hidev->sc_feature = bha.ba_feature;
- LIST_INSERT_HEAD(&sc->sc_list, hidev, sc_next);
- }
- }
-
- /*
- * start bluetooth connections
- */
- mutex_enter(&bt_lock);
- if ((sc->sc_flags & BTHID_RECONNECT) == 0)
- bthidev_listen(sc);
-
- if (sc->sc_flags & BTHID_CONNECTING)
- bthidev_connect(sc);
- mutex_exit(&bt_lock);
-}
-
-int
-bthidev_detach(struct device *self, int flags)
-{
- struct bthidev_softc *sc = (struct bthidev_softc *)self;
- struct bthidev *hidev;
-
- mutex_enter(&bt_lock);
- sc->sc_flags = 0; /* disable reconnecting */
-
- /* release interrupt listen */
- if (sc->sc_int_l != NULL) {
- l2cap_detach(&sc->sc_int_l);
- sc->sc_int_l = NULL;
- }
-
- /* release control listen */
- if (sc->sc_ctl_l != NULL) {
- l2cap_detach(&sc->sc_ctl_l);
- sc->sc_ctl_l = NULL;
- }
-
- /* close interrupt channel */
- if (sc->sc_int != NULL) {
- l2cap_disconnect(sc->sc_int, 0);
- l2cap_detach(&sc->sc_int);
- sc->sc_int = NULL;
- }
-
- /* close control channel */
- if (sc->sc_ctl != NULL) {
- l2cap_disconnect(sc->sc_ctl, 0);
- l2cap_detach(&sc->sc_ctl);
- sc->sc_ctl = NULL;
- }
-
- /* remove timeout */
- timeout_del(&sc->sc_reconnect);
-
- mutex_exit(&bt_lock);
-
- /* detach children */
- while ((hidev = LIST_FIRST(&sc->sc_list)) != NULL) {
- LIST_REMOVE(hidev, sc_next);
- config_detach(&hidev->sc_dev, flags);
- }
-
- /* release descriptor */
- if (sc->sc_desc != NULL) {
- free(sc->sc_desc, M_BTHIDEV);
- sc->sc_desc = NULL;
- }
- return 0;
-}
-
-/*
- * bthidev config print
- */
-int
-bthidev_print(void *aux, const char *pnp)
-{
- struct bthidev_attach_args *ba = aux;
-
- if (pnp != NULL)
- printf("%s:", pnp);
-
- if (ba->ba_id > 0)
- printf(" reportid %d", ba->ba_id);
-
- return UNCONF;
-}
-
-int
-bthidevsubmatch(struct device *parent, void *match, void *aux)
-{
- struct bthidev_attach_args *ba = aux;
- struct cfdata *cf = match;
-
- if (cf->bthidevcf_reportid != BTHIDEV_UNK_REPORTID &&
- cf->bthidevcf_reportid != ba->ba_id)
- return (0);
-
- return ((*cf->cf_attach->ca_match)(parent, cf, aux));
-}
-
-
-/*****************************************************************************
- *
- * bluetooth(4) HID attach/detach routines
- */
-
-/*
- * callouts are scheduled after connections have been lost, in order
- * to clean up and reconnect.
- */
-void
-bthidev_timeout(void *arg)
-{
- struct bthidev_softc *sc = arg;
-
- mutex_enter(&bt_lock);
-
- switch (sc->sc_state) {
- case BTHID_CLOSED:
- if (sc->sc_int != NULL) {
- l2cap_disconnect(sc->sc_int, 0);
- break;
- }
-
- if (sc->sc_ctl != NULL) {
- l2cap_disconnect(sc->sc_ctl, 0);
- break;
- }
-
- if (sc->sc_flags & BTHID_RECONNECT) {
- sc->sc_flags |= BTHID_CONNECTING;
- bthidev_connect(sc);
- break;
- }
-
- break;
-
- case BTHID_WAIT_CTL:
- break;
-
- case BTHID_WAIT_INT:
- break;
-
- case BTHID_OPEN:
- break;
-
- default:
- break;
- }
- mutex_exit(&bt_lock);
-}
-
-/*
- * listen for our device
- */
-int
-bthidev_listen(struct bthidev_softc *sc)
-{
- struct sockaddr_bt sa;
- int err;
-
- memset(&sa, 0, sizeof(sa));
- sa.bt_len = sizeof(sa);
- sa.bt_family = AF_BLUETOOTH;
- bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
-
- /*
- * Listen on control PSM
- */
- err = l2cap_attach(&sc->sc_ctl_l, &bthidev_ctl_proto, sc);
- if (err)
- return err;
-
- err = l2cap_setlinkmode(sc->sc_ctl_l, sc->sc_mode);
- if (err)
- return err;
-
- sa.bt_psm = sc->sc_ctlpsm;
- err = l2cap_bind(sc->sc_ctl_l, &sa);
- if (err)
- return err;
-
- err = l2cap_listen(sc->sc_ctl_l);
- if (err)
- return err;
-
- /*
- * Listen on interrupt PSM
- */
- err = l2cap_attach(&sc->sc_int_l, &bthidev_int_proto, sc);
- if (err)
- return err;
-
- err = l2cap_setlinkmode(sc->sc_int_l, sc->sc_mode);
- if (err)
- return err;
-
- sa.bt_psm = sc->sc_intpsm;
- err = l2cap_bind(sc->sc_int_l, &sa);
- if (err)
- return err;
-
- err = l2cap_listen(sc->sc_int_l);
- if (err)
- return err;
-
- sc->sc_state = BTHID_WAIT_CTL;
- return 0;
-}
-
-/*
- * start connecting to our device
- */
-int
-bthidev_connect(struct bthidev_softc *sc)
-{
- struct sockaddr_bt sa;
- int err;
-
- if (sc->sc_attempts++ > 0)
- printf("%s: connect (#%d)\n",
- sc->sc_btdev.sc_dev.dv_xname, sc->sc_attempts);
-
- memset(&sa, 0, sizeof(sa));
- sa.bt_len = sizeof(sa);
- sa.bt_family = AF_BLUETOOTH;
-
- err = l2cap_attach(&sc->sc_ctl, &bthidev_ctl_proto, sc);
- if (err) {
- printf("%s: l2cap_attach failed (%d)\n",
- sc->sc_btdev.sc_dev.dv_xname, err);
- return err;
- }
-
- err = l2cap_setlinkmode(sc->sc_ctl, sc->sc_mode);
- if (err)
- return err;
-
- bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
- err = l2cap_bind(sc->sc_ctl, &sa);
- if (err) {
- printf("%s: l2cap_bind failed (%d)\n",
- sc->sc_btdev.sc_dev.dv_xname, err);
- return err;
- }
-
- sa.bt_psm = sc->sc_ctlpsm;
- bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
- err = l2cap_connect(sc->sc_ctl, &sa);
- if (err) {
- printf("%s: l2cap_connect failed (%d)\n",
- sc->sc_btdev.sc_dev.dv_xname, err);
- return err;
- }
-
- sc->sc_state = BTHID_WAIT_CTL;
- return 0;
-}
-
-/*****************************************************************************
- *
- * bluetooth(9) callback methods for L2CAP
- *
- * All these are called from Bluetooth Protocol code, in a soft
- * interrupt context at IPL_SOFTNET.
- */
-
-void
-bthidev_connecting(void *arg)
-{
- /* don't care */
-}
-
-void
-bthidev_ctl_connected(void *arg)
-{
- struct sockaddr_bt sa;
- struct bthidev_softc *sc = arg;
- int err;
-
- if (sc->sc_state != BTHID_WAIT_CTL)
- return;
-
- KASSERT(sc->sc_ctl != NULL);
- KASSERT(sc->sc_int == NULL);
-
- if (sc->sc_flags & BTHID_CONNECTING) {
- /* initiate connect on interrupt PSM */
- err = l2cap_attach(&sc->sc_int, &bthidev_int_proto, sc);
- if (err)
- goto fail;
-
- err = l2cap_setlinkmode(sc->sc_int, sc->sc_mode);
- if (err)
- goto fail;
-
- memset(&sa, 0, sizeof(sa));
- sa.bt_len = sizeof(sa);
- sa.bt_family = AF_BLUETOOTH;
- bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
-
- err = l2cap_bind(sc->sc_int, &sa);
- if (err)
- goto fail;
-
- sa.bt_psm = sc->sc_intpsm;
- bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
- err = l2cap_connect(sc->sc_int, &sa);
- if (err)
- goto fail;
- }
-
- sc->sc_state = BTHID_WAIT_INT;
- return;
-
-fail:
- l2cap_detach(&sc->sc_ctl);
- sc->sc_ctl = NULL;
- printf("%s: connect failed (%d)\n",
- sc->sc_btdev.sc_dev.dv_xname, err);
-}
-
-void
-bthidev_int_connected(void *arg)
-{
- struct bthidev_softc *sc = arg;
-
- if (sc->sc_state != BTHID_WAIT_INT)
- return;
-
- KASSERT(sc->sc_ctl != NULL);
- KASSERT(sc->sc_int != NULL);
-
- sc->sc_attempts = 0;
- sc->sc_flags &= ~BTHID_CONNECTING;
- sc->sc_state = BTHID_OPEN;
-
- printf("%s: connected\n", sc->sc_btdev.sc_dev.dv_xname);
-}
-
-/*
- * Disconnected
- *
- * Depending on our state, this could mean several things, but essentially
- * we are lost. If both channels are closed, and we are marked to reconnect,
- * schedule another try otherwise just give up. They will contact us.
- */
-void
-bthidev_ctl_disconnected(void *arg, int err)
-{
- struct bthidev_softc *sc = arg;
-
- if (sc->sc_ctl != NULL) {
- l2cap_detach(&sc->sc_ctl);
- sc->sc_ctl = NULL;
- }
-
- sc->sc_state = BTHID_CLOSED;
-
- if (sc->sc_int == NULL) {
- printf("%s: disconnected\n", sc->sc_btdev.sc_dev.dv_xname);
- sc->sc_flags &= ~BTHID_CONNECTING;
-
- if (sc->sc_flags & BTHID_RECONNECT)
- timeout_add_sec(&sc->sc_reconnect,
- BTHID_RETRY_INTERVAL);
- else
- sc->sc_state = BTHID_WAIT_CTL;
- } else {
- /*
- * The interrupt channel should have been closed first,
- * but its potentially unsafe to detach that from here.
- * Give them a second to do the right thing or let the
- * callout handle it.
- */
- timeout_add_sec(&sc->sc_reconnect, 1);
- }
-}
-
-void
-bthidev_int_disconnected(void *arg, int err)
-{
- struct bthidev_softc *sc = arg;
-
- if (sc->sc_int != NULL) {
- l2cap_detach(&sc->sc_int);
- sc->sc_int = NULL;
- }
-
- sc->sc_state = BTHID_CLOSED;
-
- if (sc->sc_ctl == NULL) {
- printf("%s: disconnected\n", sc->sc_btdev.sc_dev.dv_xname);
- sc->sc_flags &= ~BTHID_CONNECTING;
-
- if (sc->sc_flags & BTHID_RECONNECT)
- timeout_add_sec(&sc->sc_reconnect,
- BTHID_RETRY_INTERVAL);
- else
- sc->sc_state = BTHID_WAIT_CTL;
- } else {
- /*
- * The control channel should be closing also, allow
- * them a chance to do that before we force it.
- */
- timeout_add_sec(&sc->sc_reconnect, 1);
- }
-}
-
-/*
- * New Connections
- *
- * We give a new L2CAP handle back if this matches the BDADDR we are
- * listening for and we are in the right state. bthidev_connected will
- * be called when the connection is open, so nothing else to do here
- */
-void *
-bthidev_ctl_newconn(void *arg, struct sockaddr_bt *laddr,
- struct sockaddr_bt *raddr)
-{
- struct bthidev_softc *sc = arg;
-
- if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0
- || (sc->sc_flags & BTHID_CONNECTING)
- || sc->sc_state != BTHID_WAIT_CTL
- || sc->sc_ctl != NULL
- || sc->sc_int != NULL)
- return NULL;
-
- l2cap_attach(&sc->sc_ctl, &bthidev_ctl_proto, sc);
- return sc->sc_ctl;
-}
-
-void *
-bthidev_int_newconn(void *arg, struct sockaddr_bt *laddr,
- struct sockaddr_bt *raddr)
-{
- struct bthidev_softc *sc = arg;
-
- if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0
- || (sc->sc_flags & BTHID_CONNECTING)
- || sc->sc_state != BTHID_WAIT_INT
- || sc->sc_ctl == NULL
- || sc->sc_int != NULL)
- return NULL;
-
- l2cap_attach(&sc->sc_int, &bthidev_int_proto, sc);
- return sc->sc_int;
-}
-
-void
-bthidev_complete(void *arg, int count)
-{
-
- /* dont care */
-}
-
-void
-bthidev_linkmode(void *arg, int new)
-{
- struct bthidev_softc *sc = arg;
-
- if ((sc->sc_mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH))
- printf("%s: auth failed\n", sc->sc_btdev.sc_dev.dv_xname);
- else if ((sc->sc_mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT))
- printf("%s: encrypt off\n", sc->sc_btdev.sc_dev.dv_xname);
- else if ((sc->sc_mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE))
- printf("%s: insecure\n", sc->sc_btdev.sc_dev.dv_xname);
- else
- return;
-
- if (sc->sc_int != NULL)
- l2cap_disconnect(sc->sc_int, 0);
-
- if (sc->sc_ctl != NULL)
- l2cap_disconnect(sc->sc_ctl, 0);
-}
-
-/*
- * Receive reports from the protocol stack.
- */
-void
-bthidev_input(void *arg, struct mbuf *m)
-{
- struct bthidev_softc *sc = arg;
- struct bthidev *hidev;
- uint8_t *data;
- int len;
-
- if (sc->sc_state != BTHID_OPEN)
- goto release;
-
- if (m->m_pkthdr.len > m->m_len)
- printf("%s: truncating HID report\n",
- sc->sc_btdev.sc_dev.dv_xname);
-
- len = m->m_len;
- data = mtod(m, uint8_t *);
-
- if (BTHID_TYPE(data[0]) == BTHID_DATA) {
- /*
- * data[0] == type / parameter
- * data[1] == id
- * data[2..len] == report
- */
- if (len < 3)
- goto release;
-
- LIST_FOREACH(hidev, &sc->sc_list, sc_next) {
- if (data[1] == hidev->sc_id) {
- switch (BTHID_DATA_PARAM(data[0])) {
- case BTHID_DATA_INPUT:
- (*hidev->sc_input)(hidev, data + 2, len - 2);
- break;
-
- case BTHID_DATA_FEATURE:
- (*hidev->sc_feature)(hidev, data + 2, len - 2);
- break;
-
- default:
- break;
- }
-
- goto release;
- }
- }
- printf("%s: report id %d, len = %d ignored\n",
- sc->sc_btdev.sc_dev.dv_xname, data[1], len - 2);
-
- goto release;
- }
-
- if (BTHID_TYPE(data[0]) == BTHID_CONTROL) {
- if (len < 1)
- goto release;
-
- if (BTHID_DATA_PARAM(data[0]) == BTHID_CONTROL_UNPLUG) {
- printf("%s: unplugged\n",
- sc->sc_btdev.sc_dev.dv_xname);
-
- /* close interrupt channel */
- if (sc->sc_int != NULL) {
- l2cap_disconnect(sc->sc_int, 0);
- l2cap_detach(&sc->sc_int);
- sc->sc_int = NULL;
- }
-
- /* close control channel */
- if (sc->sc_ctl != NULL) {
- l2cap_disconnect(sc->sc_ctl, 0);
- l2cap_detach(&sc->sc_ctl);
- sc->sc_ctl = NULL;
- }
- }
-
- goto release;
- }
-
-release:
- m_freem(m);
-}
-
-/*****************************************************************************
- *
- * IO routines
- */
-
-void
-bthidev_null(struct bthidev *hidev, uint8_t *report, int len)
-{
-
- /*
- * empty routine just in case the device
- * provided no method to handle this report
- */
-}
-
-int
-bthidev_output(struct bthidev *hidev, uint8_t *report, int rlen, int nolock)
-{
- struct bthidev_softc *sc = (struct bthidev_softc *)hidev->sc_parent;
- struct mbuf *m;
- int err;
-
- if (sc == NULL || sc->sc_state != BTHID_OPEN)
- return ENOTCONN;
-
- KASSERT(sc->sc_ctl != NULL);
- KASSERT(sc->sc_int != NULL);
-
- if (rlen == 0 || report == NULL)
- return 0;
-
- if (rlen > MHLEN - 2) {
- printf("%s: output report too long (%d)!\n",
- sc->sc_btdev.sc_dev.dv_xname, rlen);
-
- return EMSGSIZE;
- }
-
- m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return ENOMEM;
-
- /*
- * data[0] = type / parameter
- * data[1] = id
- * data[2..N] = report
- */
- mtod(m, uint8_t *)[0] = (uint8_t)((BTHID_DATA << 4) | BTHID_DATA_OUTPUT);
- mtod(m, uint8_t *)[1] = hidev->sc_id;
- memcpy(mtod(m, uint8_t *) + 2, report, rlen);
- m->m_pkthdr.len = m->m_len = rlen + 2;
-
- if (!nolock)
- mutex_enter(&bt_lock);
- err = l2cap_send(sc->sc_int, m);
- if (!nolock)
- mutex_exit(&bt_lock);
-
- return err;
-}
diff --git a/sys/dev/bluetooth/bthidev.h b/sys/dev/bluetooth/bthidev.h
deleted file mode 100644
index 2932d02d5c9..00000000000
--- a/sys/dev/bluetooth/bthidev.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* $OpenBSD: bthidev.h,v 1.4 2010/08/05 13:13:17 miod Exp $ */
-/* $NetBSD: bthidev.h,v 1.4 2007/11/03 17:41:03 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DEV_BLUETOOTH_BTHIDEV_H_
-#define _DEV_BLUETOOTH_BTHIDEV_H_
-
-#ifdef _KERNEL
-
-#define BTHIDBUSCF_REPORTID 0
-#define BTHIDBUSCF_REPORTID_DEFAULT -1
-
-#define bthidevcf_reportid cf_loc[BTHIDBUSCF_REPORTID]
-#define BTHIDEV_UNK_REPORTID BTHIDBUSCF_REPORTID_DEFAULT
-
-/* HID device header */
-struct bthidev {
- struct device sc_dev;
- struct btdev *sc_parent;
-
- int sc_id; /* report id */
- int sc_len; /* report len */
-
- void (*sc_input) /* input method */
- (struct bthidev *, uint8_t *, int);
-
- void (*sc_feature) /* feature method */
- (struct bthidev *, uint8_t *, int);
-
- LIST_ENTRY(bthidev) sc_next;
-};
-
-/* HID device attach arguments */
-struct bthidev_attach_args {
- void *ba_desc; /* descriptor */
- int ba_dlen; /* descriptor length */
- int ba_id; /* report id */
-
- void (*ba_input) /* input method */
- (struct bthidev *, uint8_t *, int);
- void (*ba_feature) /* feature method */
- (struct bthidev *, uint8_t *, int);
- int (*ba_output) /* output method */
- (struct bthidev *, uint8_t *, int, int);
-};
-
-#endif /* _KERNEL */
-
-#endif /* _DEV_BLUETOOTH_BTHIDEV_H_ */
diff --git a/sys/dev/bluetooth/bthub.c b/sys/dev/bluetooth/bthub.c
deleted file mode 100644
index 3780fff2382..00000000000
--- a/sys/dev/bluetooth/bthub.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* $OpenBSD: bthub.c,v 1.6 2013/12/15 14:32:38 pirofti Exp $ */
-
-/*
- * Copyright (c) 2007 Uwe Stuehler <uwe@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#include <sys/fcntl.h>
-#include <sys/vnode.h>
-
-#include <netbt/bluetooth.h>
-
-#include <dev/bluetooth/btdev.h>
-
-struct bthub_softc {
- struct device sc_dev;
- int sc_open;
- bdaddr_t sc_laddr;
- LIST_HEAD(, btdev) sc_list;
-};
-
-int bthub_match(struct device *, void *, void *);
-void bthub_attach(struct device *, struct device *, void *);
-int bthub_detach(struct device *, int);
-int bthub_print(void *, const char *);
-int bthub_devioctl(dev_t, u_long, struct btdev_attach_args *);
-int bthubopen(dev_t, int, int, struct proc *);
-int bthubclose(dev_t, int, int, struct proc *);
-int bthubioctl(dev_t, u_long, caddr_t, int, struct proc *);
-
-struct cfattach bthub_ca = {
- sizeof(struct bthub_softc), bthub_match, bthub_attach, bthub_detach
-};
-
-struct cfdriver bthub_cd = {
- NULL, "bthub", DV_DULL
-};
-
-int
-bthub_match(struct device *parent, void *match, void *aux)
-{
- return (1);
-}
-
-void
-bthub_attach(struct device *parent, struct device *self, void *aux)
-{
- struct bthub_softc *sc = (struct bthub_softc *)self;
- bdaddr_t *addr = aux;
-
- sc->sc_open = 0;
- bdaddr_copy(&sc->sc_laddr, addr);
-
- printf(" %02x:%02x:%02x:%02x:%02x:%02x\n",
- addr->b[5], addr->b[4], addr->b[3],
- addr->b[2], addr->b[1], addr->b[0]);
-}
-
-int
-bthub_detach(struct device *self, int flags)
-{
- struct bthub_softc *sc = (struct bthub_softc *)self;
- struct btdev *btdev;
- int maj, mn;
- int err;
-
- /* Locate the major number */
- for (maj = 0; maj < nchrdev; maj++)
- if (cdevsw[maj].d_open == bthubopen)
- break;
-
- /* Nuke the vnodes for any open instances (calls close) */
- mn = self->dv_unit;
- vdevgone(maj, mn, mn, VCHR);
-
- /* Detach all child devices. */
- while (!LIST_EMPTY(&sc->sc_list)) {
- btdev = LIST_FIRST(&sc->sc_list);
- LIST_REMOVE(btdev, sc_next);
-
- err = config_detach(&btdev->sc_dev, flags);
- if (err && (flags & DETACH_FORCE) == 0) {
- LIST_INSERT_HEAD(&sc->sc_list, btdev, sc_next);
- return err;
- }
- }
-
- return (0);
-}
-
-int
-bthub_print(void *aux, const char *parentname)
-{
- struct btdev_attach_args *bd = aux;
- bdaddr_t *raddr = &bd->bd_raddr;
-
- if (parentname != NULL)
- return QUIET;
-
- printf(" %02x:%02x:%02x:%02x:%02x:%02x",
- raddr->b[5], raddr->b[4], raddr->b[3], raddr->b[2],
- raddr->b[1], raddr->b[0]);
- return QUIET;
-}
-
-int
-bthubopen(dev_t dev, int flag, int mode, struct proc *p)
-{
- struct device *dv;
- struct bthub_softc *sc;
-
- dv = device_lookup(&bthub_cd, minor(dev));
- if (dv == NULL)
- return (ENXIO);
-
- sc = (struct bthub_softc *)dv;
- if (sc->sc_open) {
- device_unref(dv);
- return (EBUSY);
- }
-
- sc->sc_open = 1;
- device_unref(dv);
-
- return (0);
-}
-
-int
-bthubclose(dev_t dev, int flag, int mode, struct proc *p)
-{
- struct device *dv;
- struct bthub_softc *sc;
-
- dv = device_lookup(&bthub_cd, minor(dev));
- sc = (struct bthub_softc *)dv;
- sc->sc_open = 0;
- device_unref(dv);
-
- return (0);
-}
-
-int
-bthubioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
-{
- struct btdev_attach_args *bd;
- int err;
-
- switch (cmd) {
- case BTDEV_ATTACH:
- case BTDEV_DETACH:
- if ((flag & FWRITE) == 0)
- return (EACCES);
- default:
- break;
- }
-
- switch (cmd) {
- case BTDEV_ATTACH:
- case BTDEV_DETACH:
- bd = (struct btdev_attach_args *)data;
- err = bthub_devioctl(dev, cmd, bd);
- break;
- default:
- err = ENOTTY;
- }
-
- return err;
-}
-
-int
-bthub_devioctl(dev_t dev, u_long cmd, struct btdev_attach_args *bd)
-{
- struct device *dv;
- struct bthub_softc *sc;
- struct btdev *btdev;
- int unit;
-
- /* Locate the relevant bthub. */
- for (unit = 0; unit < bthub_cd.cd_ndevs; unit++) {
- if ((dv = bthub_cd.cd_devs[unit]) == NULL)
- continue;
-
- sc = (struct bthub_softc *)dv;
- if (bdaddr_same(&sc->sc_laddr, &bd->bd_laddr))
- break;
- }
- if (unit == bthub_cd.cd_ndevs)
- return (ENXIO);
-
- /* Locate matching child device, if any. */
- LIST_FOREACH(btdev, &sc->sc_list, sc_next) {
- if (!bdaddr_same(&btdev->sc_addr, &bd->bd_raddr))
- continue;
- if (btdev->sc_type != bd->bd_type)
- continue;
- break;
- }
-
- switch (cmd) {
- case BTDEV_ATTACH:
- if (btdev != NULL)
- return EADDRINUSE;
-
- dv = config_found(&sc->sc_dev, bd, bthub_print);
- if (dv == NULL)
- return ENXIO;
-
- btdev = (struct btdev *)dv;
- bdaddr_copy(&btdev->sc_addr, &bd->bd_raddr);
- btdev->sc_type = bd->bd_type;
- LIST_INSERT_HEAD(&sc->sc_list, btdev, sc_next);
- break;
-
- case BTDEV_DETACH:
- if (btdev == NULL)
- return ENXIO;
-
- LIST_REMOVE(btdev, sc_next);
- config_detach(&btdev->sc_dev, DETACH_FORCE);
- break;
- }
-
- return 0;
-}
-
diff --git a/sys/dev/bluetooth/btkbd.c b/sys/dev/bluetooth/btkbd.c
deleted file mode 100644
index 5de8553c04a..00000000000
--- a/sys/dev/bluetooth/btkbd.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* $OpenBSD: btkbd.c,v 1.7 2010/08/05 13:13:17 miod Exp $ */
-/* $NetBSD: btkbd.c,v 1.10 2008/09/09 03:54:56 cube Exp $ */
-
-/*
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/device.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-
-#include <dev/bluetooth/bthid.h>
-#include <dev/bluetooth/bthidev.h>
-
-#include <dev/usb/hid.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/wscons/wsconsio.h>
-#include <dev/wscons/wskbdvar.h>
-#include <dev/wscons/wsksymdef.h>
-#include <dev/wscons/wsksymvar.h>
-
-#include <dev/usb/hidkbdsc.h>
-#include <dev/usb/hidkbdvar.h>
-
-struct btkbd_softc {
- struct bthidev sc_hidev; /* device */
- struct hidkbd sc_kbd; /* keyboard state */
- int (*sc_output) /* output method */
- (struct bthidev *, uint8_t *, int, int);
- int sc_inintr;
-};
-
-/* autoconf(9) methods */
-int btkbd_match(struct device *, void *, void *);
-void btkbd_attach(struct device *, struct device *, void *);
-int btkbd_detach(struct device *, int);
-
-struct cfdriver btkbd_cd = {
- NULL, "btkbd", DV_DULL
-};
-
-const struct cfattach btkbd_ca = {
- sizeof(struct btkbd_softc),
- btkbd_match,
- btkbd_attach,
- btkbd_detach,
- /* XXX activate */
-};
-
-/* wskbd(4) accessops */
-int btkbd_enable(void *, int);
-void btkbd_set_leds(void *, int);
-int btkbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
-
-const struct wskbd_accessops btkbd_accessops = {
- btkbd_enable,
- btkbd_set_leds,
- btkbd_ioctl
-};
-
-/* bthid methods */
-void btkbd_input(struct bthidev *, uint8_t *, int);
-
-int
-btkbd_match(struct device *self, void *match, void *aux)
-{
- struct bthidev_attach_args *ba = aux;
-
- if (hid_is_collection(ba->ba_desc, ba->ba_dlen, ba->ba_id,
- HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD)))
- return 1;
-
- return 0;
-}
-
-void
-btkbd_attach(struct device *parent, struct device *self, void *aux)
-{
- struct btkbd_softc *sc = (struct btkbd_softc *)self;
- struct hidkbd *kbd = &sc->sc_kbd;
- struct bthidev_attach_args *ba = aux;
- kbd_t layout;
-
- sc->sc_output = ba->ba_output;
- ba->ba_input = btkbd_input; /* XXX ugly */
-
- if (hidkbd_attach(self, kbd, 0, 0,
- ba->ba_id, ba->ba_desc, ba->ba_dlen) != 0)
- return;
-
- printf("\n");
-
-#if defined(BTKBD_LAYOUT)
- layout = BTKBD_LAYOUT;
-#else
- layout = KB_US;
-#endif
- hidkbd_attach_wskbd(kbd, layout, &btkbd_accessops);
-}
-
-int
-btkbd_detach(struct device *self, int flags)
-{
- struct btkbd_softc *sc = (struct btkbd_softc *)self;
-
- return hidkbd_detach(&sc->sc_kbd, flags);
-}
-
-int
-btkbd_enable(void *self, int on)
-{
- struct btkbd_softc *sc = (struct btkbd_softc *)self;
- struct hidkbd *kbd = &sc->sc_kbd;
-
- return hidkbd_enable(kbd, on);
-}
-
-void
-btkbd_set_leds(void *self, int leds)
-{
- struct btkbd_softc *sc = (struct btkbd_softc *)self;
- struct hidkbd *kbd = &sc->sc_kbd;
- uint8_t report;
-
- if (hidkbd_set_leds(kbd, leds, &report) != 0) {
- if (sc->sc_output != NULL)
- (*sc->sc_output)(&sc->sc_hidev, &report,
- sizeof(report), sc->sc_inintr);
- }
-}
-
-int
-btkbd_ioctl(void *self, u_long cmd, caddr_t data, int flag, struct proc *p)
-{
- struct btkbd_softc *sc = (struct btkbd_softc *)self;
- struct hidkbd *kbd = &sc->sc_kbd;
-
- switch (cmd) {
- case WSKBDIO_GTYPE:
- *(int *)data = WSKBD_TYPE_BLUETOOTH;
- return 0;
- case WSKBDIO_SETLEDS:
- btkbd_set_leds(sc, *(int *)data);
- return 0;
- default:
- return hidkbd_ioctl(kbd, cmd, data, flag, p);
- }
-}
-
-void
-btkbd_input(struct bthidev *self, uint8_t *data, int len)
-{
- struct btkbd_softc *sc = (struct btkbd_softc *)self;
- struct hidkbd *kbd = &sc->sc_kbd;
-
- if (kbd->sc_enabled != 0) {
- sc->sc_inintr = 1;
- hidkbd_input(kbd, data, len);
- sc->sc_inintr = 0;
- }
-}
diff --git a/sys/dev/bluetooth/btms.c b/sys/dev/bluetooth/btms.c
deleted file mode 100644
index 2c188a40330..00000000000
--- a/sys/dev/bluetooth/btms.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/* $OpenBSD: btms.c,v 1.6 2011/03/04 23:57:52 kettenis Exp $ */
-/* $NetBSD: btms.c,v 1.8 2008/09/09 03:54:56 cube Exp $ */
-
-/*
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/device.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-
-#include <dev/bluetooth/bthid.h>
-#include <dev/bluetooth/bthidev.h>
-
-#include <dev/usb/hid.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/wscons/wsconsio.h>
-#include <dev/wscons/wsmousevar.h>
-
-#include <dev/usb/hidmsvar.h>
-
-struct btms_softc {
- struct bthidev sc_hidev;
- struct hidms sc_ms;
-};
-
-/* autoconf(9) methods */
-int btms_match(struct device *, void *, void *);
-void btms_attach(struct device *, struct device *, void *);
-int btms_detach(struct device *, int);
-
-struct cfdriver btms_cd = {
- NULL, "btms", DV_DULL
-};
-
-const struct cfattach btms_ca = {
- sizeof(struct btms_softc),
- btms_match,
- btms_attach,
- btms_detach,
- /* XXX activate */
-};
-
-/* wsmouse(4) accessops */
-int btms_wsmouse_enable(void *);
-int btms_wsmouse_ioctl(void *, u_long, caddr_t, int, struct proc *);
-void btms_wsmouse_disable(void *);
-
-const struct wsmouse_accessops btms_wsmouse_accessops = {
- btms_wsmouse_enable,
- btms_wsmouse_ioctl,
- btms_wsmouse_disable,
-};
-
-/* bthid methods */
-void btms_input(struct bthidev *, uint8_t *, int);
-
-
-int
-btms_match(struct device *parent, void *match, void *aux)
-{
- struct bthidev_attach_args *ba = aux;
-
- if (hid_is_collection(ba->ba_desc, ba->ba_dlen, ba->ba_id,
- HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
- return 1;
-
- return 0;
-}
-
-void
-btms_attach(struct device *parent, struct device *self, void *aux)
-{
- struct btms_softc *sc = (struct btms_softc *)self;
- struct hidms *ms = &sc->sc_ms;
- struct bthidev_attach_args *ba = aux;
-
- ba->ba_input = btms_input; /* XXX ugly */
-
- if (hidms_setup(self, ms, 0, ba->ba_id, ba->ba_desc, ba->ba_dlen) != 0)
- return;
-
- hidms_attach(ms, &btms_wsmouse_accessops);
-}
-
-int
-btms_detach(struct device *self, int flags)
-{
- struct btms_softc *sc = (struct btms_softc *)self;
- struct hidms *ms = &sc->sc_ms;
-
- return hidms_detach(ms, flags);
-}
-
-int
-btms_wsmouse_enable(void *self)
-{
- struct btms_softc *sc = (struct btms_softc *)self;
- struct hidms *ms = &sc->sc_ms;
-
- return hidms_enable(ms);
-}
-
-int
-btms_wsmouse_ioctl(void *self, u_long cmd, caddr_t data, int flag,
- struct proc *p)
-{
- struct btms_softc *sc = (struct btms_softc *)self;
- struct hidms *ms = &sc->sc_ms;
- int rc;
-
- rc = hidms_ioctl(ms, cmd, data, flag, p);
- if (rc != -1)
- return rc;
-
- switch (cmd) {
- case WSMOUSEIO_GTYPE:
- *(u_int *)data = WSMOUSE_TYPE_BLUETOOTH;
- return 0;
- default:
- return -1;
- }
-}
-
-void
-btms_wsmouse_disable(void *self)
-{
- struct btms_softc *sc = (struct btms_softc *)self;
- struct hidms *ms = &sc->sc_ms;
-
- hidms_disable(ms);
-}
-
-void
-btms_input(struct bthidev *self, uint8_t *data, int len)
-{
- struct btms_softc *sc = (struct btms_softc *)self;
- struct hidms *ms = &sc->sc_ms;
-
- if (ms->sc_enabled != 0)
- hidms_input(ms, data, len);
-}
diff --git a/sys/dev/bluetooth/btsco.c b/sys/dev/bluetooth/btsco.c
deleted file mode 100644
index 6e8beb39957..00000000000
--- a/sys/dev/bluetooth/btsco.c
+++ /dev/null
@@ -1,1224 +0,0 @@
-/* $OpenBSD: btsco.c,v 1.6 2013/05/15 08:29:24 ratchov Exp $ */
-/* $NetBSD: btsco.c,v 1.22 2008/08/06 15:01:23 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/audioio.h>
-#include <sys/conf.h>
-#include <sys/device.h>
-#include <sys/fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/kernel.h>
-#include <sys/queue.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/socketvar.h>
-#include <sys/systm.h>
-#include <sys/timeout.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/rfcomm.h>
-#include <netbt/sco.h>
-
-#include <dev/audio_if.h>
-#include <dev/auconv.h>
-#include <dev/mulaw.h>
-
-#include <dev/bluetooth/btdev.h>
-#include <dev/bluetooth/btsco.h>
-
-typedef struct audio_params audio_params_t;
-
-struct audio_format {
- void *driver_data;
- int32_t mode;
- u_int encoding;
- u_int validbits;
- u_int precision;
- u_int channels;
- u_int channel_mask;
-#define AUFMT_UNKNOWN_POSITION 0U
-#define AUFMT_FRONT_LEFT 0x00001U /* USB audio compatible */
-#define AUFMT_FRONT_RIGHT 0x00002U /* USB audio compatible */
-#define AUFMT_FRONT_CENTER 0x00004U /* USB audio compatible */
-#define AUFMT_LOW_FREQUENCY 0x00008U /* USB audio compatible */
-#define AUFMT_BACK_LEFT 0x00010U /* USB audio compatible */
-#define AUFMT_BACK_RIGHT 0x00020U /* USB audio compatible */
-#define AUFMT_FRONT_LEFT_OF_CENTER 0x00040U /* USB audio compatible */
-#define AUFMT_FRONT_RIGHT_OF_CENTER 0x00080U /* USB audio compatible */
-#define AUFMT_BACK_CENTER 0x00100U /* USB audio compatible */
-#define AUFMT_SIDE_LEFT 0x00200U /* USB audio compatible */
-#define AUFMT_SIDE_RIGHT 0x00400U /* USB audio compatible */
-#define AUFMT_TOP_CENTER 0x00800U /* USB audio compatible */
-#define AUFMT_TOP_FRONT_LEFT 0x01000U
-#define AUFMT_TOP_FRONT_CENTER 0x02000U
-#define AUFMT_TOP_FRONT_RIGHT 0x04000U
-#define AUFMT_TOP_BACK_LEFT 0x08000U
-#define AUFMT_TOP_BACK_CENTER 0x10000U
-#define AUFMT_TOP_BACK_RIGHT 0x20000U
-
-#define AUFMT_MONAURAL AUFMT_FRONT_CENTER
-#define AUFMT_STEREO (AUFMT_FRONT_LEFT | AUFMT_FRONT_RIGHT)
-#define AUFMT_SURROUND4 (AUFMT_STEREO | AUFMT_BACK_LEFT \
- | AUFMT_BACK_RIGHT)
-#define AUFMT_DOLBY_5_1 (AUFMT_SURROUND4 | AUFMT_FRONT_CENTER \
- | AUFMT_LOW_FREQUENCY)
-
- /**
- * 0: frequency[0] is lower limit, and frequency[1] is higher limit.
- * 1-16: frequency[0] to frequency[frequency_type-1] are valid.
- */
- u_int frequency_type;
-
-#define AUFMT_MAX_FREQUENCIES 16
- /**
- * sampling rates
- */
- u_int frequency[AUFMT_MAX_FREQUENCIES];
-};
-
-#undef DPRINTF
-#undef DPRINTFN
-
-#ifdef BTSCO_DEBUG
-int btsco_debug = BTSCO_DEBUG;
-#define DPRINTF(fmt, args...) do { \
- if (btsco_debug) \
- printf("%s: "fmt, __func__ , ##args); \
-} while (/* CONSTCOND */0)
-
-#define DPRINTFN(n, fmt, args...) do { \
- if (btsco_debug > (n)) \
- printf("%s: "fmt, __func__ , ##args); \
-} while (/* CONSTCOND */0)
-#else
-#define DPRINTF(...)
-#define DPRINTFN(...)
-#endif
-
-/*****************************************************************************
- *
- * Bluetooth SCO Audio device
- */
-
-/* btsco softc */
-struct btsco_softc {
- struct device sc_dev;
- struct device *sc_audio; /* MI audio device */
- uint16_t sc_flags;
- const char *sc_name; /* our device_xname */
-
- void *sc_intr; /* interrupt cookie */
- struct timeout sc_intr_to; /* interrupt trigger */
- int sc_connect; /* connect wait */
-
- /* Bluetooth */
- bdaddr_t sc_laddr; /* local address */
- bdaddr_t sc_raddr; /* remote address */
- uint16_t sc_state; /* link state */
- struct sco_pcb *sc_sco; /* SCO handle */
- struct sco_pcb *sc_sco_l; /* SCO listen handle */
- uint16_t sc_mtu; /* SCO mtu */
- uint8_t sc_channel; /* RFCOMM channel */
- int sc_err; /* stored error */
-
- /* Receive */
- int sc_rx_want; /* bytes wanted */
- uint8_t *sc_rx_block; /* receive block */
- void (*sc_rx_intr)(void *); /* callback */
- void *sc_rx_intrarg; /* callback arg */
- struct mbuf *sc_rx_mbuf; /* leftover mbuf */
-
- /* Transmit */
- int sc_tx_size; /* bytes to send */
- int sc_tx_pending; /* packets pending */
- uint8_t *sc_tx_block; /* transmit block */
- void (*sc_tx_intr)(void *); /* callback */
- void *sc_tx_intrarg; /* callback arg */
- void *sc_tx_buf; /* transmit buffer */
- int sc_tx_refcnt; /* buffer refcnt */
-
- /* mixer data */
- int sc_vgs; /* speaker volume */
- int sc_vgm; /* mic volume */
-};
-
-/* sc_state */
-#define BTSCO_CLOSED 0
-#define BTSCO_WAIT_CONNECT 1
-#define BTSCO_OPEN 2
-
-/* sc_flags */
-#define BTSCO_LISTEN (1 << 1)
-
-/* autoconf(9) glue */
-int btsco_match(struct device *, void *, void *);
-void btsco_attach(struct device *, struct device *, void *);
-int btsco_detach(struct device *, int);
-
-struct cfattach btsco_ca = {
- sizeof(struct btsco_softc),
- btsco_match,
- btsco_attach,
- btsco_detach
-};
-
-struct cfdriver btsco_cd = {
- NULL, "btsco", DV_DULL
-};
-
-/* audio(9) glue */
-static int btsco_open(void *, int);
-static void btsco_close(void *);
-static int btsco_query_encoding(void *, struct audio_encoding *);
-static int btsco_set_params(void *, int, int, audio_params_t *, audio_params_t *);
-static int btsco_round_blocksize(void *, int);
-static int btsco_start_output(void *, void *, int, void (*)(void *), void *);
-static int btsco_start_input(void *, void *, int, void (*)(void *), void *);
-static int btsco_halt_output(void *);
-static int btsco_halt_input(void *);
-static int btsco_getdev(void *, struct audio_device *);
-static int btsco_setfd(void *, int);
-static int btsco_set_port(void *, mixer_ctrl_t *);
-static int btsco_get_port(void *, mixer_ctrl_t *);
-static int btsco_query_devinfo(void *, mixer_devinfo_t *);
-static void *btsco_allocm(void *, int, size_t, int, int);
-static void btsco_freem(void *, void *, int);
-static int btsco_get_props(void *);
-#ifdef notyet
-static int btsco_dev_ioctl(void *, u_long, void *, int, struct proc *);
-#endif
-
-struct audio_hw_if btsco_if = {
- btsco_open, /* open */
- btsco_close, /* close */
- NULL, /* drain */
- btsco_query_encoding, /* query_encoding */
- btsco_set_params, /* set_params */
- btsco_round_blocksize, /* round_blocksize */
- NULL, /* commit_settings */
- NULL, /* init_output */
- NULL, /* init_input */
- btsco_start_output, /* start_output */
- btsco_start_input, /* start_input */
- btsco_halt_output, /* halt_output */
- btsco_halt_input, /* halt_input */
- NULL, /* speaker_ctl */
- btsco_getdev, /* getdev */
- btsco_setfd, /* setfd */
- btsco_set_port, /* set_port */
- btsco_get_port, /* get_port */
- btsco_query_devinfo, /* query_devinfo */
- btsco_allocm, /* allocm */
- btsco_freem, /* freem */
- NULL, /* round_buffersize */
- NULL, /* mappage */
- btsco_get_props, /* get_props */
- NULL, /* trigger_output */
- NULL, /* trigger_input */
- NULL /* get_default_params */
-};
-
-static const struct audio_device btsco_device = {
- "Bluetooth Audio",
- "",
- "btsco"
-};
-
-/* Voice_Setting == 0x0060: 8000Hz, mono, 16-bit, slinear_le */
-static const struct audio_format btsco_format = {
- NULL, /* driver_data */
- (AUMODE_PLAY | AUMODE_RECORD), /* mode */
- AUDIO_ENCODING_SLINEAR_LE, /* encoding */
- 16, /* validbits */
- 16, /* precision */
- 1, /* channels */
- AUFMT_MONAURAL, /* channel_mask */
- 1, /* frequency_type */
- { 8000 } /* frequency */
-};
-
-/* bluetooth(9) glue for SCO */
-static void btsco_sco_connecting(void *);
-static void btsco_sco_connected(void *);
-static void btsco_sco_disconnected(void *, int);
-static void *btsco_sco_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
-static void btsco_sco_complete(void *, int);
-static void btsco_sco_linkmode(void *, int);
-static void btsco_sco_input(void *, struct mbuf *);
-
-static const struct btproto btsco_sco_proto = {
- btsco_sco_connecting,
- btsco_sco_connected,
- btsco_sco_disconnected,
- btsco_sco_newconn,
- btsco_sco_complete,
- btsco_sco_linkmode,
- btsco_sco_input,
-};
-
-
-/*****************************************************************************
- *
- * btsco definitions
- */
-
-/*
- * btsco mixer class
- */
-#define BTSCO_VGS 0
-#define BTSCO_VGM 1
-#define BTSCO_INPUT_CLASS 2
-#define BTSCO_OUTPUT_CLASS 3
-
-/* connect timeout */
-#define BTSCO_TIMEOUT (30 * hz)
-
-/* misc btsco functions */
-static void btsco_extfree(caddr_t, u_int, void *);
-static void btsco_intr(void *);
-
-
-/*****************************************************************************
- *
- * btsco autoconf(9) routines
- */
-
-int
-btsco_match(struct device *self, void *cfdata, void *aux)
-{
- struct btdev_attach_args *bda = (struct btdev_attach_args *)aux;
-
- if (bda->bd_type == BTDEV_HSET || bda->bd_type == BTDEV_HF)
- return 1;
-
- return 0;
-}
-
-void
-btsco_attach(struct device *parent, struct device *self, void *aux)
-{
- struct btsco_softc *sc = (struct btsco_softc *)self;
- struct btdev_attach_args *bda = aux;
-
- /*
- * Init softc
- */
- sc->sc_vgs = 200;
- sc->sc_vgm = 200;
- sc->sc_state = BTSCO_CLOSED;
- sc->sc_name = self->dv_xname;
-
- /*
- * copy in our configuration info
- */
- bdaddr_copy(&sc->sc_laddr, &bda->bd_laddr);
- bdaddr_copy(&sc->sc_raddr, &bda->bd_raddr);
-
- if (bda->bd_type == BTDEV_HF) {
- sc->sc_flags |= BTSCO_LISTEN;
- printf(" listen mode");
- }
-
- if (bda->bd_hset.hset_channel < RFCOMM_CHANNEL_MIN ||
- bda->bd_hset.hset_channel > RFCOMM_CHANNEL_MAX) {
- printf(" invalid channel");
- return;
- }
- sc->sc_channel = bda->bd_hset.hset_channel;
-
- printf(" channel %d\n", sc->sc_channel);
-
- /*
- * set up transmit interrupt
- */
- timeout_set(&sc->sc_intr_to, btsco_intr, sc);
-
- /*
- * attach audio device
- */
- sc->sc_audio = audio_attach_mi(&btsco_if, sc, self);
- if (sc->sc_audio == NULL) {
- printf("%s: audio_attach_mi failed\n", sc->sc_dev.dv_xname);
- return;
- }
-}
-
-int
-btsco_detach(struct device *self, int flags)
-{
- struct btsco_softc *sc = (struct btsco_softc *)self;
-
- DPRINTF("sc=%p\n", sc);
-
- mutex_enter(&bt_lock);
- if (sc->sc_sco != NULL) {
- DPRINTF("sc_sco=%p\n", sc->sc_sco);
- sco_disconnect(sc->sc_sco, 0);
- sco_detach(&sc->sc_sco);
- sc->sc_sco = NULL;
- }
-
- if (sc->sc_sco_l != NULL) {
- DPRINTF("sc_sco_l=%p\n", sc->sc_sco_l);
- sco_detach(&sc->sc_sco_l);
- sc->sc_sco_l = NULL;
- }
- mutex_exit(&bt_lock);
-
- if (sc->sc_audio != NULL) {
- DPRINTF("sc_audio=%p\n", sc->sc_audio);
- config_detach(sc->sc_audio, flags);
- sc->sc_audio = NULL;
- }
-
- timeout_del(&sc->sc_intr_to);
-
- if (sc->sc_rx_mbuf != NULL) {
- m_freem(sc->sc_rx_mbuf);
- sc->sc_rx_mbuf = NULL;
- }
-
- if (sc->sc_tx_refcnt > 0) {
- printf("%s: tx_refcnt=%d!\n", sc->sc_dev.dv_xname,
- sc->sc_tx_refcnt);
-
- if ((flags & DETACH_FORCE) == 0)
- return EAGAIN;
- }
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * bluetooth(9) methods for SCO
- *
- * All these are called from Bluetooth Protocol code, in a soft
- * interrupt context at IPL_SOFTNET.
- */
-
-static void
-btsco_sco_connecting(void *arg)
-{
-/* struct btsco_softc *sc = arg; */
-
- /* dont care */
-}
-
-static void
-btsco_sco_connected(void *arg)
-{
- struct btsco_softc *sc = arg;
-
- DPRINTF("%s\n", sc->sc_name);
-
- KASSERT(sc->sc_sco != NULL);
- KASSERT(sc->sc_state == BTSCO_WAIT_CONNECT);
-
- /*
- * If we are listening, no more need
- */
- if (sc->sc_sco_l != NULL)
- sco_detach(&sc->sc_sco_l);
-
- sc->sc_state = BTSCO_OPEN;
- wakeup(&sc->sc_connect);
-}
-
-static void
-btsco_sco_disconnected(void *arg, int err)
-{
- struct btsco_softc *sc = arg;
-
- DPRINTF("%s sc_state %d\n", sc->sc_name, sc->sc_state);
-
- KASSERT(sc->sc_sco != NULL);
-
- sc->sc_err = err;
- sco_detach(&sc->sc_sco);
-
- switch (sc->sc_state) {
- case BTSCO_CLOSED: /* dont think this can happen */
- break;
-
- case BTSCO_WAIT_CONNECT: /* connect failed */
- wakeup(&sc->sc_connect);
- break;
-
- case BTSCO_OPEN: /* link lost */
- /*
- * If IO is in progress, tell the audio driver that it
- * has completed so that when it tries to send more, we
- * can indicate an error.
- */
- mtx_enter(&audio_lock);
- if (sc->sc_tx_pending > 0) {
- sc->sc_tx_pending = 0;
- (*sc->sc_tx_intr)(sc->sc_tx_intrarg);
- }
- if (sc->sc_rx_want > 0) {
- sc->sc_rx_want = 0;
- (*sc->sc_rx_intr)(sc->sc_rx_intrarg);
- }
- mtx_leave(&audio_lock);
- break;
-
- default:
- UNKNOWN(sc->sc_state);
- }
-
- sc->sc_state = BTSCO_CLOSED;
-}
-
-static void *
-btsco_sco_newconn(void *arg, struct sockaddr_bt *laddr,
- struct sockaddr_bt *raddr)
-{
- struct btsco_softc *sc = arg;
-
- DPRINTF("%s\n", sc->sc_name);
-
- if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0
- || sc->sc_state != BTSCO_WAIT_CONNECT
- || sc->sc_sco != NULL)
- return NULL;
-
- sco_attach(&sc->sc_sco, &btsco_sco_proto, sc);
- return sc->sc_sco;
-}
-
-static void
-btsco_sco_complete(void *arg, int count)
-{
- struct btsco_softc *sc = arg;
-
- DPRINTFN(10, "%s count %d\n", sc->sc_name, count);
-
- mtx_enter(&audio_lock);
- if (sc->sc_tx_pending > 0) {
- sc->sc_tx_pending -= count;
- if (sc->sc_tx_pending == 0)
- (*sc->sc_tx_intr)(sc->sc_tx_intrarg);
- }
- mtx_leave(&audio_lock);
-}
-
-static void
-btsco_sco_linkmode(void *arg, int new)
-{
-/* struct btsco_softc *sc = arg; */
-
- /* dont care */
-}
-
-static void
-btsco_sco_input(void *arg, struct mbuf *m)
-{
- struct btsco_softc *sc = arg;
- int len;
-
- DPRINTFN(10, "%s len=%d\n", sc->sc_name, m->m_pkthdr.len);
-
- mtx_enter(&audio_lock);
- if (sc->sc_rx_want == 0) {
- m_freem(m);
- } else {
- KASSERT(sc->sc_rx_intr != NULL);
- KASSERT(sc->sc_rx_block != NULL);
-
- len = MIN(sc->sc_rx_want, m->m_pkthdr.len);
- m_copydata(m, 0, len, sc->sc_rx_block);
-
- sc->sc_rx_want -= len;
- sc->sc_rx_block += len;
-
- if (len > m->m_pkthdr.len) {
- if (sc->sc_rx_mbuf != NULL)
- m_freem(sc->sc_rx_mbuf);
-
- m_adj(m, len);
- sc->sc_rx_mbuf = m;
- } else {
- m_freem(m);
- }
-
- if (sc->sc_rx_want == 0)
- (*sc->sc_rx_intr)(sc->sc_rx_intrarg);
- }
- mtx_leave(&audio_lock);
-}
-
-
-/*****************************************************************************
- *
- * audio(9) methods
- *
- */
-
-static int
-btsco_open(void *hdl, int flags)
-{
- struct sockaddr_bt sa;
- struct btsco_softc *sc = hdl;
- int err, timo;
-
- DPRINTF("%s flags 0x%x\n", sc->sc_name, flags);
- /* flags FREAD & FWRITE? */
-
- if (sc->sc_sco != NULL || sc->sc_sco_l != NULL)
- return EIO;
-
- mutex_enter(&bt_lock);
-
- memset(&sa, 0, sizeof(sa));
- sa.bt_len = sizeof(sa);
- sa.bt_family = AF_BLUETOOTH;
- bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
-
- if (sc->sc_flags & BTSCO_LISTEN) {
- err = sco_attach(&sc->sc_sco_l, &btsco_sco_proto, sc);
- if (err)
- goto done;
-
- err = sco_bind(sc->sc_sco_l, &sa);
- if (err) {
- sco_detach(&sc->sc_sco_l);
- goto done;
- }
-
- err = sco_listen(sc->sc_sco_l);
- if (err) {
- sco_detach(&sc->sc_sco_l);
- goto done;
- }
-
- timo = 0; /* no timeout */
- } else {
- err = sco_attach(&sc->sc_sco, &btsco_sco_proto, sc);
- if (err)
- goto done;
-
- err = sco_bind(sc->sc_sco, &sa);
- if (err) {
- sco_detach(&sc->sc_sco);
- goto done;
- }
-
- bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
- err = sco_connect(sc->sc_sco, &sa);
- if (err) {
- sco_detach(&sc->sc_sco);
- goto done;
- }
-
- timo = BTSCO_TIMEOUT;
- }
-
- sc->sc_state = BTSCO_WAIT_CONNECT;
- while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT)
- err = msleep(&sc->sc_connect, &bt_lock, PWAIT,
- "connect", timo);
-
- switch (sc->sc_state) {
- case BTSCO_CLOSED: /* disconnected */
- err = sc->sc_err;
-
- /* fall through to */
- case BTSCO_WAIT_CONNECT: /* error */
- if (sc->sc_sco != NULL)
- sco_detach(&sc->sc_sco);
-
- if (sc->sc_sco_l != NULL)
- sco_detach(&sc->sc_sco_l);
-
- break;
-
- case BTSCO_OPEN: /* hurrah */
- (void)sco_getopt(sc->sc_sco, SO_SCO_MTU, &sc->sc_mtu);
- break;
-
- default:
- UNKNOWN(sc->sc_state);
- break;
- }
-
-done:
- mutex_exit(&bt_lock);
-
- DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n",
- err, sc->sc_state, sc->sc_mtu);
- return err;
-}
-
-static void
-btsco_close(void *hdl)
-{
- struct btsco_softc *sc = hdl;
-
- DPRINTF("%s\n", sc->sc_name);
-
- mutex_enter(&bt_lock);
- if (sc->sc_sco != NULL) {
- sco_disconnect(sc->sc_sco, 0);
- sco_detach(&sc->sc_sco);
- }
-
- if (sc->sc_sco_l != NULL) {
- sco_detach(&sc->sc_sco_l);
- }
- mutex_exit(&bt_lock);
-
- if (sc->sc_rx_mbuf != NULL) {
- m_freem(sc->sc_rx_mbuf);
- sc->sc_rx_mbuf = NULL;
- }
-
- sc->sc_rx_want = 0;
- sc->sc_rx_block = NULL;
- sc->sc_rx_intr = NULL;
- sc->sc_rx_intrarg = NULL;
-
- sc->sc_tx_size = 0;
- sc->sc_tx_block = NULL;
- sc->sc_tx_pending = 0;
- sc->sc_tx_intr = NULL;
- sc->sc_tx_intrarg = NULL;
-}
-
-static int
-btsco_query_encoding(void *hdl, struct audio_encoding *ae)
-{
-/* struct btsco_softc *sc = hdl; */
- int err = 0;
-
- switch (ae->index) {
- case 0:
- strlcpy(ae->name, AudioEslinear_le, sizeof(ae->name));
- ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
- ae->precision = 16;
- ae->flags = 0;
- break;
- default:
- err = EINVAL;
- }
- ae->bps = AUDIO_BPS(ae->precision);
- ae->msb = 1;
-
- return err;
-}
-
-static int
-btsco_set_params(void *hdl, int setmode, int usemode,
- audio_params_t *play, audio_params_t *rec)
-{
- int i, mode;
- struct audio_params *p;
-
- DPRINTF("setmode 0x%x usemode 0x%x\n", setmode, usemode);
- DPRINTF("rate %d, precision %d, channels %d encoding %d\n",
- play->sample_rate, play->precision, play->channels, play->encoding);
-
- /*
- * If we had a list of formats, we could check the HCI_Voice_Setting
- * and select the appropriate one to use. Currently only one is
- * supported: 0x0060 == 8000Hz, mono, 16-bit, slinear_le
- */
- for (i = 0; i < 2; i++) {
- if (i) {
- mode = AUMODE_RECORD;
- p = rec;
- } else {
- mode = AUMODE_PLAY;
- p = play;
- }
- if (!(setmode & mode))
- continue;
- p->sample_rate = 8000;
- p->encoding = AUDIO_ENCODING_SLINEAR_LE;
- p->precision = 16;
- p->bps = 2;
- p->msb = 1;
- p->channels = 1;
- }
- return 0;
-}
-
-/*
- * If we have an MTU value to use, round the blocksize to that.
- */
-static int
-btsco_round_blocksize(void *hdl, int bs)
-{
- struct btsco_softc *sc = hdl;
-
- if (sc->sc_mtu > 0) {
- bs = (bs / sc->sc_mtu) * sc->sc_mtu;
- if (bs == 0)
- bs = sc->sc_mtu;
- }
-
- DPRINTF("%s bs=%d, sc_mtu=%d\n",
- sc->sc_name, bs, sc->sc_mtu);
-
- return bs;
-}
-
-/*
- * Start Output
- *
- * We dont want to be calling the network stack at splaudio() so make
- * a note of what is to be sent, and schedule an interrupt to bundle
- * it up and queue it.
- */
-static int
-btsco_start_output(void *hdl, void *block, int blksize,
- void (*intr)(void *), void *intrarg)
-{
- struct btsco_softc *sc = hdl;
-
- DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize);
-
- if (sc->sc_sco == NULL)
- return ENOTCONN; /* connection lost */
-
- sc->sc_tx_block = block;
- sc->sc_tx_pending = 0;
- sc->sc_tx_size = blksize;
- sc->sc_tx_intr = intr;
- sc->sc_tx_intrarg = intrarg;
-
- timeout_add(&sc->sc_intr_to, 0);
- return 0;
-}
-
-/*
- * Start Input
- *
- * When the SCO link is up, we are getting data in any case, so all we do
- * is note what we want and where to put it and let the sco_input routine
- * fill in the data.
- *
- * If there was any leftover data that didnt fit in the last block, retry
- * it now.
- */
-static int
-btsco_start_input(void *hdl, void *block, int blksize,
- void (*intr)(void *), void *intrarg)
-{
- struct btsco_softc *sc = hdl;
- struct mbuf *m;
-
- DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize);
-
- if (sc->sc_sco == NULL)
- return ENOTCONN;
-
- sc->sc_rx_want = blksize;
- sc->sc_rx_block = block;
- sc->sc_rx_intr = intr;
- sc->sc_rx_intrarg = intrarg;
-
- if (sc->sc_rx_mbuf != NULL) {
- m = sc->sc_rx_mbuf;
- sc->sc_rx_mbuf = NULL;
- btsco_sco_input(sc, m);
- }
-
- return 0;
-}
-
-/*
- * Halt Output
- *
- * This doesnt really halt the output, but it will look
- * that way to the audio driver. The current block will
- * still be transmitted.
- */
-static int
-btsco_halt_output(void *hdl)
-{
- struct btsco_softc *sc = hdl;
-
- DPRINTFN(5, "%s\n", sc->sc_name);
-
- sc->sc_tx_size = 0;
- sc->sc_tx_block = NULL;
- sc->sc_tx_pending = 0;
- sc->sc_tx_intr = NULL;
- sc->sc_tx_intrarg = NULL;
-
- return 0;
-}
-
-/*
- * Halt Input
- *
- * This doesnt really halt the input, but it will look
- * that way to the audio driver. Incoming data will be
- * discarded.
- */
-static int
-btsco_halt_input(void *hdl)
-{
- struct btsco_softc *sc = hdl;
-
- DPRINTFN(5, "%s\n", sc->sc_name);
-
- sc->sc_rx_want = 0;
- sc->sc_rx_block = NULL;
- sc->sc_rx_intr = NULL;
- sc->sc_rx_intrarg = NULL;
-
- if (sc->sc_rx_mbuf != NULL) {
- m_freem(sc->sc_rx_mbuf);
- sc->sc_rx_mbuf = NULL;
- }
-
- return 0;
-}
-
-static int
-btsco_getdev(void *hdl, struct audio_device *ret)
-{
-
- *ret = btsco_device;
- return 0;
-}
-
-static int
-btsco_setfd(void *hdl, int fd)
-{
- DPRINTF("set %s duplex\n", fd ? "full" : "half");
-
- return 0;
-}
-
-static int
-btsco_set_port(void *hdl, mixer_ctrl_t *mc)
-{
- struct btsco_softc *sc = hdl;
- int err = 0;
-
- DPRINTF("%s dev %d type %d\n", sc->sc_name, mc->dev, mc->type);
-
- switch (mc->dev) {
- case BTSCO_VGS:
- if (mc->type != AUDIO_MIXER_VALUE ||
- mc->un.value.num_channels != 1) {
- err = EINVAL;
- break;
- }
-
- sc->sc_vgs = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
- break;
-
- case BTSCO_VGM:
- if (mc->type != AUDIO_MIXER_VALUE ||
- mc->un.value.num_channels != 1) {
- err = EINVAL;
- break;
- }
-
- sc->sc_vgm = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
- break;
-
- default:
- err = EINVAL;
- break;
- }
-
- return err;
-}
-
-static int
-btsco_get_port(void *hdl, mixer_ctrl_t *mc)
-{
- struct btsco_softc *sc = hdl;
- int err = 0;
-
- DPRINTF("%s dev %d\n", sc->sc_name, mc->dev);
-
- switch (mc->dev) {
- case BTSCO_VGS:
- mc->type = AUDIO_MIXER_VALUE;
- mc->un.value.num_channels = 1;
- mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgs;
- break;
-
- case BTSCO_VGM:
- mc->type = AUDIO_MIXER_VALUE;
- mc->un.value.num_channels = 1;
- mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgm;
- break;
-
- default:
- err = EINVAL;
- break;
- }
-
- return err;
-}
-
-static int
-btsco_query_devinfo(void *hdl, mixer_devinfo_t *di)
-{
-/* struct btsco_softc *sc = hdl; */
- int err = 0;
-
- switch(di->index) {
- case BTSCO_VGS:
- di->mixer_class = BTSCO_OUTPUT_CLASS;
- di->next = di->prev = AUDIO_MIXER_LAST;
- strlcpy(di->label.name, AudioNspeaker,
- sizeof(di->label.name));
- di->type = AUDIO_MIXER_VALUE;
- strlcpy(di->un.v.units.name, AudioNvolume,
- sizeof(di->un.v.units.name));
- di->un.v.num_channels = 1;
- di->un.v.delta = BTSCO_DELTA;
- break;
-
- case BTSCO_VGM:
- di->mixer_class = BTSCO_INPUT_CLASS;
- di->next = di->prev = AUDIO_MIXER_LAST;
- strlcpy(di->label.name, AudioNmicrophone,
- sizeof(di->label.name));
- di->type = AUDIO_MIXER_VALUE;
- strlcpy(di->un.v.units.name, AudioNvolume,
- sizeof(di->un.v.units.name));
- di->un.v.num_channels = 1;
- di->un.v.delta = BTSCO_DELTA;
- break;
-
- case BTSCO_INPUT_CLASS:
- di->mixer_class = BTSCO_INPUT_CLASS;
- di->next = di->prev = AUDIO_MIXER_LAST;
- strlcpy(di->label.name, AudioCinputs,
- sizeof(di->label.name));
- di->type = AUDIO_MIXER_CLASS;
- break;
-
- case BTSCO_OUTPUT_CLASS:
- di->mixer_class = BTSCO_OUTPUT_CLASS;
- di->next = di->prev = AUDIO_MIXER_LAST;
- strlcpy(di->label.name, AudioCoutputs,
- sizeof(di->label.name));
- di->type = AUDIO_MIXER_CLASS;
- break;
-
- default:
- err = ENXIO;
- break;
- }
-
- return err;
-}
-
-/*
- * Allocate Ring Buffers.
- */
-static void *
-btsco_allocm(void *hdl, int direction, size_t size, int pool, int flags)
-{
- struct btsco_softc *sc = hdl;
- void *addr;
-
- DPRINTF("%s: size %d direction %d\n", sc->sc_name, size, direction);
-
- addr = malloc(size, pool, flags);
-
- if (direction == AUMODE_PLAY) {
- sc->sc_tx_buf = addr;
- sc->sc_tx_refcnt = 0;
- }
-
- return addr;
-}
-
-/*
- * Free Ring Buffers.
- *
- * Because we used external memory for the tx mbufs, we dont
- * want to free the memory until all the mbufs are done with
- *
- * Just to be sure, dont free if something is still pending.
- * This would be a memory leak but at least there is a warning..
- */
-static void
-btsco_freem(void *hdl, void *addr, int pool)
-{
- struct btsco_softc *sc = hdl;
- int count = hz / 2;
-
- if (addr == sc->sc_tx_buf) {
- DPRINTF("%s: tx_refcnt=%d\n", sc->sc_name, sc->sc_tx_refcnt);
-
- sc->sc_tx_buf = NULL;
-
- while (sc->sc_tx_refcnt> 0 && count-- > 0)
- tsleep(sc, PWAIT, "drain", 1);
-
- if (sc->sc_tx_refcnt > 0) {
- printf("%s: ring buffer unreleased!\n", sc->sc_name);
- return;
- }
- }
-
- free(addr, pool);
-}
-
-static int
-btsco_get_props(void *hdl)
-{
-
- return AUDIO_PROP_FULLDUPLEX;
-}
-
-#ifdef notyet
-/*
- * Handle private ioctl. We pass information out about how to talk
- * to the device and mixer.
- */
-static int
-btsco_dev_ioctl(void *hdl, u_long cmd, void *addr, int flag,
- struct proc *l)
-{
- struct btsco_softc *sc = hdl;
- struct btsco_info *bi = (struct btsco_info *)addr;
- int err = 0;
-
- DPRINTF("%s cmd 0x%lx flag %d\n", sc->sc_name, cmd, flag);
-
- switch (cmd) {
- case BTSCO_GETINFO:
- memset(bi, 0, sizeof(*bi));
- bdaddr_copy(&bi->laddr, &sc->sc_laddr);
- bdaddr_copy(&bi->raddr, &sc->sc_raddr);
- bi->channel = sc->sc_channel;
- bi->vgs = BTSCO_VGS;
- bi->vgm = BTSCO_VGM;
- break;
-
- default:
- err = ENOTTY;
- break;
- }
-
- return err;
-}
-#endif
-
-
-/*****************************************************************************
- *
- * misc btsco functions
- *
- */
-
-/*
- * Our transmit interrupt. This is triggered when a new block is to be
- * sent. We send mtu sized chunks of the block as mbufs with external
- * storage to sco_send()
- */
-static void
-btsco_intr(void *arg)
-{
- struct btsco_softc *sc = arg;
- struct mbuf *m;
- uint8_t *block;
- int mlen, size;
- int s;
-
- DPRINTFN(10, "%s block %p size %d\n",
- sc->sc_name, sc->sc_tx_block, sc->sc_tx_size);
-
- if (sc->sc_sco == NULL)
- return; /* connection is lost */
-
- s = splsoftnet();
-
- block = sc->sc_tx_block;
- size = sc->sc_tx_size;
- sc->sc_tx_block = NULL;
- sc->sc_tx_size = 0;
-
- mutex_enter(&bt_lock);
- while (size > 0) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- break;
-
- mlen = MIN(sc->sc_mtu, size);
-
- /* I think M_DEVBUF is true but not relevant */
- MEXTADD(m, block, mlen, M_DEVBUF, btsco_extfree, sc);
- if ((m->m_flags & M_EXT) == 0) {
- m_free(m);
- break;
- }
- sc->sc_tx_refcnt++;
-
- m->m_pkthdr.len = m->m_len = mlen;
- sc->sc_tx_pending++;
-
- if (sco_send(sc->sc_sco, m) > 0) {
- sc->sc_tx_pending--;
- break;
- }
-
- block += mlen;
- size -= mlen;
- }
- mutex_exit(&bt_lock);
-
- splx(s);
-}
-
-/*
- * Release the mbuf, we keep a reference count on the tx buffer so
- * that we dont release it before its free.
- */
-static void
-btsco_extfree(caddr_t buf, u_int size, void *arg)
-{
- struct btsco_softc *sc = arg;
-
-#ifdef notyet
- if (m != NULL)
- pool_cache_put(mb_cache, m);
-#endif
-
- sc->sc_tx_refcnt--;
-}
diff --git a/sys/dev/bluetooth/btsco.h b/sys/dev/bluetooth/btsco.h
deleted file mode 100644
index 5f7ce449d67..00000000000
--- a/sys/dev/bluetooth/btsco.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* $OpenBSD: btsco.h,v 1.1 2008/11/24 22:31:19 uwe Exp $ */
-/* $NetBSD: btsco.h,v 1.2 2006/09/10 15:45:56 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DEV_BLUETOOTH_BTSCO_H_
-#define _DEV_BLUETOOTH_BTSCO_H_
-
-#include <netbt/bluetooth.h>
-
-/* btsco(4) properties */
-#define BTSCOlisten "listen"
-#define BTSCOchannel "rfcomm-channel"
-
-/*
- * We need to provide a way to get the SCO Audio contact information
- * from the audio device so that the control channel can be set up
- */
-
-struct btsco_info {
- bdaddr_t laddr; /* controller addr */
- bdaddr_t raddr; /* remote addr */
- uint8_t channel; /* RFCOMM channel */
- int vgs; /* mixer index speaker */
- int vgm; /* mixer index mic */
-};
-
-#define BTSCO_GETINFO _IOR('b', 16, struct btsco_info)
-
-#define BTSCO_DELTA 16 /* volume delta */
-
-#endif /* _DEV_BLUETOOTH_BTSCO_H_ */
diff --git a/sys/dev/bluetooth/files.bluetooth b/sys/dev/bluetooth/files.bluetooth
deleted file mode 100644
index 7f3678bf4a1..00000000000
--- a/sys/dev/bluetooth/files.bluetooth
+++ /dev/null
@@ -1,32 +0,0 @@
-# $OpenBSD: files.bluetooth,v 1.7 2010/07/31 16:04:50 miod Exp $
-#
-# Config file and device description for machine-independent Bluetooth code.
-# Included by ports that support Bluetooth host controllers.
-
-device bthub {}
-attach bthub at btbus
-file dev/bluetooth/bthub.c bthub needs-flag
-
-# HID
-# HID "bus"
-define bthidbus {[ reportid = -1 ]}
-
-# HID Device
-device bthidev: bluetooth, bthidbus, hid
-attach bthidev at bthub
-file dev/bluetooth/bthidev.c bthidev
-
-# HID Mice
-device btms: hid, hidms, wsmousedev
-attach btms at bthidbus
-file dev/bluetooth/btms.c btms
-
-# HID Keyboard
-device btkbd: hid, hidkbd, wskbddev
-attach btkbd at bthidbus
-file dev/bluetooth/btkbd.c btkbd
-
-# SCO Audio
-device btsco: bluetooth, audio, auconv, mulaw
-attach btsco at bthub
-file dev/bluetooth/btsco.c btsco
diff --git a/sys/dev/sdmmc/files.sdmmc b/sys/dev/sdmmc/files.sdmmc
index 0212c702145..b90aaff855c 100644
--- a/sys/dev/sdmmc/files.sdmmc
+++ b/sys/dev/sdmmc/files.sdmmc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sdmmc,v 1.3 2007/05/31 18:45:09 uwe Exp $
+# $OpenBSD: files.sdmmc,v 1.4 2014/07/11 21:54:38 tedu Exp $
#
# Config file and device description for machine-independent SD/MMC code.
# Included by ports that need it.
@@ -11,8 +11,3 @@ file dev/sdmmc/sdmmc_cis.c sdmmc
file dev/sdmmc/sdmmc_io.c sdmmc
file dev/sdmmc/sdmmc_mem.c sdmmc
file dev/sdmmc/sdmmc_scsi.c sdmmc
-
-# Bluetooth SDIO cards (Type-A/B)
-device sbt: btbus, bluetooth
-attach sbt at sdmmc
-file dev/sdmmc/sbt.c sbt
diff --git a/sys/dev/sdmmc/sbt.c b/sys/dev/sdmmc/sbt.c
deleted file mode 100644
index bc62c4b1bb1..00000000000
--- a/sys/dev/sdmmc/sbt.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/* $OpenBSD: sbt.c,v 1.17 2010/08/24 14:52:23 blambert Exp $ */
-
-/*
- * Copyright (c) 2007 Uwe Stuehler <uwe@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* Driver for Type-A/B SDIO Bluetooth cards */
-
-#include <sys/param.h>
-#include <sys/device.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/systm.h>
-
-#include <netbt/hci.h>
-
-#include <dev/sdmmc/sdmmcdevs.h>
-#include <dev/sdmmc/sdmmcvar.h>
-
-#define CSR_READ_1(sc, reg) sdmmc_io_read_1((sc)->sc_sf, (reg))
-#define CSR_WRITE_1(sc, reg, val) sdmmc_io_write_1((sc)->sc_sf, (reg), (val))
-
-#define SBT_REG_DAT 0x00 /* receiver/transmitter data */
-#define SBT_REG_RPC 0x10 /* read packet control */
-#define RPC_PCRRT (1<<0) /* packet read retry */
-#define SBT_REG_WPC 0x11 /* write packet control */
-#define WPC_PCWRT (1<<0) /* packet write retry */
-#define SBT_REG_RC 0x12 /* retry control status/set */
-#define SBT_REG_ISTAT 0x13 /* interrupt status */
-#define ISTAT_INTRD (1<<0) /* packet available for read */
-#define SBT_REG_ICLR 0x13 /* interrupt clear */
-#define SBT_REG_IENA 0x14 /* interrupt enable */
-#define SBT_REG_BTMODE 0x20 /* SDIO Bluetooth card mode */
-#define BTMODE_TYPEB (1<<0) /* 1=Type-B, 0=Type-A */
-
-#define SBT_PKT_BUFSIZ 65540
-#define SBT_RXTRY_MAX 5
-
-struct sbt_softc {
- struct device sc_dev; /* base device */
- struct sdmmc_function *sc_sf; /* SDIO function */
- struct workq *sc_workq; /* transfer deferred packets */
- int sc_enabled; /* HCI enabled */
- int sc_dying; /* shutdown in progress */
- int sc_busy; /* transmitting or receiving */
- void *sc_ih;
- u_char *sc_buf;
- int sc_rxtry;
-
- struct hci_unit *sc_unit; /* MI host controller */
- struct bt_stats sc_stats; /* MI bluetooth stats */
- struct ifqueue sc_cmdq;
- struct ifqueue sc_acltxq;
- struct ifqueue sc_scotxq;
-};
-
-int sbt_match(struct device *, void *, void *);
-void sbt_attach(struct device *, struct device *, void *);
-int sbt_detach(struct device *, int);
-
-int sbt_write_packet(struct sbt_softc *, u_char *, size_t);
-int sbt_read_packet(struct sbt_softc *, u_char *, size_t *);
-
-int sbt_intr(void *);
-
-int sbt_enable(struct device *);
-void sbt_disable(struct device *);
-void sbt_start(struct sbt_softc *, struct mbuf *, struct ifqueue *, int);
-void sbt_xmit_cmd(struct device *, struct mbuf *);
-void sbt_xmit_acl(struct device *, struct mbuf *);
-void sbt_xmit_sco(struct device *, struct mbuf *);
-void sbt_start_task(void *, void *);
-
-void sbt_stats(struct device *, struct bt_stats *, int);
-
-#undef DPRINTF
-#define SBT_DEBUG
-#ifdef SBT_DEBUG
-int sbt_debug = 0;
-#define DPRINTF(s) printf s
-#define DNPRINTF(n, s) do { if ((n) <= sbt_debug) printf s; } while (0)
-#else
-#define DPRINTF(s) do {} while (0)
-#define DNPRINTF(n, s) do {} while (0)
-#endif
-
-struct cfattach sbt_ca = {
- sizeof(struct sbt_softc), sbt_match, sbt_attach, sbt_detach
-};
-
-struct cfdriver sbt_cd = {
- NULL, "sbt", DV_DULL
-};
-
-
-/*
- * Autoconf glue
- */
-
-static const struct sbt_product {
- u_int16_t sp_vendor;
- u_int16_t sp_product;
- const char *sp_cisinfo[4];
-} sbt_products[] = {
- { SDMMC_VENDOR_SOCKETCOM,
- SDMMC_PRODUCT_SOCKETCOM_BTCARD,
- SDMMC_CIS_SOCKETCOM_BTCARD }
-};
-
-const struct hci_if sbt_hci = {
- .enable = sbt_enable,
- .disable = sbt_disable,
- .output_cmd = sbt_xmit_cmd,
- .output_acl = sbt_xmit_acl,
- .output_sco = sbt_xmit_sco,
- .get_stats = sbt_stats,
- .ipl = IPL_SDMMC
-};
-
-int
-sbt_match(struct device *parent, void *match, void *aux)
-{
- struct sdmmc_attach_args *sa = aux;
- const struct sbt_product *sp;
- struct sdmmc_function *sf;
- int i;
-
- if (sa->sf == NULL)
- return 0; /* not SDIO */
-
- sf = sa->sf->sc->sc_fn0;
- sp = &sbt_products[0];
-
- for (i = 0; i < sizeof(sbt_products) / sizeof(sbt_products[0]);
- i++, sp = &sbt_products[i])
- if (sp->sp_vendor == sf->cis.manufacturer &&
- sp->sp_product == sf->cis.product)
- return 1;
- return 0;
-}
-
-void
-sbt_attach(struct device *parent, struct device *self, void *aux)
-{
- struct sbt_softc *sc = (struct sbt_softc *)self;
- struct sdmmc_attach_args *sa = aux;
-
- SDMMC_ASSERT_LOCKED(sc->sc_sf->sc);
-
- printf("\n");
-
- sc->sc_sf = sa->sf;
-
- (void)sdmmc_io_function_disable(sc->sc_sf);
- if (sdmmc_io_function_enable(sc->sc_sf)) {
- printf("%s: function not ready\n", DEVNAME(sc));
- return;
- }
-
- /* It may be Type-B, but we use it only in Type-A mode. */
- printf("%s: SDIO Bluetooth Type-A\n", DEVNAME(sc));
-
- /* Create a shared buffer for receive and transmit. */
- sc->sc_buf = malloc(SBT_PKT_BUFSIZ, M_DEVBUF, M_NOWAIT);
- if (sc->sc_buf == NULL) {
- printf("%s: can't allocate cmd buffer\n", DEVNAME(sc));
- return;
- }
-
- /* Create a work thread to transmit deferred packets. */
- sc->sc_workq = workq_create(DEVNAME(sc), 1, IPL_SDMMC);
- if (sc->sc_workq == NULL) {
- printf("%s: can't allocate workq\n", DEVNAME(sc));
- return;
- }
-
- /* Enable the HCI packet transport read interrupt. */
- CSR_WRITE_1(sc, SBT_REG_IENA, ISTAT_INTRD);
-
- /* Enable the card interrupt for this function. */
- sc->sc_ih = sdmmc_intr_establish(parent, sbt_intr, sc, DEVNAME(sc));
- if (sc->sc_ih == NULL) {
- printf("%s: can't establish interrupt\n", DEVNAME(sc));
- return;
- }
- sdmmc_intr_enable(sc->sc_sf);
-
- /*
- * Attach Bluetooth unit (machine-independent HCI).
- */
- sc->sc_unit = hci_attach(&sbt_hci, &sc->sc_dev, 0);
-}
-
-int
-sbt_detach(struct device *self, int flags)
-{
- struct sbt_softc *sc = (struct sbt_softc *)self;
-
- sc->sc_dying = 1;
-
- while (sc->sc_busy)
- tsleep(&sc->sc_busy, PWAIT, "sbtdie", 0);
-
- /* Detach HCI interface */
- if (sc->sc_unit) {
- hci_detach(sc->sc_unit);
- sc->sc_unit = NULL;
- }
-
- if (sc->sc_ih != NULL)
- sdmmc_intr_disestablish(sc->sc_ih);
-
- if (sc->sc_workq != NULL)
- workq_destroy(sc->sc_workq);
-
- if (sc->sc_buf != NULL)
- free(sc->sc_buf, M_DEVBUF);
-
- return 0;
-}
-
-
-/*
- * Bluetooth HCI packet transport
- */
-
-int
-sbt_write_packet(struct sbt_softc *sc, u_char *buf, size_t len)
-{
- u_char hdr[3];
- size_t pktlen;
- int error = EIO;
- int retry = 3;
-
-again:
- if (retry-- == 0) {
- DPRINTF(("%s: sbt_write_cmd: giving up\n", DEVNAME(sc)));
- return error;
- }
-
- /* Restart the current packet. */
- sdmmc_io_write_1(sc->sc_sf, SBT_REG_WPC, WPC_PCWRT);
-
- /* Write the packet length. */
- pktlen = len + 3;
- hdr[0] = pktlen & 0xff;
- hdr[1] = (pktlen >> 8) & 0xff;
- hdr[2] = (pktlen >> 16) & 0xff;
- error = sdmmc_io_write_multi_1(sc->sc_sf, SBT_REG_DAT, hdr, 3);
- if (error) {
- DPRINTF(("%s: sbt_write_packet: failed to send length\n",
- DEVNAME(sc)));
- goto again;
- }
-
- error = sdmmc_io_write_multi_1(sc->sc_sf, SBT_REG_DAT, buf, len);
- if (error) {
- DPRINTF(("%s: sbt_write_packet: failed to send packet data\n",
- DEVNAME(sc)));
- goto again;
- }
- return 0;
-}
-
-int
-sbt_read_packet(struct sbt_softc *sc, u_char *buf, size_t *lenp)
-{
- u_char hdr[3];
- size_t len;
- int error;
-
- error = sdmmc_io_read_multi_1(sc->sc_sf, SBT_REG_DAT, hdr, 3);
- if (error) {
- DPRINTF(("%s: sbt_read_packet: failed to read length\n",
- DEVNAME(sc)));
- goto out;
- }
- len = (hdr[0] | (hdr[1] << 8) | (hdr[2] << 16)) - 3;
- if (len > *lenp) {
- DPRINTF(("%s: sbt_read_packet: len %u > %u\n",
- DEVNAME(sc), len, *lenp));
- error = ENOBUFS;
- goto out;
- }
-
- DNPRINTF(2,("%s: sbt_read_packet: reading len %u bytes\n",
- DEVNAME(sc), len));
- error = sdmmc_io_read_multi_1(sc->sc_sf, SBT_REG_DAT, buf, len);
- if (error) {
- DPRINTF(("%s: sbt_read_packet: failed to read packet data\n",
- DEVNAME(sc)));
- goto out;
- }
-
-out:
- rw_enter_write(&sc->sc_sf->sc->sc_lock);
- if (error) {
- if (sc->sc_rxtry >= SBT_RXTRY_MAX) {
- /* Drop and request the next packet. */
- sc->sc_rxtry = 0;
- CSR_WRITE_1(sc, SBT_REG_RPC, 0);
- } else {
- /* Request the current packet again. */
- sc->sc_rxtry++;
- CSR_WRITE_1(sc, SBT_REG_RPC, RPC_PCRRT);
- }
- rw_exit(&sc->sc_sf->sc->sc_lock);
- return error;
- }
-
- /* acknowledge read packet */
- CSR_WRITE_1(sc, SBT_REG_RPC, 0);
-
- rw_exit(&sc->sc_sf->sc->sc_lock);
-
- *lenp = len;
- return 0;
-}
-
-/*
- * Interrupt handling
- */
-
-/* This function is called from the SDIO interrupt thread. */
-int
-sbt_intr(void *arg)
-{
- struct sbt_softc *sc = arg;
- struct mbuf *m = NULL;
- u_int8_t status;
- size_t len;
- int s;
-
- /* Block further SDIO interrupts; XXX not really needed? */
- s = splsdmmc();
-
- rw_enter_write(&sc->sc_sf->sc->sc_lock);
- status = CSR_READ_1(sc, SBT_REG_ISTAT);
- CSR_WRITE_1(sc, SBT_REG_ICLR, status);
- rw_exit(&sc->sc_sf->sc->sc_lock);
-
- if ((status & ISTAT_INTRD) == 0)
- return 0; /* shared SDIO card interrupt? */
-
- len = SBT_PKT_BUFSIZ;
- if (sbt_read_packet(sc, sc->sc_buf, &len) != 0 || len == 0) {
- DPRINTF(("%s: sbt_intr: read failed\n", DEVNAME(sc)));
- goto eoi;
- }
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- DPRINTF(("%s: sbt_intr: MGETHDR failed\n", DEVNAME(sc)));
- goto eoi;
- }
-
- m->m_pkthdr.len = m->m_len = MHLEN;
- m_copyback(m, 0, len, sc->sc_buf, M_NOWAIT);
- if (m->m_pkthdr.len == MAX(MHLEN, len)) {
- m->m_pkthdr.len = len;
- m->m_len = MIN(MHLEN, m->m_pkthdr.len);
- } else {
- DPRINTF(("%s: sbt_intr: m_copyback failed\n", DEVNAME(sc)));
- m_free(m);
- m = NULL;
- }
-
-eoi:
- if (m != NULL) {
- switch (sc->sc_buf[0]) {
- case HCI_ACL_DATA_PKT:
- DNPRINTF(1,("%s: recv ACL packet (%d bytes)\n",
- DEVNAME(sc), m->m_pkthdr.len));
- hci_input_acl(sc->sc_unit, m);
- break;
- case HCI_SCO_DATA_PKT:
- DNPRINTF(1,("%s: recv SCO packet (%d bytes)\n",
- DEVNAME(sc), m->m_pkthdr.len));
- hci_input_sco(sc->sc_unit, m);
- break;
- case HCI_EVENT_PKT:
- DNPRINTF(1,("%s: recv EVENT packet (%d bytes)\n",
- DEVNAME(sc), m->m_pkthdr.len));
- hci_input_event(sc->sc_unit, m);
- break;
- default:
- DPRINTF(("%s: recv 0x%x packet (%d bytes)\n",
- DEVNAME(sc), sc->sc_buf[0], m->m_pkthdr.len));
- sc->sc_stats.err_rx++;
- m_free(m);
- break;
- }
- } else
- sc->sc_stats.err_rx++;
-
- splx(s);
-
- /* Claim this interrupt. */
- return 1;
-}
-
-
-/*
- * Bluetooth HCI unit functions
- */
-
-int
-sbt_enable(struct device *self)
-{
- struct sbt_softc *sc = (struct sbt_softc *)self;
-
- if (sc->sc_enabled)
- return 0;
-
- sc->sc_enabled = 1;
- return 0;
-}
-
-void
-sbt_disable(struct device *self)
-{
- struct sbt_softc *sc = (struct sbt_softc *)self;
- int s;
-
- if (!sc->sc_enabled)
- return;
-
- s = splsdmmc();
-#ifdef notyet /* XXX */
- if (sc->sc_rxp) {
- m_freem(sc->sc_rxp);
- sc->sc_rxp = NULL;
- }
-
- if (sc->sc_txp) {
- m_freem(sc->sc_txp);
- sc->sc_txp = NULL;
- }
-#endif
- sc->sc_enabled = 0;
- splx(s);
-}
-
-void
-sbt_start(struct sbt_softc *sc, struct mbuf *m, struct ifqueue *q, int xmit)
-{
- int s;
- int len;
-#ifdef SBT_DEBUG
- const char *what;
-#endif
-
- s = splsdmmc();
- if (m != NULL)
- IF_ENQUEUE(q, m);
-
- if (sc->sc_dying || IF_IS_EMPTY(q)) {
- splx(s);
- return;
- }
-
- if (curproc == NULL || sc->sc_busy) {
- (void)workq_add_task(sc->sc_workq, 0, sbt_start_task,
- sc, (void *)(long)xmit);
- splx(s);
- return;
- }
-
- /* Defer additional transfers and reception of packets. */
- sdmmc_intr_disable(sc->sc_sf);
- sc->sc_busy++;
-
- IF_DEQUEUE(q, m);
-
-#ifdef SBT_DEBUG
- switch (xmit) {
- case BTF_XMIT_CMD:
- what = "CMD";
- break;
- case BTF_XMIT_ACL:
- what = "ACL";
- break;
- case BTF_XMIT_SCO:
- what = "SCO";
- break;
- }
- DNPRINTF(1,("%s: xmit %s packet (%d bytes)\n", DEVNAME(sc),
- what, m->m_pkthdr.len));
-#endif
-
- sc->sc_unit->hci_flags |= xmit;
-
- len = m->m_pkthdr.len;
- m_copydata(m, 0, len, sc->sc_buf);
- m_freem(m);
-
- if (sbt_write_packet(sc, sc->sc_buf, len))
- DPRINTF(("%s: sbt_write_packet failed\n", DEVNAME(sc)));
-
- sc->sc_unit->hci_flags &= ~xmit;
-
- sc->sc_busy--;
- sdmmc_intr_enable(sc->sc_sf);
-
- if (sc->sc_dying)
- wakeup(&sc->sc_busy);
-
- splx(s);
-}
-
-void
-sbt_xmit_cmd(struct device *self, struct mbuf *m)
-{
- struct sbt_softc *sc = (struct sbt_softc *)self;
-
- sbt_start(sc, m, &sc->sc_cmdq, BTF_XMIT_CMD);
-}
-
-void
-sbt_xmit_acl(struct device *self, struct mbuf *m)
-{
- struct sbt_softc *sc = (struct sbt_softc *)self;
-
- sbt_start(sc, m, &sc->sc_acltxq, BTF_XMIT_ACL);
-}
-
-void
-sbt_xmit_sco(struct device *self, struct mbuf *m)
-{
- struct sbt_softc *sc = (struct sbt_softc *)self;
-
- sbt_start(sc, m, &sc->sc_scotxq, BTF_XMIT_SCO);
-}
-
-void
-sbt_start_task(void *arg1, void *arg2)
-{
- struct sbt_softc *sc = arg1;
- int xmit = (long)arg2;
-
- switch (xmit) {
- case BTF_XMIT_CMD:
- sbt_xmit_cmd(&sc->sc_dev, NULL);
- break;
- case BTF_XMIT_ACL:
- sbt_xmit_acl(&sc->sc_dev, NULL);
- break;
- case BTF_XMIT_SCO:
- sbt_xmit_sco(&sc->sc_dev, NULL);
- break;
- }
-}
-
-void
-sbt_stats(struct device *self, struct bt_stats *dest, int flush)
-{
- struct sbt_softc *sc = (struct sbt_softc *)self;
- int s;
-
- s = splsdmmc();
- memcpy(dest, &sc->sc_stats, sizeof(struct bt_stats));
-
- if (flush)
- memset(&sc->sc_stats, 0, sizeof(struct bt_stats));
-
- splx(s);
-}
diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb
index 06729e6784e..907abcbf218 100644
--- a/sys/dev/usb/files.usb
+++ b/sys/dev/usb/files.usb
@@ -1,4 +1,4 @@
-# $OpenBSD: files.usb,v 1.114 2014/03/25 03:29:23 jsg Exp $
+# $OpenBSD: files.usb,v 1.115 2014/07/11 21:54:38 tedu Exp $
# $NetBSD: files.usb,v 1.16 2000/02/14 20:29:54 augustss Exp $
#
# Config file and device description for machine-independent USB code.
@@ -354,11 +354,6 @@ device atu: ether, ifnet, ifmedia, wlan, firmload
attach atu at uhub
file dev/usb/if_atu.c atu
-# Bluetooth
-device ubt: btbus, bluetooth
-attach ubt at uhub
-file dev/usb/ubt.c ubt
-
# Ralink Technology RT2500USB
device ural: ether, ifnet, ifmedia, wlan
attach ural at uhub
diff --git a/sys/dev/usb/ubt.c b/sys/dev/usb/ubt.c
deleted file mode 100644
index 575e81c73e7..00000000000
--- a/sys/dev/usb/ubt.c
+++ /dev/null
@@ -1,1586 +0,0 @@
-/* $OpenBSD: ubt.c,v 1.26 2013/12/15 14:28:35 pirofti Exp $ */
-/* $NetBSD: ubt.c,v 1.35 2008/07/28 14:19:26 drochner Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) and
- * David Sainty (David.Sainty@dtsp.co.nz).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * This driver originally written by Lennart Augustsson and David Sainty,
- * but was mostly rewritten for the NetBSD Bluetooth protocol stack by
- * Iain Hibbert for Itronix, Inc using the FreeBSD ng_ubt.c driver as a
- * reference.
- */
-
-#include <sys/param.h>
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/systm.h>
-#include <sys/timeout.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdevs.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-
-/*******************************************************************************
- *
- * debugging stuff
- */
-#undef DPRINTF
-#undef DPRINTFN
-
-#define UBT_DEBUG 0
-#ifdef UBT_DEBUG
-int ubt_debug = UBT_DEBUG;
-
-#define DPRINTF(fmt, args...) do { \
- if (ubt_debug) \
- printf("%s: "fmt, __func__ , ##args); \
-} while (/* CONSTCOND */0)
-
-#define DPRINTFN(n, fmt, args...) do { \
- if (ubt_debug > (n)) \
- printf("%s: "fmt, __func__ , ##args); \
-} while (/* CONSTCOND */0)
-
-#else
-#define DPRINTF(...)
-#define DPRINTFN(...)
-#endif
-
-/*******************************************************************************
- *
- * ubt softc structure
- *
- */
-
-/* buffer sizes */
-/*
- * NB: although ACL packets can extend to 65535 bytes, most devices
- * have max_acl_size at much less (largest I have seen is 384)
- */
-#define UBT_BUFSIZ_CMD (HCI_CMD_PKT_SIZE - 1)
-#define UBT_BUFSIZ_ACL (2048 - 1)
-#define UBT_BUFSIZ_EVENT (HCI_EVENT_PKT_SIZE - 1)
-
-/* Transmit timeouts */
-#define UBT_CMD_TIMEOUT USBD_DEFAULT_TIMEOUT
-#define UBT_ACL_TIMEOUT USBD_DEFAULT_TIMEOUT
-
-/*
- * ISOC transfers
- *
- * xfer buffer size depends on the frame size, and the number
- * of frames per transfer is fixed, as each frame should be
- * 1ms worth of data. This keeps the rate that xfers complete
- * fairly constant. We use multiple xfers to keep the hardware
- * busy
- */
-#define UBT_NXFERS 3 /* max xfers to queue */
-#define UBT_NFRAMES 10 /* frames per xfer */
-
-struct ubt_isoc_xfer {
- struct ubt_softc *softc;
- struct usbd_xfer *xfer;
- uint8_t *buf;
- uint16_t size[UBT_NFRAMES];
- int busy;
-};
-
-struct ubt_softc {
- struct device sc_dev;
- struct usbd_device *sc_udev;
- int sc_refcnt;
- int sc_enabled;
-
- /* Control Interface */
- struct usbd_interface *sc_iface0;
-
- /* Commands (control) */
- struct usbd_xfer *sc_cmd_xfer;
- uint8_t *sc_cmd_buf;
- int sc_cmd_busy; /* write active */
- struct ifqueue sc_cmd_queue; /* output queue */
-
- /* Events (interrupt) */
- int sc_evt_addr; /* endpoint address */
- struct usbd_pipe *sc_evt_pipe;
- uint8_t *sc_evt_buf;
-
- /* ACL data (in) */
- int sc_aclrd_addr; /* endpoint address */
- struct usbd_pipe *sc_aclrd_pipe; /* read pipe */
- struct usbd_xfer *sc_aclrd_xfer; /* read xfer */
- uint8_t *sc_aclrd_buf; /* read buffer */
- int sc_aclrd_busy; /* reading */
-
- /* ACL data (out) */
- int sc_aclwr_addr; /* endpoint address */
- struct usbd_pipe *sc_aclwr_pipe; /* write pipe */
- struct usbd_xfer *sc_aclwr_xfer; /* write xfer */
- uint8_t *sc_aclwr_buf; /* write buffer */
- int sc_aclwr_busy; /* write active */
- struct ifqueue sc_aclwr_queue;/* output queue */
-
- /* ISOC interface */
- struct usbd_interface *sc_iface1; /* ISOC interface */
- int sc_config; /* current config no */
- int sc_alt_config; /* no of alternates */
-
- /* SCO data (in) */
- int sc_scord_addr; /* endpoint address */
- struct usbd_pipe *sc_scord_pipe; /* read pipe */
- int sc_scord_size; /* frame length */
- struct ubt_isoc_xfer sc_scord[UBT_NXFERS];
- struct mbuf *sc_scord_mbuf; /* current packet */
-
- /* SCO data (out) */
- int sc_scowr_addr; /* endpoint address */
- struct usbd_pipe *sc_scowr_pipe; /* write pipe */
- int sc_scowr_size; /* frame length */
- struct ubt_isoc_xfer sc_scowr[UBT_NXFERS];
- struct mbuf *sc_scowr_mbuf; /* current packet */
- int sc_scowr_busy; /* write active */
- struct ifqueue sc_scowr_queue;/* output queue */
-
- /* Protocol structure */
- struct hci_unit *sc_unit;
- struct bt_stats sc_stats;
-
- /* Successfully attached */
- int sc_ok;
-};
-
-/*
- * Bluetooth unit/USB callback routines
- */
-int ubt_enable(struct device *);
-void ubt_disable(struct device *);
-
-void ubt_xmit_cmd(struct device *, struct mbuf *);
-void ubt_xmit_cmd_start(struct ubt_softc *);
-void ubt_xmit_cmd_complete(struct usbd_xfer *, void *, usbd_status);
-
-void ubt_xmit_acl(struct device *, struct mbuf *);
-void ubt_xmit_acl_start(struct ubt_softc *);
-void ubt_xmit_acl_complete(struct usbd_xfer *, void *, usbd_status);
-
-void ubt_xmit_sco(struct device *, struct mbuf *);
-void ubt_xmit_sco_start(struct ubt_softc *);
-void ubt_xmit_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *);
-void ubt_xmit_sco_complete(struct usbd_xfer *, void *, usbd_status);
-
-void ubt_recv_event(struct usbd_xfer *, void *, usbd_status);
-
-void ubt_recv_acl_start(struct ubt_softc *);
-void ubt_recv_acl_complete(struct usbd_xfer *, void *, usbd_status);
-
-void ubt_recv_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *);
-void ubt_recv_sco_complete(struct usbd_xfer *, void *, usbd_status);
-
-void ubt_stats(struct device *, struct bt_stats *, int);
-
-int ubt_match(struct device *, void *, void *);
-void ubt_attach(struct device *, struct device *, void *);
-int ubt_detach(struct device *, int);
-int ubt_activate(struct device *, int);
-
-struct cfdriver ubt_cd = {
- NULL, "ubt", DV_DULL
-};
-
-const struct cfattach ubt_ca = {
- sizeof(struct ubt_softc),
- ubt_match,
- ubt_attach,
- ubt_detach,
- ubt_activate,
-};
-
-const struct hci_if ubt_hci = {
- .enable = ubt_enable,
- .disable = ubt_disable,
- .output_cmd = ubt_xmit_cmd,
- .output_acl = ubt_xmit_acl,
- .output_sco = ubt_xmit_sco,
- .get_stats = ubt_stats,
- .ipl = IPL_USB, /* IPL_SOFTUSB ??? */
-};
-
-static int ubt_set_isoc_config(struct ubt_softc *);
-static void ubt_abortdealloc(struct ubt_softc *);
-
-/*
- * Match against the whole device, since we want to take
- * both interfaces. If a device should be ignored then add
- *
- * { VendorID, ProductID }
- *
- * to the ubt_ignore list.
- */
-static const struct usb_devno ubt_ignore[] = {
- { USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033NF }
-};
-
-int
-ubt_match(struct device *parent, void *match, void *aux)
-{
- struct usb_attach_arg *uaa = aux;
- usb_device_descriptor_t *dd = usbd_get_device_descriptor(uaa->device);
-
- DPRINTFN(50, "ubt_match\n");
-
- if (usb_lookup(ubt_ignore, uaa->vendor, uaa->product))
- return UMATCH_NONE;
-
- if (dd->bDeviceClass == UDCLASS_WIRELESS
- && dd->bDeviceSubClass == UDSUBCLASS_RF
- && dd->bDeviceProtocol == UDPROTO_BLUETOOTH)
- return UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO;
-
- return UMATCH_NONE;
-}
-
-
-void
-ubt_attach(struct device *parent, struct device *self, void *aux)
-{
- struct ubt_softc *sc = (struct ubt_softc *)self;
- struct usb_attach_arg *uaa = aux;
- usb_config_descriptor_t *cd;
- usb_endpoint_descriptor_t *ed;
- int err;
- uint8_t count, i;
-
- DPRINTFN(50, "ubt_attach: sc=%p\n", sc);
-
- sc->sc_udev = uaa->device;
-
-#ifndef __OpenBSD__ /* ??? */
- MBUFQ_INIT(&sc->sc_cmd_queue);
- MBUFQ_INIT(&sc->sc_aclwr_queue);
- MBUFQ_INIT(&sc->sc_scowr_queue);
-#endif
-
- /*
- * Move the device into the configured state
- */
- err = usbd_set_config_index(sc->sc_udev, 0, 1);
- if (err) {
- printf("%s: failed to set configuration idx 0: %s\n",
- sc->sc_dev.dv_xname, usbd_errstr(err));
-
- return;
- }
-
- /*
- * Interface 0 must have 3 endpoints
- * 1) Interrupt endpoint to receive HCI events
- * 2) Bulk IN endpoint to receive ACL data
- * 3) Bulk OUT endpoint to send ACL data
- */
- err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface0);
- if (err) {
- printf("%s: Could not get interface 0 handle %s (%d)\n",
- sc->sc_dev.dv_xname, usbd_errstr(err), err);
-
- return;
- }
-
- sc->sc_evt_addr = -1;
- sc->sc_aclrd_addr = -1;
- sc->sc_aclwr_addr = -1;
-
- count = 0;
- (void)usbd_endpoint_count(sc->sc_iface0, &count);
-
- for (i = 0 ; i < count ; i++) {
- int dir, type;
-
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface0, i);
- if (ed == NULL) {
- printf("%s: could not read endpoint descriptor %d\n",
- sc->sc_dev.dv_xname, i);
-
- return;
- }
-
- dir = UE_GET_DIR(ed->bEndpointAddress);
- type = UE_GET_XFERTYPE(ed->bmAttributes);
-
- if (dir == UE_DIR_IN && type == UE_INTERRUPT)
- sc->sc_evt_addr = ed->bEndpointAddress;
- else if (dir == UE_DIR_IN && type == UE_BULK)
- sc->sc_aclrd_addr = ed->bEndpointAddress;
- else if (dir == UE_DIR_OUT && type == UE_BULK)
- sc->sc_aclwr_addr = ed->bEndpointAddress;
- }
-
- if (sc->sc_evt_addr == -1) {
- printf("%s: missing INTERRUPT endpoint on interface 0\n",
- sc->sc_dev.dv_xname);
-
- return;
- }
- if (sc->sc_aclrd_addr == -1) {
- printf("%s: missing BULK IN endpoint on interface 0\n",
- sc->sc_dev.dv_xname);
-
- return;
- }
- if (sc->sc_aclwr_addr == -1) {
- printf("%s: missing BULK OUT endpoint on interface 0\n",
- sc->sc_dev.dv_xname);
-
- return;
- }
-
- /*
- * Interface 1 must have 2 endpoints
- * 1) Isochronous IN endpoint to receive SCO data
- * 2) Isochronous OUT endpoint to send SCO data
- *
- * and will have several configurations, which can be selected
- * via a sysctl variable. We select config 0 to start, which
- * means that no SCO data will be available.
- */
- err = usbd_device2interface_handle(sc->sc_udev, 1, &sc->sc_iface1);
- if (err) {
- printf("%s: Could not get interface 1 handle %s (%d)\n",
- sc->sc_dev.dv_xname, usbd_errstr(err), err);
-
- return;
- }
-
- cd = usbd_get_config_descriptor(sc->sc_udev);
- if (cd == NULL) {
- printf("%s: could not get config descriptor\n",
- sc->sc_dev.dv_xname);
-
- return;
- }
-
- sc->sc_alt_config = usbd_get_no_alts(cd, 1);
-
- /* set initial config */
- err = ubt_set_isoc_config(sc);
- if (err) {
- printf("%s: ISOC config failed\n",
- sc->sc_dev.dv_xname);
-
- return;
- }
-
- /* Attach HCI */
- sc->sc_unit = hci_attach(&ubt_hci, &sc->sc_dev, 0);
-
- sc->sc_ok = 1;
- /* XXX pmf_device_deregister in NetBSD (power hook) */
-}
-
-int
-ubt_detach(struct device *self, int flags)
-{
- struct ubt_softc *sc = (struct ubt_softc *)self;
- int s;
-
- DPRINTF("sc=%p flags=%d\n", sc, flags);
-
- /* XXX pmf_device_deregister in NetBSD (power hook) */
-
- if (!sc->sc_ok)
- return 0;
-
- /* Detach HCI interface */
- if (sc->sc_unit) {
- hci_detach(sc->sc_unit);
- sc->sc_unit = NULL;
- }
-
- /*
- * Abort all pipes. Causes processes waiting for transfer to wake.
- *
- * Actually, hci_detach() above will call ubt_disable() which may
- * call ubt_abortdealloc(), but lets be sure since doing it twice
- * wont cause an error.
- */
- ubt_abortdealloc(sc);
-
- /* wait for all processes to finish */
- s = splusb();
- if (sc->sc_refcnt-- > 0)
- usb_detach_wait(&sc->sc_dev);
-
- splx(s);
-
- DPRINTFN(1, "driver detached\n");
-
- return 0;
-}
-
-int
-ubt_activate(struct device *self, int act)
-{
- struct ubt_softc *sc = (struct ubt_softc *)self;
-
- switch (act) {
- case DVACT_DEACTIVATE:
- usbd_deactivate(sc->sc_udev);
- break;
- }
- return (0);
-}
-
-/* set ISOC configuration */
-int
-ubt_set_isoc_config(struct ubt_softc *sc)
-{
- usb_endpoint_descriptor_t *ed;
- int rd_addr, wr_addr, rd_size, wr_size;
- uint8_t count, i;
- int err;
-
- err = usbd_set_interface(sc->sc_iface1, sc->sc_config);
- if (err != USBD_NORMAL_COMPLETION) {
- printf(
- "%s: Could not set config %d on ISOC interface. %s (%d)\n",
- sc->sc_dev.dv_xname, sc->sc_config, usbd_errstr(err), err);
-
- return err == USBD_IN_USE ? EBUSY : EIO;
- }
-
- /*
- * We wont get past the above if there are any pipes open, so no
- * need to worry about buf/xfer/pipe deallocation. If we get an
- * error after this, the frame quantities will be 0 and no SCO
- * data will be possible.
- */
-
- sc->sc_scord_size = rd_size = 0;
- sc->sc_scord_addr = rd_addr = -1;
-
- sc->sc_scowr_size = wr_size = 0;
- sc->sc_scowr_addr = wr_addr = -1;
-
- count = 0;
- (void)usbd_endpoint_count(sc->sc_iface1, &count);
-
- for (i = 0 ; i < count ; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface1, i);
- if (ed == NULL) {
- printf("%s: could not read endpoint descriptor %d\n",
- sc->sc_dev.dv_xname, i);
-
- return EIO;
- }
-
- DPRINTFN(5, "%s: endpoint type %02x (%02x) addr %02x (%s)\n",
- sc->sc_dev.dv_xname,
- UE_GET_XFERTYPE(ed->bmAttributes),
- UE_GET_ISO_TYPE(ed->bmAttributes),
- ed->bEndpointAddress,
- UE_GET_DIR(ed->bEndpointAddress) ? "in" : "out");
-
- if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
- continue;
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) {
- rd_addr = ed->bEndpointAddress;
- rd_size = UGETW(ed->wMaxPacketSize);
- } else {
- wr_addr = ed->bEndpointAddress;
- wr_size = UGETW(ed->wMaxPacketSize);
- }
- }
-
- if (rd_addr == -1) {
- printf(
- "%s: missing ISOC IN endpoint on interface config %d\n",
- sc->sc_dev.dv_xname, sc->sc_config);
-
- return ENOENT;
- }
- if (wr_addr == -1) {
- printf(
- "%s: missing ISOC OUT endpoint on interface config %d\n",
- sc->sc_dev.dv_xname, sc->sc_config);
-
- return ENOENT;
- }
-
-#ifdef DIAGNOSTIC
- if (rd_size > MLEN) {
- printf("%s: rd_size=%d exceeds MLEN\n",
- sc->sc_dev.dv_xname, rd_size);
-
- return EOVERFLOW;
- }
-
- if (wr_size > MLEN) {
- printf("%s: wr_size=%d exceeds MLEN\n",
- sc->sc_dev.dv_xname, wr_size);
-
- return EOVERFLOW;
- }
-#endif
-
- sc->sc_scord_size = rd_size;
- sc->sc_scord_addr = rd_addr;
-
- sc->sc_scowr_size = wr_size;
- sc->sc_scowr_addr = wr_addr;
-
- return 0;
-}
-
-void
-ubt_abortdealloc(struct ubt_softc *sc)
-{
- int i;
-
- DPRINTFN(1, "sc=%p\n", sc);
-
- /* Abort all pipes */
- if (sc->sc_evt_pipe != NULL) {
- usbd_abort_pipe(sc->sc_evt_pipe);
- usbd_close_pipe(sc->sc_evt_pipe);
- sc->sc_evt_pipe = NULL;
- }
-
- if (sc->sc_aclrd_pipe != NULL) {
- usbd_abort_pipe(sc->sc_aclrd_pipe);
- usbd_close_pipe(sc->sc_aclrd_pipe);
- sc->sc_aclrd_pipe = NULL;
- }
-
- if (sc->sc_aclwr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_aclwr_pipe);
- usbd_close_pipe(sc->sc_aclwr_pipe);
- sc->sc_aclwr_pipe = NULL;
- }
-
- if (sc->sc_scord_pipe != NULL) {
- usbd_abort_pipe(sc->sc_scord_pipe);
- usbd_close_pipe(sc->sc_scord_pipe);
- sc->sc_scord_pipe = NULL;
- }
-
- if (sc->sc_scowr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_scowr_pipe);
- usbd_close_pipe(sc->sc_scowr_pipe);
- sc->sc_scowr_pipe = NULL;
- }
-
- /* Free event buffer */
- if (sc->sc_evt_buf != NULL) {
- free(sc->sc_evt_buf, M_USBDEV);
- sc->sc_evt_buf = NULL;
- }
-
- /* Free all xfers and xfer buffers (implicit) */
- if (sc->sc_cmd_xfer != NULL) {
- usbd_free_xfer(sc->sc_cmd_xfer);
- sc->sc_cmd_xfer = NULL;
- sc->sc_cmd_buf = NULL;
- }
-
- if (sc->sc_aclrd_xfer != NULL) {
- usbd_free_xfer(sc->sc_aclrd_xfer);
- sc->sc_aclrd_xfer = NULL;
- sc->sc_aclrd_buf = NULL;
- }
-
- if (sc->sc_aclwr_xfer != NULL) {
- usbd_free_xfer(sc->sc_aclwr_xfer);
- sc->sc_aclwr_xfer = NULL;
- sc->sc_aclwr_buf = NULL;
- }
-
- for (i = 0 ; i < UBT_NXFERS ; i++) {
- if (sc->sc_scord[i].xfer != NULL) {
- usbd_free_xfer(sc->sc_scord[i].xfer);
- sc->sc_scord[i].xfer = NULL;
- sc->sc_scord[i].buf = NULL;
- }
-
- if (sc->sc_scowr[i].xfer != NULL) {
- usbd_free_xfer(sc->sc_scowr[i].xfer);
- sc->sc_scowr[i].xfer = NULL;
- sc->sc_scowr[i].buf = NULL;
- }
- }
-
- /* Free partial SCO packets */
- if (sc->sc_scord_mbuf != NULL) {
- m_freem(sc->sc_scord_mbuf);
- sc->sc_scord_mbuf = NULL;
- }
-
- if (sc->sc_scowr_mbuf != NULL) {
- m_freem(sc->sc_scowr_mbuf);
- sc->sc_scowr_mbuf = NULL;
- }
-
- /* Empty mbuf queues */
- IF_PURGE(&sc->sc_cmd_queue);
- IF_PURGE(&sc->sc_aclwr_queue);
- IF_PURGE(&sc->sc_scowr_queue);
-}
-
-/*******************************************************************************
- *
- * Bluetooth Unit/USB callbacks
- *
- */
-int
-ubt_enable(struct device *self)
-{
- struct ubt_softc *sc = (struct ubt_softc *)self;
- usbd_status err;
- int s, i, error;
-
- DPRINTFN(1, "sc=%p\n", sc);
-
- if (sc->sc_enabled)
- return 0;
-
- s = splusb();
-
- /* Events */
- sc->sc_evt_buf = malloc(UBT_BUFSIZ_EVENT, M_USBDEV, M_NOWAIT);
- if (sc->sc_evt_buf == NULL) {
- error = ENOMEM;
- goto bad;
- }
- err = usbd_open_pipe_intr(sc->sc_iface0,
- sc->sc_evt_addr,
- USBD_SHORT_XFER_OK,
- &sc->sc_evt_pipe,
- sc,
- sc->sc_evt_buf,
- UBT_BUFSIZ_EVENT,
- ubt_recv_event,
- USBD_DEFAULT_INTERVAL);
- if (err != USBD_NORMAL_COMPLETION) {
- error = EIO;
- goto bad;
- }
-
- /* Commands */
- sc->sc_cmd_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_cmd_xfer == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_cmd_buf = usbd_alloc_buffer(sc->sc_cmd_xfer, UBT_BUFSIZ_CMD);
- if (sc->sc_cmd_buf == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_cmd_busy = 0;
-
- /* ACL read */
- err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclrd_addr,
- USBD_EXCLUSIVE_USE, &sc->sc_aclrd_pipe);
- if (err != USBD_NORMAL_COMPLETION) {
- error = EIO;
- goto bad;
- }
- sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_aclrd_xfer == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, UBT_BUFSIZ_ACL);
- if (sc->sc_aclrd_buf == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_aclrd_busy = 0;
- ubt_recv_acl_start(sc);
-
- /* ACL write */
- err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclwr_addr,
- USBD_EXCLUSIVE_USE, &sc->sc_aclwr_pipe);
- if (err != USBD_NORMAL_COMPLETION) {
- error = EIO;
- goto bad;
- }
- sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_aclwr_xfer == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, UBT_BUFSIZ_ACL);
- if (sc->sc_aclwr_buf == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_aclwr_busy = 0;
-
- /* SCO read */
- if (sc->sc_scord_size > 0) {
- err = usbd_open_pipe(sc->sc_iface1, sc->sc_scord_addr,
- USBD_EXCLUSIVE_USE, &sc->sc_scord_pipe);
- if (err != USBD_NORMAL_COMPLETION) {
- error = EIO;
- goto bad;
- }
-
- for (i = 0 ; i < UBT_NXFERS ; i++) {
- sc->sc_scord[i].xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_scord[i].xfer == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_scord[i].buf = usbd_alloc_buffer(sc->sc_scord[i].xfer,
- sc->sc_scord_size * UBT_NFRAMES);
- if (sc->sc_scord[i].buf == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_scord[i].softc = sc;
- sc->sc_scord[i].busy = 0;
- ubt_recv_sco_start1(sc, &sc->sc_scord[i]);
- }
- }
-
- /* SCO write */
- if (sc->sc_scowr_size > 0) {
- err = usbd_open_pipe(sc->sc_iface1, sc->sc_scowr_addr,
- USBD_EXCLUSIVE_USE, &sc->sc_scowr_pipe);
- if (err != USBD_NORMAL_COMPLETION) {
- error = EIO;
- goto bad;
- }
-
- for (i = 0 ; i < UBT_NXFERS ; i++) {
- sc->sc_scowr[i].xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_scowr[i].xfer == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_scowr[i].buf = usbd_alloc_buffer(sc->sc_scowr[i].xfer,
- sc->sc_scowr_size * UBT_NFRAMES);
- if (sc->sc_scowr[i].buf == NULL) {
- error = ENOMEM;
- goto bad;
- }
- sc->sc_scowr[i].softc = sc;
- sc->sc_scowr[i].busy = 0;
- }
-
- sc->sc_scowr_busy = 0;
- }
-
- sc->sc_enabled = 1;
- splx(s);
- return 0;
-
-bad:
- ubt_abortdealloc(sc);
- splx(s);
- return error;
-}
-
-void
-ubt_disable(struct device *self)
-{
- struct ubt_softc *sc = (struct ubt_softc *)self;
- int s;
-
- DPRINTFN(1, "sc=%p\n", sc);
-
- if (sc->sc_enabled == 0)
- return;
-
- s = splusb();
- ubt_abortdealloc(sc);
-
- sc->sc_enabled = 0;
- splx(s);
-}
-
-void
-ubt_xmit_cmd(struct device *self, struct mbuf *m)
-{
- struct ubt_softc *sc = (struct ubt_softc *)self;
- int s;
-
- KASSERT(sc->sc_enabled);
-
- s = splusb();
- IF_ENQUEUE(&sc->sc_cmd_queue, m);
-
- if (sc->sc_cmd_busy == 0)
- ubt_xmit_cmd_start(sc);
-
- splx(s);
-}
-
-void
-ubt_xmit_cmd_start(struct ubt_softc *sc)
-{
- usb_device_request_t req;
- usbd_status status;
- struct mbuf *m;
- int len;
-
- if (usbd_is_dying(sc->sc_udev))
- return;
-
- if (IF_IS_EMPTY(&sc->sc_cmd_queue))
- return;
-
- IF_DEQUEUE(&sc->sc_cmd_queue, m);
- KASSERT(m != NULL);
-
- DPRINTFN(15, "%s: xmit CMD packet (%d bytes)\n",
- &sc->sc_dev, m->m_pkthdr.len);
-
- sc->sc_refcnt++;
- sc->sc_cmd_busy = 1;
-
- len = m->m_pkthdr.len - 1;
- m_copydata(m, 1, len, sc->sc_cmd_buf);
- m_freem(m);
-
- memset(&req, 0, sizeof(req));
- req.bmRequestType = UT_WRITE_CLASS_DEVICE;
- USETW(req.wLength, len);
-
- usbd_setup_default_xfer(sc->sc_cmd_xfer,
- sc->sc_udev,
- sc,
- UBT_CMD_TIMEOUT,
- &req,
- sc->sc_cmd_buf,
- len,
- USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
- ubt_xmit_cmd_complete);
-
- status = usbd_transfer(sc->sc_cmd_xfer);
-
- KASSERT(status != USBD_NORMAL_COMPLETION);
-
- if (status != USBD_IN_PROGRESS) {
- DPRINTF("usbd_transfer status=%s (%d)\n",
- usbd_errstr(status), status);
-
- sc->sc_refcnt--;
- sc->sc_cmd_busy = 0;
- }
-}
-
-void
-ubt_xmit_cmd_complete(struct usbd_xfer *xfer, void *h, usbd_status status)
-{
- struct ubt_softc *sc = h;
- uint32_t count;
-
- DPRINTFN(15, "%s: CMD complete status=%s (%d)\n",
- sc->sc_dev.dv_xname, usbd_errstr(status), status);
-
- sc->sc_cmd_busy = 0;
-
- if (--sc->sc_refcnt < 0) {
- DPRINTF("sc_refcnt=%d\n", sc->sc_refcnt);
- usb_detach_wakeup(&sc->sc_dev);
- return;
- }
-
- if (usbd_is_dying(sc->sc_udev)) {
- DPRINTF("dying\n");
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF("status=%s (%d)\n",
- usbd_errstr(status), status);
-
- sc->sc_stats.err_tx++;
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- sc->sc_stats.cmd_tx++;
- sc->sc_stats.byte_tx += count;
-
- ubt_xmit_cmd_start(sc);
-}
-
-void
-ubt_xmit_acl(struct device *self, struct mbuf *m)
-{
- struct ubt_softc *sc = (struct ubt_softc *)self;
- int s;
-
- KASSERT(sc->sc_enabled);
-
- s = splusb();
- IF_ENQUEUE(&sc->sc_aclwr_queue, m);
-
- if (sc->sc_aclwr_busy == 0)
- ubt_xmit_acl_start(sc);
-
- splx(s);
-}
-
-void
-ubt_xmit_acl_start(struct ubt_softc *sc)
-{
- struct mbuf *m;
- usbd_status status;
- int len;
-
- if (usbd_is_dying(sc->sc_udev))
- return;
-
- if (IF_IS_EMPTY(&sc->sc_aclwr_queue))
- return;
-
- sc->sc_refcnt++;
- sc->sc_aclwr_busy = 1;
-
- IF_DEQUEUE(&sc->sc_aclwr_queue, m);
- KASSERT(m != NULL);
-
- DPRINTFN(15, "%s: xmit ACL packet (%d bytes)\n",
- sc->sc_dev.dv_xname, m->m_pkthdr.len);
-
- len = m->m_pkthdr.len - 1;
- if (len > UBT_BUFSIZ_ACL) {
- DPRINTF("%s: truncating ACL packet (%d => %d)!\n",
- sc->sc_dev.dv_xname, len, UBT_BUFSIZ_ACL);
-
- len = UBT_BUFSIZ_ACL;
- }
-
- m_copydata(m, 1, len, sc->sc_aclwr_buf);
- m_freem(m);
-
- sc->sc_stats.acl_tx++;
- sc->sc_stats.byte_tx += len;
-
- usbd_setup_xfer(sc->sc_aclwr_xfer,
- sc->sc_aclwr_pipe,
- sc,
- sc->sc_aclwr_buf,
- len,
- USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
- UBT_ACL_TIMEOUT,
- ubt_xmit_acl_complete);
-
- status = usbd_transfer(sc->sc_aclwr_xfer);
-
- KASSERT(status != USBD_NORMAL_COMPLETION);
-
- if (status != USBD_IN_PROGRESS) {
- DPRINTF("usbd_transfer status=%s (%d)\n",
- usbd_errstr(status), status);
-
- sc->sc_refcnt--;
- sc->sc_aclwr_busy = 0;
- }
-}
-
-void
-ubt_xmit_acl_complete(struct usbd_xfer *xfer, void *h, usbd_status status)
-{
- struct ubt_softc *sc = h;
-
- DPRINTFN(15, "%s: ACL complete status=%s (%d)\n",
- sc->sc_dev.dv_xname, usbd_errstr(status), status);
-
- sc->sc_aclwr_busy = 0;
-
- if (--sc->sc_refcnt < 0) {
- usb_detach_wakeup(&sc->sc_dev);
- return;
- }
-
- if (usbd_is_dying(sc->sc_udev))
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF("status=%s (%d)\n",
- usbd_errstr(status), status);
-
- sc->sc_stats.err_tx++;
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_aclwr_pipe);
- else
- return;
- }
-
- ubt_xmit_acl_start(sc);
-}
-
-void
-ubt_xmit_sco(struct device *self, struct mbuf *m)
-{
- struct ubt_softc *sc = (struct ubt_softc *)self;
- int s;
-
- KASSERT(sc->sc_enabled);
-
- s = splusb();
- IF_ENQUEUE(&sc->sc_scowr_queue, m);
-
- if (sc->sc_scowr_busy == 0)
- ubt_xmit_sco_start(sc);
-
- splx(s);
-}
-
-void
-ubt_xmit_sco_start(struct ubt_softc *sc)
-{
- int i;
-
- if (usbd_is_dying(sc->sc_udev) || sc->sc_scowr_size == 0)
- return;
-
- for (i = 0 ; i < UBT_NXFERS ; i++) {
- if (sc->sc_scowr[i].busy)
- continue;
-
- ubt_xmit_sco_start1(sc, &sc->sc_scowr[i]);
- }
-}
-
-void
-ubt_xmit_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
-{
- struct mbuf *m;
- uint8_t *buf;
- int num, len, size, space;
-
- space = sc->sc_scowr_size * UBT_NFRAMES;
- buf = isoc->buf;
- len = 0;
-
- /*
- * Fill the request buffer with data from the queue,
- * keeping any leftover packet on our private hook.
- *
- * Complete packets are passed back up to the stack
- * for disposal, since we can't rely on the controller
- * to tell us when it has finished with them.
- */
-
- m = sc->sc_scowr_mbuf;
- while (space > 0) {
- if (m == NULL) {
- IF_DEQUEUE(&sc->sc_scowr_queue, m);
- if (m == NULL)
- break;
-
- m_adj(m, 1); /* packet type */
- }
-
- if (m->m_pkthdr.len > 0) {
- size = MIN(m->m_pkthdr.len, space);
-
- m_copydata(m, 0, size, buf);
- m_adj(m, size);
-
- buf += size;
- len += size;
- space -= size;
- }
-
- if (m->m_pkthdr.len == 0) {
- sc->sc_stats.sco_tx++;
- if (!hci_complete_sco(sc->sc_unit, m))
- sc->sc_stats.err_tx++;
-
- m = NULL;
- }
- }
- sc->sc_scowr_mbuf = m;
-
- DPRINTFN(15, "isoc=%p, len=%d, space=%d\n", isoc, len, space);
-
- if (len == 0) /* nothing to send */
- return;
-
- sc->sc_refcnt++;
- sc->sc_scowr_busy = 1;
- sc->sc_stats.byte_tx += len;
- isoc->busy = 1;
-
- /*
- * calculate number of isoc frames and sizes
- */
-
- for (num = 0 ; len > 0 ; num++) {
- size = MIN(sc->sc_scowr_size, len);
-
- isoc->size[num] = size;
- len -= size;
- }
-
- usbd_setup_isoc_xfer(isoc->xfer,
- sc->sc_scowr_pipe,
- isoc,
- isoc->size,
- num,
- USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
- ubt_xmit_sco_complete);
-
- usbd_transfer(isoc->xfer);
-}
-
-void
-ubt_xmit_sco_complete(struct usbd_xfer *xfer, void *h, usbd_status status)
-{
- struct ubt_isoc_xfer *isoc = h;
- struct ubt_softc *sc;
- int i;
-
- KASSERT(xfer == isoc->xfer);
- sc = isoc->softc;
-
- DPRINTFN(15, "isoc=%p, status=%s (%d)\n",
- isoc, usbd_errstr(status), status);
-
- isoc->busy = 0;
-
- for (i = 0 ; ; i++) {
- if (i == UBT_NXFERS) {
- sc->sc_scowr_busy = 0;
- break;
- }
-
- if (sc->sc_scowr[i].busy)
- break;
- }
-
- if (--sc->sc_refcnt < 0) {
- usb_detach_wakeup(&sc->sc_dev);
- return;
- }
-
- if (usbd_is_dying(sc->sc_udev))
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF("status=%s (%d)\n",
- usbd_errstr(status), status);
-
- sc->sc_stats.err_tx++;
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_scowr_pipe);
- else
- return;
- }
-
- ubt_xmit_sco_start(sc);
-}
-
-/*
- * load incoming data into an mbuf with
- * leading type byte
- */
-static struct mbuf *
-ubt_mbufload(uint8_t *buf, int count, uint8_t type)
-{
- struct mbuf *m;
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return NULL;
-
- *mtod(m, uint8_t *) = type;
- m->m_pkthdr.len = m->m_len = MHLEN;
- m_copyback(m, 1, count, buf, M_NOWAIT); /* extends if this doesn't fail */
- if (m->m_pkthdr.len != MAX(MHLEN, count + 1)) {
- m_free(m);
- return NULL;
- }
-
- m->m_pkthdr.len = count + 1;
- m->m_len = MIN(MHLEN, m->m_pkthdr.len);
-
- return m;
-}
-
-void
-ubt_recv_event(struct usbd_xfer *xfer, void *h, usbd_status status)
-{
- struct ubt_softc *sc = h;
- struct mbuf *m;
- uint32_t count;
- void *buf;
-
- DPRINTFN(15, "sc=%p status=%s (%d)\n",
- sc, usbd_errstr(status), status);
-
- if (status != USBD_NORMAL_COMPLETION || usbd_is_dying(sc->sc_udev))
- return;
-
- usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
-
- if (count < sizeof(hci_event_hdr_t) - 1) {
- DPRINTF("dumped undersized event (count = %d)\n", count);
- sc->sc_stats.err_rx++;
- return;
- }
-
- sc->sc_stats.evt_rx++;
- sc->sc_stats.byte_rx += count;
-
- m = ubt_mbufload(buf, count, HCI_EVENT_PKT);
- if (m == NULL || !hci_input_event(sc->sc_unit, m))
- sc->sc_stats.err_rx++;
-}
-
-void
-ubt_recv_acl_start(struct ubt_softc *sc)
-{
- usbd_status status;
-
- DPRINTFN(15, "sc=%p\n", sc);
-
- if (sc->sc_aclrd_busy) {
- DPRINTF("sc_aclrd_busy=%d\n", sc->sc_aclrd_busy);
- return;
- }
- if (usbd_is_dying(sc->sc_udev)) {
- DPRINTF("dying");
- return;
- }
-
- sc->sc_refcnt++;
- sc->sc_aclrd_busy = 1;
-
- usbd_setup_xfer(sc->sc_aclrd_xfer,
- sc->sc_aclrd_pipe,
- sc,
- sc->sc_aclrd_buf,
- UBT_BUFSIZ_ACL,
- USBD_NO_COPY | USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT,
- ubt_recv_acl_complete);
-
- status = usbd_transfer(sc->sc_aclrd_xfer);
-
- KASSERT(status != USBD_NORMAL_COMPLETION);
-
- if (status != USBD_IN_PROGRESS) {
- DPRINTF("usbd_transfer status=%s (%d)\n",
- usbd_errstr(status), status);
-
- sc->sc_refcnt--;
- sc->sc_aclrd_busy = 0;
- }
-}
-
-void
-ubt_recv_acl_complete(struct usbd_xfer *xfer, void *h, usbd_status status)
-{
- struct ubt_softc *sc = h;
- struct mbuf *m;
- uint32_t count;
- void *buf;
-
- DPRINTFN(15, "sc=%p status=%s (%d)\n",
- sc, usbd_errstr(status), status);
-
- sc->sc_aclrd_busy = 0;
-
- if (--sc->sc_refcnt < 0) {
- DPRINTF("refcnt = %d\n", sc->sc_refcnt);
- usb_detach_wakeup(&sc->sc_dev);
- return;
- }
-
- if (usbd_is_dying(sc->sc_udev)) {
- DPRINTF("dying\n");
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF("status=%s (%d)\n",
- usbd_errstr(status), status);
-
- sc->sc_stats.err_rx++;
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_aclrd_pipe);
- else
- return;
- } else {
- usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
-
- if (count < sizeof(hci_acldata_hdr_t) - 1) {
- DPRINTF("dumped undersized packet (%d)\n", count);
- sc->sc_stats.err_rx++;
- } else {
- sc->sc_stats.acl_rx++;
- sc->sc_stats.byte_rx += count;
-
- m = ubt_mbufload(buf, count, HCI_ACL_DATA_PKT);
- if (m == NULL || !hci_input_acl(sc->sc_unit, m))
- sc->sc_stats.err_rx++;
- }
- }
-
- /* and restart */
- ubt_recv_acl_start(sc);
-}
-
-void
-ubt_recv_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
-{
- int i;
-
- DPRINTFN(15, "sc=%p, isoc=%p\n", sc, isoc);
-
- if (usbd_is_dying(sc->sc_udev)) {
- DPRINTF("dying");
- return;
- }
- if (isoc->busy || sc->sc_scord_size == 0) {
- DPRINTF("%s%s\n",
- isoc->busy ? " busy" : "",
- sc->sc_scord_size == 0 ? " size=0" : "");
-
- return;
- }
-
- sc->sc_refcnt++;
- isoc->busy = 1;
-
- for (i = 0 ; i < UBT_NFRAMES ; i++)
- isoc->size[i] = sc->sc_scord_size;
-
- usbd_setup_isoc_xfer(isoc->xfer,
- sc->sc_scord_pipe,
- isoc,
- isoc->size,
- UBT_NFRAMES,
- USBD_NO_COPY | USBD_SHORT_XFER_OK,
- ubt_recv_sco_complete);
-
- usbd_transfer(isoc->xfer);
-}
-
-void
-ubt_recv_sco_complete(struct usbd_xfer *xfer, void *h, usbd_status status)
-{
- struct ubt_isoc_xfer *isoc = h;
- struct ubt_softc *sc;
- struct mbuf *m;
- uint32_t count;
- uint8_t *ptr, *frame;
- int i, size, got, want;
-
- KASSERT(isoc != NULL);
- KASSERT(isoc->xfer == xfer);
-
- sc = isoc->softc;
- isoc->busy = 0;
-
- if (--sc->sc_refcnt < 0) {
- DPRINTF("refcnt=%d\n", sc->sc_refcnt);
- usb_detach_wakeup(&sc->sc_dev);
- return;
- }
-
- if (usbd_is_dying(sc->sc_udev)) {
- DPRINTF("dying\n");
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF("status=%s (%d)\n",
- usbd_errstr(status), status);
-
- sc->sc_stats.err_rx++;
-
- if (status == USBD_STALLED) {
- usbd_clear_endpoint_stall_async(sc->sc_scord_pipe);
- goto restart;
- }
-
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- if (count == 0)
- goto restart;
-
- DPRINTFN(15, "sc=%p, isoc=%p, count=%u\n",
- sc, isoc, count);
-
- sc->sc_stats.byte_rx += count;
-
- /*
- * Extract SCO packets from ISOC frames. The way we have it,
- * no SCO packet can be bigger than MHLEN. This is unlikely
- * to actually happen, but if we ran out of mbufs and lost
- * sync then we may get spurious data that makes it seem that
- * way, so we discard data that wont fit. This doesnt really
- * help with the lost sync situation alas.
- */
-
- m = sc->sc_scord_mbuf;
- if (m != NULL) {
- sc->sc_scord_mbuf = NULL;
- ptr = mtod(m, uint8_t *) + m->m_pkthdr.len;
- got = m->m_pkthdr.len;
- want = sizeof(hci_scodata_hdr_t);
- if (got >= want)
- want += mtod(m, hci_scodata_hdr_t *)->length ;
- } else {
- ptr = NULL;
- got = 0;
- want = 0;
- }
-
- for (i = 0 ; i < UBT_NFRAMES ; i++) {
- frame = isoc->buf + (i * sc->sc_scord_size);
-
- while (isoc->size[i] > 0) {
- size = isoc->size[i];
-
- if (m == NULL) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- printf("%s: out of memory (xfer halted)\n",
- sc->sc_dev.dv_xname);
-
- sc->sc_stats.err_rx++;
- return; /* lost sync */
- }
-
- ptr = mtod(m, uint8_t *);
- *ptr++ = HCI_SCO_DATA_PKT;
- got = 1;
- want = sizeof(hci_scodata_hdr_t);
- }
-
- if (got + size > want)
- size = want - got;
-
- if (got + size > MHLEN)
- memcpy(ptr, frame, MHLEN - got);
- else
- memcpy(ptr, frame, size);
-
- ptr += size;
- got += size;
- frame += size;
-
- if (got == want) {
- /*
- * If we only got a header, add the packet
- * length to our want count. Send complete
- * packets up to protocol stack.
- */
- if (want == sizeof(hci_scodata_hdr_t))
- want += mtod(m, hci_scodata_hdr_t *)->length;
-
- if (got == want) {
- m->m_pkthdr.len = m->m_len = got;
- sc->sc_stats.sco_rx++;
- if (!hci_input_sco(sc->sc_unit, m))
- sc->sc_stats.err_rx++;
-
- m = NULL;
- }
- }
-
- isoc->size[i] -= size;
- }
- }
-
- if (m != NULL) {
- m->m_pkthdr.len = m->m_len = got;
- sc->sc_scord_mbuf = m;
- }
-
-restart: /* and restart */
- ubt_recv_sco_start1(sc, isoc);
-}
-
-void
-ubt_stats(struct device *self, struct bt_stats *dest, int flush)
-{
- struct ubt_softc *sc = (struct ubt_softc *)self;
- int s;
-
- s = splusb();
- memcpy(dest, &sc->sc_stats, sizeof(struct bt_stats));
-
- if (flush)
- memset(&sc->sc_stats, 0, sizeof(struct bt_stats));
-
- splx(s);
-}
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index f34e03d6baf..67cbc10a424 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_domain.c,v 1.36 2014/07/08 17:19:25 deraadt Exp $ */
+/* $OpenBSD: uipc_domain.c,v 1.37 2014/07/11 21:54:38 tedu Exp $ */
/* $NetBSD: uipc_domain.c,v 1.14 1996/02/09 19:00:44 christos Exp $ */
/*
@@ -44,7 +44,6 @@
#include <sys/sysctl.h>
#include <sys/timeout.h>
-#include "bluetooth.h"
#include "bpfilter.h"
#include "pflow.h"
@@ -95,9 +94,6 @@ domaininit(void)
ADDDOMAIN(key);
#endif
#endif
-#if NBLUETOOTH > 0
- ADDDOMAIN(bt);
-#endif
ADDDOMAIN(route);
for (dp = domains; dp; dp = dp->dom_next) {
diff --git a/sys/net/if.c b/sys/net/if.c
index 86f0b35d513..1d5a1b24a1c 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.294 2014/07/08 07:10:12 dlg Exp $ */
+/* $OpenBSD: if.c,v 1.295 2014/07/11 21:54:38 tedu Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -61,7 +61,6 @@
* @(#)if.c 8.3 (Berkeley) 1/4/94
*/
-#include "bluetooth.h"
#include "bpfilter.h"
#include "bridge.h"
#include "carp.h"
diff --git a/sys/net/netisr.c b/sys/net/netisr.c
index bc0310fb347..7093418194a 100644
--- a/sys/net/netisr.c
+++ b/sys/net/netisr.c
@@ -20,7 +20,6 @@
#include <machine/intr.h>
-#include "bluetooth.h"
#include "ether.h"
#include "ppp.h"
#include "bridge.h"
@@ -68,11 +67,6 @@ netintr(void *unused) /* ARGSUSED */
if (n & (1 << NETISR_PPPOE))
pppoeintr();
#endif
-#if NBLUETOOTH > 0
- if (n & (1 << NETISR_BT))
- btintr();
-#endif
-
t |= n;
}
diff --git a/sys/netbt/bluetooth.h b/sys/netbt/bluetooth.h
deleted file mode 100644
index 027a08fee09..00000000000
--- a/sys/netbt/bluetooth.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* $OpenBSD: bluetooth.h,v 1.6 2008/11/22 04:42:58 uwe Exp $ */
-/* $NetBSD: bluetooth.h,v 1.8 2008/09/08 23:36:55 gmcgarry Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _NETBT_BLUETOOTH_H_
-#define _NETBT_BLUETOOTH_H_
-
-#include <sys/socket.h>
-#include <sys/types.h>
-
-/*
- * Bluetooth Address Family Protocol Numbers
- */
-#define BTPROTO_HCI 1
-#define BTPROTO_L2CAP 2
-#define BTPROTO_RFCOMM 3
-#define BTPROTO_SCO 4
-
-/* All sizes are in bytes */
-#define BLUETOOTH_BDADDR_SIZE 6
-
-/*
- * Bluetooth device address
- */
-typedef struct {
- uint8_t b[BLUETOOTH_BDADDR_SIZE];
-} __packed bdaddr_t;
-
-/*
- * bdaddr utility functions
- */
-static __inline int
-bdaddr_same(const bdaddr_t *a, const bdaddr_t *b)
-{
-
- return (a->b[0] == b->b[0] && a->b[1] == b->b[1]
- && a->b[2] == b->b[2] && a->b[3] == b->b[3]
- && a->b[4] == b->b[4] && a->b[5] == b->b[5]);
-}
-
-static __inline int
-bdaddr_any(const bdaddr_t *a)
-{
-
- return (a->b[0] == 0 && a->b[1] == 0 && a->b[2] == 0
- && a->b[3] == 0 && a->b[4] == 0 && a->b[5] == 0);
-}
-
-static __inline void
-bdaddr_copy(bdaddr_t *d, const bdaddr_t *s)
-{
-
- d->b[0] = s->b[0];
- d->b[1] = s->b[1];
- d->b[2] = s->b[2];
- d->b[3] = s->b[3];
- d->b[4] = s->b[4];
- d->b[5] = s->b[5];
-}
-
-/*
- * Socket address used by Bluetooth protocols
- */
-struct sockaddr_bt {
- uint8_t bt_len;
- sa_family_t bt_family;
- bdaddr_t bt_bdaddr;
- uint16_t bt_psm;
- uint8_t bt_channel;
- uint8_t bt_zero[5];
-};
-
-/* Note: this is actually 6 bytes including terminator */
-#define BDADDR_ANY ((const bdaddr_t *) "\000\000\000\000\000")
-
-#ifdef _KERNEL
-
-/*
- * Bluetooth Protocol API callback methods
- */
-struct mbuf;
-struct btproto {
- void (*connecting)(void *);
- void (*connected)(void *);
- void (*disconnected)(void *, int);
- void *(*newconn)(void *, struct sockaddr_bt *, struct sockaddr_bt *);
- void (*complete)(void *, int);
- void (*linkmode)(void *, int);
- void (*input)(void *, struct mbuf *);
-};
-
-/*
- * Debugging stuff
- */
-
-#define BLUETOOTH_DEBUG
-#ifdef BLUETOOTH_DEBUG
-extern int bluetooth_debug;
-# define DPRINTF(fmt, args...) do { \
- if (bluetooth_debug) \
- printf("%s: "fmt, __func__ , ##args); \
-} while (/* CONSTCOND */0)
-
-# define DPRINTFN(n, fmt, args...) do { \
- if (bluetooth_debug > (n)) \
- printf("%s: "fmt, __func__ , ##args); \
-} while (/* CONSTCOND */0)
-
-# define UNKNOWN(value) \
- printf("%s: %s = %d unknown!\n", __func__, #value, (value));
-#else
-# define DPRINTF(...) ((void)0)
-# define DPRINTFN(...) ((void)0)
-# define UNKNOWN(x) ((void)0)
-#endif /* BLUETOOTH_DEBUG */
-
-extern struct mutex bt_lock;
-
-/* XXX NetBSD compatibility goo, abused for debugging */
-#ifdef BLUETOOTH_DEBUG
-#define mutex_enter(mtx) do { \
- DPRINTFN(1, "mtx_enter(" __STRING(mtx) ") in %d\n", \
- curproc ? curproc->p_pid : 0); \
- mtx_enter((mtx)); \
-} while (/*CONSTCOND*/0)
-#define mutex_exit(mtx) do { \
- DPRINTFN(1, "mtx_leave(" __STRING(mtx) ") in %d\n", \
- curproc ? curproc->p_pid : 0); \
- mtx_leave((mtx)); \
-} while (/*CONSTCOND*/0)
-#else
-#define mutex_enter mtx_enter
-#define mutex_exit mtx_leave
-#endif
-
-#endif /* _KERNEL */
-
-#endif /* _NETBT_BLUETOOTH_H_ */
diff --git a/sys/netbt/bt_input.c b/sys/netbt/bt_input.c
deleted file mode 100644
index 61976fbebb4..00000000000
--- a/sys/netbt/bt_input.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* $OpenBSD: bt_input.c,v 1.5 2007/06/24 20:55:27 uwe Exp $ */
-/*
- * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/timeout.h>
-
-#include <net/netisr.h>
-
-#include <netbt/hci.h>
-
-void
-btintr(void)
-{
- struct hci_unit *unit;
-
- TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
- hci_intr(unit);
- }
-}
diff --git a/sys/netbt/bt_proto.c b/sys/netbt/bt_proto.c
deleted file mode 100644
index a291753d213..00000000000
--- a/sys/netbt/bt_proto.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $OpenBSD: bt_proto.c,v 1.6 2008/11/24 20:19:51 uwe Exp $ */
-/*
- * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/domain.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/timeout.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/bt_var.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-#include <netbt/rfcomm.h>
-#include <netbt/sco.h>
-
-struct domain btdomain;
-
-void bt_init(void);
-
-struct protosw btsw[] = {
- { SOCK_RAW, &btdomain, BTPROTO_HCI,
- PR_ATOMIC | PR_ADDR,
- NULL/*input*/, NULL/*output*/, NULL/*ctlinput*/,
- hci_ctloutput, hci_usrreq, NULL/*init*/,
- NULL/*fasttimo*/, NULL/*slowtimo*/, NULL/*drain*/,
- NULL/*sysctl*/
- },
- { SOCK_SEQPACKET, &btdomain, BTPROTO_SCO,
- PR_ATOMIC | PR_CONNREQUIRED,
- NULL/*input*/, NULL/*output*/, NULL/*ctlinput*/,
- sco_ctloutput, sco_usrreq, NULL/*init*/,
- NULL/*fasttimo*/, NULL/*slowtimo*/, NULL/*drain*/,
- NULL/*sysctl*/
- },
- { SOCK_SEQPACKET, &btdomain, BTPROTO_L2CAP,
- PR_ATOMIC | PR_CONNREQUIRED,
- NULL/*input*/, NULL/*output*/, NULL/*ctlinput*/,
- l2cap_ctloutput, l2cap_usrreq, l2cap_init,
- NULL/*fasttimo*/, NULL/*slowtimo*/, NULL/*drain*/,
- NULL/*sysctl*/
- },
- { SOCK_STREAM, &btdomain, BTPROTO_RFCOMM,
- PR_CONNREQUIRED | PR_WANTRCVD,
- NULL/*input*/, NULL/*output*/, NULL/*ctlinput*/,
- rfcomm_ctloutput, rfcomm_usrreq, rfcomm_init,
- NULL/*fasttimo*/, NULL/*slowtimo*/, NULL/*drain*/,
- NULL/*sysctl*/
- }
-};
-
-struct domain btdomain = {
- AF_BLUETOOTH, "bluetooth",
- bt_init, NULL/*externalize*/, NULL/*dispose*/,
- btsw, &btsw[sizeof(btsw) / sizeof(btsw[0])], NULL,
- NULL/*rtattach*/, 32, sizeof(struct sockaddr_bt),
- NULL/*ifattach*/, NULL/*ifdetach*/
-};
-
-struct mutex bt_lock;
-
-void
-bt_init(void)
-{
- /*
- * In accordance with mutex(9), since hci_intr() uses the
- * lock, we associate the subsystem lock with IPL_SOFTNET.
- * For unknown reasons, in NetBSD the interrupt level is
- * IPL_NONE.
- */
- mtx_init(&bt_lock, IPL_BIO);
-}
diff --git a/sys/netbt/bt_var.h b/sys/netbt/bt_var.h
deleted file mode 100644
index 6d9ecb5ea18..00000000000
--- a/sys/netbt/bt_var.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* $OpenBSD: bt_var.h,v 1.2 2007/06/24 20:55:27 uwe Exp $ */
-/*
- * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _NETBT_BT_VAR_H_
-#define _NETBT_BT_VAR_H_
-
-#endif /* !_NETBT_BT_VAR_H_ */
diff --git a/sys/netbt/hci.h b/sys/netbt/hci.h
deleted file mode 100644
index e9092e33bc1..00000000000
--- a/sys/netbt/hci.h
+++ /dev/null
@@ -1,2582 +0,0 @@
-/* $OpenBSD: hci.h,v 1.13 2008/11/25 14:00:12 uwe Exp $ */
-/* $NetBSD: hci.h,v 1.28 2008/09/08 23:36:55 gmcgarry Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/*-
- * Copyright (c) 2001 Maksim Yevmenkin <m_evmenkin@yahoo.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: hci.h,v 1.13 2008/11/25 14:00:12 uwe Exp $
- * $FreeBSD: src/sys/netgraph/bluetooth/include/ng_hci.h,v 1.6 2005/01/07 01:45:43 imp Exp $
- */
-
-/*
- * This file contains everything that applications need to know from
- * Host Controller Interface (HCI). Information taken from Bluetooth
- * Core Specifications (v1.1, v2.0 and v2.1)
- *
- * This file can be included by both kernel and userland applications.
- *
- * NOTE: Here and after Bluetooth device is called a "unit". Bluetooth
- * specification refers to both devices and units. They are the
- * same thing (I think), so to be consistent word "unit" will be
- * used.
- */
-
-#ifndef _NETBT_HCI_H_
-#define _NETBT_HCI_H_
-
-#include <netbt/bluetooth.h>
-
-#include <sys/mutex.h>
-
-/**************************************************************************
- **************************************************************************
- ** Common defines and types (HCI)
- **************************************************************************
- **************************************************************************/
-
-#define HCI_LAP_SIZE 3 /* unit LAP */
-#define HCI_KEY_SIZE 16 /* link key */
-#define HCI_PIN_SIZE 16 /* link PIN */
-#define HCI_EVENT_MASK_SIZE 8 /* event mask */
-#define HCI_CLASS_SIZE 3 /* unit class */
-#define HCI_FEATURES_SIZE 8 /* LMP features */
-#define HCI_UNIT_NAME_SIZE 248 /* unit name size */
-#define HCI_DEVNAME_SIZE 16 /* same as dv_xname */
-#define HCI_COMMANDS_SIZE 64 /* supported commands mask */
-
-/* HCI specification */
-#define HCI_SPEC_V10 0x00 /* v1.0 */
-#define HCI_SPEC_V11 0x01 /* v1.1 */
-#define HCI_SPEC_V12 0x02 /* v1.2 */
-#define HCI_SPEC_V20 0x03 /* v2.0 */
-#define HCI_SPEC_V21 0x04 /* v2.1 */
-/* 0x05 - 0xFF - reserved for future use */
-
-/* LMP features (and page 0 of extended features) */
-/* ------------------- byte 0 --------------------*/
-#define HCI_LMP_3SLOT 0x01
-#define HCI_LMP_5SLOT 0x02
-#define HCI_LMP_ENCRYPTION 0x04
-#define HCI_LMP_SLOT_OFFSET 0x08
-#define HCI_LMP_TIMIACCURACY 0x10
-#define HCI_LMP_ROLE_SWITCH 0x20
-#define HCI_LMP_HOLD_MODE 0x40
-#define HCI_LMP_SNIFF_MODE 0x80
-/* ------------------- byte 1 --------------------*/
-#define HCI_LMP_PARK_MODE 0x01
-#define HCI_LMP_RSSI 0x02
-#define HCI_LMP_CHANNEL_QUALITY 0x04
-#define HCI_LMP_SCO_LINK 0x08
-#define HCI_LMP_HV2_PKT 0x10
-#define HCI_LMP_HV3_PKT 0x20
-#define HCI_LMP_ULAW_LOG 0x40
-#define HCI_LMP_ALAW_LOG 0x80
-/* ------------------- byte 2 --------------------*/
-#define HCI_LMP_CVSD 0x01
-#define HCI_LMP_PAGISCHEME 0x02
-#define HCI_LMP_POWER_CONTROL 0x04
-#define HCI_LMP_TRANSPARENT_SCO 0x08
-#define HCI_LMP_FLOW_CONTROL_LAG0 0x10
-#define HCI_LMP_FLOW_CONTROL_LAG1 0x20
-#define HCI_LMP_FLOW_CONTROL_LAG2 0x40
-#define HCI_LMP_BC_ENCRYPTION 0x80
-/* ------------------- byte 3 --------------------*/
-/* reserved 0x01 */
-#define HCI_LMP_EDR_ACL_2MBPS 0x02
-#define HCI_LMP_EDR_ACL_3MBPS 0x04
-#define HCI_LMP_ENHANCED_ISCAN 0x08
-#define HCI_LMP_INTERLACED_ISCAN 0x10
-#define HCI_LMP_INTERLACED_PSCAN 0x20
-#define HCI_LMP_RSSI_INQUIRY 0x40
-#define HCI_LMP_EV3_PKT 0x80
-/* ------------------- byte 4 --------------------*/
-#define HCI_LMP_EV4_PKT 0x01
-#define HCI_LMP_EV5_PKT 0x02
-/* reserved 0x04 */
-#define HCI_LMP_AFH_CAPABLE_SLAVE 0x08
-#define HCI_LMP_AFH_CLASS_SLAVE 0x10
-/* reserved 0x20 */
-/* reserved 0x40 */
-#define HCI_LMP_3SLOT_EDR_ACL 0x80
-/* ------------------- byte 5 --------------------*/
-#define HCI_LMP_5SLOT_EDR_ACL 0x01
-#define HCI_LMP_SNIFF_SUBRATING 0x02
-#define HCI_LMP_PAUSE_ENCRYPTION 0x04
-#define HCI_LMP_AFH_CAPABLE_MASTER 0x08
-#define HCI_LMP_AFH_CLASS_MASTER 0x10
-#define HCI_LMP_EDR_eSCO_2MBPS 0x20
-#define HCI_LMP_EDR_eSCO_3MBPS 0x40
-#define HCI_LMP_3SLOT_EDR_eSCO 0x80
-/* ------------------- byte 6 --------------------*/
-#define HCI_LMP_EXTENDED_INQUIRY 0x01
-/* reserved 0x02 */
-/* reserved 0x04 */
-#define HCI_LMP_SIMPLE_PAIRING 0x08
-#define HCI_LMP_ENCAPSULATED_PDU 0x10
-#define HCI_LMP_ERRDATA_REPORTING 0x20
-#define HCI_LMP_NOFLUSH_PB_FLAG 0x40
-/* reserved 0x80 */
-/* ------------------- byte 7 --------------------*/
-#define HCI_LMP_LINK_SUPERVISION_TO 0x01
-#define HCI_LMP_INQ_RSP_TX_POWER 0x02
-#define HCI_LMP_EXTENDED_FEATURES 0x80
-
-/* Link types */
-#define HCI_LINK_SCO 0x00 /* Voice */
-#define HCI_LINK_ACL 0x01 /* Data */
-#define HCI_LINK_eSCO 0x02 /* eSCO */
-/* 0x03 - 0xFF - reserved for future use */
-
-/*
- * ACL/SCO packet type bits are set to enable the
- * packet type, except for 2MBPS and 3MBPS when they
- * are unset to enable the packet type.
- */
-/* ACL Packet types for "Create Connection" */
-#define HCI_PKT_2MBPS_DH1 0x0002
-#define HCI_PKT_3MBPS_DH1 0x0004
-#define HCI_PKT_DM1 0x0008
-#define HCI_PKT_DH1 0x0010
-#define HCI_PKT_2MBPS_DH3 0x0100
-#define HCI_PKT_3MBPS_DH3 0x0200
-#define HCI_PKT_DM3 0x0400
-#define HCI_PKT_DH3 0x0800
-#define HCI_PKT_2MBPS_DH5 0x1000
-#define HCI_PKT_3MBPS_DH5 0x2000
-#define HCI_PKT_DM5 0x4000
-#define HCI_PKT_DH5 0x8000
-
-/* SCO Packet types for "Setup Synchronous Connection" */
-#define HCI_PKT_HV1 0x0001
-#define HCI_PKT_HV2 0x0002
-#define HCI_PKT_HV3 0x0004
-#define HCI_PKT_EV3 0x0008
-#define HCI_PKT_EV4 0x0010
-#define HCI_PKT_EV5 0x0020
-#define HCI_PKT_2MBPS_EV3 0x0040
-#define HCI_PKT_3MBPS_EV3 0x0080
-#define HCI_PKT_2MBPS_EV5 0x0100
-#define HCI_PKT_3MBPS_EV5 0x0200
-
-/*
- * Connection modes/Unit modes
- *
- * This is confusing. It means that one of the units change its mode
- * for the specific connection. For example one connection was put on
- * hold (but i could be wrong :)
- */
-
-/* Page scan modes (are deprecated) */
-#define HCI_MANDATORY_PAGE_SCAN_MODE 0x00
-#define HCI_OPTIONAL_PAGE_SCAN_MODE1 0x01
-#define HCI_OPTIONAL_PAGE_SCAN_MODE2 0x02
-#define HCI_OPTIONAL_PAGE_SCAN_MODE3 0x03
-/* 0x04 - 0xFF - reserved for future use */
-
-/* Page scan repetition modes */
-#define HCI_SCAN_REP_MODE0 0x00
-#define HCI_SCAN_REP_MODE1 0x01
-#define HCI_SCAN_REP_MODE2 0x02
-/* 0x03 - 0xFF - reserved for future use */
-
-/* Page scan period modes */
-#define HCI_PAGE_SCAN_PERIOD_MODE0 0x00
-#define HCI_PAGE_SCAN_PERIOD_MODE1 0x01
-#define HCI_PAGE_SCAN_PERIOD_MODE2 0x02
-/* 0x03 - 0xFF - reserved for future use */
-
-/* Scan enable */
-#define HCI_NO_SCAN_ENABLE 0x00
-#define HCI_INQUIRY_SCAN_ENABLE 0x01
-#define HCI_PAGE_SCAN_ENABLE 0x02
-/* 0x04 - 0xFF - reserved for future use */
-
-/* Hold mode activities */
-#define HCI_HOLD_MODE_NO_CHANGE 0x00
-#define HCI_HOLD_MODE_SUSPEND_PAGE_SCAN 0x01
-#define HCI_HOLD_MODE_SUSPEND_INQUIRY_SCAN 0x02
-#define HCI_HOLD_MODE_SUSPEND_PERIOD_INQUIRY 0x04
-/* 0x08 - 0x80 - reserved for future use */
-
-/* Connection roles */
-#define HCI_ROLE_MASTER 0x00
-#define HCI_ROLE_SLAVE 0x01
-/* 0x02 - 0xFF - reserved for future use */
-
-/* Key flags */
-#define HCI_USE_SEMI_PERMANENT_LINK_KEYS 0x00
-#define HCI_USE_TEMPORARY_LINK_KEY 0x01
-/* 0x02 - 0xFF - reserved for future use */
-
-/* Pin types */
-#define HCI_PIN_TYPE_VARIABLE 0x00
-#define HCI_PIN_TYPE_FIXED 0x01
-
-/* Link key types */
-#define HCI_LINK_KEY_TYPE_COMBINATION_KEY 0x00
-#define HCI_LINK_KEY_TYPE_LOCAL_UNIT_KEY 0x01
-#define HCI_LINK_KEY_TYPE_REMOTE_UNIT_KEY 0x02
-/* 0x03 - 0xFF - reserved for future use */
-
-/* Encryption modes */
-#define HCI_ENCRYPTION_MODE_NONE 0x00
-#define HCI_ENCRYPTION_MODE_P2P 0x01
-#define HCI_ENCRYPTION_MODE_ALL 0x02
-/* 0x03 - 0xFF - reserved for future use */
-
-/* Quality of service types */
-#define HCI_SERVICE_TYPE_NO_TRAFFIC 0x00
-#define HCI_SERVICE_TYPE_BEST_EFFORT 0x01
-#define HCI_SERVICE_TYPE_GUARANTEED 0x02
-/* 0x03 - 0xFF - reserved for future use */
-
-/* Link policy settings */
-#define HCI_LINK_POLICY_DISABLE_ALL_LM_MODES 0x0000
-#define HCI_LINK_POLICY_ENABLE_ROLE_SWITCH 0x0001 /* Master/Slave switch */
-#define HCI_LINK_POLICY_ENABLE_HOLD_MODE 0x0002
-#define HCI_LINK_POLICY_ENABLE_SNIFF_MODE 0x0004
-#define HCI_LINK_POLICY_ENABLE_PARK_MODE 0x0008
-/* 0x0010 - 0x8000 - reserved for future use */
-
-/* Event masks */
-#define HCI_EVMSK_ALL 0x00000000ffffffff
-#define HCI_EVMSK_NONE 0x0000000000000000
-#define HCI_EVMSK_INQUIRY_COMPL 0x0000000000000001
-#define HCI_EVMSK_INQUIRY_RESULT 0x0000000000000002
-#define HCI_EVMSK_CON_COMPL 0x0000000000000004
-#define HCI_EVMSK_CON_REQ 0x0000000000000008
-#define HCI_EVMSK_DISCON_COMPL 0x0000000000000010
-#define HCI_EVMSK_AUTH_COMPL 0x0000000000000020
-#define HCI_EVMSK_REMOTE_NAME_REQ_COMPL 0x0000000000000040
-#define HCI_EVMSK_ENCRYPTION_CHANGE 0x0000000000000080
-#define HCI_EVMSK_CHANGE_CON_LINK_KEY_COMPL 0x0000000000000100
-#define HCI_EVMSK_MASTER_LINK_KEY_COMPL 0x0000000000000200
-#define HCI_EVMSK_READ_REMOTE_FEATURES_COMPL 0x0000000000000400
-#define HCI_EVMSK_READ_REMOTE_VER_INFO_COMPL 0x0000000000000800
-#define HCI_EVMSK_QOS_SETUP_COMPL 0x0000000000001000
-#define HCI_EVMSK_COMMAND_COMPL 0x0000000000002000
-#define HCI_EVMSK_COMMAND_STATUS 0x0000000000004000
-#define HCI_EVMSK_HARDWARE_ERROR 0x0000000000008000
-#define HCI_EVMSK_FLUSH_OCCUR 0x0000000000010000
-#define HCI_EVMSK_ROLE_CHANGE 0x0000000000020000
-#define HCI_EVMSK_NUM_COMPL_PKTS 0x0000000000040000
-#define HCI_EVMSK_MODE_CHANGE 0x0000000000080000
-#define HCI_EVMSK_RETURN_LINK_KEYS 0x0000000000100000
-#define HCI_EVMSK_PIN_CODE_REQ 0x0000000000200000
-#define HCI_EVMSK_LINK_KEY_REQ 0x0000000000400000
-#define HCI_EVMSK_LINK_KEY_NOTIFICATION 0x0000000000800000
-#define HCI_EVMSK_LOOPBACK_COMMAND 0x0000000001000000
-#define HCI_EVMSK_DATA_BUFFER_OVERFLOW 0x0000000002000000
-#define HCI_EVMSK_MAX_SLOT_CHANGE 0x0000000004000000
-#define HCI_EVMSK_READ_CLOCK_OFFSET_COMLETE 0x0000000008000000
-#define HCI_EVMSK_CON_PKT_TYPE_CHANGED 0x0000000010000000
-#define HCI_EVMSK_QOS_VIOLATION 0x0000000020000000
-#define HCI_EVMSK_PAGE_SCAN_MODE_CHANGE 0x0000000040000000
-#define HCI_EVMSK_PAGE_SCAN_REP_MODE_CHANGE 0x0000000080000000
-/* 0x0000000100000000 - 0x8000000000000000 - reserved for future use */
-
-/* Filter types */
-#define HCI_FILTER_TYPE_NONE 0x00
-#define HCI_FILTER_TYPE_INQUIRY_RESULT 0x01
-#define HCI_FILTER_TYPE_CON_SETUP 0x02
-/* 0x03 - 0xFF - reserved for future use */
-
-/* Filter condition types for HCI_FILTER_TYPE_INQUIRY_RESULT */
-#define HCI_FILTER_COND_INQUIRY_NEW_UNIT 0x00
-#define HCI_FILTER_COND_INQUIRY_UNIT_CLASS 0x01
-#define HCI_FILTER_COND_INQUIRY_BDADDR 0x02
-/* 0x03 - 0xFF - reserved for future use */
-
-/* Filter condition types for HCI_FILTER_TYPE_CON_SETUP */
-#define HCI_FILTER_COND_CON_ANY_UNIT 0x00
-#define HCI_FILTER_COND_CON_UNIT_CLASS 0x01
-#define HCI_FILTER_COND_CON_BDADDR 0x02
-/* 0x03 - 0xFF - reserved for future use */
-
-/* Xmit level types */
-#define HCI_XMIT_LEVEL_CURRENT 0x00
-#define HCI_XMIT_LEVEL_MAXIMUM 0x01
-/* 0x02 - 0xFF - reserved for future use */
-
-/* Host Controller to Host flow control */
-#define HCI_HC2H_FLOW_CONTROL_NONE 0x00
-#define HCI_HC2H_FLOW_CONTROL_ACL 0x01
-#define HCI_HC2H_FLOW_CONTROL_SCO 0x02
-#define HCI_HC2H_FLOW_CONTROL_BOTH 0x03
-/* 0x04 - 0xFF - reserved future use */
-
-/* Loopback modes */
-#define HCI_LOOPBACK_NONE 0x00
-#define HCI_LOOPBACK_LOCAL 0x01
-#define HCI_LOOPBACK_REMOTE 0x02
-/* 0x03 - 0xFF - reserved future use */
-
-/**************************************************************************
- **************************************************************************
- ** Link level defines, headers and types
- **************************************************************************
- **************************************************************************/
-
-/*
- * Macro(s) to combine OpCode and extract OGF (OpCode Group Field)
- * and OCF (OpCode Command Field) from OpCode.
- */
-
-#define HCI_OPCODE(gf,cf) ((((gf) & 0x3f) << 10) | ((cf) & 0x3ff))
-#define HCI_OCF(op) ((op) & 0x3ff)
-#define HCI_OGF(op) (((op) >> 10) & 0x3f)
-
-/*
- * Macro(s) to extract/combine connection handle, BC (Broadcast) and
- * PB (Packet boundary) flags.
- */
-
-#define HCI_CON_HANDLE(h) ((h) & 0x0fff)
-#define HCI_PB_FLAG(h) (((h) & 0x3000) >> 12)
-#define HCI_BC_FLAG(h) (((h) & 0xc000) >> 14)
-#define HCI_MK_CON_HANDLE(h, pb, bc) \
- (((h) & 0x0fff) | (((pb) & 3) << 12) | (((bc) & 3) << 14))
-
-/* PB flag values */
- /* 00 - reserved for future use */
-#define HCI_PACKET_FRAGMENT 0x1
-#define HCI_PACKET_START 0x2
- /* 11 - reserved for future use */
-
-/* BC flag values */
-#define HCI_POINT2POINT 0x0 /* only Host controller to Host */
-#define HCI_BROADCAST_ACTIVE 0x1 /* both directions */
-#define HCI_BROADCAST_PICONET 0x2 /* both directions */
- /* 11 - reserved for future use */
-
-/* HCI command packet header */
-typedef struct {
- uint8_t type; /* MUST be 0x01 */
- uint16_t opcode; /* OpCode */
- uint8_t length; /* parameter(s) length in bytes */
-} __packed hci_cmd_hdr_t;
-
-#define HCI_CMD_PKT 0x01
-#define HCI_CMD_PKT_SIZE (sizeof(hci_cmd_hdr_t) + 0xff)
-
-/* ACL data packet header */
-typedef struct {
- uint8_t type; /* MUST be 0x02 */
- uint16_t con_handle; /* connection handle + PB + BC flags */
- uint16_t length; /* payload length in bytes */
-} __packed hci_acldata_hdr_t;
-
-#define HCI_ACL_DATA_PKT 0x02
-#define HCI_ACL_PKT_SIZE (sizeof(hci_acldata_hdr_t) + 0xffff)
-
-/* SCO data packet header */
-typedef struct {
- uint8_t type; /* MUST be 0x03 */
- uint16_t con_handle; /* connection handle + reserved bits */
- uint8_t length; /* payload length in bytes */
-} __packed hci_scodata_hdr_t;
-
-#define HCI_SCO_DATA_PKT 0x03
-#define HCI_SCO_PKT_SIZE (sizeof(hci_scodata_hdr_t) + 0xff)
-
-/* HCI event packet header */
-typedef struct {
- uint8_t type; /* MUST be 0x04 */
- uint8_t event; /* event */
- uint8_t length; /* parameter(s) length in bytes */
-} __packed hci_event_hdr_t;
-
-#define HCI_EVENT_PKT 0x04
-#define HCI_EVENT_PKT_SIZE (sizeof(hci_event_hdr_t) + 0xff)
-
-/* HCI status return parameter */
-typedef struct {
- uint8_t status; /* 0x00 - success */
-} __packed hci_status_rp;
-
-/**************************************************************************
- **************************************************************************
- ** OGF 0x01 Link control commands and return parameters
- **************************************************************************
- **************************************************************************/
-
-#define HCI_OGF_LINK_CONTROL 0x01
-
-#define HCI_OCF_INQUIRY 0x0001
-#define HCI_CMD_INQUIRY 0x0401
-typedef struct {
- uint8_t lap[HCI_LAP_SIZE]; /* LAP */
- uint8_t inquiry_length; /* (N x 1.28) sec */
- uint8_t num_responses; /* Max. # of responses */
-} __packed hci_inquiry_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_INQUIRY_CANCEL 0x0002
-#define HCI_CMD_INQUIRY_CANCEL 0x0402
-/* No command parameter(s) */
-typedef hci_status_rp hci_inquiry_cancel_rp;
-
-#define HCI_OCF_PERIODIC_INQUIRY 0x0003
-#define HCI_CMD_PERIODIC_INQUIRY 0x0403
-typedef struct {
- uint16_t max_period_length; /* Max. and min. amount of time */
- uint16_t min_period_length; /* between consecutive inquiries */
- uint8_t lap[HCI_LAP_SIZE]; /* LAP */
- uint8_t inquiry_length; /* (inquiry_length * 1.28) sec */
- uint8_t num_responses; /* Max. # of responses */
-} __packed hci_periodic_inquiry_cp;
-
-typedef hci_status_rp hci_periodic_inquiry_rp;
-
-#define HCI_OCF_EXIT_PERIODIC_INQUIRY 0x0004
-#define HCI_CMD_EXIT_PERIODIC_INQUIRY 0x0404
-/* No command parameter(s) */
-typedef hci_status_rp hci_exit_periodic_inquiry_rp;
-
-#define HCI_OCF_CREATE_CON 0x0005
-#define HCI_CMD_CREATE_CON 0x0405
-typedef struct {
- bdaddr_t bdaddr; /* destination address */
- uint16_t pkt_type; /* packet type */
- uint8_t page_scan_rep_mode; /* page scan repetition mode */
- uint8_t page_scan_mode; /* reserved - set to 0x00 */
- uint16_t clock_offset; /* clock offset */
- uint8_t accept_role_switch; /* accept role switch? 0x00 == No */
-} __packed hci_create_con_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_DISCONNECT 0x0006
-#define HCI_CMD_DISCONNECT 0x0406
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint8_t reason; /* reason to disconnect */
-} __packed hci_discon_cp;
-/* No return parameter(s) */
-
-/* Add SCO Connection is deprecated */
-#define HCI_OCF_ADD_SCO_CON 0x0007
-#define HCI_CMD_ADD_SCO_CON 0x0407
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t pkt_type; /* packet type */
-} __packed hci_add_sco_con_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_CREATE_CON_CANCEL 0x0008
-#define HCI_CMD_CREATE_CON_CANCEL 0x0408
-typedef struct {
- bdaddr_t bdaddr; /* destination address */
-} __packed hci_create_con_cancel_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* destination address */
-} __packed hci_create_con_cancel_rp;
-
-#define HCI_OCF_ACCEPT_CON 0x0009
-#define HCI_CMD_ACCEPT_CON 0x0409
-typedef struct {
- bdaddr_t bdaddr; /* address of unit to be connected */
- uint8_t role; /* connection role */
-} __packed hci_accept_con_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_REJECT_CON 0x000a
-#define HCI_CMD_REJECT_CON 0x040A
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t reason; /* reason to reject */
-} __packed hci_reject_con_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_LINK_KEY_REP 0x000b
-#define HCI_CMD_LINK_KEY_REP 0x040B
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t key[HCI_KEY_SIZE]; /* key */
-} __packed hci_link_key_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* unit address */
-} __packed hci_link_key_rep_rp;
-
-#define HCI_OCF_LINK_KEY_NEG_REP 0x000c
-#define HCI_CMD_LINK_KEY_NEG_REP 0x040C
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_link_key_neg_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* unit address */
-} __packed hci_link_key_neg_rep_rp;
-
-#define HCI_OCF_PIN_CODE_REP 0x000d
-#define HCI_CMD_PIN_CODE_REP 0x040D
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t pin_size; /* pin code length (in bytes) */
- uint8_t pin[HCI_PIN_SIZE]; /* pin code */
-} __packed hci_pin_code_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* unit address */
-} __packed hci_pin_code_rep_rp;
-
-#define HCI_OCF_PIN_CODE_NEG_REP 0x000e
-#define HCI_CMD_PIN_CODE_NEG_REP 0x040E
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_pin_code_neg_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* unit address */
-} __packed hci_pin_code_neg_rep_rp;
-
-#define HCI_OCF_CHANGE_CON_PACKET_TYPE 0x000f
-#define HCI_CMD_CHANGE_CON_PACKET_TYPE 0x040F
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t pkt_type; /* packet type */
-} __packed hci_change_con_pkt_type_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_AUTH_REQ 0x0011
-#define HCI_CMD_AUTH_REQ 0x0411
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_auth_req_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_SET_CON_ENCRYPTION 0x0013
-#define HCI_CMD_SET_CON_ENCRYPTION 0x0413
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint8_t encryption_enable; /* 0x00 - disable, 0x01 - enable */
-} __packed hci_set_con_encryption_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_CHANGE_CON_LINK_KEY 0x0015
-#define HCI_CMD_CHANGE_CON_LINK_KEY 0x0415
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_change_con_link_key_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_MASTER_LINK_KEY 0x0017
-#define HCI_CMD_MASTER_LINK_KEY 0x0417
-typedef struct {
- uint8_t key_flag; /* key flag */
-} __packed hci_master_link_key_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_REMOTE_NAME_REQ 0x0019
-#define HCI_CMD_REMOTE_NAME_REQ 0x0419
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t page_scan_rep_mode; /* page scan repetition mode */
- uint8_t page_scan_mode; /* page scan mode */
- uint16_t clock_offset; /* clock offset */
-} __packed hci_remote_name_req_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_REMOTE_NAME_REQ_CANCEL 0x001a
-#define HCI_CMD_REMOTE_NAME_REQ_CANCEL 0x041A
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_remote_name_req_cancel_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_remote_name_req_cancel_rp;
-
-#define HCI_OCF_READ_REMOTE_FEATURES 0x001b
-#define HCI_CMD_READ_REMOTE_FEATURES 0x041B
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_remote_features_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_READ_REMOTE_EXTENDED_FEATURES 0x001c
-#define HCI_CMD_READ_REMOTE_EXTENDED_FEATURES 0x041C
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint8_t page; /* page number */
-} __packed hci_read_remote_extended_features_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_READ_REMOTE_VER_INFO 0x001d
-#define HCI_CMD_READ_REMOTE_VER_INFO 0x041D
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_remote_ver_info_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_READ_CLOCK_OFFSET 0x001f
-#define HCI_CMD_READ_CLOCK_OFFSET 0x041F
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_clock_offset_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_READ_LMP_HANDLE 0x0020
-#define HCI_CMD_READ_LMP_HANDLE 0x0420
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_lmp_handle_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t lmp_handle; /* LMP handle */
- uint32_t reserved; /* reserved */
-} __packed hci_read_lmp_handle_rp;
-
-#define HCI_OCF_SETUP_SCO_CON 0x0028
-#define HCI_CMD_SETUP_SCO_CON 0x0428
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint32_t tx_bandwidth; /* transmit bandwidth */
- uint32_t rx_bandwidth; /* receive bandwidth */
- uint16_t latency; /* maximum latency */
- uint16_t voice; /* voice setting */
- uint8_t rt_effort; /* retransmission effort */
- uint16_t pkt_type; /* packet types */
-} __packed hci_setup_sco_con_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_ACCEPT_SCO_CON_REQ 0x0029
-#define HCI_CMD_ACCEPT_SCO_CON_REQ 0x0429
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint32_t tx_bandwidth; /* transmit bandwidth */
- uint32_t rx_bandwidth; /* receive bandwidth */
- uint16_t latency; /* maximum latency */
- uint16_t content; /* voice setting */
- uint8_t rt_effort; /* retransmission effort */
- uint16_t pkt_type; /* packet types */
-} __packed hci_accept_sco_con_req_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_REJECT_SCO_CON_REQ 0x002a
-#define HCI_CMD_REJECT_SCO_CON_REQ 0x042a
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t reason; /* reject error code */
-} __packed hci_reject_sco_con_req_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_IO_CAPABILITY_REP 0x002b
-#define HCI_CMD_IO_CAPABILITY_REP 0x042a
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t io_cap; /* IO capability */
- uint8_t oob_data; /* OOB data present */
- uint8_t auth_req; /* auth requirements */
-} __packed hci_io_capability_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_io_capability_rep_rp;
-
-#define HCI_OCF_USER_CONFIRM_REP 0x002c
-#define HCI_CMD_USER_CONFIRM_REP 0x042c
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_confirm_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_confirm_rep_rp;
-
-#define HCI_OCF_USER_CONFIRM_NEG_REP 0x002d
-#define HCI_CMD_USER_CONFIRM_NEG_REP 0x042d
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_confirm_neg_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_confirm_neg_rep_rp;
-
-#define HCI_OCF_USER_PASSKEY_REP 0x002e
-#define HCI_CMD_USER_PASSKEY_REP 0x042e
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint32_t value; /* 000000 - 999999 */
-} __packed hci_user_passkey_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_passkey_rep_rp;
-
-#define HCI_OCF_USER_PASSKEY_NEG_REP 0x002f
-#define HCI_CMD_USER_PASSKEY_NEG_REP 0x042f
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_passkey_neg_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_passkey_neg_rep_rp;
-
-#define HCI_OCF_OOB_DATA_REP 0x0030
-#define HCI_CMD_OOB_DATA_REP 0x0430
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t c[16]; /* pairing hash */
- uint8_t r[16]; /* pairing randomizer */
-} __packed hci_user_oob_data_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_oob_data_rep_rp;
-
-#define HCI_OCF_OOB_DATA_NEG_REP 0x0033
-#define HCI_CMD_OOB_DATA_NEG_REP 0x0433
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_oob_data_neg_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_user_oob_data_neg_rep_rp;
-
-#define HCI_OCF_IO_CAPABILITY_NEG_REP 0x0034
-#define HCI_CMD_IO_CAPABILITY_NEG_REP 0x0434
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t reason; /* error code */
-} __packed hci_io_capability_neg_rep_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_io_capability_neg_rep_rp;
-
-/**************************************************************************
- **************************************************************************
- ** OGF 0x02 Link policy commands and return parameters
- **************************************************************************
- **************************************************************************/
-
-#define HCI_OGF_LINK_POLICY 0x02
-
-#define HCI_OCF_HOLD_MODE 0x0001
-#define HCI_CMD_HOLD_MODE 0x0801
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t max_interval; /* (max_interval * 0.625) msec */
- uint16_t min_interval; /* (max_interval * 0.625) msec */
-} __packed hci_hold_mode_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_SNIFF_MODE 0x0003
-#define HCI_CMD_SNIFF_MODE 0x0803
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t max_interval; /* (max_interval * 0.625) msec */
- uint16_t min_interval; /* (max_interval * 0.625) msec */
- uint16_t attempt; /* (2 * attempt - 1) * 0.625 msec */
- uint16_t timeout; /* (2 * attempt - 1) * 0.625 msec */
-} __packed hci_sniff_mode_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_EXIT_SNIFF_MODE 0x0004
-#define HCI_CMD_EXIT_SNIFF_MODE 0x0804
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_exit_sniff_mode_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_PARK_MODE 0x0005
-#define HCI_CMD_PARK_MODE 0x0805
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t max_interval; /* (max_interval * 0.625) msec */
- uint16_t min_interval; /* (max_interval * 0.625) msec */
-} __packed hci_park_mode_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_EXIT_PARK_MODE 0x0006
-#define HCI_CMD_EXIT_PARK_MODE 0x0806
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_exit_park_mode_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_QOS_SETUP 0x0007
-#define HCI_CMD_QOS_SETUP 0x0807
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint8_t flags; /* reserved for future use */
- uint8_t service_type; /* service type */
- uint32_t token_rate; /* bytes per second */
- uint32_t peak_bandwidth; /* bytes per second */
- uint32_t latency; /* microseconds */
- uint32_t delay_variation; /* microseconds */
-} __packed hci_qos_setup_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_ROLE_DISCOVERY 0x0009
-#define HCI_CMD_ROLE_DISCOVERY 0x0809
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_role_discovery_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t role; /* role for the connection handle */
-} __packed hci_role_discovery_rp;
-
-#define HCI_OCF_SWITCH_ROLE 0x000b
-#define HCI_CMD_SWITCH_ROLE 0x080B
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t role; /* new local role */
-} __packed hci_switch_role_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_READ_LINK_POLICY_SETTINGS 0x000c
-#define HCI_CMD_READ_LINK_POLICY_SETTINGS 0x080C
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_link_policy_settings_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint16_t settings; /* link policy settings */
-} __packed hci_read_link_policy_settings_rp;
-
-#define HCI_OCF_WRITE_LINK_POLICY_SETTINGS 0x000d
-#define HCI_CMD_WRITE_LINK_POLICY_SETTINGS 0x080D
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t settings; /* link policy settings */
-} __packed hci_write_link_policy_settings_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
-} __packed hci_write_link_policy_settings_rp;
-
-#define HCI_OCF_READ_DEFAULT_LINK_POLICY_SETTINGS 0x000e
-#define HCI_CMD_READ_DEFAULT_LINK_POLICY_SETTINGS 0x080E
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t settings; /* link policy settings */
-} __packed hci_read_default_link_policy_settings_rp;
-
-#define HCI_OCF_WRITE_DEFAULT_LINK_POLICY_SETTINGS 0x000f
-#define HCI_CMD_WRITE_DEFAULT_LINK_POLICY_SETTINGS 0x080F
-typedef struct {
- uint16_t settings; /* link policy settings */
-} __packed hci_write_default_link_policy_settings_cp;
-
-typedef hci_status_rp hci_write_default_link_policy_settings_rp;
-
-#define HCI_OCF_FLOW_SPECIFICATION 0x0010
-#define HCI_CMD_FLOW_SPECIFICATION 0x0810
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint8_t flags; /* reserved */
- uint8_t flow_direction;
- uint8_t service_type;
- uint32_t token_rate;
- uint32_t token_bucket;
- uint32_t peak_bandwidth;
- uint32_t latency;
-} __packed hci_flow_specification_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_SNIFF_SUBRATING 0x0011
-#define HCI_CMD_SNIFF_SUBRATING 0x0810
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t max_latency;
- uint16_t max_timeout; /* max remote timeout */
- uint16_t min_timeout; /* min local timeout */
-} __packed hci_sniff_subrating_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
-} __packed hci_sniff_subrating_rp;
-
-/**************************************************************************
- **************************************************************************
- ** OGF 0x03 Host Controller and Baseband commands and return parameters
- **************************************************************************
- **************************************************************************/
-
-#define HCI_OGF_HC_BASEBAND 0x03
-
-#define HCI_OCF_SET_EVENT_MASK 0x0001
-#define HCI_CMD_SET_EVENT_MASK 0x0C01
-typedef struct {
- uint8_t event_mask[HCI_EVENT_MASK_SIZE]; /* event_mask */
-} __packed hci_set_event_mask_cp;
-
-typedef hci_status_rp hci_set_event_mask_rp;
-
-#define HCI_OCF_RESET 0x0003
-#define HCI_CMD_RESET 0x0C03
-/* No command parameter(s) */
-typedef hci_status_rp hci_reset_rp;
-
-#define HCI_OCF_SET_EVENT_FILTER 0x0005
-#define HCI_CMD_SET_EVENT_FILTER 0x0C05
-typedef struct {
- uint8_t filter_type; /* filter type */
- uint8_t filter_condition_type; /* filter condition type */
-/* variable size condition
- uint8_t condition[]; -- conditions */
-} __packed hci_set_event_filter_cp;
-
-typedef hci_status_rp hci_set_event_filter_rp;
-
-#define HCI_OCF_FLUSH 0x0008
-#define HCI_CMD_FLUSH 0x0C08
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_flush_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
-} __packed hci_flush_rp;
-
-#define HCI_OCF_READ_PIN_TYPE 0x0009
-#define HCI_CMD_READ_PIN_TYPE 0x0C09
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t pin_type; /* PIN type */
-} __packed hci_read_pin_type_rp;
-
-#define HCI_OCF_WRITE_PIN_TYPE 0x000a
-#define HCI_CMD_WRITE_PIN_TYPE 0x0C0A
-typedef struct {
- uint8_t pin_type; /* PIN type */
-} __packed hci_write_pin_type_cp;
-
-typedef hci_status_rp hci_write_pin_type_rp;
-
-#define HCI_OCF_CREATE_NEW_UNIT_KEY 0x000b
-#define HCI_CMD_CREATE_NEW_UNIT_KEY 0x0C0B
-/* No command parameter(s) */
-typedef hci_status_rp hci_create_new_unit_key_rp;
-
-#define HCI_OCF_READ_STORED_LINK_KEY 0x000d
-#define HCI_CMD_READ_STORED_LINK_KEY 0x0C0D
-typedef struct {
- bdaddr_t bdaddr; /* address */
- uint8_t read_all; /* read all keys? 0x01 - yes */
-} __packed hci_read_stored_link_key_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t max_num_keys; /* Max. number of keys */
- uint16_t num_keys_read; /* Number of stored keys */
-} __packed hci_read_stored_link_key_rp;
-
-#define HCI_OCF_WRITE_STORED_LINK_KEY 0x0011
-#define HCI_CMD_WRITE_STORED_LINK_KEY 0x0C11
-typedef struct {
- uint8_t num_keys_write; /* # of keys to write */
-/* these are repeated "num_keys_write" times
- bdaddr_t bdaddr; --- remote address(es)
- uint8_t key[HCI_KEY_SIZE]; --- key(s) */
-} __packed hci_write_stored_link_key_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t num_keys_written; /* # of keys successfully written */
-} __packed hci_write_stored_link_key_rp;
-
-#define HCI_OCF_DELETE_STORED_LINK_KEY 0x0012
-#define HCI_CMD_DELETE_STORED_LINK_KEY 0x0C12
-typedef struct {
- bdaddr_t bdaddr; /* address */
- uint8_t delete_all; /* delete all keys? 0x01 - yes */
-} __packed hci_delete_stored_link_key_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t num_keys_deleted; /* Number of keys deleted */
-} __packed hci_delete_stored_link_key_rp;
-
-#define HCI_OCF_WRITE_LOCAL_NAME 0x0013
-#define HCI_CMD_WRITE_LOCAL_NAME 0x0C13
-typedef struct {
- char name[HCI_UNIT_NAME_SIZE]; /* new unit name */
-} __packed hci_write_local_name_cp;
-
-typedef hci_status_rp hci_write_local_name_rp;
-
-#define HCI_OCF_READ_LOCAL_NAME 0x0014
-#define HCI_CMD_READ_LOCAL_NAME 0x0C14
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- char name[HCI_UNIT_NAME_SIZE]; /* unit name */
-} __packed hci_read_local_name_rp;
-
-#define HCI_OCF_READ_CON_ACCEPT_TIMEOUT 0x0015
-#define HCI_CMD_READ_CON_ACCEPT_TIMEOUT 0x0C15
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t timeout; /* (timeout * 0.625) msec */
-} __packed hci_read_con_accept_timeout_rp;
-
-#define HCI_OCF_WRITE_CON_ACCEPT_TIMEOUT 0x0016
-#define HCI_CMD_WRITE_CON_ACCEPT_TIMEOUT 0x0C16
-typedef struct {
- uint16_t timeout; /* (timeout * 0.625) msec */
-} __packed hci_write_con_accept_timeout_cp;
-
-typedef hci_status_rp hci_write_con_accept_timeout_rp;
-
-#define HCI_OCF_READ_PAGE_TIMEOUT 0x0017
-#define HCI_CMD_READ_PAGE_TIMEOUT 0x0C17
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t timeout; /* (timeout * 0.625) msec */
-} __packed hci_read_page_timeout_rp;
-
-#define HCI_OCF_WRITE_PAGE_TIMEOUT 0x0018
-#define HCI_CMD_WRITE_PAGE_TIMEOUT 0x0C18
-typedef struct {
- uint16_t timeout; /* (timeout * 0.625) msec */
-} __packed hci_write_page_timeout_cp;
-
-typedef hci_status_rp hci_write_page_timeout_rp;
-
-#define HCI_OCF_READ_SCAN_ENABLE 0x0019
-#define HCI_CMD_READ_SCAN_ENABLE 0x0C19
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t scan_enable; /* Scan enable */
-} __packed hci_read_scan_enable_rp;
-
-#define HCI_OCF_WRITE_SCAN_ENABLE 0x001a
-#define HCI_CMD_WRITE_SCAN_ENABLE 0x0C1A
-typedef struct {
- uint8_t scan_enable; /* Scan enable */
-} __packed hci_write_scan_enable_cp;
-
-typedef hci_status_rp hci_write_scan_enable_rp;
-
-#define HCI_OCF_READ_PAGE_SCAN_ACTIVITY 0x001b
-#define HCI_CMD_READ_PAGE_SCAN_ACTIVITY 0x0C1B
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t page_scan_interval; /* interval * 0.625 msec */
- uint16_t page_scan_window; /* window * 0.625 msec */
-} __packed hci_read_page_scan_activity_rp;
-
-#define HCI_OCF_WRITE_PAGE_SCAN_ACTIVITY 0x001c
-#define HCI_CMD_WRITE_PAGE_SCAN_ACTIVITY 0x0C1C
-typedef struct {
- uint16_t page_scan_interval; /* interval * 0.625 msec */
- uint16_t page_scan_window; /* window * 0.625 msec */
-} __packed hci_write_page_scan_activity_cp;
-
-typedef hci_status_rp hci_write_page_scan_activity_rp;
-
-#define HCI_OCF_READ_INQUIRY_SCAN_ACTIVITY 0x001d
-#define HCI_CMD_READ_INQUIRY_SCAN_ACTIVITY 0x0C1D
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t inquiry_scan_interval; /* interval * 0.625 msec */
- uint16_t inquiry_scan_window; /* window * 0.625 msec */
-} __packed hci_read_inquiry_scan_activity_rp;
-
-#define HCI_OCF_WRITE_INQUIRY_SCAN_ACTIVITY 0x001e
-#define HCI_CMD_WRITE_INQUIRY_SCAN_ACTIVITY 0x0C1E
-typedef struct {
- uint16_t inquiry_scan_interval; /* interval * 0.625 msec */
- uint16_t inquiry_scan_window; /* window * 0.625 msec */
-} __packed hci_write_inquiry_scan_activity_cp;
-
-typedef hci_status_rp hci_write_inquiry_scan_activity_rp;
-
-#define HCI_OCF_READ_AUTH_ENABLE 0x001f
-#define HCI_CMD_READ_AUTH_ENABLE 0x0C1F
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t auth_enable; /* 0x01 - enabled */
-} __packed hci_read_auth_enable_rp;
-
-#define HCI_OCF_WRITE_AUTH_ENABLE 0x0020
-#define HCI_CMD_WRITE_AUTH_ENABLE 0x0C20
-typedef struct {
- uint8_t auth_enable; /* 0x01 - enabled */
-} __packed hci_write_auth_enable_cp;
-
-typedef hci_status_rp hci_write_auth_enable_rp;
-
-/* Read Encryption Mode is deprecated */
-#define HCI_OCF_READ_ENCRYPTION_MODE 0x0021
-#define HCI_CMD_READ_ENCRYPTION_MODE 0x0C21
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t encryption_mode; /* encryption mode */
-} __packed hci_read_encryption_mode_rp;
-
-/* Write Encryption Mode is deprecated */
-#define HCI_OCF_WRITE_ENCRYPTION_MODE 0x0022
-#define HCI_CMD_WRITE_ENCRYPTION_MODE 0x0C22
-typedef struct {
- uint8_t encryption_mode; /* encryption mode */
-} __packed hci_write_encryption_mode_cp;
-
-typedef hci_status_rp hci_write_encryption_mode_rp;
-
-#define HCI_OCF_READ_UNIT_CLASS 0x0023
-#define HCI_CMD_READ_UNIT_CLASS 0x0C23
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t uclass[HCI_CLASS_SIZE]; /* unit class */
-} __packed hci_read_unit_class_rp;
-
-#define HCI_OCF_WRITE_UNIT_CLASS 0x0024
-#define HCI_CMD_WRITE_UNIT_CLASS 0x0C24
-typedef struct {
- uint8_t uclass[HCI_CLASS_SIZE]; /* unit class */
-} __packed hci_write_unit_class_cp;
-
-typedef hci_status_rp hci_write_unit_class_rp;
-
-#define HCI_OCF_READ_VOICE_SETTING 0x0025
-#define HCI_CMD_READ_VOICE_SETTING 0x0C25
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t settings; /* voice settings */
-} __packed hci_read_voice_setting_rp;
-
-#define HCI_OCF_WRITE_VOICE_SETTING 0x0026
-#define HCI_CMD_WRITE_VOICE_SETTING 0x0C26
-typedef struct {
- uint16_t settings; /* voice settings */
-} __packed hci_write_voice_setting_cp;
-
-typedef hci_status_rp hci_write_voice_setting_rp;
-
-#define HCI_OCF_READ_AUTO_FLUSH_TIMEOUT 0x0027
-#define HCI_CMD_READ_AUTO_FLUSH_TIMEOUT 0x0C27
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_auto_flush_timeout_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint16_t timeout; /* 0x00 - no flush, timeout * 0.625 msec */
-} __packed hci_read_auto_flush_timeout_rp;
-
-#define HCI_OCF_WRITE_AUTO_FLUSH_TIMEOUT 0x0028
-#define HCI_CMD_WRITE_AUTO_FLUSH_TIMEOUT 0x0C28
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t timeout; /* 0x00 - no flush, timeout * 0.625 msec */
-} __packed hci_write_auto_flush_timeout_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
-} __packed hci_write_auto_flush_timeout_rp;
-
-#define HCI_OCF_READ_NUM_BROADCAST_RETRANS 0x0029
-#define HCI_CMD_READ_NUM_BROADCAST_RETRANS 0x0C29
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t counter; /* number of broadcast retransmissions */
-} __packed hci_read_num_broadcast_retrans_rp;
-
-#define HCI_OCF_WRITE_NUM_BROADCAST_RETRANS 0x002a
-#define HCI_CMD_WRITE_NUM_BROADCAST_RETRANS 0x0C2A
-typedef struct {
- uint8_t counter; /* number of broadcast retransmissions */
-} __packed hci_write_num_broadcast_retrans_cp;
-
-typedef hci_status_rp hci_write_num_broadcast_retrans_rp;
-
-#define HCI_OCF_READ_HOLD_MODE_ACTIVITY 0x002b
-#define HCI_CMD_READ_HOLD_MODE_ACTIVITY 0x0C2B
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t hold_mode_activity; /* Hold mode activities */
-} __packed hci_read_hold_mode_activity_rp;
-
-#define HCI_OCF_WRITE_HOLD_MODE_ACTIVITY 0x002c
-#define HCI_CMD_WRITE_HOLD_MODE_ACTIVITY 0x0C2C
-typedef struct {
- uint8_t hold_mode_activity; /* Hold mode activities */
-} __packed hci_write_hold_mode_activity_cp;
-
-typedef hci_status_rp hci_write_hold_mode_activity_rp;
-
-#define HCI_OCF_READ_XMIT_LEVEL 0x002d
-#define HCI_CMD_READ_XMIT_LEVEL 0x0C2D
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint8_t type; /* Xmit level type */
-} __packed hci_read_xmit_level_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- char level; /* -30 <= level <= 30 dBm */
-} __packed hci_read_xmit_level_rp;
-
-#define HCI_OCF_READ_SCO_FLOW_CONTROL 0x002e
-#define HCI_CMD_READ_SCO_FLOW_CONTROL 0x0C2E
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t flow_control; /* 0x00 - disabled */
-} __packed hci_read_sco_flow_control_rp;
-
-#define HCI_OCF_WRITE_SCO_FLOW_CONTROL 0x002f
-#define HCI_CMD_WRITE_SCO_FLOW_CONTROL 0x0C2F
-typedef struct {
- uint8_t flow_control; /* 0x00 - disabled */
-} __packed hci_write_sco_flow_control_cp;
-
-typedef hci_status_rp hci_write_sco_flow_control_rp;
-
-#define HCI_OCF_HC2H_FLOW_CONTROL 0x0031
-#define HCI_CMD_HC2H_FLOW_CONTROL 0x0C31
-typedef struct {
- uint8_t hc2h_flow; /* Host Controller to Host flow control */
-} __packed hci_hc2h_flow_control_cp;
-
-typedef hci_status_rp hci_h2hc_flow_control_rp;
-
-#define HCI_OCF_HOST_BUFFER_SIZE 0x0033
-#define HCI_CMD_HOST_BUFFER_SIZE 0x0C33
-typedef struct {
- uint16_t max_acl_size; /* Max. size of ACL packet (bytes) */
- uint8_t max_sco_size; /* Max. size of SCO packet (bytes) */
- uint16_t num_acl_pkts; /* Max. number of ACL packets */
- uint16_t num_sco_pkts; /* Max. number of SCO packets */
-} __packed hci_host_buffer_size_cp;
-
-typedef hci_status_rp hci_host_buffer_size_rp;
-
-#define HCI_OCF_HOST_NUM_COMPL_PKTS 0x0035
-#define HCI_CMD_HOST_NUM_COMPL_PKTS 0x0C35
-typedef struct {
- uint8_t nu_con_handles; /* # of connection handles */
-/* these are repeated "num_con_handles" times
- uint16_t con_handle; --- connection handle(s)
- uint16_t compl_pkts; --- # of completed packets */
-} __packed hci_host_num_compl_pkts_cp;
-/* No return parameter(s) */
-
-#define HCI_OCF_READ_LINK_SUPERVISION_TIMEOUT 0x0036
-#define HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT 0x0C36
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_link_supervision_timeout_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint16_t timeout; /* Link supervision timeout * 0.625 msec */
-} __packed hci_read_link_supervision_timeout_rp;
-
-#define HCI_OCF_WRITE_LINK_SUPERVISION_TIMEOUT 0x0037
-#define HCI_CMD_WRITE_LINK_SUPERVISION_TIMEOUT 0x0C37
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t timeout; /* Link supervision timeout * 0.625 msec */
-} __packed hci_write_link_supervision_timeout_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
-} __packed hci_write_link_supervision_timeout_rp;
-
-#define HCI_OCF_READ_NUM_SUPPORTED_IAC 0x0038
-#define HCI_CMD_READ_NUM_SUPPORTED_IAC 0x0C38
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t num_iac; /* # of supported IAC during scan */
-} __packed hci_read_num_supported_iac_rp;
-
-#define HCI_OCF_READ_IAC_LAP 0x0039
-#define HCI_CMD_READ_IAC_LAP 0x0C39
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t num_iac; /* # of IAC */
-/* these are repeated "num_iac" times
- uint8_t laps[HCI_LAP_SIZE]; --- LAPs */
-} __packed hci_read_iac_lap_rp;
-
-#define HCI_OCF_WRITE_IAC_LAP 0x003a
-#define HCI_CMD_WRITE_IAC_LAP 0x0C3A
-typedef struct {
- uint8_t num_iac; /* # of IAC */
-/* these are repeated "num_iac" times
- uint8_t laps[HCI_LAP_SIZE]; --- LAPs */
-} __packed hci_write_iac_lap_cp;
-
-typedef hci_status_rp hci_write_iac_lap_rp;
-
-/* Read Page Scan Period Mode is deprecated */
-#define HCI_OCF_READ_PAGE_SCAN_PERIOD 0x003b
-#define HCI_CMD_READ_PAGE_SCAN_PERIOD 0x0C3B
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t page_scan_period_mode; /* Page scan period mode */
-} __packed hci_read_page_scan_period_rp;
-
-/* Write Page Scan Period Mode is deprecated */
-#define HCI_OCF_WRITE_PAGE_SCAN_PERIOD 0x003c
-#define HCI_CMD_WRITE_PAGE_SCAN_PERIOD 0x0C3C
-typedef struct {
- uint8_t page_scan_period_mode; /* Page scan period mode */
-} __packed hci_write_page_scan_period_cp;
-
-typedef hci_status_rp hci_write_page_scan_period_rp;
-
-/* Read Page Scan Mode is deprecated */
-#define HCI_OCF_READ_PAGE_SCAN 0x003d
-#define HCI_CMD_READ_PAGE_SCAN 0x0C3D
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t page_scan_mode; /* Page scan mode */
-} __packed hci_read_page_scan_rp;
-
-/* Write Page Scan Mode is deprecated */
-#define HCI_OCF_WRITE_PAGE_SCAN 0x003e
-#define HCI_CMD_WRITE_PAGE_SCAN 0x0C3E
-typedef struct {
- uint8_t page_scan_mode; /* Page scan mode */
-} __packed hci_write_page_scan_cp;
-
-typedef hci_status_rp hci_write_page_scan_rp;
-
-#define HCI_OCF_SET_AFH_CLASSIFICATION 0x003f
-#define HCI_CMD_SET_AFH_CLASSIFICATION 0x0C3F
-typedef struct {
- uint8_t classification[10];
-} __packed hci_set_afh_classification_cp;
-
-typedef hci_status_rp hci_set_afh_classification_rp;
-
-#define HCI_OCF_READ_INQUIRY_SCAN_TYPE 0x0042
-#define HCI_CMD_READ_INQUIRY_SCAN_TYPE 0x0C42
-/* No command parameter(s) */
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t type; /* inquiry scan type */
-} __packed hci_read_inquiry_scan_type_rp;
-
-#define HCI_OCF_WRITE_INQUIRY_SCAN_TYPE 0x0043
-#define HCI_CMD_WRITE_INQUIRY_SCAN_TYPE 0x0C43
-typedef struct {
- uint8_t type; /* inquiry scan type */
-} __packed hci_write_inquiry_scan_type_cp;
-
-typedef hci_status_rp hci_write_inquiry_scan_type_rp;
-
-#define HCI_OCF_READ_INQUIRY_MODE 0x0044
-#define HCI_CMD_READ_INQUIRY_MODE 0x0C44
-/* No command parameter(s) */
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t mode; /* inquiry mode */
-} __packed hci_read_inquiry_mode_rp;
-
-#define HCI_OCF_WRITE_INQUIRY_MODE 0x0045
-#define HCI_CMD_WRITE_INQUIRY_MODE 0x0C45
-typedef struct {
- uint8_t mode; /* inquiry mode */
-} __packed hci_write_inquiry_mode_cp;
-
-typedef hci_status_rp hci_write_inquiry_mode_rp;
-
-#define HCI_OCF_READ_PAGE_SCAN_TYPE 0x0046
-#define HCI_CMD_READ_PAGE_SCAN_TYPE 0x0C46
-/* No command parameter(s) */
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t type; /* page scan type */
-} __packed hci_read_page_scan_type_rp;
-
-#define HCI_OCF_WRITE_PAGE_SCAN_TYPE 0x0047
-#define HCI_CMD_WRITE_PAGE_SCAN_TYPE 0x0C47
-typedef struct {
- uint8_t type; /* page scan type */
-} __packed hci_write_page_scan_type_cp;
-
-typedef hci_status_rp hci_write_page_scan_type_rp;
-
-#define HCI_OCF_READ_AFH_ASSESSMENT 0x0048
-#define HCI_CMD_READ_AFH_ASSESSMENT 0x0C48
-/* No command parameter(s) */
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t mode; /* assessment mode */
-} __packed hci_read_afh_assessment_rp;
-
-#define HCI_OCF_WRITE_AFH_ASSESSMENT 0x0049
-#define HCI_CMD_WRITE_AFH_ASSESSMENT 0x0C49
-typedef struct {
- uint8_t mode; /* assessment mode */
-} __packed hci_write_afh_assessment_cp;
-
-typedef hci_status_rp hci_write_afh_assessment_rp;
-
-#define HCI_OCF_READ_EXTENDED_INQUIRY_RSP 0x0051
-#define HCI_CMD_READ_EXTENDED_INQUIRY_RSP 0x0C51
-/* No command parameter(s) */
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t fec_required;
- uint8_t response[240];
-} __packed hci_read_extended_inquiry_rsp_rp;
-
-#define HCI_OCF_WRITE_EXTENDED_INQUIRY_RSP 0x0052
-#define HCI_CMD_WRITE_EXTENDED_INQUIRY_RSP 0x0C52
-typedef struct {
- uint8_t fec_required;
- uint8_t response[240];
-} __packed hci_write_extended_inquiry_rsp_cp;
-
-typedef hci_status_rp hci_write_extended_inquiry_rsp_rp;
-
-#define HCI_OCF_REFRESH_ENCRYPTION_KEY 0x0053
-#define HCI_CMD_REFRESH_ENCRYPTION_KEY 0x0C53
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_refresh_encryption_key_cp;
-
-typedef hci_status_rp hci_refresh_encryption_key_rp;
-
-#define HCI_OCF_READ_SIMPLE_PAIRING_MODE 0x0055
-#define HCI_CMD_READ_SIMPLE_PAIRING_MODE 0x0C55
-/* No command parameter(s) */
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t mode; /* simple pairing mode */
-} __packed hci_read_simple_pairing_mode_rp;
-
-#define HCI_OCF_WRITE_SIMPLE_PAIRING_MODE 0x0056
-#define HCI_CMD_WRITE_SIMPLE_PAIRING_MODE 0x0C56
-typedef struct {
- uint8_t mode; /* simple pairing mode */
-} __packed hci_write_simple_pairing_mode_cp;
-
-typedef hci_status_rp hci_write_simple_pairing_mode_rp;
-
-#define HCI_OCF_READ_LOCAL_OOB_DATA 0x0057
-#define HCI_CMD_READ_LOCAL_OOB_DATA 0x0C57
-/* No command parameter(s) */
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t c[16]; /* pairing hash */
- uint8_t r[16]; /* pairing randomizer */
-} __packed hci_read_local_oob_data_rp;
-
-#define HCI_OCF_READ_INQUIRY_RSP_XMIT_POWER 0x0058
-#define HCI_CMD_READ_INQUIRY_RSP_XMIT_POWER 0x0C58
-/* No command parameter(s) */
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- int8_t power; /* TX power */
-} __packed hci_read_inquiry_rsp_xmit_power_rp;
-
-#define HCI_OCF_WRITE_INQUIRY_RSP_XMIT_POWER 0x0059
-#define HCI_CMD_WRITE_INQUIRY_RSP_XMIT_POWER 0x0C59
-typedef struct {
- int8_t power; /* TX power */
-} __packed hci_write_inquiry_rsp_xmit_power_cp;
-
-typedef hci_status_rp hci_write_inquiry_rsp_xmit_power_rp;
-
-#define HCI_OCF_READ_DEFAULT_ERRDATA_REPORTING 0x005A
-#define HCI_CMD_READ_DEFAULT_ERRDATA_REPORTING 0x0C5A
-/* No command parameter(s) */
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t reporting; /* erroneous data reporting */
-} __packed hci_read_default_errdata_reporting_rp;
-
-#define HCI_OCF_WRITE_DEFAULT_ERRDATA_REPORTING 0x005B
-#define HCI_CMD_WRITE_DEFAULT_ERRDATA_REPORTING 0x0C5B
-typedef struct {
- uint8_t reporting; /* erroneous data reporting */
-} __packed hci_write_default_errdata_reporting_cp;
-
-typedef hci_status_rp hci_write_default_errdata_reporting_rp;
-
-#define HCI_OCF_ENHANCED_FLUSH 0x005F
-#define HCI_CMD_ENHANCED_FLUSH 0x0C5F
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint8_t packet_type;
-} __packed hci_enhanced_flush_cp;
-
-/* No response parameter(s) */
-
-#define HCI_OCF_SEND_KEYPRESS_NOTIFICATION 0x0060
-#define HCI_CMD_SEND_KEYPRESS_NOTIFICATION 0x0C60
-typedef struct {
- bdaddr_t bdaddr; /* remote address */
- uint8_t type; /* notification type */
-} __packed hci_send_keypress_notification_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote address */
-} __packed hci_send_keypress_notification_rp;
-
-/**************************************************************************
- **************************************************************************
- ** OGF 0x04 Informational commands and return parameters
- **************************************************************************
- **************************************************************************/
-
-#define HCI_OGF_INFO 0x04
-
-#define HCI_OCF_READ_LOCAL_VER 0x0001
-#define HCI_CMD_READ_LOCAL_VER 0x1001
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t hci_version; /* HCI version */
- uint16_t hci_revision; /* HCI revision */
- uint8_t lmp_version; /* LMP version */
- uint16_t manufacturer; /* Hardware manufacturer name */
- uint16_t lmp_subversion; /* LMP sub-version */
-} __packed hci_read_local_ver_rp;
-
-#define HCI_OCF_READ_LOCAL_COMMANDS 0x0002
-#define HCI_CMD_READ_LOCAL_COMMANDS 0x1002
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t commands[HCI_COMMANDS_SIZE]; /* opcode bitmask */
-} __packed hci_read_local_commands_rp;
-
-#define HCI_OCF_READ_LOCAL_FEATURES 0x0003
-#define HCI_CMD_READ_LOCAL_FEATURES 0x1003
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t features[HCI_FEATURES_SIZE]; /* LMP features bitmsk*/
-} __packed hci_read_local_features_rp;
-
-#define HCI_OCF_READ_LOCAL_EXTENDED_FEATURES 0x0004
-#define HCI_CMD_READ_LOCAL_EXTENDED_FEATURES 0x1004
-typedef struct {
- uint8_t page; /* page number */
-} __packed hci_read_local_extended_features_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t page; /* page number */
- uint8_t max_page; /* maximum page number */
- uint8_t features[HCI_FEATURES_SIZE]; /* LMP features */
-} __packed hci_read_local_extended_features_rp;
-
-#define HCI_OCF_READ_BUFFER_SIZE 0x0005
-#define HCI_CMD_READ_BUFFER_SIZE 0x1005
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t max_acl_size; /* Max. size of ACL packet (bytes) */
- uint8_t max_sco_size; /* Max. size of SCO packet (bytes) */
- uint16_t num_acl_pkts; /* Max. number of ACL packets */
- uint16_t num_sco_pkts; /* Max. number of SCO packets */
-} __packed hci_read_buffer_size_rp;
-
-/* Read Country Code is deprecated */
-#define HCI_OCF_READ_COUNTRY_CODE 0x0007
-#define HCI_CMD_READ_COUNTRY_CODE 0x1007
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t country_code; /* 0x00 - NAM, EUR, JP; 0x01 - France */
-} __packed hci_read_country_code_rp;
-
-#define HCI_OCF_READ_BDADDR 0x0009
-#define HCI_CMD_READ_BDADDR 0x1009
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* unit address */
-} __packed hci_read_bdaddr_rp;
-
-/**************************************************************************
- **************************************************************************
- ** OGF 0x05 Status commands and return parameters
- **************************************************************************
- **************************************************************************/
-
-#define HCI_OGF_STATUS 0x05
-
-#define HCI_OCF_READ_FAILED_CONTACT_CNTR 0x0001
-#define HCI_CMD_READ_FAILED_CONTACT_CNTR 0x1401
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_failed_contact_cntr_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint16_t counter; /* number of consecutive failed contacts */
-} __packed hci_read_failed_contact_cntr_rp;
-
-#define HCI_OCF_RESET_FAILED_CONTACT_CNTR 0x0002
-#define HCI_CMD_RESET_FAILED_CONTACT_CNTR 0x1402
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_reset_failed_contact_cntr_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
-} __packed hci_reset_failed_contact_cntr_rp;
-
-#define HCI_OCF_READ_LINK_QUALITY 0x0003
-#define HCI_CMD_READ_LINK_QUALITY 0x1403
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_link_quality_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t quality; /* higher value means better quality */
-} __packed hci_read_link_quality_rp;
-
-#define HCI_OCF_READ_RSSI 0x0005
-#define HCI_CMD_READ_RSSI 0x1405
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_rssi_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- char rssi; /* -127 <= rssi <= 127 dB */
-} __packed hci_read_rssi_rp;
-
-#define HCI_OCF_READ_AFH_CHANNEL_MAP 0x0006
-#define HCI_CMD_READ_AFH_CHANNEL_MAP 0x1406
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_read_afh_channel_map_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t mode; /* AFH mode */
- uint8_t map[10]; /* AFH Channel Map */
-} __packed hci_read_afh_channel_map_rp;
-
-#define HCI_OCF_READ_CLOCK 0x0007
-#define HCI_CMD_READ_CLOCK 0x1407
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint8_t clock; /* which clock */
-} __packed hci_read_clock_cp;
-
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint32_t clock; /* clock value */
- uint16_t accuracy; /* clock accuracy */
-} __packed hci_read_clock_rp;
-
-
-/**************************************************************************
- **************************************************************************
- ** OGF 0x06 Testing commands and return parameters
- **************************************************************************
- **************************************************************************/
-
-#define HCI_OGF_TESTING 0x06
-
-#define HCI_OCF_READ_LOOPBACK_MODE 0x0001
-#define HCI_CMD_READ_LOOPBACK_MODE 0x1801
-/* No command parameter(s) */
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint8_t lbmode; /* loopback mode */
-} __packed hci_read_loopback_mode_rp;
-
-#define HCI_OCF_WRITE_LOOPBACK_MODE 0x0002
-#define HCI_CMD_WRITE_LOOPBACK_MODE 0x1802
-typedef struct {
- uint8_t lbmode; /* loopback mode */
-} __packed hci_write_loopback_mode_cp;
-
-typedef hci_status_rp hci_write_loopback_mode_rp;
-
-#define HCI_OCF_ENABLE_UNIT_UNDER_TEST 0x0003
-#define HCI_CMD_ENABLE_UNIT_UNDER_TEST 0x1803
-/* No command parameter(s) */
-typedef hci_status_rp hci_enable_unit_under_test_rp;
-
-#define HCI_OCF_WRITE_SIMPLE_PAIRING_DEBUG_MODE 0x0004
-#define HCI_CMD_WRITE_SIMPLE_PAIRING_DEBUG_MODE 0x1804
-typedef struct {
- uint8_t mode; /* simple pairing debug mode */
-} __packed hci_write_simple_pairing_debug_mode_cp;
-
-typedef hci_status_rp hci_write_simple_pairing_debug_mode_rp;
-
-/**************************************************************************
- **************************************************************************
- ** OGF 0x3e Bluetooth Logo Testing
- ** OGF 0x3f Vendor Specific
- **************************************************************************
- **************************************************************************/
-
-#define HCI_OGF_BT_LOGO 0x3e
-#define HCI_OGF_VENDOR 0x3f
-
-/* Ericsson specific FC */
-#define HCI_CMD_ERICSSON_WRITE_PCM_SETTINGS 0xFC07
-#define HCI_CMD_ERICSSON_SET_UART_BAUD_RATE 0xFC09
-#define HCI_CMD_ERICSSON_SET_SCO_DATA_PATH 0xFC1D
-
-/* Cambridge Silicon Radio specific FC */
-#define HCI_CMD_CSR_EXTN 0xFC00
-
-
-/**************************************************************************
- **************************************************************************
- ** Events and event parameters
- **************************************************************************
- **************************************************************************/
-
-#define HCI_EVENT_INQUIRY_COMPL 0x01
-typedef struct {
- uint8_t status; /* 0x00 - success */
-} __packed hci_inquiry_compl_ep;
-
-#define HCI_EVENT_INQUIRY_RESULT 0x02
-typedef struct {
- uint8_t num_responses; /* number of responses */
-/* hci_inquiry_response[num_responses] -- see below */
-} __packed hci_inquiry_result_ep;
-
-typedef struct {
- bdaddr_t bdaddr; /* unit address */
- uint8_t page_scan_rep_mode; /* page scan rep. mode */
- uint8_t page_scan_period_mode; /* page scan period mode */
- uint8_t page_scan_mode; /* page scan mode */
- uint8_t uclass[HCI_CLASS_SIZE]; /* unit class */
- uint16_t clock_offset; /* clock offset */
-} __packed hci_inquiry_response;
-
-#define HCI_EVENT_CON_COMPL 0x03
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* Connection handle */
- bdaddr_t bdaddr; /* remote unit address */
- uint8_t link_type; /* Link type */
- uint8_t encryption_mode; /* Encryption mode */
-} __packed hci_con_compl_ep;
-
-#define HCI_EVENT_CON_REQ 0x04
-typedef struct {
- bdaddr_t bdaddr; /* remote unit address */
- uint8_t uclass[HCI_CLASS_SIZE]; /* remote unit class */
- uint8_t link_type; /* link type */
-} __packed hci_con_req_ep;
-
-#define HCI_EVENT_DISCON_COMPL 0x05
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t reason; /* reason to disconnect */
-} __packed hci_discon_compl_ep;
-
-#define HCI_EVENT_AUTH_COMPL 0x06
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
-} __packed hci_auth_compl_ep;
-
-#define HCI_EVENT_REMOTE_NAME_REQ_COMPL 0x07
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote unit address */
- char name[HCI_UNIT_NAME_SIZE]; /* remote unit name */
-} __packed hci_remote_name_req_compl_ep;
-
-#define HCI_EVENT_ENCRYPTION_CHANGE 0x08
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* Connection handle */
- uint8_t encryption_enable; /* 0x00 - disable */
-} __packed hci_encryption_change_ep;
-
-#define HCI_EVENT_CHANGE_CON_LINK_KEY_COMPL 0x09
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* Connection handle */
-} __packed hci_change_con_link_key_compl_ep;
-
-#define HCI_EVENT_MASTER_LINK_KEY_COMPL 0x0a
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* Connection handle */
- uint8_t key_flag; /* Key flag */
-} __packed hci_master_link_key_compl_ep;
-
-#define HCI_EVENT_READ_REMOTE_FEATURES_COMPL 0x0b
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* Connection handle */
- uint8_t features[HCI_FEATURES_SIZE]; /* LMP features bitmsk*/
-} __packed hci_read_remote_features_compl_ep;
-
-#define HCI_EVENT_READ_REMOTE_VER_INFO_COMPL 0x0c
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* Connection handle */
- uint8_t lmp_version; /* LMP version */
- uint16_t manufacturer; /* Hardware manufacturer name */
- uint16_t lmp_subversion; /* LMP sub-version */
-} __packed hci_read_remote_ver_info_compl_ep;
-
-#define HCI_EVENT_QOS_SETUP_COMPL 0x0d
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t flags; /* reserved for future use */
- uint8_t service_type; /* service type */
- uint32_t token_rate; /* bytes per second */
- uint32_t peak_bandwidth; /* bytes per second */
- uint32_t latency; /* microseconds */
- uint32_t delay_variation; /* microseconds */
-} __packed hci_qos_setup_compl_ep;
-
-#define HCI_EVENT_COMMAND_COMPL 0x0e
-typedef struct {
- uint8_t num_cmd_pkts; /* # of HCI command packets */
- uint16_t opcode; /* command OpCode */
- /* command return parameters (if any) */
-} __packed hci_command_compl_ep;
-
-#define HCI_EVENT_COMMAND_STATUS 0x0f
-typedef struct {
- uint8_t status; /* 0x00 - pending */
- uint8_t num_cmd_pkts; /* # of HCI command packets */
- uint16_t opcode; /* command OpCode */
-} __packed hci_command_status_ep;
-
-#define HCI_EVENT_HARDWARE_ERROR 0x10
-typedef struct {
- uint8_t hardware_code; /* hardware error code */
-} __packed hci_hardware_error_ep;
-
-#define HCI_EVENT_FLUSH_OCCUR 0x11
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_flush_occur_ep;
-
-#define HCI_EVENT_ROLE_CHANGE 0x12
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* address of remote unit */
- uint8_t role; /* new connection role */
-} __packed hci_role_change_ep;
-
-#define HCI_EVENT_NUM_COMPL_PKTS 0x13
-typedef struct {
- uint8_t num_con_handles; /* # of connection handles */
-/* these are repeated "num_con_handles" times
- uint16_t con_handle; --- connection handle(s)
- uint16_t compl_pkts; --- # of completed packets */
-} __packed hci_num_compl_pkts_ep;
-
-#define HCI_EVENT_MODE_CHANGE 0x14
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t unit_mode; /* remote unit mode */
- uint16_t interval; /* interval * 0.625 msec */
-} __packed hci_mode_change_ep;
-
-#define HCI_EVENT_RETURN_LINK_KEYS 0x15
-typedef struct {
- uint8_t num_keys; /* # of keys */
-/* these are repeated "num_keys" times
- bdaddr_t bdaddr; --- remote address(es)
- uint8_t key[HCI_KEY_SIZE]; --- key(s) */
-} __packed hci_return_link_keys_ep;
-
-#define HCI_EVENT_PIN_CODE_REQ 0x16
-typedef struct {
- bdaddr_t bdaddr; /* remote unit address */
-} __packed hci_pin_code_req_ep;
-
-#define HCI_EVENT_LINK_KEY_REQ 0x17
-typedef struct {
- bdaddr_t bdaddr; /* remote unit address */
-} __packed hci_link_key_req_ep;
-
-#define HCI_EVENT_LINK_KEY_NOTIFICATION 0x18
-typedef struct {
- bdaddr_t bdaddr; /* remote unit address */
- uint8_t key[HCI_KEY_SIZE]; /* link key */
- uint8_t key_type; /* type of the key */
-} __packed hci_link_key_notification_ep;
-
-#define HCI_EVENT_LOOPBACK_COMMAND 0x19
-typedef hci_cmd_hdr_t hci_loopback_command_ep;
-
-#define HCI_EVENT_DATA_BUFFER_OVERFLOW 0x1a
-typedef struct {
- uint8_t link_type; /* Link type */
-} __packed hci_data_buffer_overflow_ep;
-
-#define HCI_EVENT_MAX_SLOT_CHANGE 0x1b
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint8_t lmp_max_slots; /* Max. # of slots allowed */
-} __packed hci_max_slot_change_ep;
-
-#define HCI_EVENT_READ_CLOCK_OFFSET_COMPL 0x1c
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* Connection handle */
- uint16_t clock_offset; /* Clock offset */
-} __packed hci_read_clock_offset_compl_ep;
-
-#define HCI_EVENT_CON_PKT_TYPE_CHANGED 0x1d
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint16_t pkt_type; /* packet type */
-} __packed hci_con_pkt_type_changed_ep;
-
-#define HCI_EVENT_QOS_VIOLATION 0x1e
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_qos_violation_ep;
-
-/* Page Scan Mode Change Event is deprecated */
-#define HCI_EVENT_PAGE_SCAN_MODE_CHANGE 0x1f
-typedef struct {
- bdaddr_t bdaddr; /* destination address */
- uint8_t page_scan_mode; /* page scan mode */
-} __packed hci_page_scan_mode_change_ep;
-
-#define HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE 0x20
-typedef struct {
- bdaddr_t bdaddr; /* destination address */
- uint8_t page_scan_rep_mode; /* page scan repetition mode */
-} __packed hci_page_scan_rep_mode_change_ep;
-
-#define HCI_EVENT_FLOW_SPECIFICATION_COMPL 0x21
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t flags; /* reserved */
- uint8_t direction; /* flow direction */
- uint8_t type; /* service type */
- uint32_t token_rate; /* token rate */
- uint32_t bucket_size; /* token bucket size */
- uint32_t peak_bandwidth; /* peak bandwidth */
- uint32_t latency; /* access latency */
-} __packed hci_flow_specification_compl_ep;
-
-#define HCI_EVENT_RSSI_RESULT 0x22
-typedef struct {
- uint8_t num_responses; /* number of responses */
-/* hci_rssi_response[num_responses] -- see below */
-} __packed hci_rssi_result_ep;
-
-typedef struct {
- bdaddr_t bdaddr; /* unit address */
- uint8_t page_scan_rep_mode; /* page scan rep. mode */
- uint8_t blank; /* reserved */
- uint8_t uclass[HCI_CLASS_SIZE]; /* unit class */
- uint16_t clock_offset; /* clock offset */
- int8_t rssi; /* rssi */
-} __packed hci_rssi_response;
-
-#define HCI_EVENT_READ_REMOTE_EXTENDED_FEATURES 0x23
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t page; /* page number */
- uint8_t max; /* max page number */
- uint8_t features[HCI_FEATURES_SIZE]; /* LMP features bitmsk*/
-} __packed hci_read_remote_extended_features_ep;
-
-#define HCI_EVENT_SCO_CON_COMPL 0x2c
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- bdaddr_t bdaddr; /* unit address */
- uint8_t link_type; /* link type */
- uint8_t interval; /* transmission interval */
- uint8_t window; /* retransmission window */
- uint16_t rxlen; /* rx packet length */
- uint16_t txlen; /* tx packet length */
- uint8_t mode; /* air mode */
-} __packed hci_sco_con_compl_ep;
-
-#define HCI_EVENT_SCO_CON_CHANGED 0x2d
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint8_t interval; /* transmission interval */
- uint8_t window; /* retransmission window */
- uint16_t rxlen; /* rx packet length */
- uint16_t txlen; /* tx packet length */
-} __packed hci_sco_con_changed_ep;
-
-#define HCI_EVENT_SNIFF_SUBRATING 0x2e
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
- uint16_t tx_latency; /* max transmit latency */
- uint16_t rx_latency; /* max receive latency */
- uint16_t remote_timeout; /* remote timeout */
- uint16_t local_timeout; /* local timeout */
-} __packed hci_sniff_subrating_ep;
-
-#define HCI_EVENT_EXTENDED_RESULT 0x2f
-typedef struct {
- uint8_t num_responses; /* must be 0x01 */
- bdaddr_t bdaddr; /* remote device address */
- uint8_t page_scan_rep_mode;
- uint8_t reserved;
- uint8_t uclass[HCI_CLASS_SIZE];
- uint16_t clock_offset;
- int8_t rssi;
- uint8_t response[240]; /* extended inquiry response */
-} __packed hci_extended_result_ep;
-
-#define HCI_EVENT_ENCRYPTION_KEY_REFRESH 0x30
-typedef struct {
- uint8_t status; /* 0x00 - success */
- uint16_t con_handle; /* connection handle */
-} __packed hci_encryption_key_refresh_ep;
-
-#define HCI_EVENT_IO_CAPABILITY_REQ 0x31
-typedef struct {
- bdaddr_t bdaddr; /* remote device address */
-} __packed hci_io_capability_req_ep;
-
-#define HCI_EVENT_IO_CAPABILITY_RSP 0x32
-typedef struct {
- bdaddr_t bdaddr; /* remote device address */
- uint8_t io_capability;
- uint8_t oob_data_present;
- uint8_t auth_requirement;
-} __packed hci_io_capability_rsp_ep;
-
-#define HCI_EVENT_USER_CONFIRM_REQ 0x33
-typedef struct {
- bdaddr_t bdaddr; /* remote device address */
- uint32_t value; /* 000000 - 999999 */
-} __packed hci_user_confirm_req_ep;
-
-#define HCI_EVENT_USER_PASSKEY_REQ 0x34
-typedef struct {
- bdaddr_t bdaddr; /* remote device address */
-} __packed hci_user_passkey_req_ep;
-
-#define HCI_EVENT_REMOTE_OOB_DATA_REQ 0x35
-typedef struct {
- bdaddr_t bdaddr; /* remote device address */
-} __packed hci_remote_oob_data_req_ep;
-
-#define HCI_EVENT_SIMPLE_PAIRING_COMPL 0x36
-typedef struct {
- uint8_t status; /* 0x00 - success */
- bdaddr_t bdaddr; /* remote device address */
-} __packed hci_simple_pairing_compl_ep;
-
-#define HCI_EVENT_LINK_SUPERVISION_TO_CHANGED 0x38
-typedef struct {
- uint16_t con_handle; /* connection handle */
- uint16_t timeout; /* link supervision timeout */
-} __packed hci_link_supervision_to_changed_ep;
-
-#define HCI_EVENT_ENHANCED_FLUSH_COMPL 0x39
-typedef struct {
- uint16_t con_handle; /* connection handle */
-} __packed hci_enhanced_flush_compl_ep;
-
-#define HCI_EVENT_USER_PASSKEY_NOTIFICATION 0x3b
-typedef struct {
- bdaddr_t bdaddr; /* remote device address */
- uint32_t value; /* 000000 - 999999 */
-} __packed hci_user_passkey_notification_ep;
-
-#define HCI_EVENT_KEYPRESS_NOTIFICATION 0x3c
-typedef struct {
- bdaddr_t bdaddr; /* remote device address */
- uint8_t notification_type;
-} __packed hci_keypress_notification_ep;
-
-#define HCI_EVENT_REMOTE_FEATURES_NOTIFICATION 0x3d
-typedef struct {
- bdaddr_t bdaddr; /* remote device address */
- uint8_t features[HCI_FEATURES_SIZE]; /* LMP features bitmsk*/
-} __packed hci_remote_features_notification_ep;
-
-#define HCI_EVENT_BT_LOGO 0xfe
-
-#define HCI_EVENT_VENDOR 0xff
-
-/**************************************************************************
- **************************************************************************
- ** HCI Socket Definitions
- **************************************************************************
- **************************************************************************/
-
-/* HCI socket options */
-#define SO_HCI_EVT_FILTER 1 /* get/set event filter */
-#define SO_HCI_PKT_FILTER 2 /* get/set packet filter */
-#define SO_HCI_DIRECTION 3 /* packet direction indicator */
-
-/* Control Messages */
-#define SCM_HCI_DIRECTION SO_HCI_DIRECTION
-
-/*
- * HCI socket filter and get/set routines
- *
- * for ease of use, we filter 256 possible events/packets
- */
-struct hci_filter {
- uint32_t mask[8]; /* 256 bits */
-};
-
-static __inline void
-hci_filter_set(uint8_t bit, struct hci_filter *filter)
-{
- uint8_t off = bit - 1;
-
- off >>= 5;
- filter->mask[off] |= (1 << ((bit - 1) & 0x1f));
-}
-
-static __inline void
-hci_filter_clr(uint8_t bit, struct hci_filter *filter)
-{
- uint8_t off = bit - 1;
-
- off >>= 5;
- filter->mask[off] &= ~(1 << ((bit - 1) & 0x1f));
-}
-
-static __inline int
-hci_filter_test(uint8_t bit, struct hci_filter *filter)
-{
- uint8_t off = bit - 1;
-
- off >>= 5;
- return (filter->mask[off] & (1 << ((bit - 1) & 0x1f)));
-}
-
-/*
- * HCI socket ioctl's
- *
- * Apart from GBTINFOA, these are all indexed on the unit name
- */
-
-#define SIOCGBTINFO _IOWR('b', 5, struct btreq) /* get unit info */
-#define SIOCGBTINFOA _IOWR('b', 6, struct btreq) /* get info by address */
-#define SIOCNBTINFO _IOWR('b', 7, struct btreq) /* next unit info */
-
-#define SIOCSBTFLAGS _IOWR('b', 8, struct btreq) /* set unit flags */
-#define SIOCSBTPOLICY _IOWR('b', 9, struct btreq) /* set unit link policy */
-#define SIOCSBTPTYPE _IOWR('b', 10, struct btreq) /* set unit packet type */
-
-#define SIOCGBTSTATS _IOWR('b', 11, struct btreq) /* get unit statistics */
-#define SIOCZBTSTATS _IOWR('b', 12, struct btreq) /* zero unit statistics */
-
-#define SIOCBTDUMP _IOW('b', 13, struct btreq) /* print debug info */
-#define SIOCSBTSCOMTU _IOWR('b', 17, struct btreq) /* set sco_mtu value */
-
-struct bt_stats {
- uint32_t err_tx;
- uint32_t err_rx;
- uint32_t cmd_tx;
- uint32_t evt_rx;
- uint32_t acl_tx;
- uint32_t acl_rx;
- uint32_t sco_tx;
- uint32_t sco_rx;
- uint32_t byte_tx;
- uint32_t byte_rx;
-};
-
-struct btreq {
- char btr_name[HCI_DEVNAME_SIZE]; /* device name */
-
- union {
- struct {
- bdaddr_t btri_bdaddr; /* device bdaddr */
- uint16_t btri_flags; /* flags */
- uint16_t btri_num_cmd; /* # of free cmd buffers */
- uint16_t btri_num_acl; /* # of free ACL buffers */
- uint16_t btri_num_sco; /* # of free SCO buffers */
- uint16_t btri_acl_mtu; /* ACL mtu */
- uint16_t btri_sco_mtu; /* SCO mtu */
- uint16_t btri_link_policy; /* Link Policy */
- uint16_t btri_packet_type; /* Packet Type */
- } btri;
- struct bt_stats btrs; /* unit stats */
- } btru;
-};
-
-#define btr_flags btru.btri.btri_flags
-#define btr_bdaddr btru.btri.btri_bdaddr
-#define btr_num_cmd btru.btri.btri_num_cmd
-#define btr_num_acl btru.btri.btri_num_acl
-#define btr_num_sco btru.btri.btri_num_sco
-#define btr_acl_mtu btru.btri.btri_acl_mtu
-#define btr_sco_mtu btru.btri.btri_sco_mtu
-#define btr_link_policy btru.btri.btri_link_policy
-#define btr_packet_type btru.btri.btri_packet_type
-#define btr_stats btru.btrs
-
-/* hci_unit & btr_flags */
-#define BTF_UP (1<<0) /* unit is up */
-#define BTF_RUNNING (1<<1) /* unit is running */
-#define BTF_XMIT_CMD (1<<2) /* unit is transmitting CMD packets */
-#define BTF_XMIT_ACL (1<<3) /* unit is transmitting ACL packets */
-#define BTF_XMIT_SCO (1<<4) /* unit is transmitting SCO packets */
-#define BTF_XMIT (BTF_XMIT_CMD | BTF_XMIT_ACL | BTF_XMIT_SCO)
-#define BTF_INIT_BDADDR (1<<5) /* waiting for bdaddr */
-#define BTF_INIT_BUFFER_SIZE (1<<6) /* waiting for buffer size */
-#define BTF_INIT_FEATURES (1<<7) /* waiting for features */
-#define BTF_POWER_UP_NOOP (1<<8) /* should wait for No-op on power up */
-#define BTF_INIT_COMMANDS (1<<9) /* waiting for supported commands */
-
-#define BTF_INIT (BTF_INIT_BDADDR \
- | BTF_INIT_BUFFER_SIZE \
- | BTF_INIT_FEATURES \
- | BTF_INIT_COMMANDS)
-
-/**************************************************************************
- **************************************************************************
- ** HCI Kernel Definitions
- **************************************************************************
- **************************************************************************/
-
-#ifdef _KERNEL
-
-#include <sys/device.h>
-#include <net/if.h> /* for struct ifqueue */
-
-struct l2cap_channel;
-struct mbuf;
-struct sco_pcb;
-struct socket;
-
-/* global HCI kernel variables */
-
-/* sysctl variables */
-extern int hci_memo_expiry;
-extern int hci_acl_expiry;
-extern int hci_sendspace, hci_recvspace;
-extern int hci_eventq_max, hci_aclrxq_max, hci_scorxq_max;
-
-/*
- * HCI Connection Information
- */
-struct hci_link {
- struct hci_unit *hl_unit; /* our unit */
- TAILQ_ENTRY(hci_link) hl_next; /* next link on unit */
-
- /* common info */
- uint16_t hl_state; /* connection state */
- uint16_t hl_flags; /* link flags */
- bdaddr_t hl_bdaddr; /* dest address */
- uint16_t hl_handle; /* connection handle */
- uint8_t hl_type; /* link type */
-
- /* ACL link info */
- uint8_t hl_lastid; /* last id used */
- uint16_t hl_refcnt; /* reference count */
- uint16_t hl_mtu; /* signalling mtu for link */
- uint16_t hl_flush; /* flush timeout */
- uint16_t hl_clock; /* remote clock offset */
-
- TAILQ_HEAD(,l2cap_pdu) hl_txq; /* queue of outgoing PDUs */
- int hl_txqlen; /* number of fragments */
- struct mbuf *hl_rxp; /* incoming PDU (accumulating)*/
- struct timeout hl_expire; /* connection expiry timer */
- TAILQ_HEAD(,l2cap_req) hl_reqs; /* pending requests */
-
- /* SCO link info */
- struct hci_link *hl_link; /* SCO ACL link */
- struct sco_pcb *hl_sco; /* SCO pcb */
- struct ifqueue hl_data; /* SCO outgoing data */
-};
-
-/* hci_link state */
-#define HCI_LINK_CLOSED 0 /* closed */
-#define HCI_LINK_WAIT_CONNECT 1 /* waiting to connect */
-#define HCI_LINK_WAIT_AUTH 2 /* waiting for auth */
-#define HCI_LINK_WAIT_ENCRYPT 3 /* waiting for encrypt */
-#define HCI_LINK_WAIT_SECURE 4 /* waiting for secure */
-#define HCI_LINK_OPEN 5 /* ready and willing */
-#define HCI_LINK_BLOCK 6 /* open but blocking (see hci_acl_start) */
-
-/* hci_link flags */
-#define HCI_LINK_AUTH_REQ (1<<0) /* authentication requested */
-#define HCI_LINK_ENCRYPT_REQ (1<<1) /* encryption requested */
-#define HCI_LINK_SECURE_REQ (1<<2) /* secure link requested */
-#define HCI_LINK_AUTH (1<<3) /* link is authenticated */
-#define HCI_LINK_ENCRYPT (1<<4) /* link is encrypted */
-#define HCI_LINK_SECURE (1<<5) /* link is secured */
-#define HCI_LINK_CREATE_CON (1<<6) /* "Create Connection" pending */
-
-/*
- * Bluetooth Memo
- * cached device information for remote devices that this unit has seen
- */
-struct hci_memo {
- struct timeval time; /* time of last response */
- bdaddr_t bdaddr;
- uint8_t page_scan_rep_mode;
- uint8_t page_scan_mode;
- uint16_t clock_offset;
- LIST_ENTRY(hci_memo) next;
-};
-
-/*
- * The Bluetooth HCI interface attachment structure
- */
-struct hci_if {
- int (*enable)(struct device *);
- void (*disable)(struct device *);
- void (*output_cmd)(struct device *, struct mbuf *);
- void (*output_acl)(struct device *, struct mbuf *);
- void (*output_sco)(struct device *, struct mbuf *);
- void (*get_stats)(struct device *, struct bt_stats *, int);
- int ipl; /* for locking */
-};
-
-/*
- * The Bluetooth HCI device unit structure
- */
-struct hci_unit {
- struct device *hci_dev; /* bthci handle */
- struct device *hci_bthub; /* bthub(4) handle */
- const struct hci_if *hci_if; /* bthci driver interface */
-
- /* device info */
- bdaddr_t hci_bdaddr; /* device address */
- uint16_t hci_flags; /* see BTF_ above */
- int hci_init; /* sleep on this */
-
- uint16_t hci_packet_type; /* packet types */
- uint16_t hci_acl_mask; /* ACL packet capabilities */
- uint16_t hci_sco_mask; /* SCO packet capabilities */
-
- uint16_t hci_link_policy; /* link policy */
- uint16_t hci_lmp_mask; /* link policy capabilities */
-
- uint8_t hci_cmds[HCI_COMMANDS_SIZE]; /* opcode bitmask */
-
- /* flow control */
- uint16_t hci_max_acl_size; /* ACL payload mtu */
- uint16_t hci_num_acl_pkts; /* free ACL packet buffers */
- uint8_t hci_num_cmd_pkts; /* free CMD packet buffers */
- uint8_t hci_max_sco_size; /* SCO payload mtu */
- uint16_t hci_num_sco_pkts; /* free SCO packet buffers */
-
- TAILQ_HEAD(,hci_link) hci_links; /* list of ACL/SCO links */
- LIST_HEAD(,hci_memo) hci_memos; /* cached memo list */
-
- /* input queues */
-#ifndef __OpenBSD__
- void *hci_rxint; /* receive interrupt cookie */
-#endif
- struct mutex hci_devlock; /* device queue lock */
- struct ifqueue hci_eventq; /* Event queue */
- struct ifqueue hci_aclrxq; /* ACL rx queue */
- struct ifqueue hci_scorxq; /* SCO rx queue */
- uint16_t hci_eventqlen; /* Event queue length */
- uint16_t hci_aclrxqlen; /* ACL rx queue length */
- uint16_t hci_scorxqlen; /* SCO rx queue length */
-
- /* output queues */
- struct ifqueue hci_cmdwait; /* pending commands */
- struct ifqueue hci_scodone; /* SCO done queue */
-
- TAILQ_ENTRY(hci_unit) hci_next;
-};
-
-extern TAILQ_HEAD(hci_unit_list, hci_unit) hci_unit_list;
-
-/*
- * HCI layer function prototypes
- */
-
-/* hci_event.c */
-void hci_event(struct mbuf *, struct hci_unit *);
-
-/* hci_ioctl.c */
-int hci_ioctl(unsigned long, void *, struct proc *);
-
-/* hci_link.c */
-struct hci_link *hci_acl_open(struct hci_unit *, bdaddr_t *);
-struct hci_link *hci_acl_newconn(struct hci_unit *, bdaddr_t *);
-void hci_acl_close(struct hci_link *, int);
-void hci_acl_timeout(void *);
-int hci_acl_setmode(struct hci_link *);
-void hci_acl_linkmode(struct hci_link *);
-void hci_acl_recv(struct mbuf *, struct hci_unit *);
-int hci_acl_send(struct mbuf *, struct hci_link *, struct l2cap_channel *);
-void hci_acl_start(struct hci_link *);
-void hci_acl_complete(struct hci_link *, int);
-struct hci_link *hci_sco_newconn(struct hci_unit *, bdaddr_t *);
-void hci_sco_recv(struct mbuf *, struct hci_unit *);
-void hci_sco_start(struct hci_link *);
-void hci_sco_complete(struct hci_link *, int);
-struct hci_link *hci_link_alloc(struct hci_unit *, bdaddr_t *, uint8_t);
-void hci_link_free(struct hci_link *, int);
-struct hci_link *hci_link_lookup_bdaddr(struct hci_unit *, bdaddr_t *, uint8_t);
-struct hci_link *hci_link_lookup_handle(struct hci_unit *, uint16_t);
-
-/* hci_misc.c */
-int hci_route_lookup(bdaddr_t *, bdaddr_t *);
-struct hci_memo *hci_memo_find(struct hci_unit *, bdaddr_t *);
-struct hci_memo *hci_memo_new(struct hci_unit *, bdaddr_t *);
-void hci_memo_free(struct hci_memo *);
-
-/* hci_socket.c */
-void hci_drop(void *);
-int hci_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
- struct mbuf *, struct proc *);
-int hci_ctloutput(int, struct socket *, int, int, struct mbuf **);
-void hci_mtap(struct mbuf *, struct hci_unit *);
-
-/* hci_unit.c */
-struct hci_unit *hci_attach(const struct hci_if *, struct device *, uint16_t);
-void hci_detach(struct hci_unit *);
-int hci_enable(struct hci_unit *);
-void hci_disable(struct hci_unit *);
-struct hci_unit *hci_unit_lookup(bdaddr_t *);
-int hci_send_cmd(struct hci_unit *, uint16_t, void *, uint8_t);
-void hci_num_cmds(struct hci_unit *, uint8_t);
-int hci_input_event(struct hci_unit *, struct mbuf *);
-int hci_input_acl(struct hci_unit *, struct mbuf *);
-int hci_input_sco(struct hci_unit *, struct mbuf *);
-int hci_complete_sco(struct hci_unit *, struct mbuf *);
-void hci_output_cmd(struct hci_unit *, struct mbuf *);
-void hci_output_acl(struct hci_unit *, struct mbuf *);
-void hci_output_sco(struct hci_unit *, struct mbuf *);
-void hci_intr(void *);
-
-/* XXX mimic NetBSD for now, although we don't have these interfaces */
-#define M_GETCTX(m, t) ((t)(m)->m_pkthdr.rcvif)
-#define M_SETCTX(m, c) ((m)->m_pkthdr.rcvif = (void *)(c))
-#define splraiseipl(ipl) splbio() /* XXX */
-#define ENOLINK ENOENT /* XXX */
-#define EPASSTHROUGH ENOTTY /* XXX */
-#define device_xname(dv) (dv)->dv_xname
-
-#endif /* _KERNEL */
-
-#endif /* _NETBT_HCI_H_ */
diff --git a/sys/netbt/hci_event.c b/sys/netbt/hci_event.c
deleted file mode 100644
index 4715d3cf665..00000000000
--- a/sys/netbt/hci_event.c
+++ /dev/null
@@ -1,1112 +0,0 @@
-/* $OpenBSD: hci_event.c,v 1.9 2010/08/20 17:00:40 jsg Exp $ */
-/* $NetBSD: hci_event.c,v 1.18 2008/04/24 11:38:37 ad Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/sco.h>
-
-static void hci_event_inquiry_result(struct hci_unit *, struct mbuf *);
-static void hci_event_rssi_result(struct hci_unit *, struct mbuf *);
-static void hci_event_command_status(struct hci_unit *, struct mbuf *);
-static void hci_event_command_compl(struct hci_unit *, struct mbuf *);
-static void hci_event_con_compl(struct hci_unit *, struct mbuf *);
-static void hci_event_discon_compl(struct hci_unit *, struct mbuf *);
-static void hci_event_con_req(struct hci_unit *, struct mbuf *);
-static void hci_event_num_compl_pkts(struct hci_unit *, struct mbuf *);
-static void hci_event_auth_compl(struct hci_unit *, struct mbuf *);
-static void hci_event_encryption_change(struct hci_unit *, struct mbuf *);
-static void hci_event_change_con_link_key_compl(struct hci_unit *, struct mbuf *);
-static void hci_event_read_clock_offset_compl(struct hci_unit *, struct mbuf *);
-static void hci_cmd_read_bdaddr(struct hci_unit *, struct mbuf *);
-static void hci_cmd_read_buffer_size(struct hci_unit *, struct mbuf *);
-static void hci_cmd_read_local_features(struct hci_unit *, struct mbuf *);
-static void hci_cmd_read_local_ver(struct hci_unit *, struct mbuf *);
-static void hci_cmd_read_local_commands(struct hci_unit *, struct mbuf *);
-static void hci_cmd_reset(struct hci_unit *, struct mbuf *);
-static void hci_cmd_create_con(struct hci_unit *unit, uint8_t status);
-
-#ifdef BLUETOOTH_DEBUG
-int bluetooth_debug;
-
-static const char *hci_eventnames[] = {
-/* 0x00 */ "NULL",
-/* 0x01 */ "INQUIRY COMPLETE",
-/* 0x02 */ "INQUIRY RESULT",
-/* 0x03 */ "CONN COMPLETE",
-/* 0x04 */ "CONN REQ",
-/* 0x05 */ "DISCONN COMPLETE",
-/* 0x06 */ "AUTH COMPLETE",
-/* 0x07 */ "REMOTE NAME REQ COMPLETE",
-/* 0x08 */ "ENCRYPTION CHANGE",
-/* 0x09 */ "CHANGE CONN LINK KEY COMPLETE",
-/* 0x0a */ "MASTER LINK KEY COMPLETE",
-/* 0x0b */ "READ REMOTE FEATURES COMPLETE",
-/* 0x0c */ "READ REMOTE VERSION INFO COMPLETE",
-/* 0x0d */ "QoS SETUP COMPLETE",
-/* 0x0e */ "COMMAND COMPLETE",
-/* 0x0f */ "COMMAND STATUS",
-/* 0x10 */ "HARDWARE ERROR",
-/* 0x11 */ "FLUSH OCCUR",
-/* 0x12 */ "ROLE CHANGE",
-/* 0x13 */ "NUM COMPLETED PACKETS",
-/* 0x14 */ "MODE CHANGE",
-/* 0x15 */ "RETURN LINK KEYS",
-/* 0x16 */ "PIN CODE REQ",
-/* 0x17 */ "LINK KEY REQ",
-/* 0x18 */ "LINK KEY NOTIFICATION",
-/* 0x19 */ "LOOPBACK COMMAND",
-/* 0x1a */ "DATA BUFFER OVERFLOW",
-/* 0x1b */ "MAX SLOT CHANGE",
-/* 0x1c */ "READ CLOCK OFFSET COMPLETE",
-/* 0x1d */ "CONN PKT TYPE CHANGED",
-/* 0x1e */ "QOS VIOLATION",
-/* 0x1f */ "PAGE SCAN MODE CHANGE",
-/* 0x20 */ "PAGE SCAN REP MODE CHANGE",
-/* 0x21 */ "FLOW SPECIFICATION COMPLETE",
-/* 0x22 */ "RSSI RESULT",
-/* 0x23 */ "READ REMOTE EXT FEATURES",
-/* 0x24 */ "UNKNOWN",
-/* 0x25 */ "UNKNOWN",
-/* 0x26 */ "UNKNOWN",
-/* 0x27 */ "UNKNOWN",
-/* 0x28 */ "UNKNOWN",
-/* 0x29 */ "UNKNOWN",
-/* 0x2a */ "UNKNOWN",
-/* 0x2b */ "UNKNOWN",
-/* 0x2c */ "SCO CON COMPLETE",
-/* 0x2d */ "SCO CON CHANGED",
-/* 0x2e */ "SNIFF SUBRATING",
-/* 0x2f */ "EXTENDED INQUIRY RESULT",
-/* 0x30 */ "ENCRYPTION KEY REFRESH",
-/* 0x31 */ "IO CAPABILITY REQUEST",
-/* 0x32 */ "IO CAPABILITY RESPONSE",
-/* 0x33 */ "USER CONFIRM REQUEST",
-/* 0x34 */ "USER PASSKEY REQUEST",
-/* 0x35 */ "REMOTE OOB DATA REQUEST",
-/* 0x36 */ "SIMPLE PAIRING COMPLETE",
-/* 0x37 */ "UNKNOWN",
-/* 0x38 */ "LINK SUPERVISION TIMEOUT CHANGED",
-/* 0x39 */ "ENHANCED FLUSH COMPLETE",
-/* 0x3a */ "UNKNOWN",
-/* 0x3b */ "USER PASSKEY NOTIFICATION",
-/* 0x3c */ "KEYPRESS NOTIFICATION",
-/* 0x3d */ "REMOTE HOST FEATURES NOTIFICATION",
-};
-
-static const char *
-hci_eventstr(unsigned int event)
-{
-
- if (event < (sizeof(hci_eventnames) / sizeof(*hci_eventnames)))
- return hci_eventnames[event];
-
- switch (event) {
- case HCI_EVENT_BT_LOGO: /* 0xfe */
- return "BT_LOGO";
-
- case HCI_EVENT_VENDOR: /* 0xff */
- return "VENDOR";
- }
-
- return "UNKNOWN";
-}
-#endif /* BLUETOOTH_DEBUG */
-
-/*
- * process HCI Events
- *
- * We will free the mbuf at the end, no need for any sub
- * functions to handle that. We kind of assume that the
- * device sends us valid events.
- */
-void
-hci_event(struct mbuf *m, struct hci_unit *unit)
-{
- hci_event_hdr_t hdr;
-
- KASSERT(m->m_flags & M_PKTHDR);
-
- KASSERT(m->m_pkthdr.len >= sizeof(hdr));
- m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr);
- m_adj(m, sizeof(hdr));
-
- KASSERT(hdr.type == HCI_EVENT_PKT);
-
- DPRINTFN(1, "(%s) event %s\n",
- device_xname(unit->hci_dev), hci_eventstr(hdr.event));
-
- switch(hdr.event) {
- case HCI_EVENT_COMMAND_STATUS:
- hci_event_command_status(unit, m);
- break;
-
- case HCI_EVENT_COMMAND_COMPL:
- hci_event_command_compl(unit, m);
- break;
-
- case HCI_EVENT_NUM_COMPL_PKTS:
- hci_event_num_compl_pkts(unit, m);
- break;
-
- case HCI_EVENT_INQUIRY_RESULT:
- hci_event_inquiry_result(unit, m);
- break;
-
- case HCI_EVENT_RSSI_RESULT:
- hci_event_rssi_result(unit, m);
- break;
-
- case HCI_EVENT_CON_COMPL:
- hci_event_con_compl(unit, m);
- break;
-
- case HCI_EVENT_DISCON_COMPL:
- hci_event_discon_compl(unit, m);
- break;
-
- case HCI_EVENT_CON_REQ:
- hci_event_con_req(unit, m);
- break;
-
- case HCI_EVENT_AUTH_COMPL:
- hci_event_auth_compl(unit, m);
- break;
-
- case HCI_EVENT_ENCRYPTION_CHANGE:
- hci_event_encryption_change(unit, m);
- break;
-
- case HCI_EVENT_CHANGE_CON_LINK_KEY_COMPL:
- hci_event_change_con_link_key_compl(unit, m);
- break;
-
- case HCI_EVENT_READ_CLOCK_OFFSET_COMPL:
- hci_event_read_clock_offset_compl(unit, m);
- break;
-
- default:
- break;
- }
-
- m_freem(m);
-}
-
-/*
- * Command Status
- *
- * Restart command queue and post-process any pending commands
- */
-static void
-hci_event_command_status(struct hci_unit *unit, struct mbuf *m)
-{
- hci_command_status_ep ep;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- ep.opcode = letoh16(ep.opcode);
-
- DPRINTFN(1, "(%s) opcode (%03x|%04x) status = 0x%x num_cmd_pkts = %d\n",
- device_xname(unit->hci_dev),
- HCI_OGF(ep.opcode), HCI_OCF(ep.opcode),
- ep.status,
- ep.num_cmd_pkts);
-
- hci_num_cmds(unit, ep.num_cmd_pkts);
-
- /*
- * post processing of pending commands
- */
- switch(ep.opcode) {
- case HCI_CMD_CREATE_CON:
- hci_cmd_create_con(unit, ep.status);
- break;
-
- default:
- if (ep.status == 0)
- break;
-
- DPRINTFN(1,
- "(%s) CommandStatus opcode (%03x|%04x)"
- " failed (status=0x%02x)\n",
- device_xname(unit->hci_dev),
- HCI_OGF(ep.opcode), HCI_OCF(ep.opcode),
- ep.status);
-
- break;
- }
-}
-
-/*
- * Command Complete
- *
- * Restart command queue and handle the completed command
- */
-static void
-hci_event_command_compl(struct hci_unit *unit, struct mbuf *m)
-{
- hci_command_compl_ep ep;
- hci_status_rp rp;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- DPRINTFN(1, "(%s) opcode (%03x|%04x) num_cmd_pkts = %d\n",
- device_xname(unit->hci_dev), HCI_OGF(letoh16(ep.opcode)),
- HCI_OCF(letoh16(ep.opcode)), ep.num_cmd_pkts);
-
- hci_num_cmds(unit, ep.num_cmd_pkts);
-
- /*
- * I am not sure if this is completely correct, it is not guaranteed
- * that a command_complete packet will contain the status though most
- * do seem to.
- */
- m_copydata(m, 0, sizeof(rp), (caddr_t)&rp);
- if (rp.status > 0)
- printf("%s: CommandComplete opcode (%03x|%04x) failed (status=0x%02x)\n",
- device_xname(unit->hci_dev), HCI_OGF(letoh16(ep.opcode)),
- HCI_OCF(letoh16(ep.opcode)), rp.status);
-
- /*
- * post processing of completed commands
- */
- switch(letoh16(ep.opcode)) {
- case HCI_CMD_READ_BDADDR:
- hci_cmd_read_bdaddr(unit, m);
- break;
-
- case HCI_CMD_READ_BUFFER_SIZE:
- hci_cmd_read_buffer_size(unit, m);
- break;
-
- case HCI_CMD_READ_LOCAL_FEATURES:
- hci_cmd_read_local_features(unit, m);
- break;
-
- case HCI_CMD_READ_LOCAL_VER:
- hci_cmd_read_local_ver(unit, m);
- break;
-
- case HCI_CMD_READ_LOCAL_COMMANDS:
- hci_cmd_read_local_commands(unit, m);
- break;
-
- case HCI_CMD_RESET:
- hci_cmd_reset(unit, m);
- break;
-
- default:
- break;
- }
-}
-
-/*
- * Number of Completed Packets
- *
- * This is sent periodically by the Controller telling us how many
- * buffers are now freed up and which handle was using them. From
- * this we determine which type of buffer it was and add the qty
- * back into the relevant packet counter, then restart output on
- * links that have halted.
- */
-static void
-hci_event_num_compl_pkts(struct hci_unit *unit, struct mbuf *m)
-{
- hci_num_compl_pkts_ep ep;
- struct hci_link *link, *next;
- uint16_t handle, num;
- int num_acl = 0, num_sco = 0;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- while (ep.num_con_handles--) {
- m_copydata(m, 0, sizeof(handle), (caddr_t)&handle);
- m_adj(m, sizeof(handle));
- handle = letoh16(handle);
-
- m_copydata(m, 0, sizeof(num), (caddr_t)&num);
- m_adj(m, sizeof(num));
- num = letoh16(num);
-
- link = hci_link_lookup_handle(unit, handle);
- if (link) {
- if (link->hl_type == HCI_LINK_ACL) {
- num_acl += num;
- hci_acl_complete(link, num);
- } else {
- num_sco += num;
- hci_sco_complete(link, num);
- }
- } else {
- /* XXX need to issue Read_Buffer_Size or Reset? */
- printf("%s: unknown handle %d! "
- "(losing track of %d packet buffer%s)\n",
- device_xname(unit->hci_dev), handle,
- num, (num == 1 ? "" : "s"));
- }
- }
-
- /*
- * Move up any queued packets. When a link has sent data, it will move
- * to the back of the queue - technically then if a link had something
- * to send and there were still buffers available it could get started
- * twice but it seemed more important to to handle higher loads fairly
- * than worry about wasting cycles when we are not busy.
- */
-
- unit->hci_num_acl_pkts += num_acl;
- unit->hci_num_sco_pkts += num_sco;
-
- link = TAILQ_FIRST(&unit->hci_links);
- while (link && (unit->hci_num_acl_pkts > 0 || unit->hci_num_sco_pkts > 0)) {
- next = TAILQ_NEXT(link, hl_next);
-
- if (link->hl_type == HCI_LINK_ACL) {
- if (unit->hci_num_acl_pkts > 0 && link->hl_txqlen > 0)
- hci_acl_start(link);
- } else {
- if (unit->hci_num_sco_pkts > 0 && link->hl_txqlen > 0)
- hci_sco_start(link);
- }
-
- link = next;
- }
-}
-
-/*
- * Inquiry Result
- *
- * keep a note of devices seen, so we know which unit to use
- * on outgoing connections
- */
-static void
-hci_event_inquiry_result(struct hci_unit *unit, struct mbuf *m)
-{
- hci_inquiry_result_ep ep;
- hci_inquiry_response ir;
- struct hci_memo *memo;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- DPRINTFN(1, "(%s) %d response%s\n", device_xname(unit->hci_dev),
- ep.num_responses, (ep.num_responses == 1 ? "" : "s"));
-
- while(ep.num_responses--) {
- KASSERT(m->m_pkthdr.len >= sizeof(ir));
- m_copydata(m, 0, sizeof(ir), (caddr_t)&ir);
- m_adj(m, sizeof(ir));
-
- DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n",
- ir.bdaddr.b[5], ir.bdaddr.b[4], ir.bdaddr.b[3],
- ir.bdaddr.b[2], ir.bdaddr.b[1], ir.bdaddr.b[0]);
-
- memo = hci_memo_new(unit, &ir.bdaddr);
- if (memo != NULL) {
- memo->page_scan_rep_mode = ir.page_scan_rep_mode;
- memo->page_scan_mode = ir.page_scan_mode;
- memo->clock_offset = ir.clock_offset;
- }
- }
-}
-
-/*
- * Inquiry Result with RSSI
- *
- * as above but different packet when RSSI result is enabled
- */
-static void
-hci_event_rssi_result(struct hci_unit *unit, struct mbuf *m)
-{
- hci_rssi_result_ep ep;
- hci_rssi_response rr;
- struct hci_memo *memo;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- DPRINTFN(1, "%d response%s\n", ep.num_responses,
- (ep.num_responses == 1 ? "" : "s"));
-
- while(ep.num_responses--) {
- KASSERT(m->m_pkthdr.len >= sizeof(rr));
- m_copydata(m, 0, sizeof(rr), (caddr_t)&rr);
- m_adj(m, sizeof(rr));
-
- DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n",
- rr.bdaddr.b[5], rr.bdaddr.b[4], rr.bdaddr.b[3],
- rr.bdaddr.b[2], rr.bdaddr.b[1], rr.bdaddr.b[0]);
-
- memo = hci_memo_new(unit, &rr.bdaddr);
- if (memo != NULL) {
- memo->page_scan_rep_mode = rr.page_scan_rep_mode;
- memo->page_scan_mode = 0;
- memo->clock_offset = rr.clock_offset;
- }
- }
-}
-
-/*
- * Connection Complete
- *
- * Sent to us when a connection is made. If there is no link
- * structure already allocated for this, we must have changed
- * our mind, so just disconnect.
- */
-static void
-hci_event_con_compl(struct hci_unit *unit, struct mbuf *m)
-{
- hci_con_compl_ep ep;
- hci_write_link_policy_settings_cp cp;
- struct hci_link *link;
- int err;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- DPRINTFN(1, "(%s) %s connection complete for "
- "%02x:%02x:%02x:%02x:%02x:%02x status %#x\n",
- device_xname(unit->hci_dev),
- (ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO"),
- ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3],
- ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0],
- ep.status);
-
- link = hci_link_lookup_bdaddr(unit, &ep.bdaddr, ep.link_type);
-
- if (ep.status) {
- if (link != NULL) {
- switch (ep.status) {
- case 0x04: /* "Page Timeout" */
- err = EHOSTDOWN;
- break;
-
- case 0x08: /* "Connection Timed Out" */
- case 0x10: /* "Connection Accept Timeout Exceeded" */
- err = ETIMEDOUT;
- break;
-
- case 0x16: /* "Connection Terminated by Local Host" */
- err = 0;
- break;
-
- default:
- err = ECONNREFUSED;
- break;
- }
-
- hci_link_free(link, err);
- }
-
- return;
- }
-
- if (link == NULL) {
- hci_discon_cp dp;
-
- dp.con_handle = ep.con_handle;
- dp.reason = 0x13; /* "Remote User Terminated Connection" */
-
- hci_send_cmd(unit, HCI_CMD_DISCONNECT, &dp, sizeof(dp));
- return;
- }
-
- /* XXX could check auth_enable here */
-
- if (ep.encryption_mode)
- link->hl_flags |= (HCI_LINK_AUTH | HCI_LINK_ENCRYPT);
-
- link->hl_state = HCI_LINK_OPEN;
- link->hl_handle = HCI_CON_HANDLE(letoh16(ep.con_handle));
-
- if (ep.link_type == HCI_LINK_ACL) {
- cp.con_handle = ep.con_handle;
- cp.settings = htole16(unit->hci_link_policy);
- err = hci_send_cmd(unit, HCI_CMD_WRITE_LINK_POLICY_SETTINGS,
- &cp, sizeof(cp));
- if (err)
- printf("%s: Warning, could not write link policy\n",
- device_xname(unit->hci_dev));
-
- err = hci_send_cmd(unit, HCI_CMD_READ_CLOCK_OFFSET,
- &cp.con_handle, sizeof(cp.con_handle));
- if (err)
- printf("%s: Warning, could not read clock offset\n",
- device_xname(unit->hci_dev));
-
- err = hci_acl_setmode(link);
- if (err == EINPROGRESS)
- return;
-
- hci_acl_linkmode(link);
- } else {
- (*link->hl_sco->sp_proto->connected)(link->hl_sco->sp_upper);
- }
-}
-
-/*
- * Disconnection Complete
- *
- * This is sent in response to a disconnection request, but also if
- * the remote device goes out of range.
- */
-static void
-hci_event_discon_compl(struct hci_unit *unit, struct mbuf *m)
-{
- hci_discon_compl_ep ep;
- struct hci_link *link;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- ep.con_handle = letoh16(ep.con_handle);
-
- DPRINTFN(1, "(%s) handle #%d, status=0x%x\n",
- device_xname(unit->hci_dev), ep.con_handle, ep.status);
-
- link = hci_link_lookup_handle(unit, HCI_CON_HANDLE(ep.con_handle));
- if (link)
- hci_link_free(link, ENOENT); /* XXX NetBSD used ENOLINK here */
-}
-
-/*
- * Connect Request
- *
- * We check upstream for appropriate listeners and accept connections
- * that are wanted.
- */
-static void
-hci_event_con_req(struct hci_unit *unit, struct mbuf *m)
-{
- hci_con_req_ep ep;
- hci_accept_con_cp ap;
- hci_reject_con_cp rp;
- struct hci_link *link;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- DPRINTFN(1, "(%s) bdaddr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
- "class %2.2x%2.2x%2.2x type %s\n",
- device_xname(unit->hci_dev),
- ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3],
- ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0],
- ep.uclass[0], ep.uclass[1], ep.uclass[2],
- ep.link_type == HCI_LINK_ACL ? "ACL" : "SCO");
-
- if (ep.link_type == HCI_LINK_ACL)
- link = hci_acl_newconn(unit, &ep.bdaddr);
- else
- link = hci_sco_newconn(unit, &ep.bdaddr);
-
- if (link == NULL) {
- memset(&rp, 0, sizeof(rp));
- bdaddr_copy(&rp.bdaddr, &ep.bdaddr);
- rp.reason = 0x0f; /* Unacceptable BD_ADDR */
-
- hci_send_cmd(unit, HCI_CMD_REJECT_CON, &rp, sizeof(rp));
- } else {
- memset(&ap, 0, sizeof(ap));
- bdaddr_copy(&ap.bdaddr, &ep.bdaddr);
- if (unit->hci_link_policy & HCI_LINK_POLICY_ENABLE_ROLE_SWITCH)
- ap.role = HCI_ROLE_MASTER;
- else
- ap.role = HCI_ROLE_SLAVE;
-
- hci_send_cmd(unit, HCI_CMD_ACCEPT_CON, &ap, sizeof(ap));
- }
-}
-
-/*
- * Auth Complete
- *
- * Authentication has been completed on an ACL link. We can notify the
- * upper layer protocols unless further mode changes are pending.
- */
-static void
-hci_event_auth_compl(struct hci_unit *unit, struct mbuf *m)
-{
- hci_auth_compl_ep ep;
- struct hci_link *link;
- int err;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- ep.con_handle = HCI_CON_HANDLE(letoh16(ep.con_handle));
-
- DPRINTFN(1, "(%s) handle #%d, status=0x%x\n",
- device_xname(unit->hci_dev), ep.con_handle, ep.status);
-
- link = hci_link_lookup_handle(unit, ep.con_handle);
- if (link == NULL || link->hl_type != HCI_LINK_ACL)
- return;
-
- if (ep.status == 0) {
- link->hl_flags |= HCI_LINK_AUTH;
-
- if (link->hl_state == HCI_LINK_WAIT_AUTH)
- link->hl_state = HCI_LINK_OPEN;
-
- err = hci_acl_setmode(link);
- if (err == EINPROGRESS)
- return;
- }
-
- hci_acl_linkmode(link);
-}
-
-/*
- * Encryption Change
- *
- * The encryption status has changed. Basically, we note the change
- * then notify the upper layer protocol unless further mode changes
- * are pending.
- * Note that if encryption gets disabled when it has been requested,
- * we will attempt to enable it again.. (its a feature not a bug :)
- */
-static void
-hci_event_encryption_change(struct hci_unit *unit, struct mbuf *m)
-{
- hci_encryption_change_ep ep;
- struct hci_link *link;
- int err;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- ep.con_handle = HCI_CON_HANDLE(letoh16(ep.con_handle));
-
- DPRINTFN(1, "(%s) handle #%d, status=0x%x, encryption_enable=0x%x\n",
- device_xname(unit->hci_dev), ep.con_handle, ep.status,
- ep.encryption_enable);
-
- link = hci_link_lookup_handle(unit, ep.con_handle);
- if (link == NULL || link->hl_type != HCI_LINK_ACL)
- return;
-
- if (ep.status == 0) {
- if (ep.encryption_enable == 0)
- link->hl_flags &= ~HCI_LINK_ENCRYPT;
- else
- link->hl_flags |= (HCI_LINK_AUTH | HCI_LINK_ENCRYPT);
-
- if (link->hl_state == HCI_LINK_WAIT_ENCRYPT)
- link->hl_state = HCI_LINK_OPEN;
-
- err = hci_acl_setmode(link);
- if (err == EINPROGRESS)
- return;
- }
-
- hci_acl_linkmode(link);
-}
-
-/*
- * Change Connection Link Key Complete
- *
- * Link keys are handled in userland but if we are waiting to secure
- * this link, we should notify the upper protocols. A SECURE request
- * only needs a single key change, so we can cancel the request.
- */
-static void
-hci_event_change_con_link_key_compl(struct hci_unit *unit, struct mbuf *m)
-{
- hci_change_con_link_key_compl_ep ep;
- struct hci_link *link;
- int err;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- ep.con_handle = HCI_CON_HANDLE(letoh16(ep.con_handle));
-
- DPRINTFN(1, "(%s) handle #%d, status=0x%x\n",
- device_xname(unit->hci_dev), ep.con_handle, ep.status);
-
- link = hci_link_lookup_handle(unit, ep.con_handle);
- if (link == NULL || link->hl_type != HCI_LINK_ACL)
- return;
-
- link->hl_flags &= ~HCI_LINK_SECURE_REQ;
-
- if (ep.status == 0) {
- link->hl_flags |= (HCI_LINK_AUTH | HCI_LINK_SECURE);
-
- if (link->hl_state == HCI_LINK_WAIT_SECURE)
- link->hl_state = HCI_LINK_OPEN;
-
- err = hci_acl_setmode(link);
- if (err == EINPROGRESS)
- return;
- }
-
- hci_acl_linkmode(link);
-}
-
-/*
- * Read Clock Offset Complete
- *
- * We keep a note of the clock offset of remote devices when a
- * link is made, in order to facilitate reconnections to the device
- */
-static void
-hci_event_read_clock_offset_compl(struct hci_unit *unit, struct mbuf *m)
-{
- hci_read_clock_offset_compl_ep ep;
- struct hci_link *link;
-
- KASSERT(m->m_pkthdr.len >= sizeof(ep));
- m_copydata(m, 0, sizeof(ep), (caddr_t)&ep);
- m_adj(m, sizeof(ep));
-
- DPRINTFN(1, "handle #%d, offset=%u, status=0x%x\n",
- letoh16(ep.con_handle), letoh16(ep.clock_offset), ep.status);
-
- ep.con_handle = HCI_CON_HANDLE(letoh16(ep.con_handle));
- link = hci_link_lookup_handle(unit, ep.con_handle);
-
- if (ep.status != 0 || link == NULL)
- return;
-
- link->hl_clock = ep.clock_offset;
-}
-
-/*
- * process results of read_bdaddr command_complete event
- */
-static void
-hci_cmd_read_bdaddr(struct hci_unit *unit, struct mbuf *m)
-{
- hci_read_bdaddr_rp rp;
-
- KASSERT(m->m_pkthdr.len >= sizeof(rp));
- m_copydata(m, 0, sizeof(rp), (caddr_t)&rp);
- m_adj(m, sizeof(rp));
-
- if (rp.status > 0)
- return;
-
- if ((unit->hci_flags & BTF_INIT_BDADDR) == 0)
- return;
-
- bdaddr_copy(&unit->hci_bdaddr, &rp.bdaddr);
-
- unit->hci_flags &= ~BTF_INIT_BDADDR;
-
- wakeup(&unit->hci_init);
-}
-
-/*
- * process results of read_buffer_size command_complete event
- */
-static void
-hci_cmd_read_buffer_size(struct hci_unit *unit, struct mbuf *m)
-{
- hci_read_buffer_size_rp rp;
-
- KASSERT(m->m_pkthdr.len >= sizeof(rp));
- m_copydata(m, 0, sizeof(rp), (caddr_t)&rp);
- m_adj(m, sizeof(rp));
-
- if (rp.status > 0)
- return;
-
- if ((unit->hci_flags & BTF_INIT_BUFFER_SIZE) == 0)
- return;
-
- unit->hci_max_acl_size = letoh16(rp.max_acl_size);
- unit->hci_num_acl_pkts = letoh16(rp.num_acl_pkts);
- unit->hci_max_sco_size = rp.max_sco_size;
- unit->hci_num_sco_pkts = letoh16(rp.num_sco_pkts);
-
- unit->hci_flags &= ~BTF_INIT_BUFFER_SIZE;
-
- wakeup(&unit->hci_init);
-}
-
-/*
- * process results of read_local_features command_complete event
- */
-static void
-hci_cmd_read_local_features(struct hci_unit *unit, struct mbuf *m)
-{
- hci_read_local_features_rp rp;
-
- KASSERT(m->m_pkthdr.len >= sizeof(rp));
- m_copydata(m, 0, sizeof(rp), (caddr_t)&rp);
- m_adj(m, sizeof(rp));
-
- if (rp.status > 0)
- return;
-
- if ((unit->hci_flags & BTF_INIT_FEATURES) == 0)
- return;
-
- unit->hci_lmp_mask = 0;
-
- if (rp.features[0] & HCI_LMP_ROLE_SWITCH)
- unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_ROLE_SWITCH;
-
- if (rp.features[0] & HCI_LMP_HOLD_MODE)
- unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_HOLD_MODE;
-
- if (rp.features[0] & HCI_LMP_SNIFF_MODE)
- unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_SNIFF_MODE;
-
- if (rp.features[1] & HCI_LMP_PARK_MODE)
- unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_PARK_MODE;
-
- /* ACL packet mask */
- unit->hci_acl_mask = HCI_PKT_DM1 | HCI_PKT_DH1;
-
- if (rp.features[0] & HCI_LMP_3SLOT)
- unit->hci_acl_mask |= HCI_PKT_DM3 | HCI_PKT_DH3;
-
- if (rp.features[0] & HCI_LMP_5SLOT)
- unit->hci_acl_mask |= HCI_PKT_DM5 | HCI_PKT_DH5;
-
- if ((rp.features[3] & HCI_LMP_EDR_ACL_2MBPS) == 0)
- unit->hci_acl_mask |= HCI_PKT_2MBPS_DH1
- | HCI_PKT_2MBPS_DH3
- | HCI_PKT_2MBPS_DH5;
-
- if ((rp.features[3] & HCI_LMP_EDR_ACL_3MBPS) == 0)
- unit->hci_acl_mask |= HCI_PKT_3MBPS_DH1
- | HCI_PKT_3MBPS_DH3
- | HCI_PKT_3MBPS_DH5;
-
- if ((rp.features[4] & HCI_LMP_3SLOT_EDR_ACL) == 0)
- unit->hci_acl_mask |= HCI_PKT_2MBPS_DH3
- | HCI_PKT_3MBPS_DH3;
-
- if ((rp.features[5] & HCI_LMP_5SLOT_EDR_ACL) == 0)
- unit->hci_acl_mask |= HCI_PKT_2MBPS_DH5
- | HCI_PKT_3MBPS_DH5;
-
- unit->hci_packet_type = unit->hci_acl_mask;
-
- /* SCO packet mask */
- unit->hci_sco_mask = 0;
- if (rp.features[1] & HCI_LMP_SCO_LINK)
- unit->hci_sco_mask |= HCI_PKT_HV1;
-
- if (rp.features[1] & HCI_LMP_HV2_PKT)
- unit->hci_sco_mask |= HCI_PKT_HV2;
-
- if (rp.features[1] & HCI_LMP_HV3_PKT)
- unit->hci_sco_mask |= HCI_PKT_HV3;
-
- if (rp.features[3] & HCI_LMP_EV3_PKT)
- unit->hci_sco_mask |= HCI_PKT_EV3;
-
- if (rp.features[4] & HCI_LMP_EV4_PKT)
- unit->hci_sco_mask |= HCI_PKT_EV4;
-
- if (rp.features[4] & HCI_LMP_EV5_PKT)
- unit->hci_sco_mask |= HCI_PKT_EV5;
-
- /* XXX what do 2MBPS/3MBPS/3SLOT eSCO mean? */
-
- unit->hci_flags &= ~BTF_INIT_FEATURES;
-
- wakeup(&unit->hci_init);
-
- DPRINTFN(1, "%s: lmp_mask %4.4x, acl_mask %4.4x, sco_mask %4.4x\n",
- device_xname(unit->hci_dev), unit->hci_lmp_mask,
- unit->hci_acl_mask, unit->hci_sco_mask);
-}
-
-/*
- * process results of read_local_ver command_complete event
- *
- * reading local supported commands is only supported from 1.2 spec
- */
-static void
-hci_cmd_read_local_ver(struct hci_unit *unit, struct mbuf *m)
-{
- hci_read_local_ver_rp rp;
-
- KASSERT(m->m_pkthdr.len >= sizeof(rp));
- m_copydata(m, 0, sizeof(rp), (caddr_t)&rp);
- m_adj(m, sizeof(rp));
-
- if (rp.status != 0)
- return;
-
- if ((unit->hci_flags & BTF_INIT_COMMANDS) == 0)
- return;
-
- if (rp.hci_version < HCI_SPEC_V12) {
- unit->hci_flags &= ~BTF_INIT_COMMANDS;
- wakeup(&unit->hci_init);
- return;
- }
-
- hci_send_cmd(unit, HCI_CMD_READ_LOCAL_COMMANDS, NULL, 0);
-}
-
-/*
- * process results of read_local_commands command_complete event
- */
-static void
-hci_cmd_read_local_commands(struct hci_unit *unit, struct mbuf *m)
-{
- hci_read_local_commands_rp rp;
-
- KASSERT(m->m_pkthdr.len >= sizeof(rp));
- m_copydata(m, 0, sizeof(rp), (caddr_t)&rp);
- m_adj(m, sizeof(rp));
-
- if (rp.status != 0)
- return;
-
- if ((unit->hci_flags & BTF_INIT_COMMANDS) == 0)
- return;
-
- unit->hci_flags &= ~BTF_INIT_COMMANDS;
- memcpy(unit->hci_cmds, rp.commands, HCI_COMMANDS_SIZE);
-
- wakeup(&unit->hci_init);
-}
-
-/*
- * process results of reset command_complete event
- *
- * This has killed all the connections, so close down anything we have left,
- * and reinitialise the unit.
- */
-static void
-hci_cmd_reset(struct hci_unit *unit, struct mbuf *m)
-{
- hci_reset_rp rp;
- struct hci_link *link, *next;
- int acl;
-
- KASSERT(m->m_pkthdr.len >= sizeof(rp));
- m_copydata(m, 0, sizeof(rp), (caddr_t)&rp);
- m_adj(m, sizeof(rp));
-
- if (rp.status != 0)
- return;
-
- /*
- * release SCO links first, since they may be holding
- * an ACL link reference.
- */
- for (acl = 0 ; acl < 2 ; acl++) {
- next = TAILQ_FIRST(&unit->hci_links);
- while ((link = next) != NULL) {
- next = TAILQ_NEXT(link, hl_next);
- if (acl || link->hl_type != HCI_LINK_ACL)
- hci_link_free(link, ECONNABORTED);
- }
- }
-
- unit->hci_num_acl_pkts = 0;
- unit->hci_num_sco_pkts = 0;
-
- if (hci_send_cmd(unit, HCI_CMD_READ_BDADDR, NULL, 0))
- return;
-
- if (hci_send_cmd(unit, HCI_CMD_READ_BUFFER_SIZE, NULL, 0))
- return;
-
- if (hci_send_cmd(unit, HCI_CMD_READ_LOCAL_FEATURES, NULL, 0))
- return;
-
- if (hci_send_cmd(unit, HCI_CMD_READ_LOCAL_VER, NULL, 0))
- return;
-}
-
-/*
- * process command_status event for create_con command
- *
- * a "Create Connection" command can sometimes fail to start for whatever
- * reason and the command_status event returns failure but we get no
- * indication of which connection failed (for instance in the case where
- * we tried to open too many connections all at once) So, we keep a flag
- * on the link to indicate pending status until the command_status event
- * is returned to help us decide which needs to be failed.
- *
- * since created links are inserted at the tail of hci_links, we know that
- * the first pending link we find will be the one that this command status
- * refers to.
- */
-static void
-hci_cmd_create_con(struct hci_unit *unit, uint8_t status)
-{
- struct hci_link *link;
-
- TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
- if ((link->hl_flags & HCI_LINK_CREATE_CON) == 0)
- continue;
-
- link->hl_flags &= ~HCI_LINK_CREATE_CON;
-
- switch(status) {
- case 0x00: /* success */
- break;
-
- case 0x0c: /* "Command Disallowed" */
- hci_link_free(link, EBUSY);
- break;
-
- default: /* some other trouble */
- hci_link_free(link, /*EPROTO*/ECONNABORTED);
- break;
- }
-
- return;
- }
-}
diff --git a/sys/netbt/hci_ioctl.c b/sys/netbt/hci_ioctl.c
deleted file mode 100644
index 4ecba4faa40..00000000000
--- a/sys/netbt/hci_ioctl.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* $OpenBSD: hci_ioctl.c,v 1.2 2008/02/24 21:34:48 uwe Exp $ */
-/* $NetBSD: hci_ioctl.c,v 1.7 2007/11/28 20:16:12 plunky Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/domain.h>
-#include <sys/ioctl.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-#include <netbt/rfcomm.h>
-
-#ifdef BLUETOOTH_DEBUG
-#define BDADDR(bd) (bd).b[5], (bd).b[4], (bd).b[3], \
- (bd).b[2], (bd).b[1], (bd).b[0]
-
-static void
-hci_dump(void)
-{
- struct hci_unit *unit;
- struct hci_link *link;
- struct l2cap_channel *chan;
- struct rfcomm_session *rs;
- struct rfcomm_dlc *dlc;
-
- printf("HCI:\n");
- TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
- printf("UNIT %s: flags 0x%4.4x, "
- "num_cmd=%d, num_acl=%d, num_sco=%d\n",
- device_xname(unit->hci_dev), unit->hci_flags,
- unit->hci_num_cmd_pkts,
- unit->hci_num_acl_pkts,
- unit->hci_num_sco_pkts);
- TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
- printf("+HANDLE #%d: %s "
- "raddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
- "state %d, refcnt %d\n",
- link->hl_handle,
- (link->hl_type == HCI_LINK_ACL ? "ACL":"SCO"),
- BDADDR(link->hl_bdaddr),
- link->hl_state, link->hl_refcnt);
- }
- }
-
- printf("L2CAP:\n");
- LIST_FOREACH(chan, &l2cap_active_list, lc_ncid) {
- printf("CID #%d state %d, psm=0x%4.4x, "
- "laddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
- "raddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
- chan->lc_lcid, chan->lc_state, chan->lc_raddr.bt_psm,
- BDADDR(chan->lc_laddr.bt_bdaddr),
- BDADDR(chan->lc_raddr.bt_bdaddr));
- }
-
- LIST_FOREACH(chan, &l2cap_listen_list, lc_ncid) {
- printf("LISTEN psm=0x%4.4x, "
- "laddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
- chan->lc_laddr.bt_psm,
- BDADDR(chan->lc_laddr.bt_bdaddr));
- }
-
- printf("RFCOMM:\n");
- LIST_FOREACH(rs, &rfcomm_session_active, rs_next) {
- chan = rs->rs_l2cap;
- printf("SESSION: state=%d, flags=0x%4.4x, psm 0x%4.4x "
- "laddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
- "raddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
- rs->rs_state, rs->rs_flags, chan->lc_raddr.bt_psm,
- BDADDR(chan->lc_laddr.bt_bdaddr),
- BDADDR(chan->lc_raddr.bt_bdaddr));
- LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
- printf("+DLC channel=%d, dlci=%d, "
- "state=%d, flags=0x%4.4x, rxcred=%d, rxsize=%ld, "
- "txcred=%d, pending=%d, txqlen=%d\n",
- dlc->rd_raddr.bt_channel, dlc->rd_dlci,
- dlc->rd_state, dlc->rd_flags,
- dlc->rd_rxcred, (unsigned long)dlc->rd_rxsize,
- dlc->rd_txcred, dlc->rd_pending,
- (dlc->rd_txbuf ? dlc->rd_txbuf->m_pkthdr.len : 0));
- }
- }
-
- LIST_FOREACH(rs, &rfcomm_session_listen, rs_next) {
- chan = rs->rs_l2cap;
- printf("LISTEN: psm 0x%4.4x, "
- "laddr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
- chan->lc_laddr.bt_psm,
- BDADDR(chan->lc_laddr.bt_bdaddr));
- LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next)
- printf("+DLC channel=%d\n", dlc->rd_laddr.bt_channel);
- }
-}
-
-#undef BDADDR
-#endif
-
-int
-hci_ioctl(unsigned long cmd, void *data, struct proc *p)
-{
- struct btreq *btr = data;
- struct hci_unit *unit;
- int err = 0;
-
- DPRINTFN(1, "cmd %#lx\n", cmd);
-
- switch(cmd) {
-#ifdef BLUETOOTH_DEBUG
- case SIOCBTDUMP:
- hci_dump();
- return 0;
-#endif
- /*
- * Get unit info based on address rather than name
- */
- case SIOCGBTINFOA:
- unit = hci_unit_lookup(&btr->btr_bdaddr);
- if (unit == NULL)
- return ENXIO;
-
- break;
-
- /*
- * The remaining ioctl's all use the same btreq structure and
- * index on the name of the device, so we look that up first.
- */
- case SIOCNBTINFO:
- /* empty name means give the first unit */
- if (btr->btr_name[0] == '\0') {
- unit = NULL;
- break;
- }
-
- /* else fall through and look it up */
- case SIOCGBTINFO:
- case SIOCSBTFLAGS:
- case SIOCSBTPOLICY:
- case SIOCSBTPTYPE:
- case SIOCGBTSTATS:
- case SIOCZBTSTATS:
- case SIOCSBTSCOMTU:
- TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
- if (strncmp(device_xname(unit->hci_dev), btr->btr_name,
- HCI_DEVNAME_SIZE) == 0)
- break;
- }
-
- if (unit == NULL)
- return ENXIO;
-
- break;
-
- default: /* not one of mine */
- return EPASSTHROUGH;
- }
-
- switch(cmd) {
- case SIOCNBTINFO: /* get next info */
- if (unit)
- unit = TAILQ_NEXT(unit, hci_next);
- else
- unit = TAILQ_FIRST(&hci_unit_list);
-
- if (unit == NULL) {
- err = ENXIO;
- break;
- }
-
- /* and fall through to */
- case SIOCGBTINFO: /* get unit info */
- case SIOCGBTINFOA: /* get info by address */
- memset(btr, 0, sizeof(struct btreq));
- strlcpy(btr->btr_name, device_xname(unit->hci_dev), HCI_DEVNAME_SIZE);
- bdaddr_copy(&btr->btr_bdaddr, &unit->hci_bdaddr);
-
- btr->btr_flags = unit->hci_flags;
-
- btr->btr_num_cmd = unit->hci_num_cmd_pkts;
- btr->btr_num_acl = unit->hci_num_acl_pkts;
- btr->btr_num_sco = unit->hci_num_sco_pkts;
- btr->btr_acl_mtu = unit->hci_max_acl_size;
- btr->btr_sco_mtu = unit->hci_max_sco_size;
-
- btr->btr_packet_type = unit->hci_packet_type;
- btr->btr_link_policy = unit->hci_link_policy;
- break;
-
- case SIOCSBTFLAGS: /* set unit flags (privileged) */
- err = suser(p, 0);
- if (err)
- break;
-
- if ((unit->hci_flags & BTF_UP)
- && (btr->btr_flags & BTF_UP) == 0) {
- hci_disable(unit);
- unit->hci_flags &= ~BTF_UP;
- }
-
- unit->hci_flags |= (btr->btr_flags & BTF_INIT);
-
- if ((unit->hci_flags & BTF_UP) == 0
- && (btr->btr_flags & BTF_UP)) {
- err = hci_enable(unit);
- if (err)
- break;
-
- unit->hci_flags |= BTF_UP;
- }
-
- btr->btr_flags = unit->hci_flags;
- break;
-
- case SIOCSBTPOLICY: /* set unit link policy (privileged) */
- err = suser(p, 0);
- if (err)
- break;
-
- unit->hci_link_policy = btr->btr_link_policy;
- unit->hci_link_policy &= unit->hci_lmp_mask;
- btr->btr_link_policy = unit->hci_link_policy;
- break;
-
- case SIOCSBTPTYPE: /* set unit packet types (privileged) */
- err = suser(p, 0);
- if (err)
- break;
-
- unit->hci_packet_type = btr->btr_packet_type;
- unit->hci_packet_type &= unit->hci_acl_mask;
- btr->btr_packet_type = unit->hci_packet_type;
- break;
-
- case SIOCGBTSTATS: /* get unit statistics */
- (*unit->hci_if->get_stats)(unit->hci_dev, &btr->btr_stats, 0);
- break;
-
- case SIOCZBTSTATS: /* get & reset unit statistics */
- err = suser(p, 0);
- if (err)
- break;
-
- (*unit->hci_if->get_stats)(unit->hci_dev, &btr->btr_stats, 1);
- break;
-
- case SIOCSBTSCOMTU: /* set sco_mtu value for unit */
- /*
- * This is a temporary ioctl and may not be supported
- * in the future. The need is that if SCO packets are
- * sent to USB bluetooth controllers that are not an
- * integer number of frame sizes, the USB bus locks up.
- */
- err = suser(p, 0);
- if (err)
- break;
-
- unit->hci_max_sco_size = btr->btr_sco_mtu;
- break;
-
- default:
- err = EFAULT;
- break;
- }
-
- return err;
-}
diff --git a/sys/netbt/hci_link.c b/sys/netbt/hci_link.c
deleted file mode 100644
index 6a9055413c5..00000000000
--- a/sys/netbt/hci_link.c
+++ /dev/null
@@ -1,1047 +0,0 @@
-/* $OpenBSD: hci_link.c,v 1.11 2010/07/29 14:40:47 blambert Exp $ */
-/* $NetBSD: hci_link.c,v 1.20 2008/04/24 11:38:37 ad Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/pool.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-#include <netbt/sco.h>
-
-/*******************************************************************************
- *
- * HCI ACL Connections
- */
-
-/*
- * Automatically expire unused ACL connections after this number of
- * seconds (if zero, do not expire unused connections) [sysctl]
- */
-int hci_acl_expiry = 10; /* seconds */
-
-/*
- * hci_acl_open(unit, bdaddr)
- *
- * open ACL connection to remote bdaddr. Only one ACL connection is permitted
- * between any two Bluetooth devices, so we look for an existing one before
- * trying to start a new one.
- */
-struct hci_link *
-hci_acl_open(struct hci_unit *unit, bdaddr_t *bdaddr)
-{
- struct hci_link *link;
- struct hci_memo *memo;
- hci_create_con_cp cp;
- int err;
-
- KASSERT(unit != NULL);
- KASSERT(bdaddr != NULL);
-
- link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
- if (link == NULL) {
- link = hci_link_alloc(unit, bdaddr, HCI_LINK_ACL);
- if (link == NULL)
- return NULL;
- }
-
- switch(link->hl_state) {
- case HCI_LINK_CLOSED:
- /*
- * open connection to remote device
- */
- memset(&cp, 0, sizeof(cp));
- bdaddr_copy(&cp.bdaddr, bdaddr);
- cp.pkt_type = htole16(unit->hci_packet_type);
-
- memo = hci_memo_find(unit, bdaddr);
- if (memo != NULL) {
- cp.page_scan_rep_mode = memo->page_scan_rep_mode;
- cp.page_scan_mode = memo->page_scan_mode;
- cp.clock_offset = memo->clock_offset;
- }
-
- if (unit->hci_link_policy & HCI_LINK_POLICY_ENABLE_ROLE_SWITCH)
- cp.accept_role_switch = 1;
-
- err = hci_send_cmd(unit, HCI_CMD_CREATE_CON, &cp, sizeof(cp));
- if (err) {
- hci_link_free(link, err);
- return NULL;
- }
-
- link->hl_flags |= HCI_LINK_CREATE_CON;
- link->hl_state = HCI_LINK_WAIT_CONNECT;
- break;
-
- case HCI_LINK_WAIT_CONNECT:
- case HCI_LINK_WAIT_AUTH:
- case HCI_LINK_WAIT_ENCRYPT:
- case HCI_LINK_WAIT_SECURE:
- /*
- * somebody else already trying to connect, we just
- * sit on the bench with them..
- */
- break;
-
- case HCI_LINK_OPEN:
- /*
- * If already open, halt any expiry timeouts. We dont need
- * to care about already invoking timeouts since refcnt >0
- * will keep the link alive.
- */
- timeout_del(&link->hl_expire);
- break;
-
- default:
- UNKNOWN(link->hl_state);
- return NULL;
- }
-
- /* open */
- link->hl_refcnt++;
-
- return link;
-}
-
-/*
- * Close ACL connection. When there are no more references to this link,
- * we can either close it down or schedule a delayed closedown.
- */
-void
-hci_acl_close(struct hci_link *link, int err)
-{
-
- KASSERT(link != NULL);
-
- if (--link->hl_refcnt == 0) {
- if (link->hl_state == HCI_LINK_CLOSED)
- hci_link_free(link, err);
- else if (hci_acl_expiry > 0)
- timeout_add_sec(&link->hl_expire, hci_acl_expiry);
- }
-}
-
-/*
- * Incoming ACL connection.
- *
- * For now, we accept all connections but it would be better to check
- * the L2CAP listen list and only accept when there is a listener
- * available.
- *
- * There should not be a link to the same bdaddr already, we check
- * anyway though its left unhandled for now.
- */
-struct hci_link *
-hci_acl_newconn(struct hci_unit *unit, bdaddr_t *bdaddr)
-{
- struct hci_link *link;
-
- link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
- if (link != NULL)
- return NULL;
-
- link = hci_link_alloc(unit, bdaddr, HCI_LINK_ACL);
- if (link != NULL) {
- link->hl_state = HCI_LINK_WAIT_CONNECT;
-
- if (hci_acl_expiry > 0)
- timeout_add_sec(&link->hl_expire, hci_acl_expiry);
- }
-
- return link;
-}
-
-void
-hci_acl_timeout(void *arg)
-{
- struct hci_link *link = arg;
- hci_discon_cp cp;
- int err;
-
- mutex_enter(&bt_lock);
-
- if (link->hl_refcnt > 0)
- goto out;
-
- DPRINTF("link #%d expired\n", link->hl_handle);
-
- switch (link->hl_state) {
- case HCI_LINK_CLOSED:
- case HCI_LINK_WAIT_CONNECT:
- hci_link_free(link, ECONNRESET);
- break;
-
- case HCI_LINK_WAIT_AUTH:
- case HCI_LINK_WAIT_ENCRYPT:
- case HCI_LINK_WAIT_SECURE:
- case HCI_LINK_OPEN:
- cp.con_handle = htole16(link->hl_handle);
- cp.reason = 0x13; /* "Remote User Terminated Connection" */
-
- err = hci_send_cmd(link->hl_unit, HCI_CMD_DISCONNECT,
- &cp, sizeof(cp));
-
- if (err) {
- DPRINTF("error %d sending HCI_CMD_DISCONNECT\n",
- err);
- }
-
- break;
-
- default:
- UNKNOWN(link->hl_state);
- break;
- }
-
-out:
- mutex_exit(&bt_lock);
-}
-
-/*
- * Initiate any Link Mode change requests.
- */
-int
-hci_acl_setmode(struct hci_link *link)
-{
- int err;
-
- KASSERT(link != NULL);
- KASSERT(link->hl_unit != NULL);
-
- if (link->hl_state != HCI_LINK_OPEN)
- return EINPROGRESS;
-
- if ((link->hl_flags & HCI_LINK_AUTH_REQ)
- && !(link->hl_flags & HCI_LINK_AUTH)) {
- hci_auth_req_cp cp;
-
- DPRINTF("(%s) requesting auth for handle #%d\n",
- device_xname(link->hl_unit->hci_dev), link->hl_handle);
-
- link->hl_state = HCI_LINK_WAIT_AUTH;
- cp.con_handle = htole16(link->hl_handle);
- err = hci_send_cmd(link->hl_unit, HCI_CMD_AUTH_REQ,
- &cp, sizeof(cp));
-
- return (err == 0 ? EINPROGRESS : err);
- }
-
- if ((link->hl_flags & HCI_LINK_ENCRYPT_REQ)
- && !(link->hl_flags & HCI_LINK_ENCRYPT)) {
- hci_set_con_encryption_cp cp;
-
- /* XXX we should check features for encryption capability */
-
- DPRINTF("(%s) requesting encryption for handle #%d\n",
- device_xname(link->hl_unit->hci_dev), link->hl_handle);
-
- link->hl_state = HCI_LINK_WAIT_ENCRYPT;
- cp.con_handle = htole16(link->hl_handle);
- cp.encryption_enable = 0x01;
-
- err = hci_send_cmd(link->hl_unit, HCI_CMD_SET_CON_ENCRYPTION,
- &cp, sizeof(cp));
-
- return (err == 0 ? EINPROGRESS : err);
- }
-
- if ((link->hl_flags & HCI_LINK_SECURE_REQ)) {
- hci_change_con_link_key_cp cp;
-
- /* always change link key for SECURE requests */
- link->hl_flags &= ~HCI_LINK_SECURE;
-
- DPRINTF("(%s) changing link key for handle #%d\n",
- device_xname(link->hl_unit->hci_dev), link->hl_handle);
-
- link->hl_state = HCI_LINK_WAIT_SECURE;
- cp.con_handle = htole16(link->hl_handle);
-
- err = hci_send_cmd(link->hl_unit, HCI_CMD_CHANGE_CON_LINK_KEY,
- &cp, sizeof(cp));
-
- return (err == 0 ? EINPROGRESS : err);
- }
-
- return 0;
-}
-
-/*
- * Link Mode changed.
- *
- * This is called from event handlers when the mode change
- * is complete. We notify upstream and restart the link.
- */
-void
-hci_acl_linkmode(struct hci_link *link)
-{
- struct l2cap_channel *chan, *next;
- int err, mode = 0;
-
- DPRINTF("(%s) handle #%d, auth %s, encrypt %s, secure %s\n",
- device_xname(link->hl_unit->hci_dev), link->hl_handle,
- (link->hl_flags & HCI_LINK_AUTH ? "on" : "off"),
- (link->hl_flags & HCI_LINK_ENCRYPT ? "on" : "off"),
- (link->hl_flags & HCI_LINK_SECURE ? "on" : "off"));
-
- if (link->hl_flags & HCI_LINK_AUTH)
- mode |= L2CAP_LM_AUTH;
-
- if (link->hl_flags & HCI_LINK_ENCRYPT)
- mode |= L2CAP_LM_ENCRYPT;
-
- if (link->hl_flags & HCI_LINK_SECURE)
- mode |= L2CAP_LM_SECURE;
-
- /*
- * The link state will only be OPEN here if the mode change
- * was successful. So, we can proceed with L2CAP connections,
- * or notify already establshed channels, to allow any that
- * are dissatisfied to disconnect before we restart.
- */
- next = LIST_FIRST(&l2cap_active_list);
- while ((chan = next) != NULL) {
- next = LIST_NEXT(chan, lc_ncid);
-
- if (chan->lc_link != link)
- continue;
-
- switch(chan->lc_state) {
- case L2CAP_WAIT_SEND_CONNECT_REQ: /* we are connecting */
- if ((mode & chan->lc_mode) != chan->lc_mode) {
- l2cap_close(chan, ECONNABORTED);
- break;
- }
-
- chan->lc_state = L2CAP_WAIT_RECV_CONNECT_RSP;
- err = l2cap_send_connect_req(chan);
- if (err) {
- l2cap_close(chan, err);
- break;
- }
- break;
-
- case L2CAP_WAIT_SEND_CONNECT_RSP: /* they are connecting */
- if ((mode & chan->lc_mode) != chan->lc_mode) {
- l2cap_send_connect_rsp(link, chan->lc_ident,
- 0, chan->lc_rcid,
- L2CAP_SECURITY_BLOCK);
-
- l2cap_close(chan, ECONNABORTED);
- break;
- }
-
- l2cap_send_connect_rsp(link, chan->lc_ident,
- chan->lc_lcid, chan->lc_rcid,
- L2CAP_SUCCESS);
-
- chan->lc_state = L2CAP_WAIT_CONFIG;
- chan->lc_flags |= (L2CAP_WAIT_CONFIG_RSP | L2CAP_WAIT_CONFIG_REQ);
- err = l2cap_send_config_req(chan);
- if (err) {
- l2cap_close(chan, err);
- break;
- }
- break;
-
- case L2CAP_WAIT_RECV_CONNECT_RSP:
- case L2CAP_WAIT_CONFIG:
- case L2CAP_OPEN: /* already established */
- (*chan->lc_proto->linkmode)(chan->lc_upper, mode);
- break;
-
- default:
- break;
- }
- }
-
- link->hl_state = HCI_LINK_OPEN;
- hci_acl_start(link);
-}
-
-/*
- * Receive ACL Data
- *
- * we accumulate packet fragments on the hci_link structure
- * until a full L2CAP frame is ready, then send it on.
- */
-void
-hci_acl_recv(struct mbuf *m, struct hci_unit *unit)
-{
- struct hci_link *link;
- hci_acldata_hdr_t hdr;
- uint16_t handle, want;
- int pb, got;
-
- KASSERT(m != NULL);
- KASSERT(unit != NULL);
-
- KASSERT(m->m_pkthdr.len >= sizeof(hdr));
- m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr);
- m_adj(m, sizeof(hdr));
-
-#ifdef DIAGNOSTIC
- if (hdr.type != HCI_ACL_DATA_PKT) {
- printf("%s: bad ACL packet type\n",
- device_xname(unit->hci_dev));
- goto bad;
- }
-
- if (m->m_pkthdr.len != letoh16(hdr.length)) {
- printf("%s: bad ACL packet length (%d != %d)\n",
- device_xname(unit->hci_dev), m->m_pkthdr.len,
- letoh16(hdr.length));
- goto bad;
- }
-#endif
-
- hdr.length = letoh16(hdr.length);
- hdr.con_handle = letoh16(hdr.con_handle);
- handle = HCI_CON_HANDLE(hdr.con_handle);
- pb = HCI_PB_FLAG(hdr.con_handle);
-
- link = hci_link_lookup_handle(unit, handle);
- if (link == NULL) {
- hci_discon_cp cp;
-
- DPRINTF("%s: dumping packet for unknown handle #%d\n",
- device_xname(unit->hci_dev), handle);
-
- /*
- * There is no way to find out what this connection handle is
- * for, just get rid of it. This may happen, if a USB dongle
- * is plugged into a self powered hub and does not reset when
- * the system is shut down.
- */
- cp.con_handle = htole16(handle);
- cp.reason = 0x13; /* "Remote User Terminated Connection" */
- hci_send_cmd(unit, HCI_CMD_DISCONNECT, &cp, sizeof(cp));
- goto bad;
- }
-
- switch (pb) {
- case HCI_PACKET_START:
- if (link->hl_rxp != NULL)
- printf("%s: dropped incomplete ACL packet\n",
- device_xname(unit->hci_dev));
-
- if (m->m_pkthdr.len < sizeof(l2cap_hdr_t)) {
- printf("%s: short ACL packet\n",
- device_xname(unit->hci_dev));
-
- goto bad;
- }
-
- link->hl_rxp = m;
- got = m->m_pkthdr.len;
- break;
-
- case HCI_PACKET_FRAGMENT:
- if (link->hl_rxp == NULL) {
- printf("%s: unexpected packet fragment\n",
- device_xname(unit->hci_dev));
-
- goto bad;
- }
-
- got = m->m_pkthdr.len + link->hl_rxp->m_pkthdr.len;
- m_cat(link->hl_rxp, m);
- m = link->hl_rxp;
- m->m_pkthdr.len = got;
- break;
-
- default:
- printf("%s: unknown packet type\n",
- device_xname(unit->hci_dev));
-
- goto bad;
- }
-
- m_copydata(m, 0, sizeof(want), (caddr_t)&want);
- want = letoh16(want) + sizeof(l2cap_hdr_t) - got;
-
- if (want > 0)
- return;
-
- link->hl_rxp = NULL;
-
- if (want == 0) {
- l2cap_recv_frame(m, link);
- return;
- }
-
-bad:
- m_freem(m);
-}
-
-/*
- * Send ACL data on link
- *
- * We must fragment packets into chunks of less than unit->hci_max_acl_size and
- * prepend a relevant ACL header to each fragment. We keep a PDU structure
- * attached to the link, so that completed fragments can be marked off and
- * more data requested from above once the PDU is sent.
- */
-int
-hci_acl_send(struct mbuf *m, struct hci_link *link,
- struct l2cap_channel *chan)
-{
- struct l2cap_pdu *pdu;
- struct mbuf *n = NULL;
- int plen, mlen, num = 0;
-
- KASSERT(link != NULL);
- KASSERT(m != NULL);
- KASSERT(m->m_flags & M_PKTHDR);
- KASSERT(m->m_pkthdr.len > 0);
-
- if (link->hl_state == HCI_LINK_CLOSED) {
- m_freem(m);
- return ENETDOWN;
- }
-
- pdu = pool_get(&l2cap_pdu_pool, PR_NOWAIT);
- if (pdu == NULL)
- goto nomem;
-
- bzero(pdu, sizeof *pdu);
- pdu->lp_chan = chan;
- pdu->lp_pending = 0;
-
- plen = m->m_pkthdr.len;
- mlen = link->hl_unit->hci_max_acl_size;
-
- DPRINTFN(5, "%s: handle #%d, plen = %d, max = %d\n",
- device_xname(link->hl_unit->hci_dev), link->hl_handle, plen, mlen);
-
- while (plen > 0) {
- if (plen > mlen) {
- n = m_split(m, mlen, M_DONTWAIT);
- if (n == NULL)
- goto nomem;
- } else {
- mlen = plen;
- }
-
- if (num++ == 0)
- m->m_flags |= M_PROTO1; /* tag first fragment */
-
- DPRINTFN(10, "(%s) chunk of %d (plen = %d) bytes\n",
- device_xname(link->hl_unit->hci_dev), mlen, plen);
- IF_ENQUEUE(&pdu->lp_data, m);
- m = n;
- plen -= mlen;
- }
-
- TAILQ_INSERT_TAIL(&link->hl_txq, pdu, lp_next);
- link->hl_txqlen += num;
-
- hci_acl_start(link);
-
- return 0;
-
-nomem:
- if (m) m_freem(m);
- if (pdu) {
- IF_PURGE(&pdu->lp_data);
- pool_put(&l2cap_pdu_pool, pdu);
- }
-
- return ENOMEM;
-}
-
-/*
- * Start sending ACL data on link.
- *
- * This is called when the queue may need restarting: as new data
- * is queued, after link mode changes have completed, or when device
- * buffers have cleared.
- *
- * We may use all the available packet slots. The reason that we add
- * the ACL encapsulation here rather than in hci_acl_send() is that L2CAP
- * signal packets may be queued before the handle is given to us..
- */
-void
-hci_acl_start(struct hci_link *link)
-{
- struct hci_unit *unit;
- hci_acldata_hdr_t *hdr;
- struct l2cap_pdu *pdu;
- struct mbuf *m;
- uint16_t handle;
-
- KASSERT(link != NULL);
-
- unit = link->hl_unit;
- KASSERT(unit != NULL);
-
- /* this is mainly to block ourselves (below) */
- if (link->hl_state != HCI_LINK_OPEN)
- return;
-
- if (link->hl_txqlen == 0 || unit->hci_num_acl_pkts == 0)
- return;
-
- /* find first PDU with data to send */
- pdu = TAILQ_FIRST(&link->hl_txq);
- for (;;) {
- if (pdu == NULL)
- return;
-
- if (!IF_IS_EMPTY(&pdu->lp_data))
- break;
-
- pdu = TAILQ_NEXT(pdu, lp_next);
- }
-
- while (unit->hci_num_acl_pkts > 0) {
- IF_DEQUEUE(&pdu->lp_data, m);
- KASSERT(m != NULL);
-
- if (m->m_flags & M_PROTO1)
- handle = HCI_MK_CON_HANDLE(link->hl_handle,
- HCI_PACKET_START, 0);
- else
- handle = HCI_MK_CON_HANDLE(link->hl_handle,
- HCI_PACKET_FRAGMENT, 0);
-
- M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
- if (m == NULL)
- break;
-
- hdr = mtod(m, hci_acldata_hdr_t *);
- hdr->type = HCI_ACL_DATA_PKT;
- hdr->con_handle = htole16(handle);
- hdr->length = htole16(m->m_pkthdr.len - sizeof(*hdr));
-
- link->hl_txqlen--;
- pdu->lp_pending++;
-
- hci_output_acl(unit, m);
-
- if (IF_IS_EMPTY(&pdu->lp_data)) {
- if (pdu->lp_chan) {
- /*
- * This should enable streaming of PDUs - when
- * we have placed all the fragments on the acl
- * output queue, we trigger the L2CAP layer to
- * send us down one more. Use a false state so
- * we dont run into ourselves coming back from
- * the future..
- */
- link->hl_state = HCI_LINK_BLOCK;
- l2cap_start(pdu->lp_chan);
- link->hl_state = HCI_LINK_OPEN;
- }
-
- pdu = TAILQ_NEXT(pdu, lp_next);
- if (pdu == NULL)
- break;
- }
- }
-
- /*
- * We had our turn now, move to the back of the queue to let
- * other links have a go at the output buffers..
- */
- if (TAILQ_NEXT(link, hl_next)) {
- TAILQ_REMOVE(&unit->hci_links, link, hl_next);
- TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next);
- }
-}
-
-/*
- * Confirm ACL packets cleared from Controller buffers. We scan our PDU
- * list to clear pending fragments and signal upstream for more data
- * when a PDU is complete.
- */
-void
-hci_acl_complete(struct hci_link *link, int num)
-{
- struct l2cap_pdu *pdu;
- struct l2cap_channel *chan;
-
- DPRINTFN(5, "(%s) handle #%d (%d)\n",
- device_xname(link->hl_unit->hci_dev), link->hl_handle, num);
-
- while (num > 0) {
- pdu = TAILQ_FIRST(&link->hl_txq);
- if (pdu == NULL) {
- printf("%s: %d packets completed on handle #%x "
- "but none pending!\n",
- device_xname(link->hl_unit->hci_dev), num,
- link->hl_handle);
- return;
- }
-
- if (num >= pdu->lp_pending) {
- num -= pdu->lp_pending;
- pdu->lp_pending = 0;
-
- if (IF_IS_EMPTY(&pdu->lp_data)) {
- TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
- chan = pdu->lp_chan;
- if (chan != NULL) {
- chan->lc_pending--;
- (*chan->lc_proto->complete)
- (chan->lc_upper, 1);
-
- if (chan->lc_pending == 0)
- l2cap_start(chan);
- }
-
- pool_put(&l2cap_pdu_pool, pdu);
- }
- } else {
- pdu->lp_pending -= num;
- num = 0;
- }
- }
-}
-
-/*******************************************************************************
- *
- * HCI SCO Connections
- */
-
-/*
- * Incoming SCO Connection. We check the list for anybody willing
- * to take it.
- */
-struct hci_link *
-hci_sco_newconn(struct hci_unit *unit, bdaddr_t *bdaddr)
-{
- struct sockaddr_bt laddr, raddr;
- struct sco_pcb *pcb, *new;
- struct hci_link *sco, *acl;
-
- memset(&laddr, 0, sizeof(laddr));
- laddr.bt_len = sizeof(laddr);
- laddr.bt_family = AF_BLUETOOTH;
- bdaddr_copy(&laddr.bt_bdaddr, &unit->hci_bdaddr);
-
- memset(&raddr, 0, sizeof(raddr));
- raddr.bt_len = sizeof(raddr);
- raddr.bt_family = AF_BLUETOOTH;
- bdaddr_copy(&raddr.bt_bdaddr, bdaddr);
-
- /*
- * There should already be an ACL link up and running before
- * the controller sends us SCO connection requests, but you
- * never know..
- */
- acl = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
- if (acl == NULL || acl->hl_state != HCI_LINK_OPEN)
- return NULL;
-
- LIST_FOREACH(pcb, &sco_pcb, sp_next) {
- if ((pcb->sp_flags & SP_LISTENING) == 0)
- continue;
-
- new = (*pcb->sp_proto->newconn)(pcb->sp_upper, &laddr, &raddr);
- if (new == NULL)
- continue;
-
- /*
- * Ok, got new pcb so we can start a new link and fill
- * in all the details.
- */
- bdaddr_copy(&new->sp_laddr, &unit->hci_bdaddr);
- bdaddr_copy(&new->sp_raddr, bdaddr);
-
- sco = hci_link_alloc(unit, bdaddr, HCI_LINK_SCO);
- if (sco == NULL) {
- sco_detach(&new);
- return NULL;
- }
-
- sco->hl_link = hci_acl_open(unit, bdaddr);
- KASSERT(sco->hl_link == acl);
-
- sco->hl_sco = new;
- new->sp_link = sco;
-
- new->sp_mtu = unit->hci_max_sco_size;
- return sco;
- }
-
- return NULL;
-}
-
-/*
- * receive SCO packet, we only need to strip the header and send
- * it to the right handler
- */
-void
-hci_sco_recv(struct mbuf *m, struct hci_unit *unit)
-{
- struct hci_link *link;
- hci_scodata_hdr_t hdr;
- uint16_t handle;
-
- KASSERT(m != NULL);
- KASSERT(unit != NULL);
-
- KASSERT(m->m_pkthdr.len >= sizeof(hdr));
- m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr);
- m_adj(m, sizeof(hdr));
-
-#ifdef DIAGNOSTIC
- if (hdr.type != HCI_SCO_DATA_PKT) {
- printf("%s: bad SCO packet type\n",
- device_xname(unit->hci_dev));
- goto bad;
- }
-
- if (m->m_pkthdr.len != hdr.length) {
- printf("%s: bad SCO packet length (%d != %d)\n",
- device_xname(unit->hci_dev), m->m_pkthdr.len, hdr.length);
- goto bad;
- }
-#endif
-
- hdr.con_handle = letoh16(hdr.con_handle);
- handle = HCI_CON_HANDLE(hdr.con_handle);
-
- link = hci_link_lookup_handle(unit, handle);
- if (link == NULL || link->hl_type == HCI_LINK_ACL) {
- DPRINTF("%s: dumping packet for unknown handle #%d\n",
- device_xname(unit->hci_dev), handle);
-
- goto bad;
- }
-
- (*link->hl_sco->sp_proto->input)(link->hl_sco->sp_upper, m);
- return;
-
-bad:
- m_freem(m);
-}
-
-void
-hci_sco_start(struct hci_link *link)
-{
-}
-
-/*
- * SCO packets have completed at the controller, so we can
- * signal up to free the buffer space.
- */
-void
-hci_sco_complete(struct hci_link *link, int num)
-{
-
- DPRINTFN(5, "handle #%d (num=%d)\n", link->hl_handle, num);
- link->hl_sco->sp_pending--;
- (*link->hl_sco->sp_proto->complete)(link->hl_sco->sp_upper, num);
-}
-
-/*******************************************************************************
- *
- * Generic HCI Connection alloc/free/lookup etc
- */
-
-struct hci_link *
-hci_link_alloc(struct hci_unit *unit, bdaddr_t *bdaddr, uint8_t type)
-{
- struct hci_link *link;
-
- KASSERT(unit != NULL);
-
- link = malloc(sizeof *link, M_BLUETOOTH, M_NOWAIT | M_ZERO);
- if (link == NULL)
- return NULL;
-
- link->hl_unit = unit;
- link->hl_type = type;
- link->hl_state = HCI_LINK_CLOSED;
- bdaddr_copy(&link->hl_bdaddr, bdaddr);
-
- /* init ACL portion */
- timeout_set(&link->hl_expire, hci_acl_timeout, link);
-
- TAILQ_INIT(&link->hl_txq); /* outgoing packets */
- TAILQ_INIT(&link->hl_reqs); /* request queue */
-
- link->hl_mtu = L2CAP_MTU_DEFAULT; /* L2CAP signal mtu */
- link->hl_flush = L2CAP_FLUSH_TIMO_DEFAULT; /* flush timeout */
-
- /* init SCO portion */
- /* &link->hl_data is already zero-initialized. */
-
- /* attach to unit */
- TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next);
- return link;
-}
-
-void
-hci_link_free(struct hci_link *link, int err)
-{
- struct l2cap_req *req;
- struct l2cap_pdu *pdu;
- struct l2cap_channel *chan, *next;
-
- KASSERT(link != NULL);
-
- DPRINTF("(%s) #%d, type = %d, state = %d, refcnt = %d\n",
- device_xname(link->hl_unit->hci_dev), link->hl_handle,
- link->hl_type, link->hl_state, link->hl_refcnt);
-
- /* ACL reference count */
- if (link->hl_refcnt > 0) {
- next = LIST_FIRST(&l2cap_active_list);
- while ((chan = next) != NULL) {
- next = LIST_NEXT(chan, lc_ncid);
- if (chan->lc_link == link)
- l2cap_close(chan, err);
- }
- }
- KASSERT(link->hl_refcnt == 0);
-
- /* ACL L2CAP requests.. */
- while ((req = TAILQ_FIRST(&link->hl_reqs)) != NULL)
- l2cap_request_free(req);
-
- KASSERT(TAILQ_EMPTY(&link->hl_reqs));
-
- /* ACL outgoing data queue */
- while ((pdu = TAILQ_FIRST(&link->hl_txq)) != NULL) {
- TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
- IF_PURGE(&pdu->lp_data);
- if (pdu->lp_pending)
- link->hl_unit->hci_num_acl_pkts += pdu->lp_pending;
-
- pool_put(&l2cap_pdu_pool, pdu);
- }
-
- KASSERT(TAILQ_EMPTY(&link->hl_txq));
-
- /* ACL incoming data packet */
- if (link->hl_rxp != NULL) {
- m_freem(link->hl_rxp);
- link->hl_rxp = NULL;
- }
-
- /* SCO master ACL link */
- if (link->hl_link != NULL) {
- hci_acl_close(link->hl_link, err);
- link->hl_link = NULL;
- }
-
- /* SCO pcb */
- if (link->hl_sco != NULL) {
- struct sco_pcb *pcb;
-
- pcb = link->hl_sco;
- pcb->sp_link = NULL;
- link->hl_sco = NULL;
- (*pcb->sp_proto->disconnected)(pcb->sp_upper, err);
- }
-
- /* flush any SCO data */
- IF_PURGE(&link->hl_data);
-
- /*
- * Halt the timeout - if its already running we cannot free the
- * link structure but the timeout function will call us back in
- * any case.
- */
- link->hl_state = HCI_LINK_CLOSED;
- timeout_del(&link->hl_expire);
- if (timeout_triggered(&link->hl_expire))
- return;
-
- /*
- * If we made a note of clock offset, keep it in a memo
- * to facilitate reconnections to this device
- */
- if (link->hl_clock != 0) {
- struct hci_memo *memo;
-
- memo = hci_memo_new(link->hl_unit, &link->hl_bdaddr);
- if (memo != NULL)
- memo->clock_offset = link->hl_clock;
- }
-
- TAILQ_REMOVE(&link->hl_unit->hci_links, link, hl_next);
- free(link, M_BLUETOOTH);
-}
-
-/*
- * Lookup HCI link by address and type. Note that for SCO links there may
- * be more than one link per address, so we only return links with no
- * handle (ie new links)
- */
-struct hci_link *
-hci_link_lookup_bdaddr(struct hci_unit *unit, bdaddr_t *bdaddr, uint8_t type)
-{
- struct hci_link *link;
-
- KASSERT(unit != NULL);
- KASSERT(bdaddr != NULL);
-
- TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
- if (link->hl_type != type)
- continue;
-
- if (type == HCI_LINK_SCO && link->hl_handle != 0)
- continue;
-
- if (bdaddr_same(&link->hl_bdaddr, bdaddr))
- break;
- }
-
- return link;
-}
-
-struct hci_link *
-hci_link_lookup_handle(struct hci_unit *unit, uint16_t handle)
-{
- struct hci_link *link;
-
- KASSERT(unit != NULL);
-
- TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
- if (handle == link->hl_handle)
- break;
- }
-
- return link;
-}
diff --git a/sys/netbt/hci_misc.c b/sys/netbt/hci_misc.c
deleted file mode 100644
index 5cb144036a5..00000000000
--- a/sys/netbt/hci_misc.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/* $OpenBSD: hci_misc.c,v 1.2 2008/02/24 21:34:48 uwe Exp $ */
-/* $NetBSD: hci_misc.c,v 1.3 2007/09/16 19:59:30 plunky Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-
-/*
- * cache Inquiry Responses for this number of seconds for routing
- * purposes [sysctl]
- */
-int hci_memo_expiry = 600;
-
-/*
- * set 'src' address for routing to 'dest'
- */
-int
-hci_route_lookup(bdaddr_t *src, bdaddr_t *dest)
-{
- struct hci_unit *unit;
- struct hci_link *link;
- struct hci_memo *memo;
-
- /*
- * Walk the ACL connections, if we have a connection
- * to 'dest' already then thats best..
- */
- TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
- if ((unit->hci_flags & BTF_UP) == 0)
- continue;
-
- TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
- if (link->hl_type != HCI_LINK_ACL)
- continue;
-
- if (bdaddr_same(&link->hl_bdaddr, dest))
- goto found;
- }
- }
-
- /*
- * Now check all the memos to see if there has been an
- * inquiry repsonse..
- */
- TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
- if ((unit->hci_flags & BTF_UP) == 0)
- continue;
-
- memo = hci_memo_find(unit, dest);
- if (memo)
- goto found;
- }
-
- /*
- * Last ditch effort, lets use the first unit we find
- * thats up and running. (XXX settable default route?)
- */
- TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
- if ((unit->hci_flags & BTF_UP) == 0)
- continue;
-
- goto found;
- }
-
- return EHOSTUNREACH;
-
-found:
- bdaddr_copy(src, &unit->hci_bdaddr);
- return 0;
-}
-
-/*
- * find unit memo from bdaddr
- */
-struct hci_memo *
-hci_memo_find(struct hci_unit *unit, bdaddr_t *bdaddr)
-{
- struct hci_memo *memo, *m0;
- struct timeval now;
-
- microtime(&now);
-
- m0 = LIST_FIRST(&unit->hci_memos);
- while ((memo = m0) != NULL) {
- m0 = LIST_NEXT(memo, next);
-
- if (now.tv_sec > memo->time.tv_sec + hci_memo_expiry) {
- DPRINTF("memo %p too old (expiring)\n", memo);
- hci_memo_free(memo);
- continue;
- }
-
- if (bdaddr_same(bdaddr, &memo->bdaddr)) {
- DPRINTF("memo %p found\n", memo);
- return memo;
- }
- }
-
- DPRINTF("no memo found\n");
- return NULL;
-}
-
-/*
- * Make a new memo on unit for bdaddr. If a memo exists, just
- * update the timestamp.
- */
-struct hci_memo *
-hci_memo_new(struct hci_unit *unit, bdaddr_t *bdaddr)
-{
- struct hci_memo *memo;
-
- memo = hci_memo_find(unit, bdaddr);
- if (memo == NULL) {
- memo = malloc(sizeof(struct hci_memo),
- M_BLUETOOTH, M_NOWAIT | M_ZERO);
-
- if (memo == NULL) {
- DPRINTFN(0, "no memory for memo!\n");
- return NULL;
- }
-
- DPRINTF("memo created for %02x:%02x:%02x:%02x:%02x:%02x\n",
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
-
- bdaddr_copy(&memo->bdaddr, bdaddr);
- LIST_INSERT_HEAD(&unit->hci_memos, memo, next);
- }
- else
- DPRINTF("memo updated for %02x:%02x:%02x:%02x:%02x:%02x\n",
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
-
- microtime(&memo->time);
- return memo;
-}
-
-void
-hci_memo_free(struct hci_memo *memo)
-{
-
- LIST_REMOVE(memo, next);
- free(memo, M_BLUETOOTH);
-}
diff --git a/sys/netbt/hci_socket.c b/sys/netbt/hci_socket.c
deleted file mode 100644
index d9d161cd185..00000000000
--- a/sys/netbt/hci_socket.c
+++ /dev/null
@@ -1,946 +0,0 @@
-/* $OpenBSD: hci_socket.c,v 1.8 2009/11/21 13:05:32 guenther Exp $ */
-/* $NetBSD: hci_socket.c,v 1.17 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* load symbolic names */
-#ifdef BLUETOOTH_DEBUG
-#define PRUREQUESTS
-#define PRCOREQUESTS
-#endif
-
-#include <sys/param.h>
-#include <sys/domain.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-
-/*******************************************************************************
- *
- * HCI SOCK_RAW Sockets - for control of Bluetooth Devices
- *
- */
-
-/*
- * the raw HCI protocol control block
- */
-struct hci_pcb {
- struct socket *hp_socket; /* socket */
- unsigned int hp_flags; /* flags */
- bdaddr_t hp_laddr; /* local address */
- bdaddr_t hp_raddr; /* remote address */
- struct hci_filter hp_efilter; /* user event filter */
- struct hci_filter hp_pfilter; /* user packet filter */
- LIST_ENTRY(hci_pcb) hp_next; /* next HCI pcb */
-};
-
-/* hp_flags */
-#define HCI_PRIVILEGED (1<<0) /* no security filter for root */
-#define HCI_DIRECTION (1<<1) /* direction control messages */
-#define HCI_PROMISCUOUS (1<<2) /* listen to all units */
-
-LIST_HEAD(hci_pcb_list, hci_pcb) hci_pcb = LIST_HEAD_INITIALIZER(hci_pcb);
-
-/* sysctl defaults */
-int hci_sendspace = HCI_CMD_PKT_SIZE;
-int hci_recvspace = 4096;
-
-/* supported commands opcode table */
-static const struct {
- uint16_t opcode;
- uint8_t offs; /* 0 - 63 */
- uint8_t mask; /* bit 0 - 7 */
- int16_t length; /* -1 if privileged */
-} hci_cmds[] = {
- { HCI_CMD_INQUIRY,
- 0, 0x01, sizeof(hci_inquiry_cp) },
- { HCI_CMD_INQUIRY_CANCEL,
- 0, 0x02, -1 },
- { HCI_CMD_PERIODIC_INQUIRY,
- 0, 0x04, -1 },
- { HCI_CMD_EXIT_PERIODIC_INQUIRY,
- 0, 0x08, -1 },
- { HCI_CMD_CREATE_CON,
- 0, 0x10, -1 },
- { HCI_CMD_DISCONNECT,
- 0, 0x20, -1 },
- { HCI_CMD_ADD_SCO_CON,
- 0, 0x40, -1 },
- { HCI_CMD_CREATE_CON_CANCEL,
- 0, 0x80, -1 },
- { HCI_CMD_ACCEPT_CON,
- 1, 0x01, -1 },
- { HCI_CMD_REJECT_CON,
- 1, 0x02, -1 },
- { HCI_CMD_LINK_KEY_REP,
- 1, 0x04, -1 },
- { HCI_CMD_LINK_KEY_NEG_REP,
- 1, 0x08, -1 },
- { HCI_CMD_PIN_CODE_REP,
- 1, 0x10, -1 },
- { HCI_CMD_PIN_CODE_NEG_REP,
- 1, 0x20, -1 },
- { HCI_CMD_CHANGE_CON_PACKET_TYPE,
- 1, 0x40, -1 },
- { HCI_CMD_AUTH_REQ,
- 1, 0x80, -1 },
- { HCI_CMD_SET_CON_ENCRYPTION,
- 2, 0x01, -1 },
- { HCI_CMD_CHANGE_CON_LINK_KEY,
- 2, 0x02, -1 },
- { HCI_CMD_MASTER_LINK_KEY,
- 2, 0x04, -1 },
- { HCI_CMD_REMOTE_NAME_REQ,
- 2, 0x08, sizeof(hci_remote_name_req_cp) },
- { HCI_CMD_REMOTE_NAME_REQ_CANCEL,
- 2, 0x10, -1 },
- { HCI_CMD_READ_REMOTE_FEATURES,
- 2, 0x20, sizeof(hci_read_remote_features_cp) },
- { HCI_CMD_READ_REMOTE_EXTENDED_FEATURES,
- 2, 0x40, sizeof(hci_read_remote_extended_features_cp) },
- { HCI_CMD_READ_REMOTE_VER_INFO,
- 2, 0x80, sizeof(hci_read_remote_ver_info_cp) },
- { HCI_CMD_READ_CLOCK_OFFSET,
- 3, 0x01, sizeof(hci_read_clock_offset_cp) },
- { HCI_CMD_READ_LMP_HANDLE,
- 3, 0x02, sizeof(hci_read_lmp_handle_cp) },
- { HCI_CMD_HOLD_MODE,
- 4, 0x02, -1 },
- { HCI_CMD_SNIFF_MODE,
- 4, 0x04, -1 },
- { HCI_CMD_EXIT_SNIFF_MODE,
- 4, 0x08, -1 },
- { HCI_CMD_PARK_MODE,
- 4, 0x10, -1 },
- { HCI_CMD_EXIT_PARK_MODE,
- 4, 0x20, -1 },
- { HCI_CMD_QOS_SETUP,
- 4, 0x40, -1 },
- { HCI_CMD_ROLE_DISCOVERY,
- 4, 0x80, sizeof(hci_role_discovery_cp) },
- { HCI_CMD_SWITCH_ROLE,
- 5, 0x01, -1 },
- { HCI_CMD_READ_LINK_POLICY_SETTINGS,
- 5, 0x02, sizeof(hci_read_link_policy_settings_cp) },
- { HCI_CMD_WRITE_LINK_POLICY_SETTINGS,
- 5, 0x04, -1 },
- { HCI_CMD_READ_DEFAULT_LINK_POLICY_SETTINGS,
- 5, 0x08, 0 },
- { HCI_CMD_WRITE_DEFAULT_LINK_POLICY_SETTINGS,
- 5, 0x10, -1 },
- { HCI_CMD_FLOW_SPECIFICATION,
- 5, 0x20, -1 },
- { HCI_CMD_SET_EVENT_MASK,
- 5, 0x40, -1 },
- { HCI_CMD_RESET,
- 5, 0x80, -1 },
- { HCI_CMD_SET_EVENT_FILTER,
- 6, 0x01, -1 },
- { HCI_CMD_FLUSH,
- 6, 0x02, -1 },
- { HCI_CMD_READ_PIN_TYPE,
- 6, 0x04, 0 },
- { HCI_CMD_WRITE_PIN_TYPE,
- 6, 0x08, -1 },
- { HCI_CMD_CREATE_NEW_UNIT_KEY,
- 6, 0x10, -1 },
- { HCI_CMD_READ_STORED_LINK_KEY,
- 6, 0x20, -1 },
- { HCI_CMD_WRITE_STORED_LINK_KEY,
- 6, 0x40, -1 },
- { HCI_CMD_DELETE_STORED_LINK_KEY,
- 6, 0x80, -1 },
- { HCI_CMD_WRITE_LOCAL_NAME,
- 7, 0x01, -1 },
- { HCI_CMD_READ_LOCAL_NAME,
- 7, 0x02, 0 },
- { HCI_CMD_READ_CON_ACCEPT_TIMEOUT,
- 7, 0x04, 0 },
- { HCI_CMD_WRITE_CON_ACCEPT_TIMEOUT,
- 7, 0x08, -1 },
- { HCI_CMD_READ_PAGE_TIMEOUT,
- 7, 0x10, 0 },
- { HCI_CMD_WRITE_PAGE_TIMEOUT,
- 7, 0x20, -1 },
- { HCI_CMD_READ_SCAN_ENABLE,
- 7, 0x40, 0 },
- { HCI_CMD_WRITE_SCAN_ENABLE,
- 7, 0x80, -1 },
- { HCI_CMD_READ_PAGE_SCAN_ACTIVITY,
- 8, 0x01, 0 },
- { HCI_CMD_WRITE_PAGE_SCAN_ACTIVITY,
- 8, 0x02, -1 },
- { HCI_CMD_READ_INQUIRY_SCAN_ACTIVITY,
- 8, 0x04, 0 },
- { HCI_CMD_WRITE_INQUIRY_SCAN_ACTIVITY,
- 8, 0x08, -1 },
- { HCI_CMD_READ_AUTH_ENABLE,
- 8, 0x10, 0 },
- { HCI_CMD_WRITE_AUTH_ENABLE,
- 8, 0x20, -1 },
- { HCI_CMD_READ_ENCRYPTION_MODE,
- 8, 0x40, 0 },
- { HCI_CMD_WRITE_ENCRYPTION_MODE,
- 8, 0x80, -1 },
- { HCI_CMD_READ_UNIT_CLASS,
- 9, 0x01, 0 },
- { HCI_CMD_WRITE_UNIT_CLASS,
- 9, 0x02, -1 },
- { HCI_CMD_READ_VOICE_SETTING,
- 9, 0x04, 0 },
- { HCI_CMD_WRITE_VOICE_SETTING,
- 9, 0x08, -1 },
- { HCI_CMD_READ_AUTO_FLUSH_TIMEOUT,
- 9, 0x10, sizeof(hci_read_auto_flush_timeout_cp) },
- { HCI_CMD_WRITE_AUTO_FLUSH_TIMEOUT,
- 9, 0x20, -1 },
- { HCI_CMD_READ_NUM_BROADCAST_RETRANS,
- 9, 0x40, 0 },
- { HCI_CMD_WRITE_NUM_BROADCAST_RETRANS,
- 9, 0x80, -1 },
- { HCI_CMD_READ_HOLD_MODE_ACTIVITY,
- 10, 0x01, 0 },
- { HCI_CMD_WRITE_HOLD_MODE_ACTIVITY,
- 10, 0x02, -1 },
- { HCI_CMD_READ_XMIT_LEVEL,
- 10, 0x04, sizeof(hci_read_xmit_level_cp) },
- { HCI_CMD_READ_SCO_FLOW_CONTROL,
- 10, 0x08, 0 },
- { HCI_CMD_WRITE_SCO_FLOW_CONTROL,
- 10, 0x10, -1 },
- { HCI_CMD_HC2H_FLOW_CONTROL,
- 10, 0x20, -1 },
- { HCI_CMD_HOST_BUFFER_SIZE,
- 10, 0x40, -1 },
- { HCI_CMD_HOST_NUM_COMPL_PKTS,
- 10, 0x80, -1 },
- { HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT,
- 11, 0x01, sizeof(hci_read_link_supervision_timeout_cp) },
- { HCI_CMD_WRITE_LINK_SUPERVISION_TIMEOUT,
- 11, 0x02, -1 },
- { HCI_CMD_READ_NUM_SUPPORTED_IAC,
- 11, 0x04, 0 },
- { HCI_CMD_READ_IAC_LAP,
- 11, 0x08, 0 },
- { HCI_CMD_WRITE_IAC_LAP,
- 11, 0x10, -1 },
- { HCI_CMD_READ_PAGE_SCAN_PERIOD,
- 11, 0x20, 0 },
- { HCI_CMD_WRITE_PAGE_SCAN_PERIOD,
- 11, 0x40, -1 },
- { HCI_CMD_READ_PAGE_SCAN,
- 11, 0x80, 0 },
- { HCI_CMD_WRITE_PAGE_SCAN,
- 12, 0x01, -1 },
- { HCI_CMD_SET_AFH_CLASSIFICATION,
- 12, 0x02, -1 },
- { HCI_CMD_READ_INQUIRY_SCAN_TYPE,
- 12, 0x10, 0 },
- { HCI_CMD_WRITE_INQUIRY_SCAN_TYPE,
- 12, 0x20, -1 },
- { HCI_CMD_READ_INQUIRY_MODE,
- 12, 0x40, 0 },
- { HCI_CMD_WRITE_INQUIRY_MODE,
- 12, 0x80, -1 },
- { HCI_CMD_READ_PAGE_SCAN_TYPE,
- 13, 0x01, 0 },
- { HCI_CMD_WRITE_PAGE_SCAN_TYPE,
- 13, 0x02, -1 },
- { HCI_CMD_READ_AFH_ASSESSMENT,
- 13, 0x04, 0 },
- { HCI_CMD_WRITE_AFH_ASSESSMENT,
- 13, 0x08, -1 },
- { HCI_CMD_READ_LOCAL_VER,
- 14, 0x08, 0 },
- { HCI_CMD_READ_LOCAL_COMMANDS,
- 14, 0x10, 0 },
- { HCI_CMD_READ_LOCAL_FEATURES,
- 14, 0x20, 0 },
- { HCI_CMD_READ_LOCAL_EXTENDED_FEATURES,
- 14, 0x40, sizeof(hci_read_local_extended_features_cp) },
- { HCI_CMD_READ_BUFFER_SIZE,
- 14, 0x80, 0 },
- { HCI_CMD_READ_COUNTRY_CODE,
- 15, 0x01, 0 },
- { HCI_CMD_READ_BDADDR,
- 15, 0x02, 0 },
- { HCI_CMD_READ_FAILED_CONTACT_CNTR,
- 15, 0x04, sizeof(hci_read_failed_contact_cntr_cp) },
- { HCI_CMD_RESET_FAILED_CONTACT_CNTR,
- 15, 0x08, -1 },
- { HCI_CMD_READ_LINK_QUALITY,
- 15, 0x10, sizeof(hci_read_link_quality_cp) },
- { HCI_CMD_READ_RSSI,
- 15, 0x20, sizeof(hci_read_rssi_cp) },
- { HCI_CMD_READ_AFH_CHANNEL_MAP,
- 15, 0x40, sizeof(hci_read_afh_channel_map_cp) },
- { HCI_CMD_READ_CLOCK,
- 15, 0x80, sizeof(hci_read_clock_cp) },
- { HCI_CMD_READ_LOOPBACK_MODE,
- 16, 0x01, 0 },
- { HCI_CMD_WRITE_LOOPBACK_MODE,
- 16, 0x02, -1 },
- { HCI_CMD_ENABLE_UNIT_UNDER_TEST,
- 16, 0x04, -1 },
- { HCI_CMD_SETUP_SCO_CON,
- 16, 0x08, -1 },
- { HCI_CMD_ACCEPT_SCO_CON_REQ,
- 16, 0x10, -1 },
- { HCI_CMD_REJECT_SCO_CON_REQ,
- 16, 0x20, -1 },
- { HCI_CMD_READ_EXTENDED_INQUIRY_RSP,
- 17, 0x01, 0 },
- { HCI_CMD_WRITE_EXTENDED_INQUIRY_RSP,
- 17, 0x02, -1 },
- { HCI_CMD_REFRESH_ENCRYPTION_KEY,
- 17, 0x04, -1 },
- { HCI_CMD_SNIFF_SUBRATING,
- 17, 0x10, -1 },
- { HCI_CMD_READ_SIMPLE_PAIRING_MODE,
- 17, 0x20, 0 },
- { HCI_CMD_WRITE_SIMPLE_PAIRING_MODE,
- 17, 0x40, -1 },
- { HCI_CMD_READ_LOCAL_OOB_DATA,
- 17, 0x80, -1 },
- { HCI_CMD_READ_INQUIRY_RSP_XMIT_POWER,
- 18, 0x01, 0 },
- { HCI_CMD_WRITE_INQUIRY_RSP_XMIT_POWER,
- 18, 0x02, -1 },
- { HCI_CMD_READ_DEFAULT_ERRDATA_REPORTING,
- 18, 0x04, 0 },
- { HCI_CMD_WRITE_DEFAULT_ERRDATA_REPORTING,
- 18, 0x08, -1 },
- { HCI_CMD_IO_CAPABILITY_REP,
- 18, 0x80, -1 },
- { HCI_CMD_USER_CONFIRM_REP,
- 19, 0x01, -1 },
- { HCI_CMD_USER_CONFIRM_NEG_REP,
- 19, 0x02, -1 },
- { HCI_CMD_USER_PASSKEY_REP,
- 19, 0x04, -1 },
- { HCI_CMD_USER_PASSKEY_NEG_REP,
- 19, 0x08, -1 },
- { HCI_CMD_OOB_DATA_REP,
- 19, 0x10, -1 },
- { HCI_CMD_WRITE_SIMPLE_PAIRING_DEBUG_MODE,
- 19, 0x20, -1 },
- { HCI_CMD_ENHANCED_FLUSH,
- 19, 0x40, -1 },
- { HCI_CMD_OOB_DATA_NEG_REP,
- 19, 0x80, -1 },
- { HCI_CMD_SEND_KEYPRESS_NOTIFICATION,
- 20, 0x40, -1 },
- { HCI_CMD_IO_CAPABILITY_NEG_REP,
- 20, 0x80, -1 },
-};
-
-/*
- * Security filter routines for unprivileged users.
- * Allow all but a few critical events, and only permit read commands.
- * If a unit is given, verify the command is supported.
- */
-
-static int
-hci_security_check_opcode(struct hci_unit *unit, uint16_t opcode)
-{
- int i;
-
- for (i = 0 ; i < sizeof(hci_cmds) / sizeof(hci_cmds[0]); i++) {
- if (opcode != hci_cmds[i].opcode)
- continue;
-
- if (unit == NULL
- || (unit->hci_cmds[hci_cmds[i].offs] & hci_cmds[i].mask))
- return hci_cmds[i].length;
-
- break;
- }
-
- return -1;
-}
-
-static int
-hci_security_check_event(uint8_t event)
-{
-
- switch (event) {
- case HCI_EVENT_RETURN_LINK_KEYS:
- case HCI_EVENT_LINK_KEY_NOTIFICATION:
- case HCI_EVENT_USER_CONFIRM_REQ:
- case HCI_EVENT_USER_PASSKEY_NOTIFICATION:
- case HCI_EVENT_VENDOR:
- return -1; /* disallowed */
- }
-
- return 0; /* ok */
-}
-
-/*
- * When command packet reaches the device, we can drop
- * it from the socket buffer (called from hci_output_acl)
- */
-void
-hci_drop(void *arg)
-{
- struct socket *so = arg;
-
- sbdroprecord(&so->so_snd);
- sowwakeup(so);
-}
-
-/*
- * HCI socket is going away and has some pending packets. We let them
- * go by design, but remove the context pointer as it will be invalid
- * and we no longer need to be notified.
- */
-static void
-hci_cmdwait_flush(struct socket *so)
-{
- struct hci_unit *unit;
- struct socket *ctx;
- struct mbuf *m;
-
- DPRINTF("flushing %p\n", so);
-
- TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
- IF_POLL(&unit->hci_cmdwait, m);
- while (m != NULL) {
- ctx = M_GETCTX(m, struct socket *);
- if (ctx == so)
- M_SETCTX(m, NULL);
-
- m = m->m_nextpkt;
- }
- }
-}
-
-/*
- * HCI send packet
- * This came from userland, so check it out.
- */
-static int
-hci_send(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr)
-{
- struct hci_unit *unit;
- struct mbuf *m0;
- hci_cmd_hdr_t hdr;
- int err;
-
- KASSERT(m != NULL);
- KASSERT(addr != NULL);
-
- /* wants at least a header to start with */
- if (m->m_pkthdr.len < sizeof(hdr)) {
- err = EMSGSIZE;
- goto bad;
- }
- m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr);
- hdr.opcode = letoh16(hdr.opcode);
-
- /* only allows CMD packets to be sent */
- if (hdr.type != HCI_CMD_PKT) {
- err = EINVAL;
- goto bad;
- }
-
- /* validates packet length */
- if (m->m_pkthdr.len != sizeof(hdr) + hdr.length) {
- err = EMSGSIZE;
- goto bad;
- }
-
- /* finds destination */
- unit = hci_unit_lookup(addr);
- if (unit == NULL) {
- err = ENETDOWN;
- goto bad;
- }
-
- /* security checks for unprivileged users */
- if ((pcb->hp_flags & HCI_PRIVILEGED) == 0
- && hci_security_check_opcode(unit, hdr.opcode) != hdr.length) {
- err = EPERM;
- goto bad;
- }
-
- /* makes a copy for precious to keep */
- m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
- if (m0 == NULL) {
- err = ENOMEM;
- goto bad;
- }
- sbappendrecord(&pcb->hp_socket->so_snd, m0);
- M_SETCTX(m, pcb->hp_socket); /* enable drop callback */
-
- DPRINTFN(2, "(%s) opcode (%03x|%04x)\n", device_xname(unit->hci_dev),
- HCI_OGF(hdr.opcode), HCI_OCF(hdr.opcode));
-
- /* Sendss it */
- if (unit->hci_num_cmd_pkts == 0)
- IF_ENQUEUE(&unit->hci_cmdwait, m);
- else
- hci_output_cmd(unit, m);
-
- return 0;
-
-bad:
- DPRINTF("packet (%d bytes) not sent (error %d)\n",
- m->m_pkthdr.len, err);
- if (m) m_freem(m);
- return err;
-}
-
-/*
- * User Request.
- * up is socket
- * m is either
- * optional mbuf chain containing message
- * ioctl command (PRU_CONTROL)
- * nam is either
- * optional mbuf chain containing an address
- * ioctl data (PRU_CONTROL)
- * optionally, protocol number (PRU_ATTACH)
- * ctl is optional mbuf chain containing socket options
- * l is pointer to process requesting action (if any)
- *
- * we are responsible for disposing of m and ctl if
- * they are mbuf chains
- */
-int
-hci_usrreq(struct socket *up, int req, struct mbuf *m,
- struct mbuf *nam, struct mbuf *ctl, struct proc *p)
-{
- struct hci_pcb *pcb = (struct hci_pcb *)up->so_pcb;
- struct sockaddr_bt *sa;
- int err = 0;
-
-#ifdef notyet /* XXX */
- DPRINTFN(2, "%s\n", prurequests[req]);
-#endif
-
- switch(req) {
- case PRU_CONTROL:
- mutex_enter(&bt_lock);
- err = hci_ioctl((unsigned long)m, (void *)nam, curproc);
- mutex_exit(&bt_lock);
- return err;
-
- case PRU_ATTACH:
- /* XXX solock() and bt_lock fiddling in NetBSD */
- if (pcb)
- return EINVAL;
- err = soreserve(up, hci_sendspace, hci_recvspace);
- if (err)
- return err;
-
- pcb = malloc(sizeof *pcb, M_PCB, M_NOWAIT | M_ZERO);
- if (pcb == NULL)
- return ENOMEM;
-
- up->so_pcb = pcb;
- pcb->hp_socket = up;
-
- if (curproc == NULL || suser(curproc, 0) == 0)
- pcb->hp_flags |= HCI_PRIVILEGED;
-
- /*
- * Set default user filter. By default, socket only passes
- * Command_Complete and Command_Status Events.
- */
- hci_filter_set(HCI_EVENT_COMMAND_COMPL, &pcb->hp_efilter);
- hci_filter_set(HCI_EVENT_COMMAND_STATUS, &pcb->hp_efilter);
- hci_filter_set(HCI_EVENT_PKT, &pcb->hp_pfilter);
-
- LIST_INSERT_HEAD(&hci_pcb, pcb, hp_next);
-
- return 0;
- }
-
- /* anything after here *requires* a pcb */
- if (pcb == NULL) {
- err = EINVAL;
- goto release;
- }
-
- switch(req) {
- case PRU_DISCONNECT:
- bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY);
-
- /* XXX we cannot call soisdisconnected() here, as it sets
- * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being,
- * that soisconnected() does not clear these and if you
- * try to reconnect this socket (which is permitted) you
- * get a broken pipe when you try to write any data.
- */
- up->so_state &= ~SS_ISCONNECTED;
- break;
-
- case PRU_ABORT:
- soisdisconnected(up);
- /* fall through to */
- case PRU_DETACH:
- if (up->so_snd.sb_mb != NULL)
- hci_cmdwait_flush(up);
-
- up->so_pcb = NULL;
- LIST_REMOVE(pcb, hp_next);
- free(pcb, M_PCB);
- return 0;
-
- case PRU_BIND:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- bdaddr_copy(&pcb->hp_laddr, &sa->bt_bdaddr);
-
- if (bdaddr_any(&sa->bt_bdaddr))
- pcb->hp_flags |= HCI_PROMISCUOUS;
- else
- pcb->hp_flags &= ~HCI_PROMISCUOUS;
-
- return 0;
-
- case PRU_CONNECT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- if (hci_unit_lookup(&sa->bt_bdaddr) == NULL)
- return EADDRNOTAVAIL;
-
- bdaddr_copy(&pcb->hp_raddr, &sa->bt_bdaddr);
- soisconnected(up);
- return 0;
-
- case PRU_PEERADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- memset(sa, 0, sizeof(struct sockaddr_bt));
- nam->m_len =
- sa->bt_len = sizeof(struct sockaddr_bt);
- sa->bt_family = AF_BLUETOOTH;
- bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_raddr);
- return 0;
-
- case PRU_SOCKADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- memset(sa, 0, sizeof(struct sockaddr_bt));
- nam->m_len =
- sa->bt_len = sizeof(struct sockaddr_bt);
- sa->bt_family = AF_BLUETOOTH;
- bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_laddr);
- return 0;
-
- case PRU_SHUTDOWN:
- socantsendmore(up);
- break;
-
- case PRU_SEND:
- sa = NULL;
- if (nam) {
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt)) {
- err = EINVAL;
- goto release;
- }
-
- if (sa->bt_family != AF_BLUETOOTH) {
- err = EAFNOSUPPORT;
- goto release;
- }
- }
-
- if (ctl) /* have no use for this */
- m_freem(ctl);
-
- return hci_send(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr));
-
- case PRU_SENSE:
- return 0; /* (no sense - Doh!) */
-
- case PRU_RCVD:
- case PRU_RCVOOB:
- return EOPNOTSUPP; /* (no release) */
-
- case PRU_ACCEPT:
- case PRU_CONNECT2:
- case PRU_LISTEN:
- case PRU_SENDOOB:
- case PRU_FASTTIMO:
- case PRU_SLOWTIMO:
- case PRU_PROTORCV:
- case PRU_PROTOSEND:
- err = EOPNOTSUPP;
- break;
-
- default:
- UNKNOWN(req);
- err = EOPNOTSUPP;
- break;
- }
-
-release:
- if (m)
- m_freem(m);
- if (ctl)
- m_freem(ctl);
- return err;
-}
-
-/*
- * get/set socket options
- */
-int
-hci_ctloutput(int req, struct socket *so, int level,
- int optname, struct mbuf **opt)
-{
- struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb;
- struct mbuf *m;
- int err = 0;
-
-#ifdef notyet /* XXX */
- DPRINTFN(2, "req %s\n", prcorequests[req]);
-#endif
-
- if (pcb == NULL)
- return EINVAL;
-
- if (level != BTPROTO_HCI) {
- err = EINVAL;
- if (req == PRCO_SETOPT && *opt)
- m_free(*opt);
- } else switch(req) {
- case PRCO_GETOPT:
- m = m_get(M_WAIT, MT_SOOPTS);
- switch (optname) {
- case SO_HCI_EVT_FILTER:
- m->m_len = sizeof(struct hci_filter);
- memcpy(mtod(m, void *), &pcb->hp_efilter, m->m_len);
- break;
-
- case SO_HCI_PKT_FILTER:
- m->m_len = sizeof(struct hci_filter);
- memcpy(mtod(m, void *), &pcb->hp_pfilter, m->m_len);
- break;
-
- case SO_HCI_DIRECTION:
- m->m_len = sizeof(int);
- if (pcb->hp_flags & HCI_DIRECTION)
- *mtod(m, int *) = 1;
- else
- *mtod(m, int *) = 0;
- break;
-
- default:
- err = ENOPROTOOPT;
- m_freem(m);
- m = NULL;
- break;
- }
- *opt = m;
- break;
-
- case PRCO_SETOPT:
- m = *opt;
- if (m) switch (optname) {
- case SO_HCI_EVT_FILTER: /* set event filter */
- if (m == NULL || m->m_len > sizeof(struct hci_filter))
- err = EINVAL;
- else {
- memcpy(&pcb->hp_efilter, mtod(m, void *),
- m->m_len);
- memset((char *)&pcb->hp_efilter + m->m_len,
- 0, sizeof(struct hci_filter) - m->m_len);
- }
- break;
-
- case SO_HCI_PKT_FILTER: /* set packet filter */
- if (m == NULL || m->m_len > sizeof(struct hci_filter))
- err = EINVAL;
- else {
- memcpy(&pcb->hp_pfilter, mtod(m, void *),
- m->m_len);
- memset((char *)&pcb->hp_pfilter + m->m_len,
- 0, sizeof(struct hci_filter) - m->m_len);
- }
- break;
-
- case SO_HCI_DIRECTION: /* request direction ctl messages */
- if (m == NULL || m->m_len != sizeof(int))
- err = EINVAL;
- else {
- if (*mtod(m, int *))
- pcb->hp_flags |= HCI_DIRECTION;
- else
- pcb->hp_flags &= ~HCI_DIRECTION;
- }
- break;
-
- default:
- err = ENOPROTOOPT;
- break;
- }
- m_freem(m);
- break;
-
- default:
- err = ENOPROTOOPT;
- break;
- }
-
- return err;
-}
-
-/*
- * HCI mbuf tap routine
- *
- * copy packets to any raw HCI sockets that wish (and are
- * permitted) to see them
- */
-void
-hci_mtap(struct mbuf *m, struct hci_unit *unit)
-{
- struct hci_pcb *pcb;
- struct mbuf *m0, *ctlmsg, **ctl;
- struct sockaddr_bt sa;
- uint8_t type;
- uint8_t event;
- uint16_t opcode;
-
- KASSERT(m->m_len >= sizeof(type));
-
- type = *mtod(m, uint8_t *);
-
- memset(&sa, 0, sizeof(sa));
- sa.bt_len = sizeof(struct sockaddr_bt);
- sa.bt_family = AF_BLUETOOTH;
- bdaddr_copy(&sa.bt_bdaddr, &unit->hci_bdaddr);
-
- LIST_FOREACH(pcb, &hci_pcb, hp_next) {
- /*
- * filter according to source address
- */
- if ((pcb->hp_flags & HCI_PROMISCUOUS) == 0
- && bdaddr_same(&pcb->hp_laddr, &sa.bt_bdaddr) == 0)
- continue;
-
- /*
- * filter according to packet type filter
- */
- if (hci_filter_test(type, &pcb->hp_pfilter) == 0)
- continue;
-
- /*
- * filter according to event/security filters
- */
- switch(type) {
- case HCI_EVENT_PKT:
- KASSERT(m->m_len >= sizeof(hci_event_hdr_t));
-
- event = mtod(m, hci_event_hdr_t *)->event;
-
- if (hci_filter_test(event, &pcb->hp_efilter) == 0)
- continue;
-
- if ((pcb->hp_flags & HCI_PRIVILEGED) == 0
- && hci_security_check_event(event) == -1)
- continue;
- break;
-
- case HCI_CMD_PKT:
- KASSERT(m->m_len >= sizeof(hci_cmd_hdr_t));
-
- opcode = letoh16(mtod(m, hci_cmd_hdr_t *)->opcode);
-
- if ((pcb->hp_flags & HCI_PRIVILEGED) == 0
- && hci_security_check_opcode(NULL, opcode) == -1)
- continue;
- break;
-
- case HCI_ACL_DATA_PKT:
- case HCI_SCO_DATA_PKT:
- default:
- if ((pcb->hp_flags & HCI_PRIVILEGED) == 0)
- continue;
-
- break;
- }
-
- /*
- * create control messages
- */
- ctlmsg = NULL;
- ctl = &ctlmsg;
- if (pcb->hp_flags & HCI_DIRECTION) {
- int dir = m->m_flags & M_LINK0 ? 1 : 0;
-
- *ctl = sbcreatecontrol((void *)&dir, sizeof(dir),
- SCM_HCI_DIRECTION, BTPROTO_HCI);
-
- if (*ctl != NULL)
- ctl = &((*ctl)->m_next);
- }
-
- /*
- * copy to socket
- */
- m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
- if (m0 && sbappendaddr(&pcb->hp_socket->so_rcv,
- (struct sockaddr *)&sa, m0, ctlmsg)) {
- sorwakeup(pcb->hp_socket);
- } else {
- m_freem(ctlmsg);
- m_freem(m0);
- }
- }
-}
diff --git a/sys/netbt/hci_unit.c b/sys/netbt/hci_unit.c
deleted file mode 100644
index 8a08dfcc2e5..00000000000
--- a/sys/netbt/hci_unit.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/* $OpenBSD: hci_unit.c,v 1.12 2011/07/06 02:42:28 henning Exp $ */
-/* $NetBSD: hci_unit.c,v 1.12 2008/06/26 14:17:27 plunky Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/device.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/systm.h>
-
-#include <net/netisr.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-
-struct hci_unit_list hci_unit_list = TAILQ_HEAD_INITIALIZER(hci_unit_list);
-
-/*
- * HCI Input Queue max lengths.
- */
-int hci_eventq_max = 20;
-int hci_aclrxq_max = 50;
-int hci_scorxq_max = 50;
-int hci_cmdwait_max = 50;
-int hci_scodone_max = 50;
-
-/*
- * This is the default minimum command set supported by older
- * devices. Anything conforming to 1.2 spec or later will get
- * updated during init.
- */
-static const uint8_t hci_cmds_v10[HCI_COMMANDS_SIZE] = {
- 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0x7f, 0x32, 0x03, 0xb8, 0xfe,
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/*
- * bluetooth unit functions
- */
-
-struct hci_unit *
-hci_attach(const struct hci_if *hci_if, struct device *dev, uint16_t flags)
-{
- struct hci_unit *unit;
-
- KASSERT(dev != NULL);
- KASSERT(hci_if->enable != NULL);
- KASSERT(hci_if->disable != NULL);
- KASSERT(hci_if->output_cmd != NULL);
- KASSERT(hci_if->output_acl != NULL);
- KASSERT(hci_if->output_sco != NULL);
- KASSERT(hci_if->get_stats != NULL);
-
- unit = malloc(sizeof(struct hci_unit), M_BLUETOOTH, M_ZERO | M_WAITOK);
- KASSERT(unit != NULL);
-
- unit->hci_dev = dev;
- unit->hci_if = hci_if;
- unit->hci_flags = flags;
-
- mtx_init(&unit->hci_devlock, hci_if->ipl);
- unit->hci_init = 0; /* kcondvar_t in NetBSD */
-
- IFQ_SET_MAXLEN(&unit->hci_eventq, hci_eventq_max);
- IFQ_SET_MAXLEN(&unit->hci_aclrxq, hci_aclrxq_max);
- IFQ_SET_MAXLEN(&unit->hci_scorxq, hci_scorxq_max);
- IFQ_SET_MAXLEN(&unit->hci_cmdwait, hci_cmdwait_max);
- IFQ_SET_MAXLEN(&unit->hci_scodone, hci_scodone_max);
-
- TAILQ_INIT(&unit->hci_links);
- LIST_INIT(&unit->hci_memos);
-
- mutex_enter(&bt_lock);
- TAILQ_INSERT_TAIL(&hci_unit_list, unit, hci_next);
- mutex_exit(&bt_lock);
-
- return unit;
-}
-
-void
-hci_detach(struct hci_unit *unit)
-{
-
- mutex_enter(&bt_lock);
- hci_disable(unit);
-
- TAILQ_REMOVE(&hci_unit_list, unit, hci_next);
- mutex_exit(&bt_lock);
-
- /* mutex_destroy(&unit->hci_devlock) in NetBSD */
- free(unit, M_BLUETOOTH);
-}
-
-int
-hci_enable(struct hci_unit *unit)
-{
- int err;
-
- /*
- * Block further attempts to enable the interface until the
- * previous attempt has completed.
- */
- if (unit->hci_flags & BTF_INIT)
- return EBUSY;
-
- /*
- * Bluetooth spec says that a device can accept one
- * command on power up until they send a Command Status
- * or Command Complete event with more information, but
- * it seems that some devices cant and prefer to send a
- * No-op Command Status packet when they are ready.
- */
- unit->hci_num_cmd_pkts = (unit->hci_flags & BTF_POWER_UP_NOOP) ? 0 : 1;
- unit->hci_num_acl_pkts = 0;
- unit->hci_num_sco_pkts = 0;
-
- /*
- * only allow the basic packet types until
- * the features report is in
- */
- unit->hci_acl_mask = HCI_PKT_DM1 | HCI_PKT_DH1;
- unit->hci_packet_type = unit->hci_acl_mask;
-
- memcpy(unit->hci_cmds, hci_cmds_v10, HCI_COMMANDS_SIZE);
-
-#ifndef __OpenBSD__
- unit->hci_rxint = softint_establish(SOFTINT_NET, &hci_intr, unit);
- if (unit->hci_rxint == NULL)
- return EIO;
-#endif
-
- err = (*unit->hci_if->enable)(unit->hci_dev);
- if (err)
- goto bad1;
-
- unit->hci_flags |= BTF_RUNNING;
-
- /*
- * Reset the device, this will trigger initialisation
- * and wake us up.
- */
- unit->hci_flags |= BTF_INIT;
-
- err = hci_send_cmd(unit, HCI_CMD_RESET, NULL, 0);
- if (err)
- goto bad2;
-
- while (unit->hci_flags & BTF_INIT) {
- err = msleep(&unit->hci_init, &bt_lock, PWAIT | PCATCH,
- __func__, 5 * hz);
- if (err)
- goto bad2;
-
- /* XXX
- * "What If", while we were sleeping, the device
- * was removed and detached? Ho Hum.
- */
- }
-
- /*
- * Attach Bluetooth Device Hub
- */
- unit->hci_bthub = config_found(unit->hci_dev,
- &unit->hci_bdaddr, NULL);
-
- return 0;
-
-bad2:
- (*unit->hci_if->disable)(unit->hci_dev);
- unit->hci_flags &= ~BTF_RUNNING;
-bad1:
-#ifndef __OpenBSD__
- softint_disestablish(unit->hci_rxint);
- unit->hci_rxint = NULL;
-#endif
-
- return err;
-}
-
-void
-hci_disable(struct hci_unit *unit)
-{
- struct hci_link *link, *next;
- struct hci_memo *memo;
- int acl;
-
- if (unit->hci_bthub) {
- struct device *hub;
-
- hub = unit->hci_bthub;
- unit->hci_bthub = NULL;
-
- mutex_exit(&bt_lock);
- config_detach(hub, DETACH_FORCE);
- mutex_enter(&bt_lock);
- }
-
-#ifndef __OpenBSD__
- if (unit->hci_rxint) {
- softint_disestablish(unit->hci_rxint);
- unit->hci_rxint = NULL;
- }
-#endif
-
- (*unit->hci_if->disable)(unit->hci_dev);
- unit->hci_flags &= ~BTF_RUNNING;
-
- /*
- * close down any links, take care to close SCO first since
- * they may depend on ACL links.
- */
- for (acl = 0 ; acl < 2 ; acl++) {
- next = TAILQ_FIRST(&unit->hci_links);
- while ((link = next) != NULL) {
- next = TAILQ_NEXT(link, hl_next);
- if (acl || link->hl_type != HCI_LINK_ACL)
- hci_link_free(link, ECONNABORTED);
- }
- }
-
- while ((memo = LIST_FIRST(&unit->hci_memos)) != NULL)
- hci_memo_free(memo);
-
- /* (no need to hold hci_devlock, the driver is disabled) */
-
- IF_PURGE(&unit->hci_eventq);
- unit->hci_eventqlen = 0;
-
- IF_PURGE(&unit->hci_aclrxq);
- unit->hci_aclrxqlen = 0;
-
- IF_PURGE(&unit->hci_scorxq);
- unit->hci_scorxqlen = 0;
-
- IF_PURGE(&unit->hci_cmdwait);
- IF_PURGE(&unit->hci_scodone);
-}
-
-struct hci_unit *
-hci_unit_lookup(bdaddr_t *addr)
-{
- struct hci_unit *unit;
-
- TAILQ_FOREACH(unit, &hci_unit_list, hci_next) {
- if ((unit->hci_flags & BTF_UP) == 0)
- continue;
-
- if (bdaddr_same(&unit->hci_bdaddr, addr))
- break;
- }
-
- return unit;
-}
-
-/*
- * construct and queue a HCI command packet
- */
-int
-hci_send_cmd(struct hci_unit *unit, uint16_t opcode, void *buf, uint8_t len)
-{
- struct mbuf *m;
- hci_cmd_hdr_t *p;
-
- KASSERT(unit != NULL);
-
- m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return ENOMEM;
-
- p = mtod(m, hci_cmd_hdr_t *);
- p->type = HCI_CMD_PKT;
- p->opcode = htole16(opcode);
- p->length = len;
- m->m_pkthdr.len = m->m_len = sizeof(hci_cmd_hdr_t);
- M_SETCTX(m, NULL); /* XXX is this needed? */
-
- if (len) {
- KASSERT(buf != NULL);
-
- m_copyback(m, sizeof(hci_cmd_hdr_t), len, buf, M_NOWAIT);
- if (m->m_pkthdr.len != (sizeof(hci_cmd_hdr_t) + len)) {
- m_freem(m);
- return ENOMEM;
- }
- }
-
- DPRINTFN(2, "(%s) opcode (%3.3x|%4.4x)\n", device_xname(unit->hci_dev),
- HCI_OGF(opcode), HCI_OCF(opcode));
-
- /* and send it on */
- if (unit->hci_num_cmd_pkts == 0)
- IF_ENQUEUE(&unit->hci_cmdwait, m);
- else
- hci_output_cmd(unit, m);
-
- return 0;
-}
-
-/*
- * Incoming packet processing. Since the code is single threaded
- * in any case (IPL_SOFTNET), we handle it all in one interrupt function
- * picking our way through more important packets first so that hopefully
- * we will never get clogged up with bulk data.
- */
-void
-hci_intr(void *arg)
-{
- struct hci_unit *unit = arg;
- struct mbuf *m;
-
- mutex_enter(&bt_lock);
-another:
- mutex_enter(&unit->hci_devlock);
-
- if (unit->hci_eventqlen > 0) {
- IF_DEQUEUE(&unit->hci_eventq, m);
- unit->hci_eventqlen--;
- mutex_exit(&unit->hci_devlock);
-
- KASSERT(m != NULL);
-
- DPRINTFN(10, "(%s) recv event, len = %d\n",
- device_xname(unit->hci_dev), m->m_pkthdr.len);
-
- m->m_flags |= M_LINK0; /* mark incoming packet */
- hci_mtap(m, unit);
- hci_event(m, unit);
-
- goto another;
- }
-
- if (unit->hci_scorxqlen > 0) {
- IF_DEQUEUE(&unit->hci_scorxq, m);
- unit->hci_scorxqlen--;
- mutex_exit(&unit->hci_devlock);
-
- KASSERT(m != NULL);
-
- DPRINTFN(10, "(%s) recv SCO, len = %d\n",
- device_xname(unit->hci_dev), m->m_pkthdr.len);
-
- m->m_flags |= M_LINK0; /* mark incoming packet */
- hci_mtap(m, unit);
- hci_sco_recv(m, unit);
-
- goto another;
- }
-
- if (unit->hci_aclrxqlen > 0) {
- IF_DEQUEUE(&unit->hci_aclrxq, m);
- unit->hci_aclrxqlen--;
- mutex_exit(&unit->hci_devlock);
-
- KASSERT(m != NULL);
-
- DPRINTFN(10, "(%s) recv ACL, len = %d\n",
- device_xname(unit->hci_dev), m->m_pkthdr.len);
-
- m->m_flags |= M_LINK0; /* mark incoming packet */
- hci_mtap(m, unit);
- hci_acl_recv(m, unit);
-
- goto another;
- }
-
- IF_DEQUEUE(&unit->hci_scodone, m);
- if (m != NULL) {
- struct hci_link *link;
-
- mutex_exit(&unit->hci_devlock);
-
- DPRINTFN(11, "(%s) complete SCO\n",
- device_xname(unit->hci_dev));
-
- TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
- if (link == M_GETCTX(m, struct hci_link *)) {
- hci_sco_complete(link, 1);
- break;
- }
- }
-
- unit->hci_num_sco_pkts++;
- m_freem(m);
-
- goto another;
- }
-
- mutex_exit(&unit->hci_devlock);
- mutex_exit(&bt_lock);
-
- DPRINTFN(10, "done\n");
-}
-
-/**********************************************************************
- *
- * IO routines
- *
- * input & complete routines will be called from device drivers,
- * possibly in interrupt context. We return success or failure to
- * enable proper accounting but we own the mbuf.
- */
-
-int
-hci_input_event(struct hci_unit *unit, struct mbuf *m)
-{
- int rv;
-
- mutex_enter(&unit->hci_devlock);
-
- if (unit->hci_eventqlen > hci_eventq_max) {
- DPRINTF("(%s) dropped event packet.\n", device_xname(unit->hci_dev));
- m_freem(m);
- rv = 0;
- } else {
- unit->hci_eventqlen++;
- IF_ENQUEUE(&unit->hci_eventq, m);
- schednetisr(NETISR_BT);
- rv = 1;
- }
-
- mutex_exit(&unit->hci_devlock);
- return rv;
-}
-
-int
-hci_input_acl(struct hci_unit *unit, struct mbuf *m)
-{
- int rv;
-
- mutex_enter(&unit->hci_devlock);
-
- if (unit->hci_aclrxqlen > hci_aclrxq_max) {
- DPRINTF("(%s) dropped ACL packet.\n", device_xname(unit->hci_dev));
- m_freem(m);
- rv = 0;
- } else {
- unit->hci_aclrxqlen++;
- IF_ENQUEUE(&unit->hci_aclrxq, m);
- schednetisr(NETISR_BT);
- rv = 1;
- }
-
- mutex_exit(&unit->hci_devlock);
- return rv;
-}
-
-int
-hci_input_sco(struct hci_unit *unit, struct mbuf *m)
-{
- int rv;
-
- mutex_enter(&unit->hci_devlock);
-
- if (unit->hci_scorxqlen > hci_scorxq_max) {
- DPRINTF("(%s) dropped SCO packet.\n", device_xname(unit->hci_dev));
- m_freem(m);
- rv = 0;
- } else {
- unit->hci_scorxqlen++;
- IF_ENQUEUE(&unit->hci_scorxq, m);
- schednetisr(NETISR_BT);
- rv = 1;
- }
-
- mutex_exit(&unit->hci_devlock);
- return rv;
-}
-
-void
-hci_output_cmd(struct hci_unit *unit, struct mbuf *m)
-{
- void *arg;
-
- hci_mtap(m, unit);
-
- DPRINTFN(10, "(%s) num_cmd_pkts=%d\n",
- device_xname(unit->hci_dev), unit->hci_num_cmd_pkts);
-
- unit->hci_num_cmd_pkts--;
-
- /*
- * If context is set, this was from a HCI raw socket
- * and a record needs to be dropped from the sockbuf.
- */
- arg = M_GETCTX(m, void *);
- if (arg != NULL)
- hci_drop(arg);
-
- (*unit->hci_if->output_cmd)(unit->hci_dev, m);
-}
-
-void
-hci_output_acl(struct hci_unit *unit, struct mbuf *m)
-{
-
- hci_mtap(m, unit);
-
- DPRINTFN(10, "(%s) num_acl_pkts=%d\n",
- device_xname(unit->hci_dev), unit->hci_num_acl_pkts);
-
- unit->hci_num_acl_pkts--;
- (*unit->hci_if->output_acl)(unit->hci_dev, m);
-}
-
-void
-hci_output_sco(struct hci_unit *unit, struct mbuf *m)
-{
-
- hci_mtap(m, unit);
-
- DPRINTFN(10, "(%s) num_sco_pkts=%d\n",
- device_xname(unit->hci_dev), unit->hci_num_sco_pkts);
-
- unit->hci_num_sco_pkts--;
- (*unit->hci_if->output_sco)(unit->hci_dev, m);
-}
-
-int
-hci_complete_sco(struct hci_unit *unit, struct mbuf *m)
-{
-
-#ifndef __OpenBSD__
- if (unit->hci_rxint == NULL) {
- DPRINTFN(10, "(%s) complete SCO!\n", device_xname(unit->hci_dev));
- m_freem(m);
- return 0;
- }
-#endif
-
- mutex_enter(&unit->hci_devlock);
-
- IF_ENQUEUE(&unit->hci_scodone, m);
- schednetisr(NETISR_BT);
-
- mutex_exit(&unit->hci_devlock);
- return 1;
-}
-
-/*
- * update num_cmd_pkts and push on pending commands queue
- */
-void
-hci_num_cmds(struct hci_unit *unit, uint8_t num)
-{
- struct mbuf *m;
-
- unit->hci_num_cmd_pkts = num;
-
- while (unit->hci_num_cmd_pkts > 0 && !IF_IS_EMPTY(&unit->hci_cmdwait)) {
- IF_DEQUEUE(&unit->hci_cmdwait, m);
- hci_output_cmd(unit, m);
- }
-}
diff --git a/sys/netbt/l2cap.h b/sys/netbt/l2cap.h
deleted file mode 100644
index 8a9b2d52104..00000000000
--- a/sys/netbt/l2cap.h
+++ /dev/null
@@ -1,490 +0,0 @@
-/* $OpenBSD: l2cap.h,v 1.8 2009/11/21 13:05:32 guenther Exp $ */
-/* $NetBSD: l2cap.h,v 1.8 2008/09/08 23:36:55 gmcgarry Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/*-
- * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: l2cap.h,v 1.8 2009/11/21 13:05:32 guenther Exp $
- * $FreeBSD: src/sys/netgraph/bluetooth/include/l2cap.h,v 1.4 2005/08/31 18:13:23 emax Exp $
- */
-
-/*
- * This file contains everything that application needs to know about
- * Link Layer Control and Adaptation Protocol (L2CAP). All information
- * was obtained from Bluetooth Specification Books (v1.1 and up)
- *
- * This file can be included by both kernel and userland applications.
- */
-
-#ifndef _NETBT_L2CAP_H_
-#define _NETBT_L2CAP_H_
-
-#include <sys/types.h>
-
-/**************************************************************************
- **************************************************************************
- ** Common defines and types (L2CAP)
- **************************************************************************
- **************************************************************************/
-
-/*
- * Channel IDs are assigned per machine. So the total number of channels that
- * a machine can have open at the same time is 0xffff - 0x0040 = 0xffbf (65471).
- * This number does not depend on number of HCI connections.
- */
-
-#define L2CAP_NULL_CID 0x0000 /* DO NOT USE THIS CID */
-#define L2CAP_SIGNAL_CID 0x0001 /* signaling channel ID */
-#define L2CAP_CLT_CID 0x0002 /* connectionless channel ID */
- /* 0x0003 - 0x003f Reserved */
-#define L2CAP_FIRST_CID 0x0040 /* dynamically alloc. (start) */
-#define L2CAP_LAST_CID 0xffff /* dynamically alloc. (end) */
-
-/* L2CAP MTU */
-#define L2CAP_MTU_MINIMUM 48
-#define L2CAP_MTU_DEFAULT 672
-#define L2CAP_MTU_MAXIMUM 0xffff
-
-/* L2CAP flush and link timeouts */
-#define L2CAP_FLUSH_TIMO_DEFAULT 0xffff /* always retransmit */
-#define L2CAP_LINK_TIMO_DEFAULT 0xffff
-
-/* L2CAP Command Reject reasons */
-#define L2CAP_REJ_NOT_UNDERSTOOD 0x0000
-#define L2CAP_REJ_MTU_EXCEEDED 0x0001
-#define L2CAP_REJ_INVALID_CID 0x0002
-/* 0x0003 - 0xffff - reserved for future use */
-
-/* Protocol/Service Multiplexor (PSM) values */
-#define L2CAP_PSM_ANY 0x0000 /* Any/Invalid PSM */
-#define L2CAP_PSM_SDP 0x0001 /* Service Discovery Protocol */
-#define L2CAP_PSM_RFCOMM 0x0003 /* RFCOMM protocol */
-#define L2CAP_PSM_TCP 0x0005 /* Telephony Control Protocol */
-#define L2CAP_PSM_TCS 0x0007 /* TCS cordless */
-#define L2CAP_PSM_BNEP 0x000f /* Bluetooth Network */
- /* Encapsulation Protocol*/
-#define L2CAP_PSM_HID_CNTL 0x0011 /* HID Control */
-#define L2CAP_PSM_HID_INTR 0x0013 /* HID Interrupt */
-#define L2CAP_PSM_ESDP 0x0015 /* Extended Service */
- /* Discovery Profile */
-#define L2CAP_PSM_AVCTP 0x0017 /* Audio/Visual Control */
- /* Transport Protocol */
-#define L2CAP_PSM_AVDTP 0x0019 /* Audio/Visual Distribution */
- /* Transport Protocol */
-/* 0x0019 - 0x1000 - reserved for future use */
-
-#define L2CAP_PSM_INVALID(psm) (((psm) & 0x0101) != 0x0001)
-
-/* L2CAP Connection response command result codes */
-#define L2CAP_SUCCESS 0x0000
-#define L2CAP_PENDING 0x0001
-#define L2CAP_PSM_NOT_SUPPORTED 0x0002
-#define L2CAP_SECURITY_BLOCK 0x0003
-#define L2CAP_NO_RESOURCES 0x0004
-#define L2CAP_TIMEOUT 0xeeee
-#define L2CAP_UNKNOWN 0xffff
-/* 0x0005 - 0xffff - reserved for future use */
-
-/* L2CAP Connection response status codes */
-#define L2CAP_NO_INFO 0x0000
-#define L2CAP_AUTH_PENDING 0x0001
-#define L2CAP_AUTZ_PENDING 0x0002
-/* 0x0003 - 0xffff - reserved for future use */
-
-/* L2CAP Configuration response result codes */
-#define L2CAP_UNACCEPTABLE_PARAMS 0x0001
-#define L2CAP_REJECT 0x0002
-#define L2CAP_UNKNOWN_OPTION 0x0003
-/* 0x0003 - 0xffff - reserved for future use */
-
-/* L2CAP Configuration options */
-#define L2CAP_OPT_CFLAG_BIT 0x0001
-#define L2CAP_OPT_CFLAG(flags) ((flags) & L2CAP_OPT_CFLAG_BIT)
-#define L2CAP_OPT_HINT_BIT 0x80
-#define L2CAP_OPT_HINT(type) ((type) & L2CAP_OPT_HINT_BIT)
-#define L2CAP_OPT_HINT_MASK 0x7f
-#define L2CAP_OPT_MTU 0x01
-#define L2CAP_OPT_MTU_SIZE sizeof(uint16_t)
-#define L2CAP_OPT_FLUSH_TIMO 0x02
-#define L2CAP_OPT_FLUSH_TIMO_SIZE sizeof(uint16_t)
-#define L2CAP_OPT_QOS 0x03
-#define L2CAP_OPT_QOS_SIZE sizeof(l2cap_qos_t)
-#define L2CAP_OPT_RFC 0x04
-#define L2CAP_OPT_RFC_SIZE sizeof(l2cap_rfc_t)
-/* 0x05 - 0xff - reserved for future use */
-
-/* L2CAP Information request type codes */
-#define L2CAP_CONNLESS_MTU 0x0001
-#define L2CAP_EXTENDED_FEATURES 0x0002
-/* 0x0003 - 0xffff - reserved for future use */
-
-/* L2CAP Information response codes */
-#define L2CAP_NOT_SUPPORTED 0x0001
-/* 0x0002 - 0xffff - reserved for future use */
-
-/* L2CAP Quality of Service option */
-typedef struct {
- uint8_t flags; /* reserved for future use */
- uint8_t service_type; /* service type */
- uint32_t token_rate; /* bytes per second */
- uint32_t token_bucket_size; /* bytes */
- uint32_t peak_bandwidth; /* bytes per second */
- uint32_t latency; /* microseconds */
- uint32_t delay_variation; /* microseconds */
-} __packed l2cap_qos_t;
-
-/* L2CAP QoS type */
-#define L2CAP_QOS_NO_TRAFFIC 0x00
-#define L2CAP_QOS_BEST_EFFORT 0x01 /* (default) */
-#define L2CAP_QOS_GUARANTEED 0x02
-/* 0x03 - 0xff - reserved for future use */
-
-/* L2CAP Retransmission & Flow Control option */
-typedef struct {
- uint8_t mode; /* RFC mode */
- uint8_t window_size; /* bytes */
- uint8_t max_transmit; /* max retransmissions */
- uint16_t retransmit_timo; /* milliseconds */
- uint16_t monitor_timo; /* milliseconds */
- uint16_t max_pdu_size; /* bytes */
-} __packed l2cap_rfc_t;
-
-/* L2CAP RFC mode */
-#define L2CAP_RFC_BASIC 0x00 /* (default) */
-#define L2CAP_RFC_RETRANSMIT 0x01
-#define L2CAP_RFC_FLOW 0x02
-/* 0x03 - 0xff - reserved for future use */
-
-/**************************************************************************
- **************************************************************************
- ** Link level defines, headers and types
- **************************************************************************
- **************************************************************************/
-
-/* L2CAP header */
-typedef struct {
- uint16_t length; /* payload size */
- uint16_t dcid; /* destination channel ID */
-} __packed l2cap_hdr_t;
-
-/* L2CAP ConnectionLess Traffic (dcid == L2CAP_CLT_CID) */
-typedef struct {
- uint16_t psm; /* Protocol/Service Multiplexor */
-} __packed l2cap_clt_hdr_t;
-
-#define L2CAP_CLT_MTU_MAXIMUM \
- (L2CAP_MTU_MAXIMUM - sizeof(l2cap_clt_hdr_t))
-
-/* L2CAP Command header (dcid == L2CAP_SIGNAL_CID) */
-typedef struct {
- uint8_t code; /* command OpCode */
- uint8_t ident; /* identifier to match request and response */
- uint16_t length; /* command parameters length */
-} __packed l2cap_cmd_hdr_t;
-
-/* L2CAP Command Reject */
-#define L2CAP_COMMAND_REJ 0x01
-typedef struct {
- uint16_t reason; /* reason to reject command */
- uint16_t data[2];/* optional data */
-} __packed l2cap_cmd_rej_cp;
-
-/* L2CAP Connection Request */
-#define L2CAP_CONNECT_REQ 0x02
-typedef struct {
- uint16_t psm; /* Protocol/Service Multiplexor (PSM) */
- uint16_t scid; /* source channel ID */
-} __packed l2cap_con_req_cp;
-
-/* L2CAP Connection Response */
-#define L2CAP_CONNECT_RSP 0x03
-typedef struct {
- uint16_t dcid; /* destination channel ID */
- uint16_t scid; /* source channel ID */
- uint16_t result; /* 0x00 - success */
- uint16_t status; /* more info if result != 0x00 */
-} __packed l2cap_con_rsp_cp;
-
-/* L2CAP Configuration Request */
-#define L2CAP_CONFIG_REQ 0x04
-typedef struct {
- uint16_t dcid; /* destination channel ID */
- uint16_t flags; /* flags */
-/* uint8_t options[] -- options */
-} __packed l2cap_cfg_req_cp;
-
-/* L2CAP Configuration Response */
-#define L2CAP_CONFIG_RSP 0x05
-typedef struct {
- uint16_t scid; /* source channel ID */
- uint16_t flags; /* flags */
- uint16_t result; /* 0x00 - success */
-/* uint8_t options[] -- options */
-} __packed l2cap_cfg_rsp_cp;
-
-/* L2CAP configuration option */
-typedef struct {
- uint8_t type;
- uint8_t length;
-/* uint8_t value[] -- option value (depends on type) */
-} __packed l2cap_cfg_opt_t;
-
-/* L2CAP configuration option value */
-typedef union {
- uint16_t mtu; /* L2CAP_OPT_MTU */
- uint16_t flush_timo; /* L2CAP_OPT_FLUSH_TIMO */
- l2cap_qos_t qos; /* L2CAP_OPT_QOS */
- l2cap_rfc_t rfc; /* L2CAP_OPT_RFC */
-} l2cap_cfg_opt_val_t;
-
-/* L2CAP Disconnect Request */
-#define L2CAP_DISCONNECT_REQ 0x06
-typedef struct {
- uint16_t dcid; /* destination channel ID */
- uint16_t scid; /* source channel ID */
-} __packed l2cap_discon_req_cp;
-
-/* L2CAP Disconnect Response */
-#define L2CAP_DISCONNECT_RSP 0x07
-typedef l2cap_discon_req_cp l2cap_discon_rsp_cp;
-
-/* L2CAP Echo Request */
-#define L2CAP_ECHO_REQ 0x08
-/* No command parameters, only optional data */
-
-/* L2CAP Echo Response */
-#define L2CAP_ECHO_RSP 0x09
-#define L2CAP_MAX_ECHO_SIZE \
- (L2CAP_MTU_MAXIMUM - sizeof(l2cap_cmd_hdr_t))
-/* No command parameters, only optional data */
-
-/* L2CAP Information Request */
-#define L2CAP_INFO_REQ 0x0a
-typedef struct {
- uint16_t type; /* requested information type */
-} __packed l2cap_info_req_cp;
-
-/* L2CAP Information Response */
-#define L2CAP_INFO_RSP 0x0b
-typedef struct {
- uint16_t type; /* requested information type */
- uint16_t result; /* 0x00 - success */
-/* uint8_t info[] -- info data (depends on type)
- *
- * L2CAP_CONNLESS_MTU - 2 bytes connectionless MTU
- */
-} __packed l2cap_info_rsp_cp;
-
-typedef union {
- /* L2CAP_CONNLESS_MTU */
- struct {
- uint16_t mtu;
- } __packed mtu;
-} l2cap_info_rsp_data_t;
-
-/**************************************************************************
- **************************************************************************
- ** L2CAP Socket Definitions
- **************************************************************************
- **************************************************************************/
-
-/* Socket options */
-#define SO_L2CAP_IMTU 1 /* incoming MTU */
-#define SO_L2CAP_OMTU 2 /* outgoing MTU */
-#define SO_L2CAP_IQOS 3 /* incoming QoS */
-#define SO_L2CAP_OQOS 4 /* outgoing QoS */
-#define SO_L2CAP_FLUSH 5 /* flush timeout */
-#define SO_L2CAP_LM 6 /* link mode */
-
-/* L2CAP link mode flags */
-#define L2CAP_LM_AUTH (1<<0) /* want authentication */
-#define L2CAP_LM_ENCRYPT (1<<1) /* want encryption */
-#define L2CAP_LM_SECURE (1<<2) /* want secured link */
-
-#ifdef _KERNEL
-
-#include <net/if.h> /* for struct ifqueue */
-
-LIST_HEAD(l2cap_channel_list, l2cap_channel);
-
-/* global variables */
-extern struct l2cap_channel_list l2cap_active_list;
-extern struct l2cap_channel_list l2cap_listen_list;
-extern struct pool l2cap_pdu_pool;
-extern struct pool l2cap_req_pool;
-extern const l2cap_qos_t l2cap_default_qos;
-
-/* sysctl variables */
-extern int l2cap_response_timeout;
-extern int l2cap_response_extended_timeout;
-extern int l2cap_sendspace, l2cap_recvspace;
-
-/*
- * L2CAP Channel
- */
-struct l2cap_channel {
- struct hci_link *lc_link; /* ACL connection (down) */
- uint16_t lc_state; /* channel state */
- uint16_t lc_flags; /* channel flags */
- uint8_t lc_ident; /* cached request id */
-
- uint16_t lc_lcid; /* local channel ID */
- struct sockaddr_bt lc_laddr; /* local address */
-
- uint16_t lc_rcid; /* remote channel ID */
- struct sockaddr_bt lc_raddr; /* remote address */
-
- int lc_mode; /* link mode */
- uint16_t lc_imtu; /* incoming mtu */
- uint16_t lc_omtu; /* outgoing mtu */
- uint16_t lc_flush; /* flush timeout */
- l2cap_qos_t lc_iqos; /* incoming QoS flow control */
- l2cap_qos_t lc_oqos; /* outgoing Qos flow control */
-
- uint8_t lc_pending; /* num of pending PDUs */
- struct ifqueue lc_txq; /* transmit queue */
-
- const struct btproto *lc_proto; /* upper layer callbacks */
- void *lc_upper; /* upper layer argument */
-
- LIST_ENTRY(l2cap_channel)lc_ncid; /* next channel (ascending CID) */
-};
-
-/* l2cap_channel state */
-#define L2CAP_CLOSED 0 /* closed */
-#define L2CAP_WAIT_SEND_CONNECT_REQ 1 /* waiting to send connect request */
-#define L2CAP_WAIT_RECV_CONNECT_RSP 2 /* waiting to recv connect response */
-#define L2CAP_WAIT_SEND_CONNECT_RSP 3 /* waiting to send connect response */
-#define L2CAP_WAIT_CONFIG 4 /* waiting for configuration */
-#define L2CAP_OPEN 5 /* user data transfer state */
-#define L2CAP_WAIT_DISCONNECT 6 /* have sent disconnect request */
-
-/* l2cap_channel flags */
-#define L2CAP_SHUTDOWN (1<<0) /* channel is closing */
-#define L2CAP_WAIT_CONFIG_REQ (1<<1) /* waiting for config request */
-#define L2CAP_WAIT_CONFIG_RSP (1<<2) /* waiting for config response */
-
-/*
- * L2CAP Request
- */
-struct l2cap_req {
- struct hci_link *lr_link; /* ACL connection */
- struct l2cap_channel *lr_chan; /* channel pointer */
- uint8_t lr_code; /* request code */
- uint8_t lr_id; /* request id */
- struct timeout lr_rtx; /* response timer */
- TAILQ_ENTRY(l2cap_req) lr_next; /* next request on link */
-};
-
-/*
- * L2CAP Protocol Data Unit
- */
-struct l2cap_pdu {
- struct l2cap_channel *lp_chan; /* PDU owner */
- struct ifqueue lp_data; /* PDU data */
- TAILQ_ENTRY(l2cap_pdu) lp_next; /* next PDU on link */
- int lp_pending; /* # of fragments pending */
-};
-
-/*
- * L2CAP function prototypes
- */
-
-struct socket;
-struct mbuf;
-
-/* l2cap_lower.c */
-void l2cap_close(struct l2cap_channel *, int);
-void l2cap_recv_frame(struct mbuf *, struct hci_link *);
-int l2cap_start(struct l2cap_channel *);
-
-/* l2cap_misc.c */
-void l2cap_init(void);
-int l2cap_setmode(struct l2cap_channel *);
-int l2cap_cid_alloc(struct l2cap_channel *);
-struct l2cap_channel *l2cap_cid_lookup(uint16_t);
-int l2cap_request_alloc(struct l2cap_channel *, uint8_t);
-struct l2cap_req *l2cap_request_lookup(struct hci_link *, uint8_t);
-void l2cap_request_free(struct l2cap_req *);
-void l2cap_rtx(void *);
-
-/* l2cap_signal.c */
-void l2cap_recv_signal(struct mbuf *, struct hci_link *);
-int l2cap_send_connect_req(struct l2cap_channel *);
-int l2cap_send_config_req(struct l2cap_channel *);
-int l2cap_send_disconnect_req(struct l2cap_channel *);
-int l2cap_send_connect_rsp(struct hci_link *, uint8_t, uint16_t, uint16_t, uint16_t);
-
-/* l2cap_socket.c */
-int l2cap_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
- struct mbuf *, struct proc *);
-int l2cap_ctloutput(int, struct socket *, int, int, struct mbuf **);
-
-/* l2cap_upper.c */
-int l2cap_attach(struct l2cap_channel **, const struct btproto *, void *);
-int l2cap_bind(struct l2cap_channel *, struct sockaddr_bt *);
-int l2cap_sockaddr(struct l2cap_channel *, struct sockaddr_bt *);
-int l2cap_connect(struct l2cap_channel *, struct sockaddr_bt *);
-int l2cap_peeraddr(struct l2cap_channel *, struct sockaddr_bt *);
-int l2cap_disconnect(struct l2cap_channel *, int);
-int l2cap_detach(struct l2cap_channel **);
-int l2cap_listen(struct l2cap_channel *);
-int l2cap_send(struct l2cap_channel *, struct mbuf *);
-int l2cap_setlinkmode(struct l2cap_channel *, int);
-int l2cap_setopt(struct l2cap_channel *, int, struct mbuf *);
-int l2cap_getopt(struct l2cap_channel *, int, void *);
-
-#endif /* _KERNEL */
-
-#endif /* _NETBT_L2CAP_H_ */
diff --git a/sys/netbt/l2cap_lower.c b/sys/netbt/l2cap_lower.c
deleted file mode 100644
index 24cdb467f57..00000000000
--- a/sys/netbt/l2cap_lower.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* $OpenBSD: l2cap_lower.c,v 1.3 2008/11/22 04:42:58 uwe Exp $ */
-/* $NetBSD: l2cap_lower.c,v 1.9 2008/08/05 13:08:31 plunky Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-
-/****************************************************************************
- *
- * L2CAP Channel Lower Layer interface
- */
-
-/*
- * L2CAP channel is disconnected, could be:
- *
- * HCI layer received "Disconnect Complete" event for ACL link
- * some Request timed out
- * Config failed
- * Other end reported invalid CID
- * Normal disconnection
- * Change link mode failed
- */
-void
-l2cap_close(struct l2cap_channel *chan, int err)
-{
- struct l2cap_pdu *pdu;
- struct l2cap_req *req, *n;
-
- if (chan->lc_state == L2CAP_CLOSED)
- return;
-
- /*
- * Since any potential PDU could be half sent we just let it go,
- * but disassociate ourselves from it as links deal with ownerless
- * PDU's in any case. We could try harder to flush unsent packets
- * but maybe its better to leave them in the queue?
- */
- TAILQ_FOREACH(pdu, &chan->lc_link->hl_txq, lp_next) {
- if (pdu->lp_chan == chan)
- pdu->lp_chan = NULL;
- }
-
- /*
- * and clear any outstanding requests..
- */
- req = TAILQ_FIRST(&chan->lc_link->hl_reqs);
- while (req != NULL) {
- n = TAILQ_NEXT(req, lr_next);
- if (req->lr_chan == chan)
- l2cap_request_free(req);
-
- req = n;
- }
-
- chan->lc_pending = 0;
- chan->lc_state = L2CAP_CLOSED;
- hci_acl_close(chan->lc_link, err);
- chan->lc_link = NULL;
-
- (*chan->lc_proto->disconnected)(chan->lc_upper, err);
-}
-
-/*
- * Process incoming L2CAP frame from ACL link. We take off the B-Frame
- * header (which is present in all packets), verify the data length
- * and distribute the rest of the frame to the relevant channel
- * handler.
- */
-void
-l2cap_recv_frame(struct mbuf *m, struct hci_link *link)
-{
- struct l2cap_channel *chan;
- l2cap_hdr_t hdr;
-
- m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr);
- m_adj(m, sizeof(hdr));
-
- hdr.length = letoh16(hdr.length);
- hdr.dcid = letoh16(hdr.dcid);
-
- DPRINTFN(5, "(%s) received packet (%d bytes)\n",
- device_xname(link->hl_unit->hci_dev), hdr.length);
-
- if (hdr.length != m->m_pkthdr.len)
- goto failed;
-
- if (hdr.dcid == L2CAP_SIGNAL_CID) {
- l2cap_recv_signal(m, link);
- return;
- }
-
- if (hdr.dcid == L2CAP_CLT_CID) {
- m_freem(m); /* TODO */
- return;
- }
-
- chan = l2cap_cid_lookup(hdr.dcid);
- if (chan != NULL && chan->lc_link == link
- && chan->lc_imtu >= hdr.length
- && chan->lc_state == L2CAP_OPEN) {
- (*chan->lc_proto->input)(chan->lc_upper, m);
- return;
- }
-
- DPRINTF("(%s) invalid L2CAP packet dropped, CID #%d, length %d\n",
- device_xname(link->hl_unit->hci_dev), hdr.dcid, hdr.length);
-
-failed:
- m_freem(m);
-}
-
-/*
- * Start another L2CAP packet on its way. This is called from l2cap_send
- * (when no PDU is pending) and hci_acl_start (when PDU has been placed on
- * device queue). Thus we can have more than one PDU waiting at the device
- * if space is available but no single channel will hog the link.
- */
-int
-l2cap_start(struct l2cap_channel *chan)
-{
- struct mbuf *m;
- int err = 0;
-
- if (chan->lc_state != L2CAP_OPEN)
- return 0;
-
- if (IF_IS_EMPTY(&chan->lc_txq)) {
- DPRINTFN(5, "no data, pending = %d\n", chan->lc_pending);
- /*
- * If we are just waiting for the queue to flush
- * and it has, we may disconnect..
- */
- if (chan->lc_flags & L2CAP_SHUTDOWN
- && chan->lc_pending == 0) {
- chan->lc_state = L2CAP_WAIT_DISCONNECT;
- err = l2cap_send_disconnect_req(chan);
- if (err)
- l2cap_close(chan, err);
- }
-
- return err;
- }
-
- /*
- * We could check QoS/RFC mode here and optionally not send
- * the packet if we are not ready for any reason
- *
- * Also to support flush timeout then we might want to start
- * the timer going? (would need to keep some kind of record
- * of packets sent, possibly change it so that we allocate
- * the l2cap_pdu and fragment the packet, then hand it down
- * and get it back when its completed). Hm.
- */
-
- IF_DEQUEUE(&chan->lc_txq, m);
-
- KASSERT(chan->lc_link != NULL);
- KASSERT(m != NULL);
-
- DPRINTFN(5, "CID #%d sending packet (%d bytes)\n",
- chan->lc_lcid, m->m_pkthdr.len);
-
- chan->lc_pending++;
- return hci_acl_send(m, chan->lc_link, chan);
-}
diff --git a/sys/netbt/l2cap_misc.c b/sys/netbt/l2cap_misc.c
deleted file mode 100644
index 650f34910c8..00000000000
--- a/sys/netbt/l2cap_misc.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/* $OpenBSD: l2cap_misc.c,v 1.8 2010/07/29 14:40:47 blambert Exp $ */
-/* $NetBSD: l2cap_misc.c,v 1.6 2008/04/24 11:38:37 ad Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/pool.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-
-struct l2cap_channel_list
- l2cap_active_list = LIST_HEAD_INITIALIZER(l2cap_active_list);
-struct l2cap_channel_list
- l2cap_listen_list = LIST_HEAD_INITIALIZER(l2cap_listen_list);
-
-struct pool l2cap_req_pool;
-struct pool l2cap_pdu_pool;
-
-const l2cap_qos_t l2cap_default_qos = {
- 0, /* flags */
- L2CAP_QOS_BEST_EFFORT, /* service type */
- 0x00000000, /* token rate */
- 0x00000000, /* token bucket size */
- 0x00000000, /* peak bandwidth */
- 0xffffffff, /* latency */
- 0xffffffff /* delay variation */
-};
-
-/*
- * L2CAP request timeouts
- */
-int l2cap_response_timeout = 30; /* seconds */
-int l2cap_response_extended_timeout = 180; /* seconds */
-
-void
-l2cap_init(void)
-{
- pool_init(&l2cap_req_pool, sizeof(struct l2cap_req), 0, 0, 0,
- "l2cap_req", NULL);
- pool_init(&l2cap_pdu_pool, sizeof(struct l2cap_pdu), 0, 0, 0,
- "l2cap_pdu", NULL);
-}
-
-/*
- * Set Link Mode on channel
- */
-int
-l2cap_setmode(struct l2cap_channel *chan)
-{
-
- KASSERT(chan != NULL);
- KASSERT(chan->lc_link != NULL);
-
- DPRINTF("(%s) CID #%d, auth %s, encrypt %s, secure %s\n",
- device_xname(chan->lc_link->hl_unit->hci_dev), chan->lc_lcid,
- (chan->lc_mode & L2CAP_LM_AUTH ? "yes" : "no"),
- (chan->lc_mode & L2CAP_LM_ENCRYPT ? "yes" : "no"),
- (chan->lc_mode & L2CAP_LM_SECURE ? "yes" : "no"));
-
- if (chan->lc_mode & L2CAP_LM_AUTH)
- chan->lc_link->hl_flags |= HCI_LINK_AUTH_REQ;
-
- if (chan->lc_mode & L2CAP_LM_ENCRYPT)
- chan->lc_link->hl_flags |= HCI_LINK_ENCRYPT_REQ;
-
- if (chan->lc_mode & L2CAP_LM_SECURE)
- chan->lc_link->hl_flags |= HCI_LINK_SECURE_REQ;
-
- return hci_acl_setmode(chan->lc_link);
-}
-
-/*
- * Allocate a new Request structure & ID and set the timer going
- */
-int
-l2cap_request_alloc(struct l2cap_channel *chan, uint8_t code)
-{
- struct hci_link *link = chan->lc_link;
- struct l2cap_req *req;
- int next_id;
-
- if (link == NULL)
- return ENETDOWN;
-
- /* find next ID (0 is not allowed) */
- next_id = link->hl_lastid + 1;
- if (next_id > 0xff)
- next_id = 1;
-
- /* Ouroboros check */
- req = TAILQ_FIRST(&link->hl_reqs);
- if (req && req->lr_id == next_id)
- return ENFILE;
-
- req = pool_get(&l2cap_req_pool, PR_NOWAIT);
- if (req == NULL)
- return ENOMEM;
-
- req->lr_id = link->hl_lastid = next_id;
-
- req->lr_code = code;
- req->lr_chan = chan;
- req->lr_link = link;
-
- timeout_set(&req->lr_rtx, l2cap_rtx, req);
- timeout_add_sec(&req->lr_rtx, l2cap_response_timeout);
-
- TAILQ_INSERT_TAIL(&link->hl_reqs, req, lr_next);
-
- return 0;
-}
-
-/*
- * Find a running request for this link
- */
-struct l2cap_req *
-l2cap_request_lookup(struct hci_link *link, uint8_t id)
-{
- struct l2cap_req *req;
-
- TAILQ_FOREACH(req, &link->hl_reqs, lr_next) {
- if (req->lr_id == id)
- return req;
- }
-
- return NULL;
-}
-
-/*
- * Halt and free a request
- */
-void
-l2cap_request_free(struct l2cap_req *req)
-{
- struct hci_link *link = req->lr_link;
-
- if (timeout_triggered(&req->lr_rtx))
- return;
- timeout_del(&req->lr_rtx);
-
- TAILQ_REMOVE(&link->hl_reqs, req, lr_next);
- pool_put(&l2cap_req_pool, req);
-}
-
-/*
- * Response Timeout eXpired
- *
- * No response to our request, so deal with it as best we can.
- *
- * XXX should try again at least with ertx?
- */
-void
-l2cap_rtx(void *arg)
-{
- struct l2cap_req *req = arg;
- struct l2cap_channel *chan;
-
- mutex_enter(&bt_lock);
-
- chan = req->lr_chan;
- DPRINTF("cid %d, ident %d\n", (chan ? chan->lc_lcid : 0), req->lr_id);
-
- l2cap_request_free(req);
-
- if (chan && chan->lc_state != L2CAP_CLOSED)
- l2cap_close(chan, ETIMEDOUT);
-
- mutex_exit(&bt_lock);
-}
-
-/*
- * Allocate next available CID to channel. We keep a single
- * ordered list of channels, so find the first gap.
- *
- * If this turns out to be not enough (!), could use a
- * list per HCI unit..
- */
-int
-l2cap_cid_alloc(struct l2cap_channel *chan)
-{
- struct l2cap_channel *used, *prev = NULL;
- uint16_t cid = L2CAP_FIRST_CID;
-
- if (chan->lc_lcid != L2CAP_NULL_CID || chan->lc_state != L2CAP_CLOSED)
- return EISCONN;
-
- LIST_FOREACH(used, &l2cap_active_list, lc_ncid) {
- if (used->lc_lcid > cid)
- break; /* found our gap */
-
- KASSERT(used->lc_lcid == cid);
- cid++;
-
- if (cid == L2CAP_LAST_CID)
- return ENFILE;
-
- prev = used; /* for insert after */
- }
-
- chan->lc_lcid = cid;
-
- if (prev)
- LIST_INSERT_AFTER(prev, chan, lc_ncid);
- else
- LIST_INSERT_HEAD(&l2cap_active_list, chan, lc_ncid);
-
- return 0;
-}
-
-/*
- * Find channel with CID
- */
-struct l2cap_channel *
-l2cap_cid_lookup(uint16_t cid)
-{
- struct l2cap_channel *chan;
-
- LIST_FOREACH(chan, &l2cap_active_list, lc_ncid) {
- if (chan->lc_lcid == cid)
- return chan;
-
- if (chan->lc_lcid > cid)
- return NULL;
- }
-
- return NULL;
-}
diff --git a/sys/netbt/l2cap_signal.c b/sys/netbt/l2cap_signal.c
deleted file mode 100644
index 5d4f0dc6da5..00000000000
--- a/sys/netbt/l2cap_signal.c
+++ /dev/null
@@ -1,1152 +0,0 @@
-/* $OpenBSD: l2cap_signal.c,v 1.6 2010/07/02 02:40:16 blambert Exp $ */
-/* $NetBSD: l2cap_signal.c,v 1.9 2007/11/10 23:12:23 plunky Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-
-/*******************************************************************************
- *
- * L2CAP Signal processing
- */
-
-static void l2cap_recv_command_rej(struct mbuf *, struct hci_link *);
-static void l2cap_recv_connect_req(struct mbuf *, struct hci_link *);
-static void l2cap_recv_connect_rsp(struct mbuf *, struct hci_link *);
-static void l2cap_recv_config_req(struct mbuf *, struct hci_link *);
-static void l2cap_recv_config_rsp(struct mbuf *, struct hci_link *);
-static void l2cap_recv_disconnect_req(struct mbuf *, struct hci_link *);
-static void l2cap_recv_disconnect_rsp(struct mbuf *, struct hci_link *);
-static void l2cap_recv_info_req(struct mbuf *, struct hci_link *);
-static int l2cap_send_signal(struct hci_link *, uint8_t, uint8_t, uint16_t, void *);
-static int l2cap_send_command_rej(struct hci_link *, uint8_t, uint32_t, ...);
-
-/*
- * process incoming signal packets (CID 0x0001). Can contain multiple
- * requests/responses.
- */
-void
-l2cap_recv_signal(struct mbuf *m, struct hci_link *link)
-{
- l2cap_cmd_hdr_t cmd;
-
- for(;;) {
- if (m->m_pkthdr.len == 0)
- goto finish;
-
- if (m->m_pkthdr.len < sizeof(cmd))
- goto reject;
-
- m_copydata(m, 0, sizeof(cmd), (caddr_t)&cmd);
- cmd.length = letoh16(cmd.length);
-
- if (m->m_pkthdr.len < sizeof(cmd) + cmd.length)
- goto reject;
-
- DPRINTFN(2, "(%s) code %d, ident %d, len %d\n",
- device_xname(link->hl_unit->hci_dev),
- cmd.code, cmd.ident, cmd.length);
-
- switch (cmd.code) {
- case L2CAP_COMMAND_REJ:
- if (cmd.length > sizeof(l2cap_cmd_rej_cp))
- goto finish;
-
- l2cap_recv_command_rej(m, link);
- break;
-
- case L2CAP_CONNECT_REQ:
- if (cmd.length != sizeof(l2cap_con_req_cp))
- goto reject;
-
- l2cap_recv_connect_req(m, link);
- break;
-
- case L2CAP_CONNECT_RSP:
- if (cmd.length != sizeof(l2cap_con_rsp_cp))
- goto finish;
-
- l2cap_recv_connect_rsp(m, link);
- break;
-
- case L2CAP_CONFIG_REQ:
- l2cap_recv_config_req(m, link);
- break;
-
- case L2CAP_CONFIG_RSP:
- l2cap_recv_config_rsp(m, link);
- break;
-
- case L2CAP_DISCONNECT_REQ:
- if (cmd.length != sizeof(l2cap_discon_req_cp))
- goto reject;
-
- l2cap_recv_disconnect_req(m, link);
- break;
-
- case L2CAP_DISCONNECT_RSP:
- if (cmd.length != sizeof(l2cap_discon_rsp_cp))
- goto finish;
-
- l2cap_recv_disconnect_rsp(m, link);
- break;
-
- case L2CAP_ECHO_REQ:
- m_adj(m, sizeof(cmd) + cmd.length);
- l2cap_send_signal(link, L2CAP_ECHO_RSP, cmd.ident,
- 0, NULL);
- break;
-
- case L2CAP_ECHO_RSP:
- m_adj(m, sizeof(cmd) + cmd.length);
- break;
-
- case L2CAP_INFO_REQ:
- if (cmd.length != sizeof(l2cap_info_req_cp))
- goto reject;
-
- l2cap_recv_info_req(m, link);
- break;
-
- case L2CAP_INFO_RSP:
- m_adj(m, sizeof(cmd) + cmd.length);
- break;
-
- default:
- goto reject;
- }
- }
-
-#ifdef DIAGNOSTIC
- panic("impossible!");
-#endif
-
-reject:
- l2cap_send_command_rej(link, cmd.ident, L2CAP_REJ_NOT_UNDERSTOOD);
-finish:
- m_freem(m);
-}
-
-/*
- * Process Received Command Reject. For now we dont try to recover gracefully
- * from this, it probably means that the link is garbled or the other end is
- * insufficiently capable of handling normal traffic. (not *my* fault, no way!)
- */
-static void
-l2cap_recv_command_rej(struct mbuf *m, struct hci_link *link)
-{
- struct l2cap_req *req;
- struct l2cap_channel *chan;
- l2cap_cmd_hdr_t cmd;
- l2cap_cmd_rej_cp cp;
-
- m_copydata(m, 0, sizeof(cmd), (caddr_t)&cmd);
- m_adj(m, sizeof(cmd));
-
- cmd.length = letoh16(cmd.length);
-
- m_copydata(m, 0, cmd.length, (caddr_t)&cp);
- m_adj(m, cmd.length);
-
- req = l2cap_request_lookup(link, cmd.ident);
- if (req == NULL)
- return;
-
- switch (letoh16(cp.reason)) {
- case L2CAP_REJ_NOT_UNDERSTOOD:
- /*
- * I dont know what to do, just move up the timeout
- */
- timeout_add(&req->lr_rtx, 0);
- break;
-
- case L2CAP_REJ_MTU_EXCEEDED:
- /*
- * I didnt send any commands over L2CAP_MTU_MINIMUM size, but..
- *
- * XXX maybe we should resend this, instead?
- */
- link->hl_mtu = letoh16(cp.data[0]);
- timeout_add(&req->lr_rtx, 0);
- break;
-
- case L2CAP_REJ_INVALID_CID:
- /*
- * Well, if they dont have such a channel then our channel is
- * most likely closed. Make it so.
- */
- chan = req->lr_chan;
- l2cap_request_free(req);
- if (chan != NULL && chan->lc_state != L2CAP_CLOSED)
- l2cap_close(chan, ECONNABORTED);
-
- break;
-
- default:
- UNKNOWN(letoh16(cp.reason));
- break;
- }
-}
-
-/*
- * Process Received Connect Request. Find listening channel matching
- * psm & addr and ask upper layer for a new channel.
- */
-static void
-l2cap_recv_connect_req(struct mbuf *m, struct hci_link *link)
-{
- struct sockaddr_bt laddr, raddr;
- struct l2cap_channel *chan, *new;
- l2cap_cmd_hdr_t cmd;
- l2cap_con_req_cp cp;
- int err;
-
- /* extract cmd */
- m_copydata(m, 0, sizeof(cmd), (caddr_t)&cmd);
- m_adj(m, sizeof(cmd));
-
- /* extract request */
- m_copydata(m, 0, sizeof(cp), (caddr_t)&cp);
- m_adj(m, sizeof(cp));
-
- cp.scid = letoh16(cp.scid);
- cp.psm = letoh16(cp.psm);
-
- memset(&laddr, 0, sizeof(struct sockaddr_bt));
- laddr.bt_len = sizeof(struct sockaddr_bt);
- laddr.bt_family = AF_BLUETOOTH;
- laddr.bt_psm = cp.psm;
- bdaddr_copy(&laddr.bt_bdaddr, &link->hl_unit->hci_bdaddr);
-
- memset(&raddr, 0, sizeof(struct sockaddr_bt));
- raddr.bt_len = sizeof(struct sockaddr_bt);
- raddr.bt_family = AF_BLUETOOTH;
- raddr.bt_psm = cp.psm;
- bdaddr_copy(&raddr.bt_bdaddr, &link->hl_bdaddr);
-
- LIST_FOREACH(chan, &l2cap_listen_list, lc_ncid) {
- if (chan->lc_laddr.bt_psm != laddr.bt_psm
- && chan->lc_laddr.bt_psm != L2CAP_PSM_ANY)
- continue;
-
- if (!bdaddr_same(&laddr.bt_bdaddr, &chan->lc_laddr.bt_bdaddr)
- && bdaddr_any(&chan->lc_laddr.bt_bdaddr) == 0)
- continue;
-
- new= (*chan->lc_proto->newconn)(chan->lc_upper, &laddr, &raddr);
- if (new == NULL)
- continue;
-
- err = l2cap_cid_alloc(new);
- if (err) {
- l2cap_send_connect_rsp(link, cmd.ident,
- 0, cp.scid,
- L2CAP_NO_RESOURCES);
-
- (*new->lc_proto->disconnected)(new->lc_upper, err);
- return;
- }
-
- new->lc_link = hci_acl_open(link->hl_unit, &link->hl_bdaddr);
- KASSERT(new->lc_link == link);
-
- new->lc_rcid = cp.scid;
- new->lc_ident = cmd.ident;
-
- memcpy(&new->lc_laddr, &laddr, sizeof(struct sockaddr_bt));
- memcpy(&new->lc_raddr, &raddr, sizeof(struct sockaddr_bt));
-
- new->lc_mode = chan->lc_mode;
-
- err = l2cap_setmode(new);
- if (err == EINPROGRESS) {
- new->lc_state = L2CAP_WAIT_SEND_CONNECT_RSP;
- (*new->lc_proto->connecting)(new->lc_upper);
- return;
- }
- if (err) {
- new->lc_state = L2CAP_CLOSED;
- hci_acl_close(link, err);
- new->lc_link = NULL;
-
- l2cap_send_connect_rsp(link, cmd.ident,
- 0, cp.scid,
- L2CAP_NO_RESOURCES);
-
- (*new->lc_proto->disconnected)(new->lc_upper, err);
- return;
- }
-
- err = l2cap_send_connect_rsp(link, cmd.ident,
- new->lc_lcid, new->lc_rcid,
- L2CAP_SUCCESS);
- if (err) {
- l2cap_close(new, err);
- return;
- }
-
- new->lc_state = L2CAP_WAIT_CONFIG;
- new->lc_flags |= (L2CAP_WAIT_CONFIG_REQ | L2CAP_WAIT_CONFIG_RSP);
- err = l2cap_send_config_req(new);
- if (err)
- l2cap_close(new, err);
-
- return;
- }
-
- l2cap_send_connect_rsp(link, cmd.ident,
- 0, cp.scid,
- L2CAP_PSM_NOT_SUPPORTED);
-}
-
-/*
- * Process Received Connect Response.
- */
-static void
-l2cap_recv_connect_rsp(struct mbuf *m, struct hci_link *link)
-{
- l2cap_cmd_hdr_t cmd;
- l2cap_con_rsp_cp cp;
- struct l2cap_req *req;
- struct l2cap_channel *chan;
-
- m_copydata(m, 0, sizeof(cmd), (caddr_t)&cmd);
- m_adj(m, sizeof(cmd));
-
- m_copydata(m, 0, sizeof(cp), (caddr_t)&cp);
- m_adj(m, sizeof(cp));
-
- cp.scid = letoh16(cp.scid);
- cp.dcid = letoh16(cp.dcid);
- cp.result = letoh16(cp.result);
-
- req = l2cap_request_lookup(link, cmd.ident);
- if (req == NULL || req->lr_code != L2CAP_CONNECT_REQ)
- return;
-
- chan = req->lr_chan;
- if (chan != NULL && chan->lc_lcid != cp.scid)
- return;
-
- if (chan == NULL || chan->lc_state != L2CAP_WAIT_RECV_CONNECT_RSP) {
- l2cap_request_free(req);
- return;
- }
-
- switch (cp.result) {
- case L2CAP_SUCCESS:
- /*
- * Ok, at this point we have a connection to the other party. We
- * could indicate upstream that we are ready for business and
- * wait for a "Configure Channel Request" but I'm not so sure
- * that is required in our case - we will proceed directly to
- * sending our config request. We set two state bits because in
- * the config state we are waiting for requests and responses.
- */
- l2cap_request_free(req);
- chan->lc_rcid = cp.dcid;
- chan->lc_state = L2CAP_WAIT_CONFIG;
- chan->lc_flags |= (L2CAP_WAIT_CONFIG_REQ | L2CAP_WAIT_CONFIG_RSP);
- l2cap_send_config_req(chan);
- break;
-
- case L2CAP_PENDING:
- /* XXX dont release request, should start eRTX timeout? */
- (*chan->lc_proto->connecting)(chan->lc_upper);
- break;
-
- case L2CAP_PSM_NOT_SUPPORTED:
- case L2CAP_SECURITY_BLOCK:
- case L2CAP_NO_RESOURCES:
- default:
- l2cap_request_free(req);
- l2cap_close(chan, ECONNREFUSED);
- break;
- }
-}
-
-/*
- * Process Received Config Request.
- */
-static void
-l2cap_recv_config_req(struct mbuf *m, struct hci_link *link)
-{
- uint8_t buf[L2CAP_MTU_MINIMUM];
- l2cap_cmd_hdr_t cmd;
- l2cap_cfg_req_cp cp;
- l2cap_cfg_opt_t opt;
- l2cap_cfg_opt_val_t val;
- l2cap_cfg_rsp_cp rp;
- struct l2cap_channel *chan;
- int left, len;
-
- m_copydata(m, 0, sizeof(cmd), (caddr_t)&cmd);
- m_adj(m, sizeof(cmd));
- left = letoh16(cmd.length);
-
- if (left < sizeof(cp))
- goto reject;
-
- m_copydata(m, 0, sizeof(cp), (caddr_t)&cp);
- m_adj(m, sizeof(cp));
- left -= sizeof(cp);
-
- cp.dcid = letoh16(cp.dcid);
- cp.flags = letoh16(cp.flags);
-
- chan = l2cap_cid_lookup(cp.dcid);
- if (chan == NULL || chan->lc_link != link
- || chan->lc_state != L2CAP_WAIT_CONFIG
- || (chan->lc_flags & L2CAP_WAIT_CONFIG_REQ) == 0) {
- /* XXX we should really accept reconfiguration requests */
- l2cap_send_command_rej(link, cmd.ident, L2CAP_REJ_INVALID_CID,
- L2CAP_NULL_CID, cp.dcid);
- goto out;
- }
-
- /* ready our response packet */
- rp.scid = htole16(chan->lc_rcid);
- rp.flags = 0; /* "No Continuation" */
- rp.result = L2CAP_SUCCESS;
- len = sizeof(rp);
-
- /*
- * Process the packet. We build the return packet on the fly adding any
- * unacceptable parameters as we go. As we can only return one result,
- * unknown option takes precedence so we start our return packet anew
- * and ignore option values thereafter as they will be re-sent.
- *
- * Since we do not support enough options to make overflowing the min
- * MTU size an issue in normal use, we just reject config requests that
- * make that happen. This could be because options are repeated or the
- * packet is corrupted in some way.
- *
- * If unknown option types threaten to overflow the packet, we just
- * ignore them. We can deny them next time.
- */
- while (left > 0) {
- if (left < sizeof(opt))
- goto reject;
-
- m_copydata(m, 0, sizeof(opt), (caddr_t)&opt);
- m_adj(m, sizeof(opt));
- left -= sizeof(opt);
-
- if (left < opt.length)
- goto reject;
-
- switch(opt.type & L2CAP_OPT_HINT_MASK) {
- case L2CAP_OPT_MTU:
- if (rp.result == L2CAP_UNKNOWN_OPTION)
- break;
-
- if (opt.length != L2CAP_OPT_MTU_SIZE)
- goto reject;
-
- m_copydata(m, 0, L2CAP_OPT_MTU_SIZE, (caddr_t)&val);
- val.mtu = letoh16(val.mtu);
-
- /*
- * XXX how do we know what the minimum acceptable MTU is
- * for a channel? Spec says some profiles have a higher
- * minimum but I have no way to find that out at this
- * juncture..
- */
- if (val.mtu < L2CAP_MTU_MINIMUM) {
- if (len + sizeof(opt) + L2CAP_OPT_MTU_SIZE > sizeof(buf))
- goto reject;
-
- rp.result = L2CAP_UNACCEPTABLE_PARAMS;
- memcpy(buf + len, &opt, sizeof(opt));
- len += sizeof(opt);
- val.mtu = htole16(L2CAP_MTU_MINIMUM);
- memcpy(buf + len, &val, L2CAP_OPT_MTU_SIZE);
- len += L2CAP_OPT_MTU_SIZE;
- } else
- chan->lc_omtu = val.mtu;
-
- break;
-
- case L2CAP_OPT_FLUSH_TIMO:
- if (rp.result == L2CAP_UNKNOWN_OPTION)
- break;
-
- if (opt.length != L2CAP_OPT_FLUSH_TIMO_SIZE)
- goto reject;
-
- /*
- * I think that this is informational only - he is
- * informing us of the flush timeout he will be using.
- * I dont think this affects us in any significant way,
- * so just ignore this value for now.
- */
- break;
-
- case L2CAP_OPT_QOS:
- if (rp.result == L2CAP_UNKNOWN_OPTION)
- break;
-
- if (opt.length != L2CAP_OPT_QOS_SIZE)
- goto reject;
-
- m_copydata(m, 0, L2CAP_OPT_QOS_SIZE, (caddr_t)&val);
- if (val.qos.service_type == L2CAP_QOS_NO_TRAFFIC ||
- val.qos.service_type == L2CAP_QOS_BEST_EFFORT)
- /*
- * In accordance with the spec, we choose to
- * ignore the fields an provide no response.
- */
- break;
-
- if (len + sizeof(opt) + L2CAP_OPT_QOS_SIZE > sizeof(buf))
- goto reject;
-
- if (val.qos.service_type != L2CAP_QOS_GUARANTEED) {
- /*
- * Instead of sending an "unacceptable
- * parameters" response, treat this as an
- * unknown option and include the option
- * value in the response.
- */
- rp.result = L2CAP_UNKNOWN_OPTION;
- } else {
- /*
- * According to the spec, we must return
- * specific values for wild card parameters.
- * I don't know what to return without lying,
- * so return "unacceptable parameters" and
- * specify the preferred service type as
- * "Best Effort".
- */
- rp.result = L2CAP_UNACCEPTABLE_PARAMS;
- val.qos.service_type = L2CAP_QOS_BEST_EFFORT;
- }
-
- memcpy(buf + len, &opt, sizeof(opt));
- len += sizeof(opt);
- memcpy(buf + len, &val, L2CAP_OPT_QOS_SIZE);
- len += L2CAP_OPT_QOS_SIZE;
- break;
-
- default:
- /* ignore hints */
- if (opt.type & L2CAP_OPT_HINT_BIT)
- break;
-
- /* unknown options supersede all else */
- if (rp.result != L2CAP_UNKNOWN_OPTION) {
- rp.result = L2CAP_UNKNOWN_OPTION;
- len = sizeof(rp);
- }
-
- /* ignore if it doesn't fit */
- if (len + sizeof(opt) > sizeof(buf))
- break;
-
- /* return unknown option type, but no data */
- buf[len++] = opt.type;
- buf[len++] = 0;
- break;
- }
-
- m_adj(m, opt.length);
- left -= opt.length;
- }
-
- rp.result = htole16(rp.result);
- memcpy(buf, &rp, sizeof(rp));
- l2cap_send_signal(link, L2CAP_CONFIG_RSP, cmd.ident, len, buf);
-
- if ((cp.flags & L2CAP_OPT_CFLAG_BIT) == 0
- && rp.result == letoh16(L2CAP_SUCCESS)) {
-
- chan->lc_flags &= ~L2CAP_WAIT_CONFIG_REQ;
-
- if ((chan->lc_flags & L2CAP_WAIT_CONFIG_RSP) == 0) {
- chan->lc_state = L2CAP_OPEN;
- /* XXX how to distinguish REconfiguration? */
- (*chan->lc_proto->connected)(chan->lc_upper);
- }
- }
- return;
-
-reject:
- l2cap_send_command_rej(link, cmd.ident, L2CAP_REJ_NOT_UNDERSTOOD);
-out:
- m_adj(m, left);
-}
-
-/*
- * Process Received Config Response.
- */
-static void
-l2cap_recv_config_rsp(struct mbuf *m, struct hci_link *link)
-{
- l2cap_cmd_hdr_t cmd;
- l2cap_cfg_rsp_cp cp;
- l2cap_cfg_opt_t opt;
- l2cap_cfg_opt_val_t val;
- struct l2cap_req *req;
- struct l2cap_channel *chan;
- int left;
-
- m_copydata(m, 0, sizeof(cmd), (caddr_t)&cmd);
- m_adj(m, sizeof(cmd));
- left = letoh16(cmd.length);
-
- if (left < sizeof(cp))
- goto out;
-
- m_copydata(m, 0, sizeof(cp), (caddr_t)&cp);
- m_adj(m, sizeof(cp));
- left -= sizeof(cp);
-
- cp.scid = letoh16(cp.scid);
- cp.flags = letoh16(cp.flags);
- cp.result = letoh16(cp.result);
-
- req = l2cap_request_lookup(link, cmd.ident);
- if (req == NULL || req->lr_code != L2CAP_CONFIG_REQ)
- goto out;
-
- chan = req->lr_chan;
- if (chan != NULL && chan->lc_lcid != cp.scid)
- goto out;
-
- l2cap_request_free(req);
-
- if (chan == NULL || chan->lc_state != L2CAP_WAIT_CONFIG
- || (chan->lc_flags & L2CAP_WAIT_CONFIG_RSP) == 0)
- goto out;
-
- if ((cp.flags & L2CAP_OPT_CFLAG_BIT)) {
- l2cap_cfg_req_cp rp;
-
- /*
- * They have more to tell us and want another ID to
- * use, so send an empty config request
- */
- if (l2cap_request_alloc(chan, L2CAP_CONFIG_REQ))
- goto discon;
-
- rp.dcid = htole16(cp.scid);
- rp.flags = 0;
-
- if (l2cap_send_signal(link, L2CAP_CONFIG_REQ, link->hl_lastid,
- sizeof(rp), &rp))
- goto discon;
- }
-
- switch(cp.result) {
- case L2CAP_SUCCESS:
- /*
- * If continuation flag was not set, our config request was
- * accepted. We may have to wait for their config request to
- * complete, so check that but otherwise we are open
- *
- * There may be 'advisory' values in the packet but we just
- * ignore those..
- */
- if ((cp.flags & L2CAP_OPT_CFLAG_BIT) == 0) {
- chan->lc_flags &= ~L2CAP_WAIT_CONFIG_RSP;
-
- if ((chan->lc_flags & L2CAP_WAIT_CONFIG_REQ) == 0) {
- chan->lc_state = L2CAP_OPEN;
- /* XXX how to distinguish REconfiguration? */
- (*chan->lc_proto->connected)(chan->lc_upper);
- }
- }
- goto out;
-
- case L2CAP_UNACCEPTABLE_PARAMS:
- /*
- * Packet contains unacceptable parameters with preferred values
- */
- while (left > 0) {
- if (left < sizeof(opt))
- goto discon;
-
- m_copydata(m, 0, sizeof(opt), (caddr_t)&opt);
- m_adj(m, sizeof(opt));
- left -= sizeof(opt);
-
- if (left < opt.length)
- goto discon;
-
- switch (opt.type) {
- case L2CAP_OPT_MTU:
- if (opt.length != L2CAP_OPT_MTU_SIZE)
- goto discon;
-
- m_copydata(m, 0, L2CAP_OPT_MTU_SIZE, (caddr_t)&val);
- chan->lc_imtu = letoh16(val.mtu);
- if (chan->lc_imtu < L2CAP_MTU_MINIMUM)
- chan->lc_imtu = L2CAP_MTU_DEFAULT;
- break;
-
- case L2CAP_OPT_FLUSH_TIMO:
- if (opt.length != L2CAP_OPT_FLUSH_TIMO_SIZE)
- goto discon;
-
- /*
- * Spec says: If we cannot honor proposed value,
- * either disconnect or try again with original
- * value. I can't really see why they want to
- * interfere with OUR flush timeout in any case
- * so we just punt for now.
- */
- goto discon;
-
- case L2CAP_OPT_QOS:
- break;
-
- default:
- UNKNOWN(opt.type);
- goto discon;
- }
-
- m_adj(m, opt.length);
- left -= opt.length;
- }
-
- if ((cp.flags & L2CAP_OPT_CFLAG_BIT) == 0)
- l2cap_send_config_req(chan); /* no state change */
-
- goto out;
-
- case L2CAP_REJECT:
- goto discon;
-
- case L2CAP_UNKNOWN_OPTION:
- /*
- * Packet contains options not understood. Turn off unknown
- * options by setting them to default values (means they will
- * not be requested again).
- *
- * If our option was already off then fail (paranoia?)
- *
- * XXX Should we consider that options were set for a reason?
- */
- while (left > 0) {
- if (left < sizeof(opt))
- goto discon;
-
- m_copydata(m, 0, sizeof(opt), (caddr_t)&opt);
- m_adj(m, sizeof(opt));
- left -= sizeof(opt);
-
- if (left < opt.length)
- goto discon;
-
- m_adj(m, opt.length);
- left -= opt.length;
-
- switch(opt.type) {
- case L2CAP_OPT_MTU:
- if (chan->lc_imtu == L2CAP_MTU_DEFAULT)
- goto discon;
-
- chan->lc_imtu = L2CAP_MTU_DEFAULT;
- break;
-
- case L2CAP_OPT_FLUSH_TIMO:
- if (chan->lc_flush == L2CAP_FLUSH_TIMO_DEFAULT)
- goto discon;
-
- chan->lc_flush = L2CAP_FLUSH_TIMO_DEFAULT;
- break;
-
- case L2CAP_OPT_QOS:
- break;
-
- default:
- UNKNOWN(opt.type);
- goto discon;
- }
- }
-
- if ((cp.flags & L2CAP_OPT_CFLAG_BIT) == 0)
- l2cap_send_config_req(chan); /* no state change */
-
- goto out;
-
- default:
- UNKNOWN(cp.result);
- goto discon;
- }
-
- DPRINTF("how did I get here!?\n");
-
-discon:
- l2cap_send_disconnect_req(chan);
- l2cap_close(chan, ECONNABORTED);
-
-out:
- m_adj(m, left);
-}
-
-/*
- * Process Received Disconnect Request. We must validate scid and dcid
- * just in case but otherwise this connection is finished.
- */
-static void
-l2cap_recv_disconnect_req(struct mbuf *m, struct hci_link *link)
-{
- l2cap_cmd_hdr_t cmd;
- l2cap_discon_req_cp cp;
- l2cap_discon_rsp_cp rp;
- struct l2cap_channel *chan;
-
- m_copydata(m, 0, sizeof(cmd), (caddr_t)&cmd);
- m_adj(m, sizeof(cmd));
-
- m_copydata(m, 0, sizeof(cp), (caddr_t)&cp);
- m_adj(m, sizeof(cp));
-
- cp.scid = letoh16(cp.scid);
- cp.dcid = letoh16(cp.dcid);
-
- chan = l2cap_cid_lookup(cp.dcid);
- if (chan == NULL || chan->lc_link != link || chan->lc_rcid != cp.scid) {
- l2cap_send_command_rej(link, cmd.ident, L2CAP_REJ_INVALID_CID,
- cp.dcid, cp.scid);
- return;
- }
-
- rp.dcid = htole16(chan->lc_lcid);
- rp.scid = htole16(chan->lc_rcid);
- l2cap_send_signal(link, L2CAP_DISCONNECT_RSP, cmd.ident,
- sizeof(rp), &rp);
-
- if (chan->lc_state != L2CAP_CLOSED)
- l2cap_close(chan, ECONNRESET);
-}
-
-/*
- * Process Received Disconnect Response. We must validate scid and dcid but
- * unless we were waiting for this signal, ignore it.
- */
-static void
-l2cap_recv_disconnect_rsp(struct mbuf *m, struct hci_link *link)
-{
- l2cap_cmd_hdr_t cmd;
- l2cap_discon_rsp_cp cp;
- struct l2cap_req *req;
- struct l2cap_channel *chan;
-
- m_copydata(m, 0, sizeof(cmd), (caddr_t)&cmd);
- m_adj(m, sizeof(cmd));
-
- m_copydata(m, 0, sizeof(cp), (caddr_t)&cp);
- m_adj(m, sizeof(cp));
-
- cp.scid = letoh16(cp.scid);
- cp.dcid = letoh16(cp.dcid);
-
- req = l2cap_request_lookup(link, cmd.ident);
- if (req == NULL || req->lr_code != L2CAP_DISCONNECT_REQ)
- return;
-
- chan = req->lr_chan;
- if (chan == NULL
- || chan->lc_lcid != cp.scid
- || chan->lc_rcid != cp.dcid)
- return;
-
- l2cap_request_free(req);
-
- if (chan->lc_state != L2CAP_WAIT_DISCONNECT)
- return;
-
- l2cap_close(chan, 0);
-}
-
-/*
- * Process Received Info Request. We must respond but alas dont
- * support anything as yet so thats easy.
- */
-static void
-l2cap_recv_info_req(struct mbuf *m, struct hci_link *link)
-{
- l2cap_cmd_hdr_t cmd;
- l2cap_info_req_cp cp;
- l2cap_info_rsp_cp rp;
-
- m_copydata(m, 0, sizeof(cmd), (caddr_t)&cmd);
- m_adj(m, sizeof(cmd));
-
- m_copydata(m, 0, sizeof(cp), (caddr_t)&cp);
- m_adj(m, sizeof(cp));
-
- switch(letoh16(cp.type)) {
- case L2CAP_CONNLESS_MTU:
- case L2CAP_EXTENDED_FEATURES:
- default:
- rp.type = cp.type;
- rp.result = htole16(L2CAP_NOT_SUPPORTED);
-
- l2cap_send_signal(link, L2CAP_INFO_RSP, cmd.ident,
- sizeof(rp), &rp);
- break;
- }
-}
-
-/*
- * Construct signal and wrap in C-Frame for link.
- */
-static int
-l2cap_send_signal(struct hci_link *link, uint8_t code, uint8_t ident,
- uint16_t length, void *data)
-{
- struct mbuf *m;
- l2cap_hdr_t *hdr;
- l2cap_cmd_hdr_t *cmd;
-
-#ifdef DIAGNOSTIC
- if (link == NULL)
- return ENETDOWN;
-
- if (sizeof(l2cap_cmd_hdr_t) + length > link->hl_mtu)
- printf("(%s) exceeding L2CAP Signal MTU for link!\n",
- device_xname(link->hl_unit->hci_dev));
-#endif
-
- m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return ENOMEM;
-
- hdr = mtod(m, l2cap_hdr_t *);
- cmd = (l2cap_cmd_hdr_t *)(hdr + 1);
-
- m->m_len = m->m_pkthdr.len = MHLEN;
-
- /* Command Data */
- if (length > 0)
- m_copyback(m, sizeof(*hdr) + sizeof(*cmd), length, data,
- M_NOWAIT);
-
- /* Command Header */
- cmd->code = code;
- cmd->ident = ident;
- cmd->length = htole16(length);
- length += sizeof(*cmd);
-
- /* C-Frame Header */
- hdr->length = htole16(length);
- hdr->dcid = htole16(L2CAP_SIGNAL_CID);
- length += sizeof(*hdr);
-
- if (m->m_pkthdr.len != MAX(MHLEN, length)) {
- m_freem(m);
- return ENOMEM;
- }
-
- m->m_pkthdr.len = length;
- m->m_len = MIN(length, MHLEN);
-
- DPRINTFN(2, "(%s) code %d, ident %d, len %d\n",
- device_xname(link->hl_unit->hci_dev), code, ident, length);
-
- return hci_acl_send(m, link, NULL);
-}
-
-/*
- * Send Command Reject packet.
- */
-static int
-l2cap_send_command_rej(struct hci_link *link, uint8_t ident,
- uint32_t reason, ...)
-{
- l2cap_cmd_rej_cp cp;
- int len = 0;
- va_list ap;
-
- va_start(ap, reason);
-
- cp.reason = htole16(reason);
-
- switch (reason) {
- case L2CAP_REJ_NOT_UNDERSTOOD:
- len = 2;
- break;
-
- case L2CAP_REJ_MTU_EXCEEDED:
- len = 4;
- cp.data[0] = va_arg(ap, int); /* SigMTU */
- cp.data[0] = htole16(cp.data[0]);
- break;
-
- case L2CAP_REJ_INVALID_CID:
- len = 6;
- cp.data[0] = va_arg(ap, int); /* dcid */
- cp.data[0] = htole16(cp.data[0]);
- cp.data[1] = va_arg(ap, int); /* scid */
- cp.data[1] = htole16(cp.data[1]);
- break;
-
- default:
- UNKNOWN(reason);
- return EINVAL;
- }
-
- va_end(ap);
-
- return l2cap_send_signal(link, L2CAP_COMMAND_REJ, ident, len, &cp);
-}
-
-/*
- * Send Connect Request
- */
-int
-l2cap_send_connect_req(struct l2cap_channel *chan)
-{
- l2cap_con_req_cp cp;
- int err;
-
- err = l2cap_request_alloc(chan, L2CAP_CONNECT_REQ);
- if (err)
- return err;
-
- cp.psm = htole16(chan->lc_raddr.bt_psm);
- cp.scid = htole16(chan->lc_lcid);
-
- return l2cap_send_signal(chan->lc_link, L2CAP_CONNECT_REQ,
- chan->lc_link->hl_lastid, sizeof(cp), &cp);
-}
-
-/*
- * Send Config Request
- *
- * For outgoing config request, we only put options in the packet if they
- * differ from the default and would have to be actioned. We dont support
- * enough option types to make overflowing SigMTU an issue so it can all
- * go in one packet.
- */
-int
-l2cap_send_config_req(struct l2cap_channel *chan)
-{
- l2cap_cfg_req_cp *cp;
- l2cap_cfg_opt_t *opt;
- l2cap_cfg_opt_val_t *val;
- uint8_t *next, buf[L2CAP_MTU_MINIMUM];
- int err;
-
- err = l2cap_request_alloc(chan, L2CAP_CONFIG_REQ);
- if (err)
- return err;
-
- /* Config Header (4 octets) */
- cp = (l2cap_cfg_req_cp *)buf;
- cp->dcid = htole16(chan->lc_rcid);
- cp->flags = 0; /* "No Continuation" */
-
- next = buf + sizeof(l2cap_cfg_req_cp);
-
- /* Incoming MTU (4 octets) */
- if (chan->lc_imtu != L2CAP_MTU_DEFAULT) {
- opt = (l2cap_cfg_opt_t *)next;
- opt->type = L2CAP_OPT_MTU;
- opt->length = L2CAP_OPT_MTU_SIZE;
-
- val = (l2cap_cfg_opt_val_t *)(opt + 1);
- val->mtu = htole16(chan->lc_imtu);
-
- next += sizeof(l2cap_cfg_opt_t) + L2CAP_OPT_MTU_SIZE;
- }
-
- /* Flush Timeout (4 octets) */
- if (chan->lc_flush != L2CAP_FLUSH_TIMO_DEFAULT) {
- opt = (l2cap_cfg_opt_t *)next;
- opt->type = L2CAP_OPT_FLUSH_TIMO;
- opt->length = L2CAP_OPT_FLUSH_TIMO_SIZE;
-
- val = (l2cap_cfg_opt_val_t *)(opt + 1);
- val->flush_timo = htole16(chan->lc_flush);
-
- next += sizeof(l2cap_cfg_opt_t) + L2CAP_OPT_FLUSH_TIMO_SIZE;
- }
-
- /* Outgoing QoS Flow (24 octets) */
- /* Retransmission & Flow Control (11 octets) */
- /*
- * From here we need to start paying attention to SigMTU as we have
- * possibly overflowed the minimum supported..
- */
-
- return l2cap_send_signal(chan->lc_link, L2CAP_CONFIG_REQ,
- chan->lc_link->hl_lastid, (int)(next - buf), buf);
-}
-
-/*
- * Send Disconnect Request
- */
-int
-l2cap_send_disconnect_req(struct l2cap_channel *chan)
-{
- l2cap_discon_req_cp cp;
- int err;
-
- err = l2cap_request_alloc(chan, L2CAP_DISCONNECT_REQ);
- if (err)
- return err;
-
- cp.dcid = htole16(chan->lc_rcid);
- cp.scid = htole16(chan->lc_lcid);
-
- return l2cap_send_signal(chan->lc_link, L2CAP_DISCONNECT_REQ,
- chan->lc_link->hl_lastid, sizeof(cp), &cp);
-}
-
-/*
- * Send Connect Response
- */
-int
-l2cap_send_connect_rsp(struct hci_link *link, uint8_t ident, uint16_t dcid,
- uint16_t scid, uint16_t result)
-{
- l2cap_con_rsp_cp cp;
-
- memset(&cp, 0, sizeof(cp));
- cp.dcid = htole16(dcid);
- cp.scid = htole16(scid);
- cp.result = htole16(result);
-
- return l2cap_send_signal(link, L2CAP_CONNECT_RSP, ident, sizeof(cp), &cp);
-}
diff --git a/sys/netbt/l2cap_socket.c b/sys/netbt/l2cap_socket.c
deleted file mode 100644
index 5a584f59598..00000000000
--- a/sys/netbt/l2cap_socket.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/* $OpenBSD: l2cap_socket.c,v 1.5 2012/12/05 23:20:23 deraadt Exp $ */
-/* $NetBSD: l2cap_socket.c,v 1.9 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* load symbolic names */
-#ifdef BLUETOOTH_DEBUG
-#define PRUREQUESTS
-#define PRCOREQUESTS
-#endif
-
-#include <sys/param.h>
-#include <sys/domain.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h> /* XXX for EPASSTHROUGH */
-#include <netbt/l2cap.h>
-
-/*
- * L2CAP Sockets
- *
- * SOCK_SEQPACKET - normal L2CAP connection
- *
- * SOCK_DGRAM - connectionless L2CAP - XXX not yet
- */
-
-static void l2cap_connecting(void *);
-static void l2cap_connected(void *);
-static void l2cap_disconnected(void *, int);
-static void *l2cap_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
-static void l2cap_complete(void *, int);
-static void l2cap_linkmode(void *, int);
-static void l2cap_input(void *, struct mbuf *);
-
-static const struct btproto l2cap_proto = {
- l2cap_connecting,
- l2cap_connected,
- l2cap_disconnected,
- l2cap_newconn,
- l2cap_complete,
- l2cap_linkmode,
- l2cap_input,
-};
-
-/* sysctl variables */
-int l2cap_sendspace = 4096;
-int l2cap_recvspace = 4096;
-
-/*
- * User Request.
- * up is socket
- * m is either
- * optional mbuf chain containing message
- * ioctl command (PRU_CONTROL)
- * nam is either
- * optional mbuf chain containing an address
- * ioctl data (PRU_CONTROL)
- * optionally protocol number (PRU_ATTACH)
- * message flags (PRU_RCVD)
- * ctl is either
- * optional mbuf chain containing socket options
- * optional interface pointer (PRU_CONTROL, PRU_PURGEIF)
- * l is pointer to process requesting action (if any)
- *
- * we are responsible for disposing of m and ctl if
- * they are mbuf chains
- */
-int
-l2cap_usrreq(struct socket *up, int req, struct mbuf *m,
- struct mbuf *nam, struct mbuf *ctl, struct proc *p)
-{
- struct l2cap_channel *pcb = up->so_pcb;
- struct sockaddr_bt *sa;
- struct mbuf *m0;
- int err = 0;
-
-#ifdef notyet /* XXX */
- DPRINTFN(2, "%s\n", prurequests[req]);
-#endif
-
- switch (req) {
- case PRU_CONTROL:
- return EPASSTHROUGH;
-
-#ifdef notyet /* XXX */
- case PRU_PURGEIF:
- return EOPNOTSUPP;
-#endif
-
- case PRU_ATTACH:
- /* XXX solock() and bt_lock fiddling in NetBSD */
- if (pcb != NULL)
- return EINVAL;
- /*
- * For L2CAP socket PCB we just use an l2cap_channel structure
- * since we have nothing to add..
- */
- err = soreserve(up, l2cap_sendspace, l2cap_recvspace);
- if (err)
- return err;
-
- return l2cap_attach((struct l2cap_channel **)&up->so_pcb,
- &l2cap_proto, up);
- }
-
- if (pcb == NULL) {
- err = EINVAL;
- goto release;
- }
-
- switch(req) {
- case PRU_DISCONNECT:
- soisdisconnecting(up);
- return l2cap_disconnect(pcb, up->so_linger);
-
- case PRU_ABORT:
- l2cap_disconnect(pcb, 0);
- soisdisconnected(up);
- /* fall through to */
- case PRU_DETACH:
- return l2cap_detach((struct l2cap_channel **)&up->so_pcb);
-
- case PRU_BIND:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- return l2cap_bind(pcb, sa);
-
- case PRU_CONNECT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- soisconnecting(up);
- return l2cap_connect(pcb, sa);
-
- case PRU_PEERADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return l2cap_peeraddr(pcb, sa);
-
- case PRU_SOCKADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return l2cap_sockaddr(pcb, sa);
-
- case PRU_SHUTDOWN:
- socantsendmore(up);
- break;
-
- case PRU_SEND:
- KASSERT(m != NULL);
- if (m->m_pkthdr.len == 0)
- break;
-
- if (m->m_pkthdr.len > pcb->lc_omtu) {
- err = EMSGSIZE;
- break;
- }
-
- m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
- if (m0 == NULL) {
- err = ENOMEM;
- break;
- }
-
- if (ctl) /* no use for that */
- m_freem(ctl);
-
- sbappendrecord(&up->so_snd, m);
- return l2cap_send(pcb, m0);
-
- case PRU_SENSE:
- return 0; /* (no release) */
-
- case PRU_RCVD:
- case PRU_RCVOOB:
- return EOPNOTSUPP; /* (no release) */
-
- case PRU_LISTEN:
- return l2cap_listen(pcb);
-
- case PRU_ACCEPT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return l2cap_peeraddr(pcb, sa);
-
- case PRU_CONNECT2:
- case PRU_SENDOOB:
- case PRU_FASTTIMO:
- case PRU_SLOWTIMO:
- case PRU_PROTORCV:
- case PRU_PROTOSEND:
- err = EOPNOTSUPP;
- break;
-
- default:
- UNKNOWN(req);
- err = EOPNOTSUPP;
- break;
- }
-
-release:
- if (m) m_freem(m);
- if (ctl) m_freem(ctl);
- return err;
-}
-
-/*
- * l2cap_ctloutput(request, socket, level, optname, opt)
- *
- * Apply configuration commands to channel. This corresponds to
- * "Reconfigure Channel Request" in the L2CAP specification.
- */
-int
-l2cap_ctloutput(int req, struct socket *so, int level,
- int optname, struct mbuf **opt)
-{
- struct l2cap_channel *pcb = so->so_pcb;
- struct mbuf *m;
- int err = 0;
-
-#ifdef notyet /* XXX */
- DPRINTFN(2, "%s\n", prcorequests[req]);
-#endif
-
- if (pcb == NULL)
- return EINVAL;
-
- if (level != BTPROTO_L2CAP) {
- err = EINVAL;
- if (req == PRCO_SETOPT && *opt)
- m_free(*opt);
- } else switch(req) {
- case PRCO_GETOPT:
- m = m_get(M_WAIT, MT_SOOPTS);
- m->m_len = l2cap_getopt(pcb, optname, mtod(m, void *));
- if (m->m_len == 0) {
- m_freem(m);
- m = NULL;
- err = ENOPROTOOPT;
- }
- *opt = m;
- break;
-
- case PRCO_SETOPT:
- m = *opt;
- err = l2cap_setopt(pcb, optname, m);
- m_freem(m);
- break;
-
- default:
- err = ENOPROTOOPT;
- break;
- }
-
- return err;
-}
-
-/**********************************************************************
- *
- * L2CAP Protocol socket callbacks
- *
- */
-
-static void
-l2cap_connecting(void *arg)
-{
- struct socket *so = arg;
-
- DPRINTF("Connecting\n");
- soisconnecting(so);
-}
-
-static void
-l2cap_connected(void *arg)
-{
- struct socket *so = arg;
-
- DPRINTF("Connected\n");
- soisconnected(so);
-}
-
-static void
-l2cap_disconnected(void *arg, int err)
-{
- struct socket *so = arg;
-
- DPRINTF("Disconnected (%d)\n", err);
-
- so->so_error = err;
- soisdisconnected(so);
-}
-
-static void *
-l2cap_newconn(void *arg, struct sockaddr_bt *laddr,
- struct sockaddr_bt *raddr)
-{
- struct socket *so = arg;
-
- DPRINTF("New Connection\n");
- so = sonewconn(so, 0);
- if (so == NULL)
- return NULL;
-
- soisconnecting(so);
-
- return so->so_pcb;
-}
-
-static void
-l2cap_complete(void *arg, int count)
-{
- struct socket *so = arg;
-
- while (count-- > 0)
- sbdroprecord(&so->so_snd);
-
- sowwakeup(so);
-}
-
-static void
-l2cap_linkmode(void *arg, int new)
-{
- struct socket *so = arg;
- int mode;
-
- DPRINTF("auth %s, encrypt %s, secure %s\n",
- (new & L2CAP_LM_AUTH ? "on" : "off"),
- (new & L2CAP_LM_ENCRYPT ? "on" : "off"),
- (new & L2CAP_LM_SECURE ? "on" : "off"));
-
- (void)l2cap_getopt(so->so_pcb, SO_L2CAP_LM, &mode);
- if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH))
- || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT))
- || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE)))
- l2cap_disconnect(so->so_pcb, 0);
-}
-
-static void
-l2cap_input(void *arg, struct mbuf *m)
-{
- struct socket *so = arg;
-
- if (m->m_pkthdr.len > sbspace(&so->so_rcv)) {
- printf("%s: packet (%d bytes) dropped (socket buffer full)\n",
- __func__, m->m_pkthdr.len);
- m_freem(m);
- return;
- }
-
- DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len);
-
- sbappendrecord(&so->so_rcv, m);
- sorwakeup(so);
-}
diff --git a/sys/netbt/l2cap_upper.c b/sys/netbt/l2cap_upper.c
deleted file mode 100644
index bcefcf54719..00000000000
--- a/sys/netbt/l2cap_upper.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/* $OpenBSD: l2cap_upper.c,v 1.6 2013/01/06 22:06:54 martynas Exp $ */
-/* $NetBSD: l2cap_upper.c,v 1.9 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2005 Iain Hibbert.
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-
-/*******************************************************************************
- *
- * L2CAP Channel - Upper Protocol API
- */
-
-/*
- * l2cap_attach(handle, btproto, upper)
- *
- * attach new l2cap_channel to handle, populate
- * with reasonable defaults
- */
-int
-l2cap_attach(struct l2cap_channel **handle,
- const struct btproto *proto, void *upper)
-{
- struct l2cap_channel *chan;
-
- KASSERT(handle != NULL);
- KASSERT(proto != NULL);
- KASSERT(upper != NULL);
-
- chan = malloc(sizeof(*chan), M_BLUETOOTH, M_NOWAIT | M_ZERO);
- if (chan == NULL)
- return ENOMEM;
-
- chan->lc_proto = proto;
- chan->lc_upper = upper;
-
- chan->lc_state = L2CAP_CLOSED;
-
- chan->lc_lcid = L2CAP_NULL_CID;
- chan->lc_rcid = L2CAP_NULL_CID;
-
- chan->lc_laddr.bt_len = sizeof(struct sockaddr_bt);
- chan->lc_laddr.bt_family = AF_BLUETOOTH;
- chan->lc_laddr.bt_psm = L2CAP_PSM_ANY;
-
- chan->lc_raddr.bt_len = sizeof(struct sockaddr_bt);
- chan->lc_raddr.bt_family = AF_BLUETOOTH;
- chan->lc_raddr.bt_psm = L2CAP_PSM_ANY;
-
- chan->lc_imtu = L2CAP_MTU_DEFAULT;
- chan->lc_omtu = L2CAP_MTU_DEFAULT;
- chan->lc_flush = L2CAP_FLUSH_TIMO_DEFAULT;
-
- memcpy(&chan->lc_iqos, &l2cap_default_qos, sizeof(l2cap_qos_t));
- memcpy(&chan->lc_oqos, &l2cap_default_qos, sizeof(l2cap_qos_t));
-
- *handle = chan;
- return 0;
-}
-
-/*
- * l2cap_bind(l2cap_channel, sockaddr)
- *
- * set local address of channel
- */
-int
-l2cap_bind(struct l2cap_channel *chan, struct sockaddr_bt *addr)
-{
-
- memcpy(&chan->lc_laddr, addr, sizeof(struct sockaddr_bt));
- return 0;
-}
-
-/*
- * l2cap_sockaddr(l2cap_channel, sockaddr)
- *
- * get local address of channel
- */
-int
-l2cap_sockaddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
-{
-
- memcpy(addr, &chan->lc_laddr, sizeof(struct sockaddr_bt));
- return 0;
-}
-
-/*
- * l2cap_connect(l2cap_channel, sockaddr)
- *
- * Initiate a connection to destination. This corresponds to
- * "Open Channel Request" in the L2CAP specification and will
- * result in one of the following:
- *
- * proto->connected(upper)
- * proto->disconnected(upper, error)
- *
- * and, optionally
- * proto->connecting(upper)
- */
-int
-l2cap_connect(struct l2cap_channel *chan, struct sockaddr_bt *dest)
-{
- struct hci_unit *unit;
- int err;
-
- memcpy(&chan->lc_raddr, dest, sizeof(struct sockaddr_bt));
-
- if (L2CAP_PSM_INVALID(chan->lc_raddr.bt_psm))
- return EINVAL;
-
- if (bdaddr_any(&chan->lc_raddr.bt_bdaddr))
- return EDESTADDRREQ;
-
- /* set local address if it needs setting */
- if (bdaddr_any(&chan->lc_laddr.bt_bdaddr)) {
- err = hci_route_lookup(&chan->lc_laddr.bt_bdaddr,
- &chan->lc_raddr.bt_bdaddr);
- if (err)
- return err;
- }
-
- unit = hci_unit_lookup(&chan->lc_laddr.bt_bdaddr);
- if (unit == NULL)
- return EHOSTUNREACH;
-
- /* attach to active list */
- err = l2cap_cid_alloc(chan);
- if (err)
- return err;
-
- /* open link to remote device */
- chan->lc_link = hci_acl_open(unit, &chan->lc_raddr.bt_bdaddr);
- if (chan->lc_link == NULL)
- return EHOSTUNREACH;
-
- /* set the link mode */
- err = l2cap_setmode(chan);
- if (err == EINPROGRESS) {
- chan->lc_state = L2CAP_WAIT_SEND_CONNECT_REQ;
- (*chan->lc_proto->connecting)(chan->lc_upper);
- return 0;
- }
- if (err)
- goto fail;
-
- /*
- * We can queue a connect request now even though the link may
- * not yet be open; Our mode setting is assured, and the queue
- * will be started automatically at the right time.
- */
- chan->lc_state = L2CAP_WAIT_RECV_CONNECT_RSP;
- err = l2cap_send_connect_req(chan);
- if (err)
- goto fail;
-
- return 0;
-
-fail:
- chan->lc_state = L2CAP_CLOSED;
- hci_acl_close(chan->lc_link, err);
- chan->lc_link = NULL;
- return err;
-}
-
-/*
- * l2cap_peeraddr(l2cap_channel, sockaddr)
- *
- * get remote address of channel
- */
-int
-l2cap_peeraddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
-{
-
- memcpy(addr, &chan->lc_raddr, sizeof(struct sockaddr_bt));
- return 0;
-}
-
-/*
- * l2cap_disconnect(l2cap_channel, linger)
- *
- * Initiate L2CAP disconnection. This corresponds to
- * "Close Channel Request" in the L2CAP specification
- * and will result in a call to
- *
- * proto->disconnected(upper, error)
- *
- * when the disconnection is complete. If linger is set,
- * the call will not be made until data has flushed from
- * the queue.
- */
-int
-l2cap_disconnect(struct l2cap_channel *chan, int linger)
-{
- int err = 0;
-
- if (chan->lc_state == L2CAP_CLOSED
- || chan->lc_state == L2CAP_WAIT_DISCONNECT)
- return EINVAL;
-
- chan->lc_flags |= L2CAP_SHUTDOWN;
-
- /*
- * no need to do anything unless the queue is empty or
- * we are not lingering..
- */
- if ((IF_IS_EMPTY(&chan->lc_txq) && chan->lc_pending == 0)
- || linger == 0) {
- chan->lc_state = L2CAP_WAIT_DISCONNECT;
- err = l2cap_send_disconnect_req(chan);
- if (err)
- l2cap_close(chan, err);
- }
- return err;
-}
-
-/*
- * l2cap_detach(handle)
- *
- * Detach l2cap channel from handle & close it down
- */
-int
-l2cap_detach(struct l2cap_channel **handle)
-{
- struct l2cap_channel *chan;
-
- chan = *handle;
- *handle = NULL;
-
- if (chan->lc_state != L2CAP_CLOSED)
- l2cap_close(chan, 0);
-
- if (chan->lc_lcid != L2CAP_NULL_CID) {
- LIST_REMOVE(chan, lc_ncid);
- chan->lc_lcid = L2CAP_NULL_CID;
- }
-
- IF_PURGE(&chan->lc_txq);
-
- /*
- * Could implement some kind of delayed expunge to make sure that the
- * CID is really dead before it becomes available for reuse?
- */
-
- free(chan, M_BLUETOOTH);
- return 0;
-}
-
-/*
- * l2cap_listen(l2cap_channel)
- *
- * Use this channel as a listening post (until detached). This will
- * result in calls to:
- *
- * proto->newconn(upper, laddr, raddr)
- *
- * for incoming connections matching the psm and local address of the
- * channel (NULL psm/address are permitted and match any protocol/device).
- *
- * The upper layer should create and return a new channel.
- *
- * You cannot use this channel for anything else subsequent to this call
- */
-int
-l2cap_listen(struct l2cap_channel *chan)
-{
- struct l2cap_channel *used, *prev = NULL;
-
- if (chan->lc_lcid != L2CAP_NULL_CID)
- return EINVAL;
-
- if (chan->lc_laddr.bt_psm != L2CAP_PSM_ANY
- && L2CAP_PSM_INVALID(chan->lc_laddr.bt_psm))
- return EADDRNOTAVAIL;
-
- /*
- * This CID is irrelevant, as the channel is not stored on the active
- * list and the socket code does not allow operations on listening
- * sockets, but we set it so the detach code knows to LIST_REMOVE the
- * channel.
- */
- chan->lc_lcid = L2CAP_SIGNAL_CID;
-
- /*
- * The list of listening channels is stored in an order such that new
- * listeners dont usurp current listeners, but that specific listening
- * takes precedence over promiscuous, and the connect request code can
- * easily use the first matching entry.
- */
- LIST_FOREACH(used, &l2cap_listen_list, lc_ncid) {
- if (used->lc_laddr.bt_psm < chan->lc_laddr.bt_psm)
- break;
-
- if (used->lc_laddr.bt_psm == chan->lc_laddr.bt_psm
- && bdaddr_any(&used->lc_laddr.bt_bdaddr)
- && !bdaddr_any(&chan->lc_laddr.bt_bdaddr))
- break;
-
- prev = used;
- }
-
- if (prev == NULL)
- LIST_INSERT_HEAD(&l2cap_listen_list, chan, lc_ncid);
- else
- LIST_INSERT_AFTER(prev, chan, lc_ncid);
-
- return 0;
-}
-
-/*
- * l2cap_send(l2cap_channel, mbuf)
- *
- * Output SDU on channel described by channel. This corresponds
- * to "Send Data Request" in the L2CAP specification. The upper
- * layer will be notified when SDU's have completed sending by a
- * call to:
- *
- * proto->complete(upper, n)
- *
- * (currently n == 1)
- *
- * Note: I'm not sure how this will work out, but I think that
- * if outgoing Retransmission Mode or Flow Control Mode is
- * negotiated then this call will not be made until the SDU has
- * been acknowledged by the peer L2CAP entity. For 'Best Effort'
- * it will be made when the packet has cleared the controller
- * buffers.
- *
- * We only support Basic mode so far, so encapsulate with a
- * B-Frame header and start sending if we are not already
- */
-int
-l2cap_send(struct l2cap_channel *chan, struct mbuf *m)
-{
- l2cap_hdr_t *hdr;
- int plen;
-
- if (chan->lc_state == L2CAP_CLOSED) {
- m_freem(m);
- return ENOTCONN;
- }
-
- plen = m->m_pkthdr.len;
-
- DPRINTFN(5, "send %d bytes on CID #%d (pending = %d)\n",
- plen, chan->lc_lcid, chan->lc_pending);
-
- /* Encapsulate with B-Frame */
- M_PREPEND(m, sizeof(l2cap_hdr_t), M_DONTWAIT);
- if (m == NULL)
- return ENOMEM;
-
- hdr = mtod(m, l2cap_hdr_t *);
- hdr->length = htole16(plen);
- hdr->dcid = htole16(chan->lc_rcid);
-
- /* Queue it on our list */
- IF_ENQUEUE(&chan->lc_txq, m);
-
- /* If we are not sending, then start doing so */
- if (chan->lc_pending == 0)
- return l2cap_start(chan);
-
- return 0;
-}
-
-int
-l2cap_setlinkmode(struct l2cap_channel *chan, int mode)
-{
- int err = 0;
-
- mode &= (L2CAP_LM_SECURE | L2CAP_LM_ENCRYPT | L2CAP_LM_AUTH);
-
- if (mode & L2CAP_LM_SECURE)
- mode |= L2CAP_LM_ENCRYPT;
-
- if (mode & L2CAP_LM_ENCRYPT)
- mode |= L2CAP_LM_AUTH;
-
- chan->lc_mode = mode;
-
- if (chan->lc_state == L2CAP_OPEN)
- err = l2cap_setmode(chan);
- return (err);
-}
-
-/*
- * l2cap_setopt(l2cap_channel, opt, addr)
- *
- * Apply configuration options to channel. This corresponds to
- * "Configure Channel Request" in the L2CAP specification.
- *
- * for SO_L2CAP_LM, the settings will take effect when the
- * channel is established. If the channel is already open,
- * a call to
- * proto->linkmode(upper, new)
- *
- * will be made when the change is complete.
- */
-int
-l2cap_setopt(struct l2cap_channel *chan, int opt, struct mbuf *m)
-{
- int err = 0;
- uint16_t mtu;
-
- switch (opt) {
- case SO_L2CAP_IMTU: /* set Incoming MTU */
- if (m == NULL || m->m_len != sizeof(uint16_t))
- err = EINVAL;
- else {
- mtu = *mtod(m, uint16_t *);
- if (mtu < L2CAP_MTU_MINIMUM)
- err = EINVAL;
- else if (chan->lc_state == L2CAP_CLOSED)
- chan->lc_imtu = mtu;
- else
- err = EBUSY;
- }
-
- break;
-
- case SO_L2CAP_LM: /* set link mode */
- if (m == NULL || m->m_len != sizeof(int))
- err = EINVAL;
- else {
- err = l2cap_setlinkmode(chan, *mtod(m, int *));
- }
-
- break;
-
- case SO_L2CAP_OQOS: /* set Outgoing QoS flow spec */
- case SO_L2CAP_FLUSH: /* set Outgoing Flush Timeout */
- default:
- err = ENOPROTOOPT;
- break;
- }
-
- return err;
-}
-
-/*
- * l2cap_getopt(l2cap_channel, opt, addr)
- *
- * Return configuration parameters.
- */
-int
-l2cap_getopt(struct l2cap_channel *chan, int opt, void *addr)
-{
-
- switch (opt) {
- case SO_L2CAP_IMTU: /* get Incoming MTU */
- *(uint16_t *)addr = chan->lc_imtu;
- return sizeof(uint16_t);
-
- case SO_L2CAP_OMTU: /* get Outgoing MTU */
- *(uint16_t *)addr = chan->lc_omtu;
- return sizeof(uint16_t);
-
- case SO_L2CAP_IQOS: /* get Incoming QoS flow spec */
- memcpy(addr, &chan->lc_iqos, sizeof(l2cap_qos_t));
- return sizeof(l2cap_qos_t);
-
- case SO_L2CAP_OQOS: /* get Outgoing QoS flow spec */
- memcpy(addr, &chan->lc_oqos, sizeof(l2cap_qos_t));
- return sizeof(l2cap_qos_t);
-
- case SO_L2CAP_FLUSH: /* get Flush Timeout */
- *(uint16_t *)addr = chan->lc_flush;
- return sizeof(uint16_t);
-
- case SO_L2CAP_LM: /* get link mode */
- *(int *)addr = chan->lc_mode;
- return sizeof(int);
-
- default:
- break;
- }
-
- return 0;
-}
diff --git a/sys/netbt/rfcomm.h b/sys/netbt/rfcomm.h
deleted file mode 100644
index ba7149e3ef3..00000000000
--- a/sys/netbt/rfcomm.h
+++ /dev/null
@@ -1,427 +0,0 @@
-/* $OpenBSD: rfcomm.h,v 1.5 2009/11/21 13:05:32 guenther Exp $ */
-/* $NetBSD: rfcomm.h,v 1.8 2008/09/08 23:36:55 gmcgarry Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/*-
- * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: rfcomm.h,v 1.5 2009/11/21 13:05:32 guenther Exp $
- * $FreeBSD: src/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h,v 1.4 2005/01/11 01:39:53 emax Exp $
- */
-
-#ifndef _NETBT_RFCOMM_H_
-#define _NETBT_RFCOMM_H_
-
-#include <sys/types.h>
-
-/*************************************************************************
- *************************************************************************
- ** RFCOMM **
- *************************************************************************
- *************************************************************************/
-
-#define RFCOMM_MTU_MAX 32767
-#define RFCOMM_MTU_MIN 23
-#define RFCOMM_MTU_DEFAULT 127
-
-#define RFCOMM_CREDITS_MAX 255 /* in any single packet */
-#define RFCOMM_CREDITS_DEFAULT 7 /* default initial value */
-
-#define RFCOMM_CHANNEL_ANY 0
-#define RFCOMM_CHANNEL_MIN 1
-#define RFCOMM_CHANNEL_MAX 30
-
-/* RFCOMM frame types */
-#define RFCOMM_FRAME_SABM 0x2f
-#define RFCOMM_FRAME_DISC 0x43
-#define RFCOMM_FRAME_UA 0x63
-#define RFCOMM_FRAME_DM 0x0f
-#define RFCOMM_FRAME_UIH 0xef
-
-/* RFCOMM MCC commands */
-#define RFCOMM_MCC_TEST 0x08 /* Test */
-#define RFCOMM_MCC_FCON 0x28 /* Flow Control on */
-#define RFCOMM_MCC_FCOFF 0x18 /* Flow Control off */
-#define RFCOMM_MCC_MSC 0x38 /* Modem Status Command */
-#define RFCOMM_MCC_RPN 0x24 /* Remote Port Negotiation */
-#define RFCOMM_MCC_RLS 0x14 /* Remote Line Status */
-#define RFCOMM_MCC_PN 0x20 /* Port Negotiation */
-#define RFCOMM_MCC_NSC 0x04 /* Non Supported Command */
-
-/* RFCOMM modem signals */
-#define RFCOMM_MSC_FC 0x02 /* Flow Control asserted */
-#define RFCOMM_MSC_RTC 0x04 /* Ready To Communicate */
-#define RFCOMM_MSC_RTR 0x08 /* Ready To Receive */
-#define RFCOMM_MSC_IC 0x40 /* Incomming Call (RING) */
-#define RFCOMM_MSC_DV 0x80 /* Data Valid */
-
-/* RPN parameters - baud rate */
-#define RFCOMM_RPN_BR_2400 0x0
-#define RFCOMM_RPN_BR_4800 0x1
-#define RFCOMM_RPN_BR_7200 0x2
-#define RFCOMM_RPN_BR_9600 0x3
-#define RFCOMM_RPN_BR_19200 0x4
-#define RFCOMM_RPN_BR_38400 0x5
-#define RFCOMM_RPN_BR_57600 0x6
-#define RFCOMM_RPN_BR_115200 0x7
-#define RFCOMM_RPN_BR_230400 0x8
-
-/* RPN parameters - data bits */
-#define RFCOMM_RPN_DATA_5 0x0
-#define RFCOMM_RPN_DATA_6 0x1
-#define RFCOMM_RPN_DATA_7 0x2
-#define RFCOMM_RPN_DATA_8 0x3
-
-/* RPN parameters - stop bit */
-#define RFCOMM_RPN_STOP_1 0
-#define RFCOMM_RPN_STOP_15 1
-
-/* RPN parameters - parity enable */
-#define RFCOMM_RPN_PARITY_NONE 0x0
-
-/* RPN parameters - parity type */
-#define RFCOMM_RPN_PARITY_ODD 0x0
-#define RFCOMM_RPN_PARITY_EVEN 0x1
-#define RFCOMM_RPN_PARITY_MARK 0x2
-#define RFCOMM_RPN_PARITY_SPACE 0x3
-
-/* RPN parameters - default line_setting */
-#define RFCOMM_RPN_8_N_1 0x03
-
-/* RPN parameters - flow control */
-#define RFCOMM_RPN_XON_CHAR 0x11
-#define RFCOMM_RPN_XOFF_CHAR 0x13
-#define RFCOMM_RPN_FLOW_NONE 0x00
-
-/* RPN parameters - mask */
-#define RFCOMM_RPN_PM_RATE 0x0001
-#define RFCOMM_RPN_PM_DATA 0x0002
-#define RFCOMM_RPN_PM_STOP 0x0004
-#define RFCOMM_RPN_PM_PARITY 0x0008
-#define RFCOMM_RPN_PM_PTYPE 0x0010
-#define RFCOMM_RPN_PM_XON 0x0020
-#define RFCOMM_RPN_PM_XOFF 0x0040
-
-#define RFCOMM_RPN_PM_FLOW 0x3f00
-
-#define RFCOMM_RPN_PM_ALL 0x3f7f
-
-/* RFCOMM command frame header */
-struct rfcomm_cmd_hdr
-{
- uint8_t address;
- uint8_t control;
- uint8_t length;
- uint8_t fcs;
-} __packed;
-
-/* RFCOMM MSC command */
-struct rfcomm_mcc_msc
-{
- uint8_t address;
- uint8_t modem;
- uint8_t brk;
-} __packed;
-
-/* RFCOMM RPN command */
-struct rfcomm_mcc_rpn
-{
- uint8_t dlci;
- uint8_t bit_rate;
- uint8_t line_settings;
- uint8_t flow_control;
- uint8_t xon_char;
- uint8_t xoff_char;
- uint16_t param_mask;
-} __packed;
-
-/* RFCOMM RLS command */
-struct rfcomm_mcc_rls
-{
- uint8_t address;
- uint8_t status;
-} __packed;
-
-/* RFCOMM PN command */
-struct rfcomm_mcc_pn
-{
- uint8_t dlci;
- uint8_t flow_control;
- uint8_t priority;
- uint8_t ack_timer;
- uint16_t mtu;
- uint8_t max_retrans;
- uint8_t credits;
-} __packed;
-
-/* RFCOMM frame parsing macros */
-#define RFCOMM_DLCI(b) (((b) & 0xfc) >> 2)
-#define RFCOMM_TYPE(b) (((b) & 0xef))
-
-#define RFCOMM_EA(b) (((b) & 0x01))
-#define RFCOMM_CR(b) (((b) & 0x02) >> 1)
-#define RFCOMM_PF(b) (((b) & 0x10) >> 4)
-
-#define RFCOMM_CHANNEL(dlci) (((dlci) >> 1) & 0x2f)
-#define RFCOMM_DIRECTION(dlci) ((dlci) & 0x1)
-
-#define RFCOMM_MKADDRESS(cr, dlci) \
- ((((dlci) & 0x3f) << 2) | ((cr) << 1) | 0x01)
-
-#define RFCOMM_MKCONTROL(type, pf) ((((type) & 0xef) | ((pf) << 4)))
-#define RFCOMM_MKDLCI(dir, channel) ((((channel) & 0x1f) << 1) | (dir))
-
-/* RFCOMM MCC macros */
-#define RFCOMM_MCC_TYPE(b) (((b) & 0xfc) >> 2)
-#define RFCOMM_MCC_LENGTH(b) (((b) & 0xfe) >> 1)
-#define RFCOMM_MKMCC_TYPE(cr, type) ((((type) << 2) | ((cr) << 1) | 0x01))
-
-/* RPN macros */
-#define RFCOMM_RPN_DATA_BITS(line) ((line) & 0x3)
-#define RFCOMM_RPN_STOP_BITS(line) (((line) >> 2) & 0x1)
-#define RFCOMM_RPN_PARITY(line) (((line) >> 3) & 0x1)
-
-/*************************************************************************
- *************************************************************************
- ** SOCK_STREAM RFCOMM sockets **
- *************************************************************************
- *************************************************************************/
-
-/* Socket options */
-#define SO_RFCOMM_MTU 1 /* mtu */
-#define SO_RFCOMM_FC_INFO 2 /* flow control info (below) */
-#define SO_RFCOMM_LM 3 /* link mode */
-
-/* Flow control information */
-struct rfcomm_fc_info {
- uint8_t lmodem; /* modem signals (local) */
- uint8_t rmodem; /* modem signals (remote) */
- uint8_t tx_cred; /* TX credits */
- uint8_t rx_cred; /* RX credits */
- uint8_t cfc; /* credit flow control */
- uint8_t reserved;
-};
-
-/* RFCOMM link mode flags */
-#define RFCOMM_LM_AUTH (1<<0) /* want authentication */
-#define RFCOMM_LM_ENCRYPT (1<<1) /* want encryption */
-#define RFCOMM_LM_SECURE (1<<2) /* want secured link */
-
-#ifdef _KERNEL
-
-/* sysctl variables */
-extern int rfcomm_sendspace;
-extern int rfcomm_recvspace;
-extern int rfcomm_mtu_default;
-extern int rfcomm_ack_timeout;
-extern int rfcomm_mcc_timeout;
-
-/*
- * Bluetooth RFCOMM session data
- * One L2CAP connection == one RFCOMM session
- */
-
-/* Credit note */
-struct rfcomm_credit {
- struct rfcomm_dlc *rc_dlc; /* owner */
- uint16_t rc_len; /* length */
- SIMPLEQ_ENTRY(rfcomm_credit) rc_next; /* next credit */
-};
-
-/* RFCOMM session data (one L2CAP channel) */
-struct rfcomm_session {
- struct l2cap_channel *rs_l2cap; /* L2CAP pointer */
- uint16_t rs_flags; /* session flags */
- uint16_t rs_state; /* session state */
- uint16_t rs_mtu; /* default MTU */
-
- SIMPLEQ_HEAD(,rfcomm_credit) rs_credits; /* credit notes */
- LIST_HEAD(,rfcomm_dlc) rs_dlcs; /* DLC list */
-
- struct timeout rs_timeout; /* timeout */
-
- LIST_ENTRY(rfcomm_session) rs_next; /* next session */
-};
-
-LIST_HEAD(rfcomm_session_list, rfcomm_session);
-extern struct rfcomm_session_list rfcomm_session_active;
-extern struct rfcomm_session_list rfcomm_session_listen;
-
-/* Session state */
-#define RFCOMM_SESSION_CLOSED 0
-#define RFCOMM_SESSION_WAIT_CONNECT 1
-#define RFCOMM_SESSION_OPEN 2
-#define RFCOMM_SESSION_WAIT_DISCONNECT 3
-#define RFCOMM_SESSION_LISTEN 4
-
-/* Session flags */
-#define RFCOMM_SESSION_INITIATOR (1 << 0) /* we are initiator */
-#define RFCOMM_SESSION_CFC (1 << 1) /* credit flow control */
-#define RFCOMM_SESSION_LFC (1 << 2) /* local flow control */
-#define RFCOMM_SESSION_RFC (1 << 3) /* remote flow control */
-#define RFCOMM_SESSION_FREE (1 << 4) /* self lock out for free */
-
-#define IS_INITIATOR(rs) ((rs)->rs_flags & RFCOMM_SESSION_INITIATOR)
-
-/* Bluetooth RFCOMM DLC data (connection) */
-struct rfcomm_dlc {
- struct rfcomm_session *rd_session; /* RFCOMM session */
- uint8_t rd_dlci; /* RFCOMM DLCI */
-
- uint16_t rd_flags; /* DLC flags */
- uint16_t rd_state; /* DLC state */
- uint16_t rd_mtu; /* MTU */
- int rd_mode; /* link mode */
-
- struct sockaddr_bt rd_laddr; /* local address */
- struct sockaddr_bt rd_raddr; /* remote address */
-
- uint8_t rd_lmodem; /* local modem signls */
- uint8_t rd_rmodem; /* remote modem signals */
-
- int rd_rxcred; /* receive credits (sent) */
- size_t rd_rxsize; /* receive buffer (bytes, avail) */
- int rd_txcred; /* transmit credits (unused) */
- int rd_pending; /* packets sent but not complete */
-
- struct timeout rd_timeout; /* timeout */
- struct mbuf *rd_txbuf; /* transmit buffer */
-
- const struct btproto *rd_proto; /* upper layer callbacks */
- void *rd_upper; /* upper layer argument */
-
- LIST_ENTRY(rfcomm_dlc) rd_next; /* next dlc on session */
-};
-
-/*
- * Credit Flow Control works in the following way.
- *
- * txcred is how many packets we can send. Received credit
- * is added to this value, and it is decremented each time
- * we send a packet.
- *
- * rxsize is the number of bytes that are available in the
- * upstream receive buffer.
- *
- * rxcred is the number of credits that we have previously
- * sent that are still unused. This value will be decreased
- * for each packet we receive and we will add to it when we
- * send credits. We calculate the amount of credits to send
- * by the cunning formula "(space / mtu) - sent" so that if
- * we get a bunch of small packets, we can continue sending
- * credits without risking buffer overflow.
- */
-
-/* DLC flags */
-#define RFCOMM_DLC_DETACH (1 << 0) /* DLC to be detached */
-#define RFCOMM_DLC_SHUTDOWN (1 << 1) /* DLC to be shutdown */
-
-/* DLC state */
-#define RFCOMM_DLC_CLOSED 0 /* no session */
-#define RFCOMM_DLC_WAIT_SESSION 1 /* waiting for session */
-#define RFCOMM_DLC_WAIT_CONNECT 2 /* waiting for connect */
-#define RFCOMM_DLC_WAIT_SEND_SABM 3 /* waiting to send SABM */
-#define RFCOMM_DLC_WAIT_SEND_UA 4 /* waiting to send UA */
-#define RFCOMM_DLC_WAIT_RECV_UA 5 /* waiting to receive UA */
-#define RFCOMM_DLC_OPEN 6 /* can send/receive */
-#define RFCOMM_DLC_WAIT_DISCONNECT 7 /* waiting for disconnect */
-#define RFCOMM_DLC_LISTEN 8 /* listening DLC */
-
-/*
- * Bluetooth RFCOMM socket kernel prototypes
- */
-
-struct socket;
-
-/* rfcomm_dlc.c */
-struct rfcomm_dlc *rfcomm_dlc_lookup(struct rfcomm_session *, int);
-struct rfcomm_dlc *rfcomm_dlc_newconn(struct rfcomm_session *, int);
-void rfcomm_dlc_close(struct rfcomm_dlc *, int);
-void rfcomm_dlc_timeout(void *);
-int rfcomm_dlc_setmode(struct rfcomm_dlc *);
-int rfcomm_dlc_connect(struct rfcomm_dlc *);
-int rfcomm_dlc_open(struct rfcomm_dlc *);
-void rfcomm_dlc_start(struct rfcomm_dlc *);
-
-/* rfcomm_session.c */
-void rfcomm_init(void);
-struct rfcomm_session *rfcomm_session_alloc(struct rfcomm_session_list *, struct sockaddr_bt *);
-struct rfcomm_session *rfcomm_session_lookup(struct sockaddr_bt *, struct sockaddr_bt *);
-void rfcomm_session_free(struct rfcomm_session *);
-int rfcomm_session_send_frame(struct rfcomm_session *, int, int);
-int rfcomm_session_send_uih(struct rfcomm_session *, struct rfcomm_dlc *, int, struct mbuf *);
-int rfcomm_session_send_mcc(struct rfcomm_session *, int, uint8_t, void *, int);
-
-/* rfcomm_socket.c */
-int rfcomm_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
- struct mbuf *, struct proc *);
-int rfcomm_ctloutput(int, struct socket *, int, int, struct mbuf **);
-
-/* rfcomm_upper.c */
-int rfcomm_attach(struct rfcomm_dlc **, const struct btproto *, void *);
-int rfcomm_bind(struct rfcomm_dlc *, struct sockaddr_bt *);
-int rfcomm_sockaddr(struct rfcomm_dlc *, struct sockaddr_bt *);
-int rfcomm_connect(struct rfcomm_dlc *, struct sockaddr_bt *);
-int rfcomm_peeraddr(struct rfcomm_dlc *, struct sockaddr_bt *);
-int rfcomm_disconnect(struct rfcomm_dlc *, int);
-int rfcomm_detach(struct rfcomm_dlc **);
-int rfcomm_listen(struct rfcomm_dlc *);
-int rfcomm_send(struct rfcomm_dlc *, struct mbuf *);
-int rfcomm_rcvd(struct rfcomm_dlc *, size_t);
-int rfcomm_setopt(struct rfcomm_dlc *, int, struct mbuf *);
-int rfcomm_getopt(struct rfcomm_dlc *, int, void *);
-
-#endif /* _KERNEL */
-
-#endif /* _NETBT_RFCOMM_H_ */
diff --git a/sys/netbt/rfcomm_dlc.c b/sys/netbt/rfcomm_dlc.c
deleted file mode 100644
index 843474c8ca1..00000000000
--- a/sys/netbt/rfcomm_dlc.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/* $OpenBSD: rfcomm_dlc.c,v 1.5 2009/11/21 13:05:32 guenther Exp $ */
-/* $NetBSD: rfcomm_dlc.c,v 1.6 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-#include <netbt/rfcomm.h>
-
-/*
- * rfcomm_dlc_lookup(rfcomm_session, dlci)
- *
- * Find DLC on session with matching dlci
- */
-struct rfcomm_dlc *
-rfcomm_dlc_lookup(struct rfcomm_session *rs, int dlci)
-{
- struct rfcomm_dlc *dlc;
-
- LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
- if (dlc->rd_dlci == dlci)
- break;
- }
-
- return dlc;
-}
-
-/*
- * rfcomm_dlc_newconn(rfcomm_session, dlci)
- *
- * handle a new dlc request (since its called from a couple of places)
- */
-struct rfcomm_dlc *
-rfcomm_dlc_newconn(struct rfcomm_session *rs, int dlci)
-{
- struct rfcomm_session *ls;
- struct rfcomm_dlc *new, *dlc, *any, *best;
- struct sockaddr_bt laddr, raddr, addr;
- int chan;
-
- /*
- * Search amongst the listening DLC community for the best match for
- * address & channel. We keep listening DLC's hanging on listening
- * sessions in a last first order, so scan the entire bunch and keep
- * a note of the best address and BDADDR_ANY matches in order to find
- * the oldest and most specific match.
- */
- l2cap_sockaddr(rs->rs_l2cap, &laddr);
- l2cap_peeraddr(rs->rs_l2cap, &raddr);
- chan = RFCOMM_CHANNEL(dlci);
- new = NULL;
-
- any = best = NULL;
- LIST_FOREACH(ls, &rfcomm_session_listen, rs_next) {
- l2cap_sockaddr(ls->rs_l2cap, &addr);
-
- if (addr.bt_psm != laddr.bt_psm)
- continue;
-
- if (bdaddr_same(&laddr.bt_bdaddr, &addr.bt_bdaddr)) {
- LIST_FOREACH(dlc, &ls->rs_dlcs, rd_next) {
- if (dlc->rd_laddr.bt_channel == chan)
- best = dlc;
- }
- }
-
- if (bdaddr_any(&addr.bt_bdaddr)) {
- LIST_FOREACH(dlc, &ls->rs_dlcs, rd_next) {
- if (dlc->rd_laddr.bt_channel == chan)
- any = dlc;
- }
- }
- }
-
- dlc = best ? best : any;
-
- /* XXX
- * Note that if this fails, we could have missed a chance to open
- * a connection - really need to rewrite the strategy for storing
- * listening DLC's so all can be checked in turn..
- */
- if (dlc != NULL)
- new = (*dlc->rd_proto->newconn)(dlc->rd_upper, &laddr, &raddr);
-
- if (new == NULL) {
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM, dlci);
- return NULL;
- }
-
- new->rd_dlci = dlci;
- new->rd_mtu = rfcomm_mtu_default;
- new->rd_mode = dlc->rd_mode;
-
- memcpy(&new->rd_laddr, &laddr, sizeof(struct sockaddr_bt));
- new->rd_laddr.bt_channel = chan;
-
- memcpy(&new->rd_raddr, &raddr, sizeof(struct sockaddr_bt));
- new->rd_raddr.bt_channel = chan;
-
- new->rd_session = rs;
- new->rd_state = RFCOMM_DLC_WAIT_CONNECT;
- LIST_INSERT_HEAD(&rs->rs_dlcs, new, rd_next);
-
- return new;
-}
-
-/*
- * rfcomm_dlc_close(dlc, error)
- *
- * detach DLC from session and clean up
- */
-void
-rfcomm_dlc_close(struct rfcomm_dlc *dlc, int err)
-{
- struct rfcomm_session *rs;
- struct rfcomm_credit *credit;
-
- KASSERT(dlc->rd_state != RFCOMM_DLC_CLOSED);
-
- /* Clear credit history */
- rs = dlc->rd_session;
- SIMPLEQ_FOREACH(credit, &rs->rs_credits, rc_next)
- if (credit->rc_dlc == dlc)
- credit->rc_dlc = NULL;
-
- timeout_del(&dlc->rd_timeout);
-
- LIST_REMOVE(dlc, rd_next);
- dlc->rd_session = NULL;
- dlc->rd_state = RFCOMM_DLC_CLOSED;
-
- (*dlc->rd_proto->disconnected)(dlc->rd_upper, err);
-
- /*
- * It is the responsibility of the party who sends the last
- * DISC(dlci) to disconnect the session, but we will schedule
- * an expiry just in case that doesnt happen..
- */
- if (LIST_EMPTY(&rs->rs_dlcs)) {
- if (rs->rs_state == RFCOMM_SESSION_LISTEN)
- rfcomm_session_free(rs);
- else
- timeout_add_sec(&rs->rs_timeout, rfcomm_ack_timeout);
- }
-}
-
-/*
- * rfcomm_dlc_timeout(dlc)
- *
- * DLC timeout function is schedUled when we sent any of SABM,
- * DISC, MCC_MSC, or MCC_PN and should be cancelled when we get
- * the relevant response. There is nothing to do but shut this
- * DLC down.
- */
-void
-rfcomm_dlc_timeout(void *arg)
-{
- struct rfcomm_dlc *dlc = arg;
-
- mutex_enter(&bt_lock);
-
- if (dlc->rd_state != RFCOMM_DLC_CLOSED)
- rfcomm_dlc_close(dlc, ETIMEDOUT);
- else if (dlc->rd_flags & RFCOMM_DLC_DETACH)
- free(dlc, M_BLUETOOTH);
-
- mutex_exit(&bt_lock);
-}
-
-/*
- * rfcomm_dlc_setmode(rfcomm_dlc)
- *
- * Set link mode for DLC. This is only called when the session is
- * already open, so we don't need to worry about any previous mode
- * settings.
- */
-int
-rfcomm_dlc_setmode(struct rfcomm_dlc *dlc)
-{
- int mode = 0;
-
- KASSERT(dlc->rd_session != NULL);
- KASSERT(dlc->rd_session->rs_state == RFCOMM_SESSION_OPEN);
-
- DPRINTF("dlci %d, auth %s, encrypt %s, secure %s\n", dlc->rd_dlci,
- (dlc->rd_mode & RFCOMM_LM_AUTH ? "yes" : "no"),
- (dlc->rd_mode & RFCOMM_LM_ENCRYPT ? "yes" : "no"),
- (dlc->rd_mode & RFCOMM_LM_SECURE ? "yes" : "no"));
-
- if (dlc->rd_mode & RFCOMM_LM_AUTH)
- mode |= L2CAP_LM_AUTH;
-
- if (dlc->rd_mode & RFCOMM_LM_ENCRYPT)
- mode |= L2CAP_LM_ENCRYPT;
-
- if (dlc->rd_mode & RFCOMM_LM_SECURE)
- mode |= L2CAP_LM_SECURE;
-
- return l2cap_setlinkmode(dlc->rd_session->rs_l2cap, mode);
-}
-
-/*
- * rfcomm_dlc_connect(rfcomm_dlc)
- *
- * initiate DLC connection (session is already connected)
- */
-int
-rfcomm_dlc_connect(struct rfcomm_dlc *dlc)
-{
- struct rfcomm_mcc_pn pn;
- int err = 0;
-
- KASSERT(dlc->rd_session != NULL);
- KASSERT(dlc->rd_session->rs_state == RFCOMM_SESSION_OPEN);
- KASSERT(dlc->rd_state == RFCOMM_DLC_WAIT_SESSION);
-
- /*
- * If we have not already sent a PN on the session, we must send
- * a PN to negotiate Credit Flow Control, and this setting will
- * apply to all future connections for this session. We ask for
- * this every time, in order to establish initial credits.
- */
- memset(&pn, 0, sizeof(pn));
- pn.dlci = dlc->rd_dlci;
- pn.priority = dlc->rd_dlci | 0x07;
- pn.mtu = htole16(dlc->rd_mtu);
-
- pn.flow_control = 0xf0;
- dlc->rd_rxcred = (dlc->rd_rxsize / dlc->rd_mtu);
- dlc->rd_rxcred = min(dlc->rd_rxcred, RFCOMM_CREDITS_DEFAULT);
- pn.credits = dlc->rd_rxcred;
-
- err = rfcomm_session_send_mcc(dlc->rd_session, 1,
- RFCOMM_MCC_PN, &pn, sizeof(pn));
- if (err)
- return err;
-
- dlc->rd_state = RFCOMM_DLC_WAIT_CONNECT;
- timeout_add_sec(&dlc->rd_timeout, rfcomm_mcc_timeout);
-
- return 0;
-}
-
-/*
- * rfcomm_dlc_open(rfcomm_dlc)
- *
- * send "Modem Status Command" and mark DLC as open.
- */
-int
-rfcomm_dlc_open(struct rfcomm_dlc *dlc)
-{
- struct rfcomm_mcc_msc msc;
- int err;
-
- KASSERT(dlc->rd_session != NULL);
- KASSERT(dlc->rd_session->rs_state == RFCOMM_SESSION_OPEN);
-
- memset(&msc, 0, sizeof(msc));
- msc.address = RFCOMM_MKADDRESS(1, dlc->rd_dlci);
- msc.modem = dlc->rd_lmodem & 0xfe; /* EA = 0 */
- msc.brk = 0x00 | 0x01; /* EA = 1 */
-
- err = rfcomm_session_send_mcc(dlc->rd_session, 1,
- RFCOMM_MCC_MSC, &msc, sizeof(msc));
- if (err)
- return err;
-
- timeout_add_sec(&dlc->rd_timeout, rfcomm_mcc_timeout);
-
- dlc->rd_state = RFCOMM_DLC_OPEN;
- (*dlc->rd_proto->connected)(dlc->rd_upper);
-
- return 0;
-}
-
-/*
- * rfcomm_dlc_start(rfcomm_dlc)
- *
- * Start sending data (and/or credits) for DLC. Our strategy is to
- * send anything we can down to the l2cap layer. When credits run
- * out, data will naturally bunch up. When not using credit flow
- * control, we limit the number of packets we have pending to reduce
- * flow control lag.
- * We should deal with channel priority somehow.
- */
-void
-rfcomm_dlc_start(struct rfcomm_dlc *dlc)
-{
- struct rfcomm_session *rs = dlc->rd_session;
- struct mbuf *m;
- int len, credits;
-
- KASSERT(rs != NULL);
- KASSERT(rs->rs_state == RFCOMM_SESSION_OPEN);
- KASSERT(dlc->rd_state == RFCOMM_DLC_OPEN);
-
- for (;;) {
- credits = 0;
- len = dlc->rd_mtu;
- if (rs->rs_flags & RFCOMM_SESSION_CFC) {
- credits = (dlc->rd_rxsize / dlc->rd_mtu);
- credits -= dlc->rd_rxcred;
- credits = min(credits, RFCOMM_CREDITS_MAX);
-
- if (credits > 0)
- len--;
-
- if (dlc->rd_txcred == 0)
- len = 0;
- } else {
- if (rs->rs_flags & RFCOMM_SESSION_RFC)
- break;
-
- if (dlc->rd_rmodem & RFCOMM_MSC_FC)
- break;
-
- if (dlc->rd_pending > RFCOMM_CREDITS_DEFAULT)
- break;
- }
-
- if (dlc->rd_txbuf == NULL)
- len = 0;
-
- if (len == 0) {
- if (credits == 0)
- break;
-
- /*
- * No need to send small numbers of credits on their
- * own unless the other end hasn't many left.
- */
- if (credits < RFCOMM_CREDITS_DEFAULT
- && dlc->rd_rxcred > RFCOMM_CREDITS_DEFAULT)
- break;
-
- m = NULL;
- } else {
- /*
- * take what data we can from (front of) txbuf
- */
- m = dlc->rd_txbuf;
- if (len < m->m_pkthdr.len) {
- dlc->rd_txbuf = m_split(m, len, M_DONTWAIT);
- if (dlc->rd_txbuf == NULL) {
- dlc->rd_txbuf = m;
- break;
- }
- } else {
- dlc->rd_txbuf = NULL;
- len = m->m_pkthdr.len;
- }
- }
-
- DPRINTFN(10, "dlci %d send %d bytes, %d credits, rxcred = %d\n",
- dlc->rd_dlci, len, credits, dlc->rd_rxcred);
-
- if (rfcomm_session_send_uih(rs, dlc, credits, m)) {
- printf("%s: lost %d bytes on DLCI %d\n",
- __func__, len, dlc->rd_dlci);
-
- break;
- }
-
- dlc->rd_pending++;
-
- if (rs->rs_flags & RFCOMM_SESSION_CFC) {
- if (len > 0)
- dlc->rd_txcred--;
-
- if (credits > 0)
- dlc->rd_rxcred += credits;
- }
- }
-}
diff --git a/sys/netbt/rfcomm_session.c b/sys/netbt/rfcomm_session.c
deleted file mode 100644
index d3e9e4aa9f9..00000000000
--- a/sys/netbt/rfcomm_session.c
+++ /dev/null
@@ -1,1686 +0,0 @@
-/* $OpenBSD: rfcomm_session.c,v 1.8 2010/07/29 14:40:47 blambert Exp $ */
-/* $NetBSD: rfcomm_session.c,v 1.14 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/pool.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/types.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-#include <netbt/rfcomm.h>
-
-/******************************************************************************
- *
- * RFCOMM Multiplexer Sessions sit directly on L2CAP channels, and can
- * multiplex up to 30 incoming and 30 outgoing connections.
- * Only one Multiplexer is allowed between any two devices.
- */
-
-static void rfcomm_session_timeout(void *);
-static void rfcomm_session_recv_sabm(struct rfcomm_session *, int);
-static void rfcomm_session_recv_disc(struct rfcomm_session *, int);
-static void rfcomm_session_recv_ua(struct rfcomm_session *, int);
-static void rfcomm_session_recv_dm(struct rfcomm_session *, int);
-static void rfcomm_session_recv_uih(struct rfcomm_session *, int, int, struct mbuf *, int);
-static void rfcomm_session_recv_mcc(struct rfcomm_session *, struct mbuf *);
-static void rfcomm_session_recv_mcc_test(struct rfcomm_session *, int, struct mbuf *);
-static void rfcomm_session_recv_mcc_fcon(struct rfcomm_session *, int);
-static void rfcomm_session_recv_mcc_fcoff(struct rfcomm_session *, int);
-static void rfcomm_session_recv_mcc_msc(struct rfcomm_session *, int, struct mbuf *);
-static void rfcomm_session_recv_mcc_rpn(struct rfcomm_session *, int, struct mbuf *);
-static void rfcomm_session_recv_mcc_rls(struct rfcomm_session *, int, struct mbuf *);
-static void rfcomm_session_recv_mcc_pn(struct rfcomm_session *, int, struct mbuf *);
-static void rfcomm_session_recv_mcc_nsc(struct rfcomm_session *, int, struct mbuf *);
-
-/* L2CAP callbacks */
-static void rfcomm_session_connecting(void *);
-static void rfcomm_session_connected(void *);
-static void rfcomm_session_disconnected(void *, int);
-static void *rfcomm_session_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
-static void rfcomm_session_complete(void *, int);
-static void rfcomm_session_linkmode(void *, int);
-static void rfcomm_session_input(void *, struct mbuf *);
-
-static const struct btproto rfcomm_session_proto = {
- rfcomm_session_connecting,
- rfcomm_session_connected,
- rfcomm_session_disconnected,
- rfcomm_session_newconn,
- rfcomm_session_complete,
- rfcomm_session_linkmode,
- rfcomm_session_input,
-};
-
-struct rfcomm_session_list
- rfcomm_session_active = LIST_HEAD_INITIALIZER(rfcomm_session_active);
-
-struct rfcomm_session_list
- rfcomm_session_listen = LIST_HEAD_INITIALIZER(rfcomm_session_listen);
-
-struct pool rfcomm_credit_pool;
-
-/*
- * RFCOMM System Parameters (see section 5.3)
- */
-int rfcomm_mtu_default = 127; /* bytes */
-int rfcomm_ack_timeout = 20; /* seconds */
-int rfcomm_mcc_timeout = 20; /* seconds */
-
-/*
- * Reversed CRC table as per TS 07.10 Annex B.3.5
- */
-static const uint8_t crctable[256] = { /* reversed, 8-bit, poly=0x07 */
- 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
- 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
- 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
- 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
-
- 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
- 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
- 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
- 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
-
- 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
- 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
- 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
- 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
-
- 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
- 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
- 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
- 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
-
- 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
- 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
- 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
- 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
-
- 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
- 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
- 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
- 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
-
- 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
- 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
- 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
- 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
-
- 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
- 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
- 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
- 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
-};
-
-#define FCS(f, d) crctable[(f) ^ (d)]
-
-/*
- * rfcomm_init()
- *
- * initialize the "credit pool".
- */
-void
-rfcomm_init(void)
-{
- pool_init(&rfcomm_credit_pool, 0, 0, 0, 0, "rfcomm_credit", NULL);
-}
-
-/*
- * rfcomm_session_alloc(list, sockaddr)
- *
- * allocate a new session and fill in the blanks, then
- * attach session to front of specified list (active or listen)
- */
-struct rfcomm_session *
-rfcomm_session_alloc(struct rfcomm_session_list *list,
- struct sockaddr_bt *laddr)
-{
- struct rfcomm_session *rs;
- int err;
-
- rs = malloc(sizeof(*rs), M_BLUETOOTH, M_NOWAIT | M_ZERO);
- if (rs == NULL)
- return NULL;
-
- rs->rs_state = RFCOMM_SESSION_CLOSED;
-
- timeout_set(&rs->rs_timeout, rfcomm_session_timeout, rs);
-
- SIMPLEQ_INIT(&rs->rs_credits);
- LIST_INIT(&rs->rs_dlcs);
-
- err = l2cap_attach(&rs->rs_l2cap, &rfcomm_session_proto, rs);
- if (err) {
- free(rs, M_BLUETOOTH);
- return NULL;
- }
-
- (void)l2cap_getopt(rs->rs_l2cap, SO_L2CAP_OMTU, &rs->rs_mtu);
-
- if (laddr->bt_psm == L2CAP_PSM_ANY)
- laddr->bt_psm = L2CAP_PSM_RFCOMM;
-
- (void)l2cap_bind(rs->rs_l2cap, laddr);
-
- LIST_INSERT_HEAD(list, rs, rs_next);
-
- return rs;
-}
-
-/*
- * rfcomm_session_free(rfcomm_session)
- *
- * release a session, including any cleanup
- */
-void
-rfcomm_session_free(struct rfcomm_session *rs)
-{
- struct rfcomm_credit *credit;
-
- KASSERT(rs != NULL);
- KASSERT(LIST_EMPTY(&rs->rs_dlcs));
-
- rs->rs_state = RFCOMM_SESSION_CLOSED;
-
- /*
- * If the callout is already invoked we have no way to stop it,
- * but it will call us back right away (there are no DLC's) so
- * not to worry.
- */
- timeout_del(&rs->rs_timeout);
- if (timeout_triggered(&rs->rs_timeout))
- return;
-
- /*
- * Take care that rfcomm_session_disconnected() doesnt call
- * us back either as it will do if the l2cap_channel has not
- * been closed when we detach it..
- */
- if (rs->rs_flags & RFCOMM_SESSION_FREE)
- return;
-
- rs->rs_flags |= RFCOMM_SESSION_FREE;
-
- /* throw away any remaining credit notes */
- while ((credit = SIMPLEQ_FIRST(&rs->rs_credits)) != NULL) {
- SIMPLEQ_REMOVE_HEAD(&rs->rs_credits, rc_next);
- pool_put(&rfcomm_credit_pool, credit);
- }
-
- KASSERT(SIMPLEQ_EMPTY(&rs->rs_credits));
-
- /* Goodbye! */
- LIST_REMOVE(rs, rs_next);
- l2cap_detach(&rs->rs_l2cap);
- free(rs, M_BLUETOOTH);
-}
-
-/*
- * rfcomm_session_lookup(sockaddr, sockaddr)
- *
- * Find active rfcomm session matching src and dest addresses
- * when src is BDADDR_ANY match any local address
- */
-struct rfcomm_session *
-rfcomm_session_lookup(struct sockaddr_bt *src, struct sockaddr_bt *dest)
-{
- struct rfcomm_session *rs;
- struct sockaddr_bt addr;
-
- LIST_FOREACH(rs, &rfcomm_session_active, rs_next) {
- if (rs->rs_state == RFCOMM_SESSION_CLOSED)
- continue;
-
- l2cap_sockaddr(rs->rs_l2cap, &addr);
-
- if (bdaddr_same(&src->bt_bdaddr, &addr.bt_bdaddr) == 0)
- if (bdaddr_any(&src->bt_bdaddr) == 0)
- continue;
-
- l2cap_peeraddr(rs->rs_l2cap, &addr);
-
- if (addr.bt_psm != dest->bt_psm)
- continue;
-
- if (bdaddr_same(&dest->bt_bdaddr, &addr.bt_bdaddr))
- break;
- }
-
- return rs;
-}
-
-/*
- * rfcomm_session_timeout(rfcomm_session)
- *
- * Session timeouts are scheduled when a session is left or
- * created with no DLCs, and when SABM(0) or DISC(0) are
- * sent.
- *
- * So, if it is in an open state with DLC's attached then
- * we leave it alone, otherwise the session is lost.
- */
-static void
-rfcomm_session_timeout(void *arg)
-{
- struct rfcomm_session *rs = arg;
- struct rfcomm_dlc *dlc;
-
- KASSERT(rs != NULL);
-
- mutex_enter(&bt_lock);
-
- if (rs->rs_state != RFCOMM_SESSION_OPEN) {
- DPRINTF("timeout\n");
- rs->rs_state = RFCOMM_SESSION_CLOSED;
-
- while (!LIST_EMPTY(&rs->rs_dlcs)) {
- dlc = LIST_FIRST(&rs->rs_dlcs);
-
- rfcomm_dlc_close(dlc, ETIMEDOUT);
- }
- }
-
- if (LIST_EMPTY(&rs->rs_dlcs)) {
- DPRINTF("expiring\n");
- rfcomm_session_free(rs);
- }
- mutex_exit(&bt_lock);
-}
-
-/***********************************************************************
- *
- * RFCOMM Session L2CAP protocol callbacks
- *
- */
-
-static void
-rfcomm_session_connecting(void *arg)
-{
- /* struct rfcomm_session *rs = arg; */
-
- DPRINTF("Connecting\n");
-}
-
-static void
-rfcomm_session_connected(void *arg)
-{
- struct rfcomm_session *rs = arg;
-
- DPRINTF("Connected\n");
-
- /*
- * L2CAP is open.
- *
- * If we are initiator, we can send our SABM(0)
- * a timeout should be active?
- *
- * We must take note of the L2CAP MTU because currently
- * the L2CAP implementation can only do Basic Mode.
- */
- l2cap_getopt(rs->rs_l2cap, SO_L2CAP_OMTU, &rs->rs_mtu);
-
- rs->rs_mtu -= 6; /* (RFCOMM overhead could be this big) */
- if (rs->rs_mtu < RFCOMM_MTU_MIN) {
- rfcomm_session_disconnected(rs, EINVAL);
- return;
- }
-
- if (IS_INITIATOR(rs)) {
- int err;
-
- err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_SABM, 0);
- if (err)
- rfcomm_session_disconnected(rs, err);
-
- timeout_add_sec(&rs->rs_timeout, rfcomm_ack_timeout);
- }
-}
-
-static void
-rfcomm_session_disconnected(void *arg, int err)
-{
- struct rfcomm_session *rs = arg;
- struct rfcomm_dlc *dlc;
-
- DPRINTF("Disconnected\n");
-
- rs->rs_state = RFCOMM_SESSION_CLOSED;
-
- while (!LIST_EMPTY(&rs->rs_dlcs)) {
- dlc = LIST_FIRST(&rs->rs_dlcs);
-
- rfcomm_dlc_close(dlc, err);
- }
-
- rfcomm_session_free(rs);
-}
-
-static void *
-rfcomm_session_newconn(void *arg, struct sockaddr_bt *laddr,
- struct sockaddr_bt *raddr)
-{
- struct rfcomm_session *new, *rs = arg;
-
- DPRINTF("New Connection\n");
-
- /*
- * Incoming session connect request. We should return a new
- * session pointer if this is acceptable. The L2CAP layer
- * passes local and remote addresses, which we must check as
- * only one RFCOMM session is allowed between any two devices
- */
- new = rfcomm_session_lookup(laddr, raddr);
- if (new != NULL)
- return NULL;
-
- new = rfcomm_session_alloc(&rfcomm_session_active, laddr);
- if (new == NULL)
- return NULL;
-
- new->rs_mtu = rs->rs_mtu;
- new->rs_state = RFCOMM_SESSION_WAIT_CONNECT;
-
- /*
- * schedule an expiry so that if nothing comes of it we
- * can punt.
- */
- timeout_add_sec(&new->rs_timeout, rfcomm_mcc_timeout);
-
- return new->rs_l2cap;
-}
-
-static void
-rfcomm_session_complete(void *arg, int count)
-{
- struct rfcomm_session *rs = arg;
- struct rfcomm_credit *credit;
- struct rfcomm_dlc *dlc;
-
- /*
- * count L2CAP packets are 'complete', meaning that they are cleared
- * our buffers (for best effort) or arrived safe (for guaranteed) so
- * we can take it off our list and pass the message on, so that
- * eventually the data can be removed from the sockbuf
- */
- while (count-- > 0) {
- credit = SIMPLEQ_FIRST(&rs->rs_credits);
-#ifdef DIAGNOSTIC
- if (credit == NULL) {
- printf("%s: too many packets completed!\n", __func__);
- break;
- }
-#endif
- dlc = credit->rc_dlc;
- if (dlc != NULL) {
- dlc->rd_pending--;
- (*dlc->rd_proto->complete)
- (dlc->rd_upper, credit->rc_len);
-
- /*
- * if not using credit flow control, we may push
- * more data now
- */
- if ((rs->rs_flags & RFCOMM_SESSION_CFC) == 0
- && dlc->rd_state == RFCOMM_DLC_OPEN) {
- rfcomm_dlc_start(dlc);
- }
-
- /*
- * When shutdown is indicated, we are just waiting to
- * clear outgoing data.
- */
- if ((dlc->rd_flags & RFCOMM_DLC_SHUTDOWN)
- && dlc->rd_txbuf == NULL && dlc->rd_pending == 0) {
- dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
- dlc->rd_dlci);
- timeout_add_sec(&dlc->rd_timeout,
- rfcomm_ack_timeout);
- }
- }
-
- SIMPLEQ_REMOVE_HEAD(&rs->rs_credits, rc_next);
- pool_put(&rfcomm_credit_pool, credit);
- }
-
- /*
- * If session is closed, we are just waiting to clear the queue
- */
- if (rs->rs_state == RFCOMM_SESSION_CLOSED) {
- if (SIMPLEQ_EMPTY(&rs->rs_credits))
- l2cap_disconnect(rs->rs_l2cap, 0);
- }
-}
-
-/*
- * Link Mode changed
- *
- * This is called when a mode change is complete. Proceed with connections
- * where appropriate, or pass the new mode to any active DLCs.
- */
-static void
-rfcomm_session_linkmode(void *arg, int new)
-{
- struct rfcomm_session *rs = arg;
- struct rfcomm_dlc *dlc, *next;
- int err, mode = 0;
-
- DPRINTF("auth %s, encrypt %s, secure %s\n",
- (new & L2CAP_LM_AUTH ? "on" : "off"),
- (new & L2CAP_LM_ENCRYPT ? "on" : "off"),
- (new & L2CAP_LM_SECURE ? "on" : "off"));
-
- if (new & L2CAP_LM_AUTH)
- mode |= RFCOMM_LM_AUTH;
-
- if (new & L2CAP_LM_ENCRYPT)
- mode |= RFCOMM_LM_ENCRYPT;
-
- if (new & L2CAP_LM_SECURE)
- mode |= RFCOMM_LM_SECURE;
-
- next = LIST_FIRST(&rs->rs_dlcs);
- while ((dlc = next) != NULL) {
- next = LIST_NEXT(dlc, rd_next);
-
- switch (dlc->rd_state) {
- case RFCOMM_DLC_WAIT_SEND_SABM: /* we are connecting */
- if ((mode & dlc->rd_mode) != dlc->rd_mode) {
- rfcomm_dlc_close(dlc, ECONNABORTED);
- } else {
- err = rfcomm_session_send_frame(rs,
- RFCOMM_FRAME_SABM, dlc->rd_dlci);
- if (err) {
- rfcomm_dlc_close(dlc, err);
- } else {
- dlc->rd_state = RFCOMM_DLC_WAIT_RECV_UA;
- timeout_add_sec(&dlc->rd_timeout,
- rfcomm_ack_timeout);
- break;
- }
- }
-
- /*
- * If we aborted the connection and there are no more DLCs
- * on the session, it is our responsibility to disconnect.
- */
- if (!LIST_EMPTY(&rs->rs_dlcs))
- break;
-
- rs->rs_state = RFCOMM_SESSION_WAIT_DISCONNECT;
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC, 0);
- timeout_add_sec(&rs->rs_timeout, rfcomm_ack_timeout);
- break;
-
- case RFCOMM_DLC_WAIT_SEND_UA: /* they are connecting */
- if ((mode & dlc->rd_mode) != dlc->rd_mode) {
- rfcomm_session_send_frame(rs,
- RFCOMM_FRAME_DM, dlc->rd_dlci);
- rfcomm_dlc_close(dlc, ECONNABORTED);
- break;
- }
-
- err = rfcomm_session_send_frame(rs,
- RFCOMM_FRAME_UA, dlc->rd_dlci);
- if (err) {
- rfcomm_session_send_frame(rs,
- RFCOMM_FRAME_DM, dlc->rd_dlci);
- rfcomm_dlc_close(dlc, err);
- break;
- }
-
- err = rfcomm_dlc_open(dlc);
- if (err) {
- rfcomm_session_send_frame(rs,
- RFCOMM_FRAME_DM, dlc->rd_dlci);
- rfcomm_dlc_close(dlc, err);
- break;
- }
-
- break;
-
- case RFCOMM_DLC_WAIT_RECV_UA:
- case RFCOMM_DLC_OPEN: /* already established */
- (*dlc->rd_proto->linkmode)(dlc->rd_upper, mode);
- break;
-
- default:
- break;
- }
- }
-}
-
-/*
- * Receive data from L2CAP layer for session. There is always exactly one
- * RFCOMM frame contained in each L2CAP frame.
- */
-static void
-rfcomm_session_input(void *arg, struct mbuf *m)
-{
- struct rfcomm_session *rs = arg;
- int dlci, len, type, pf;
- uint8_t fcs, b;
-
- KASSERT(m != NULL);
- KASSERT(rs != NULL);
-
- /*
- * UIH frames: FCS is only calculated on address and control fields
- * For other frames: FCS is calculated on address, control and length
- * Length may extend to two octets
- */
- fcs = 0xff;
-
- if (m->m_pkthdr.len < 4) {
- DPRINTF("short frame (%d), discarded\n", m->m_pkthdr.len);
- goto done;
- }
-
- /* address - one octet */
- m_copydata(m, 0, 1, &b);
- m_adj(m, 1);
- fcs = FCS(fcs, b);
- dlci = RFCOMM_DLCI(b);
-
- /* control - one octet */
- m_copydata(m, 0, 1, &b);
- m_adj(m, 1);
- fcs = FCS(fcs, b);
- type = RFCOMM_TYPE(b);
- pf = RFCOMM_PF(b);
-
- /* length - may be two octets */
- m_copydata(m, 0, 1, &b);
- m_adj(m, 1);
- if (type != RFCOMM_FRAME_UIH)
- fcs = FCS(fcs, b);
- len = (b >> 1) & 0x7f;
-
- if (RFCOMM_EA(b) == 0) {
- if (m->m_pkthdr.len < 2) {
- DPRINTF("short frame (%d, EA = 0), discarded\n",
- m->m_pkthdr.len);
- goto done;
- }
-
- m_copydata(m, 0, 1, &b);
- m_adj(m, 1);
- if (type != RFCOMM_FRAME_UIH)
- fcs = FCS(fcs, b);
-
- len |= (b << 7);
- }
-
- /* FCS byte is last octet in frame */
- m_copydata(m, m->m_pkthdr.len - 1, 1, &b);
- m_adj(m, -1);
- fcs = FCS(fcs, b);
-
- if (fcs != 0xcf) {
- DPRINTF("Bad FCS value (%#2.2x), frame discarded\n", fcs);
- goto done;
- }
-
- DPRINTFN(10, "dlci %d, type %2.2x, len = %d\n", dlci, type, len);
-
- switch (type) {
- case RFCOMM_FRAME_SABM:
- if (pf)
- rfcomm_session_recv_sabm(rs, dlci);
- break;
-
- case RFCOMM_FRAME_DISC:
- if (pf)
- rfcomm_session_recv_disc(rs, dlci);
- break;
-
- case RFCOMM_FRAME_UA:
- if (pf)
- rfcomm_session_recv_ua(rs, dlci);
- break;
-
- case RFCOMM_FRAME_DM:
- rfcomm_session_recv_dm(rs, dlci);
- break;
-
- case RFCOMM_FRAME_UIH:
- rfcomm_session_recv_uih(rs, dlci, pf, m, len);
- return; /* (no release) */
-
- default:
- UNKNOWN(type);
- break;
- }
-
-done:
- m_freem(m);
-}
-
-/***********************************************************************
- *
- * RFCOMM Session receive processing
- */
-
-/*
- * rfcomm_session_recv_sabm(rfcomm_session, dlci)
- *
- * Set Asyncrhonous Balanced Mode - open the channel.
- */
-static void
-rfcomm_session_recv_sabm(struct rfcomm_session *rs, int dlci)
-{
- struct rfcomm_dlc *dlc;
- int err;
-
- DPRINTFN(5, "SABM(%d)\n", dlci);
-
- if (dlci == 0) { /* Open Session */
- rs->rs_state = RFCOMM_SESSION_OPEN;
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, 0);
- LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
- if (dlc->rd_state == RFCOMM_DLC_WAIT_SESSION)
- rfcomm_dlc_connect(dlc);
- }
- return;
- }
-
- if (rs->rs_state != RFCOMM_SESSION_OPEN) {
- DPRINTF("session was not even open!\n");
- return;
- }
-
- /* validate direction bit */
- if ((IS_INITIATOR(rs) && !RFCOMM_DIRECTION(dlci))
- || (!IS_INITIATOR(rs) && RFCOMM_DIRECTION(dlci))) {
- DPRINTF("Invalid direction bit on DLCI\n");
- return;
- }
-
- /*
- * look for our DLC - this may exist if we received PN
- * already, or we may have to fabricate a new one.
- */
- dlc = rfcomm_dlc_lookup(rs, dlci);
- if (dlc == NULL) {
- dlc = rfcomm_dlc_newconn(rs, dlci);
- if (dlc == NULL)
- return; /* (DM is sent) */
- }
-
- /*
- * ..but if this DLC is not waiting to connect, they did
- * something wrong, ignore it.
- */
- if (dlc->rd_state != RFCOMM_DLC_WAIT_CONNECT)
- return;
-
- /* set link mode */
- err = rfcomm_dlc_setmode(dlc);
- if (err == EINPROGRESS) {
- dlc->rd_state = RFCOMM_DLC_WAIT_SEND_UA;
- (*dlc->rd_proto->connecting)(dlc->rd_upper);
- return;
- }
- if (err)
- goto close;
-
- err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, dlci);
- if (err)
- goto close;
-
- /* and mark it open */
- err = rfcomm_dlc_open(dlc);
- if (err)
- goto close;
-
- return;
-
-close:
- rfcomm_dlc_close(dlc, err);
-}
-
-/*
- * Receive Disconnect Command
- */
-static void
-rfcomm_session_recv_disc(struct rfcomm_session *rs, int dlci)
-{
- struct rfcomm_dlc *dlc;
-
- DPRINTFN(5, "DISC(%d)\n", dlci);
-
- if (dlci == 0) {
- /*
- * Disconnect Session
- *
- * We set the session state to CLOSED so that when
- * the UA frame is clear the session will be closed
- * automatically. We wont bother to close any DLC's
- * just yet as there should be none. In the unlikely
- * event that something is left, it will get flushed
- * out as the session goes down.
- */
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, 0);
- rs->rs_state = RFCOMM_SESSION_CLOSED;
- return;
- }
-
- dlc = rfcomm_dlc_lookup(rs, dlci);
- if (dlc == NULL) {
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM, dlci);
- return;
- }
-
- rfcomm_dlc_close(dlc, ECONNRESET);
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, dlci);
-}
-
-/*
- * Receive Unnumbered Acknowledgement Response
- *
- * This should be a response to a DISC or SABM frame that we
- * have previously sent. If unexpected, ignore it.
- */
-static void
-rfcomm_session_recv_ua(struct rfcomm_session *rs, int dlci)
-{
- struct rfcomm_dlc *dlc;
-
- DPRINTFN(5, "UA(%d)\n", dlci);
-
- if (dlci == 0) {
- switch (rs->rs_state) {
- case RFCOMM_SESSION_WAIT_CONNECT: /* We sent SABM */
- timeout_del(&rs->rs_timeout);
- rs->rs_state = RFCOMM_SESSION_OPEN;
- LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
- if (dlc->rd_state == RFCOMM_DLC_WAIT_SESSION)
- rfcomm_dlc_connect(dlc);
- }
- break;
-
- case RFCOMM_SESSION_WAIT_DISCONNECT: /* We sent DISC */
- timeout_del(&rs->rs_timeout);
- rs->rs_state = RFCOMM_SESSION_CLOSED;
- l2cap_disconnect(rs->rs_l2cap, 0);
- break;
-
- default:
- DPRINTF("Received spurious UA(0)!\n");
- break;
- }
-
- return;
- }
-
- /*
- * If we have no DLC on this dlci, we may have aborted
- * without shutting down properly, so check if the session
- * needs disconnecting.
- */
- dlc = rfcomm_dlc_lookup(rs, dlci);
- if (dlc == NULL)
- goto check;
-
- switch (dlc->rd_state) {
- case RFCOMM_DLC_WAIT_RECV_UA: /* We sent SABM */
- rfcomm_dlc_open(dlc);
- return;
-
- case RFCOMM_DLC_WAIT_DISCONNECT: /* We sent DISC */
- rfcomm_dlc_close(dlc, 0);
- break;
-
- default:
- DPRINTF("Received spurious UA(%d)!\n", dlci);
- return;
- }
-
-check: /* last one out turns out the light */
- if (LIST_EMPTY(&rs->rs_dlcs)) {
- rs->rs_state = RFCOMM_SESSION_WAIT_DISCONNECT;
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC, 0);
- timeout_add_sec(&rs->rs_timeout, rfcomm_ack_timeout);
- }
-}
-
-/*
- * Receive Disconnected Mode Response
- *
- * If this does not apply to a known DLC then we may ignore it.
- */
-static void
-rfcomm_session_recv_dm(struct rfcomm_session *rs, int dlci)
-{
- struct rfcomm_dlc *dlc;
-
- DPRINTFN(5, "DM(%d)\n", dlci);
-
- dlc = rfcomm_dlc_lookup(rs, dlci);
- if (dlc == NULL)
- return;
-
- if (dlc->rd_state == RFCOMM_DLC_WAIT_CONNECT)
- rfcomm_dlc_close(dlc, ECONNREFUSED);
- else
- rfcomm_dlc_close(dlc, ECONNRESET);
-}
-
-/*
- * Receive Unnumbered Information with Header check (MCC or data packet)
- */
-static void
-rfcomm_session_recv_uih(struct rfcomm_session *rs, int dlci,
- int pf, struct mbuf *m, int len)
-{
- struct rfcomm_dlc *dlc;
- uint8_t credits = 0;
-
- DPRINTFN(10, "UIH(%d)\n", dlci);
-
- if (dlci == 0) {
- rfcomm_session_recv_mcc(rs, m);
- return;
- }
-
- if (m->m_pkthdr.len != len + pf) {
- DPRINTF("Bad Frame Length (%d), frame discarded\n",
- m->m_pkthdr.len);
-
- goto discard;
- }
-
- dlc = rfcomm_dlc_lookup(rs, dlci);
- if (dlc == NULL) {
- DPRINTF("UIH received for non existent DLC, discarded\n");
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM, dlci);
- goto discard;
- }
-
- if (dlc->rd_state != RFCOMM_DLC_OPEN) {
- DPRINTF("non-open DLC (state = %d), discarded\n",
- dlc->rd_state);
- goto discard;
- }
-
- /* if PF is set, credits were included */
- if (rs->rs_flags & RFCOMM_SESSION_CFC) {
- if (pf != 0) {
- if (m->m_pkthdr.len < sizeof(credits)) {
- DPRINTF("Bad PF value, UIH discarded\n");
- goto discard;
- }
-
- m_copydata(m, 0, sizeof(credits), &credits);
- m_adj(m, sizeof(credits));
-
- dlc->rd_txcred += credits;
-
- if (credits > 0 && dlc->rd_txbuf != NULL)
- rfcomm_dlc_start(dlc);
- }
-
- if (len == 0)
- goto discard;
-
- if (dlc->rd_rxcred == 0) {
- DPRINTF("Credit limit reached, UIH discarded\n");
- goto discard;
- }
-
- if (len > dlc->rd_rxsize) {
- DPRINTF("UIH frame exceeds rxsize, discarded\n");
- goto discard;
- }
-
- dlc->rd_rxcred--;
- dlc->rd_rxsize -= len;
- }
-
- (*dlc->rd_proto->input)(dlc->rd_upper, m);
- return;
-
-discard:
- m_freem(m);
-}
-
-/*
- * Receive Multiplexer Control Command
- */
-static void
-rfcomm_session_recv_mcc(struct rfcomm_session *rs, struct mbuf *m)
-{
- int type, cr, len;
- uint8_t b;
-
- /*
- * Extract MCC header.
- *
- * Fields are variable length using extension bit = 1 to signify the
- * last octet in the sequence.
- *
- * Only single octet types are defined in TS 07.10/RFCOMM spec
- *
- * Length can realistically only use 15 bits (max RFCOMM MTU)
- */
- if (m->m_pkthdr.len < sizeof(b)) {
- DPRINTF("Short MCC header, discarded\n");
- goto release;
- }
-
- m_copydata(m, 0, sizeof(b), &b);
- m_adj(m, sizeof(b));
-
- if (RFCOMM_EA(b) == 0) { /* verify no extensions */
- DPRINTF("MCC type EA = 0, discarded\n");
- goto release;
- }
-
- type = RFCOMM_MCC_TYPE(b);
- cr = RFCOMM_CR(b);
-
- len = 0;
- do {
- if (m->m_pkthdr.len < sizeof(b)) {
- DPRINTF("Short MCC header, discarded\n");
- goto release;
- }
-
- m_copydata(m, 0, sizeof(b), &b);
- m_adj(m, sizeof(b));
-
- len = (len << 7) | (b >> 1);
- len = min(len, RFCOMM_MTU_MAX);
- } while (RFCOMM_EA(b) == 0);
-
- if (len != m->m_pkthdr.len) {
- DPRINTF("Incorrect MCC length, discarded\n");
- goto release;
- }
-
- DPRINTFN(2, "MCC %s type %2.2x (%d bytes)\n",
- (cr ? "command" : "response"), type, len);
-
- /*
- * pass to command handler
- */
- switch(type) {
- case RFCOMM_MCC_TEST: /* Test */
- rfcomm_session_recv_mcc_test(rs, cr, m);
- break;
-
- case RFCOMM_MCC_FCON: /* Flow Control On */
- rfcomm_session_recv_mcc_fcon(rs, cr);
- break;
-
- case RFCOMM_MCC_FCOFF: /* Flow Control Off */
- rfcomm_session_recv_mcc_fcoff(rs, cr);
- break;
-
- case RFCOMM_MCC_MSC: /* Modem Status Command */
- rfcomm_session_recv_mcc_msc(rs, cr, m);
- break;
-
- case RFCOMM_MCC_RPN: /* Remote Port Negotiation */
- rfcomm_session_recv_mcc_rpn(rs, cr, m);
- break;
-
- case RFCOMM_MCC_RLS: /* Remote Line Status */
- rfcomm_session_recv_mcc_rls(rs, cr, m);
- break;
-
- case RFCOMM_MCC_PN: /* Parameter Negotiation */
- rfcomm_session_recv_mcc_pn(rs, cr, m);
- break;
-
- case RFCOMM_MCC_NSC: /* Non Supported Command */
- rfcomm_session_recv_mcc_nsc(rs, cr, m);
- break;
-
- default:
- b = RFCOMM_MKMCC_TYPE(cr, type);
- rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_NSC, &b, sizeof(b));
- }
-
-release:
- m_freem(m);
-}
-
-/*
- * process TEST command/response
- */
-static void
-rfcomm_session_recv_mcc_test(struct rfcomm_session *rs, int cr, struct mbuf *m)
-{
- void *data;
- int len;
-
- if (cr == 0) /* ignore ack */
- return;
-
- /*
- * we must send all the data they included back as is
- */
-
- len = m->m_pkthdr.len;
- if (len > RFCOMM_MTU_MAX)
- return;
-
- data = malloc(len, M_BLUETOOTH, M_NOWAIT);
- if (data == NULL)
- return;
-
- m_copydata(m, 0, len, data);
- rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_TEST, data, len);
- free(data, M_BLUETOOTH);
-}
-
-/*
- * process Flow Control ON command/response
- */
-static void
-rfcomm_session_recv_mcc_fcon(struct rfcomm_session *rs, int cr)
-{
-
- if (cr == 0) /* ignore ack */
- return;
-
- rs->rs_flags |= RFCOMM_SESSION_RFC;
- rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_FCON, NULL, 0);
-}
-
-/*
- * process Flow Control OFF command/response
- */
-static void
-rfcomm_session_recv_mcc_fcoff(struct rfcomm_session *rs, int cr)
-{
-
- if (cr == 0) /* ignore ack */
- return;
-
- rs->rs_flags &= ~RFCOMM_SESSION_RFC;
- rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_FCOFF, NULL, 0);
-}
-
-/*
- * process Modem Status Command command/response
- */
-static void
-rfcomm_session_recv_mcc_msc(struct rfcomm_session *rs, int cr, struct mbuf *m)
-{
- struct rfcomm_mcc_msc msc; /* (3 octets) */
- struct rfcomm_dlc *dlc;
- int len = 0;
-
- /* [ADDRESS] */
- if (m->m_pkthdr.len < sizeof(msc.address))
- return;
-
- m_copydata(m, 0, sizeof(msc.address), &msc.address);
- m_adj(m, sizeof(msc.address));
- len += sizeof(msc.address);
-
- dlc = rfcomm_dlc_lookup(rs, RFCOMM_DLCI(msc.address));
-
- if (cr == 0) { /* ignore acks */
- if (dlc != NULL)
- timeout_del(&dlc->rd_timeout);
-
- return;
- }
-
- if (dlc == NULL) {
- rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM,
- RFCOMM_DLCI(msc.address));
- return;
- }
-
- /* [SIGNALS] */
- if (m->m_pkthdr.len < sizeof(msc.modem))
- return;
-
- m_copydata(m, 0, sizeof(msc.modem), &msc.modem);
- m_adj(m, sizeof(msc.modem));
- len += sizeof(msc.modem);
-
- dlc->rd_rmodem = msc.modem;
- /* XXX how do we signal this upstream? */
-
- if (RFCOMM_EA(msc.modem) == 0) {
- if (m->m_pkthdr.len < sizeof(msc.brk))
- return;
-
- m_copydata(m, 0, sizeof(msc.brk), &msc.brk);
- m_adj(m, sizeof(msc.brk));
- len += sizeof(msc.brk);
-
- /* XXX how do we signal this upstream? */
- }
-
- rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_MSC, &msc, len);
-}
-
-/*
- * process Remote Port Negotiation command/response
- */
-static void
-rfcomm_session_recv_mcc_rpn(struct rfcomm_session *rs, int cr, struct mbuf *m)
-{
- struct rfcomm_mcc_rpn rpn;
- uint16_t mask;
-
- if (cr == 0) /* ignore ack */
- return;
-
- /* default values */
- rpn.bit_rate = RFCOMM_RPN_BR_9600;
- rpn.line_settings = RFCOMM_RPN_8_N_1;
- rpn.flow_control = RFCOMM_RPN_FLOW_NONE;
- rpn.xon_char = RFCOMM_RPN_XON_CHAR;
- rpn.xoff_char = RFCOMM_RPN_XOFF_CHAR;
-
- if (m->m_pkthdr.len == sizeof(rpn)) {
- m_copydata(m, 0, sizeof(rpn), (caddr_t)&rpn);
- rpn.param_mask = RFCOMM_RPN_PM_ALL;
- } else if (m->m_pkthdr.len == 1) {
- m_copydata(m, 0, 1, (caddr_t)&rpn);
- rpn.param_mask = letoh16(rpn.param_mask);
- } else {
- DPRINTF("Bad RPN length (%d)\n", m->m_pkthdr.len);
- return;
- }
-
- mask = 0;
-
- if (rpn.param_mask & RFCOMM_RPN_PM_RATE)
- mask |= RFCOMM_RPN_PM_RATE;
-
- if (rpn.param_mask & RFCOMM_RPN_PM_DATA
- && RFCOMM_RPN_DATA_BITS(rpn.line_settings) == RFCOMM_RPN_DATA_8)
- mask |= RFCOMM_RPN_PM_DATA;
-
- if (rpn.param_mask & RFCOMM_RPN_PM_STOP
- && RFCOMM_RPN_STOP_BITS(rpn.line_settings) == RFCOMM_RPN_STOP_1)
- mask |= RFCOMM_RPN_PM_STOP;
-
- if (rpn.param_mask & RFCOMM_RPN_PM_PARITY
- && RFCOMM_RPN_PARITY(rpn.line_settings) == RFCOMM_RPN_PARITY_NONE)
- mask |= RFCOMM_RPN_PM_PARITY;
-
- if (rpn.param_mask & RFCOMM_RPN_PM_XON
- && rpn.xon_char == RFCOMM_RPN_XON_CHAR)
- mask |= RFCOMM_RPN_PM_XON;
-
- if (rpn.param_mask & RFCOMM_RPN_PM_XOFF
- && rpn.xoff_char == RFCOMM_RPN_XOFF_CHAR)
- mask |= RFCOMM_RPN_PM_XOFF;
-
- if (rpn.param_mask & RFCOMM_RPN_PM_FLOW
- && rpn.flow_control == RFCOMM_RPN_FLOW_NONE)
- mask |= RFCOMM_RPN_PM_FLOW;
-
- rpn.param_mask = htole16(mask);
-
- rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_RPN, &rpn, sizeof(rpn));
-}
-
-/*
- * process Remote Line Status command/response
- */
-static void
-rfcomm_session_recv_mcc_rls(struct rfcomm_session *rs, int cr, struct mbuf *m)
-{
- struct rfcomm_mcc_rls rls;
-
- if (cr == 0) /* ignore ack */
- return;
-
- if (m->m_pkthdr.len != sizeof(rls)) {
- DPRINTF("Bad RLS length %d\n", m->m_pkthdr.len);
- return;
- }
-
- m_copydata(m, 0, sizeof(rls), (caddr_t)&rls);
-
- /*
- * So far as I can tell, we just send back what
- * they sent us. This signifies errors that seem
- * irrelevent for RFCOMM over L2CAP.
- */
- rls.address |= 0x03; /* EA = 1, CR = 1 */
- rls.status &= 0x0f; /* only 4 bits valid */
-
- rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_RLS, &rls, sizeof(rls));
-}
-
-/*
- * process Parameter Negotiation command/response
- */
-static void
-rfcomm_session_recv_mcc_pn(struct rfcomm_session *rs, int cr, struct mbuf *m)
-{
- struct rfcomm_dlc *dlc;
- struct rfcomm_mcc_pn pn;
- int err;
-
- if (m->m_pkthdr.len != sizeof(pn)) {
- DPRINTF("Bad PN length %d\n", m->m_pkthdr.len);
- return;
- }
-
- m_copydata(m, 0, sizeof(pn), (caddr_t)&pn);
-
- pn.dlci &= 0x3f;
- pn.mtu = letoh16(pn.mtu);
-
- dlc = rfcomm_dlc_lookup(rs, pn.dlci);
- if (cr) { /* Command */
- /*
- * If there is no DLC present, this is a new
- * connection so attempt to make one
- */
- if (dlc == NULL) {
- dlc = rfcomm_dlc_newconn(rs, pn.dlci);
- if (dlc == NULL)
- return; /* (DM is sent) */
- }
-
- /* accept any valid MTU, and offer it back */
- pn.mtu = min(pn.mtu, RFCOMM_MTU_MAX);
- pn.mtu = min(pn.mtu, rs->rs_mtu);
- pn.mtu = max(pn.mtu, RFCOMM_MTU_MIN);
- dlc->rd_mtu = pn.mtu;
- pn.mtu = htole16(pn.mtu);
-
- /* credits are only set before DLC is open */
- if (dlc->rd_state == RFCOMM_DLC_WAIT_CONNECT
- && (pn.flow_control & 0xf0) == 0xf0) {
- rs->rs_flags |= RFCOMM_SESSION_CFC;
- dlc->rd_txcred = pn.credits & 0x07;
-
- dlc->rd_rxcred = (dlc->rd_rxsize / dlc->rd_mtu);
- dlc->rd_rxcred = min(dlc->rd_rxcred,
- RFCOMM_CREDITS_DEFAULT);
-
- pn.flow_control = 0xe0;
- pn.credits = dlc->rd_rxcred;
- } else {
- pn.flow_control = 0x00;
- pn.credits = 0x00;
- }
-
- /* unused fields must be ignored and set to zero */
- pn.ack_timer = 0;
- pn.max_retrans = 0;
-
- /* send our response */
- err = rfcomm_session_send_mcc(rs, 0,
- RFCOMM_MCC_PN, &pn, sizeof(pn));
- if (err)
- goto close;
-
- } else { /* Response */
- /* ignore responses with no matching DLC */
- if (dlc == NULL)
- return;
-
- timeout_del(&dlc->rd_timeout);
-
- if (pn.mtu > RFCOMM_MTU_MAX || pn.mtu > dlc->rd_mtu) {
- dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
- err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
- pn.dlci);
- if (err)
- goto close;
-
- timeout_add_sec(&dlc->rd_timeout, rfcomm_ack_timeout);
- return;
- }
- dlc->rd_mtu = pn.mtu;
-
- /* if DLC is not waiting to connect, we are done */
- if (dlc->rd_state != RFCOMM_DLC_WAIT_CONNECT)
- return;
-
- /* set initial credits according to RFCOMM spec */
- if ((pn.flow_control & 0xf0) == 0xe0) {
- rs->rs_flags |= RFCOMM_SESSION_CFC;
- dlc->rd_txcred = (pn.credits & 0x07);
- }
-
- timeout_add_sec(&dlc->rd_timeout, rfcomm_ack_timeout);
-
- /* set link mode */
- err = rfcomm_dlc_setmode(dlc);
- if (err == EINPROGRESS) {
- dlc->rd_state = RFCOMM_DLC_WAIT_SEND_SABM;
- (*dlc->rd_proto->connecting)(dlc->rd_upper);
- return;
- }
- if (err)
- goto close;
-
- /* we can proceed now */
- err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_SABM, pn.dlci);
- if (err)
- goto close;
-
- dlc->rd_state = RFCOMM_DLC_WAIT_RECV_UA;
- }
- return;
-
-close:
- rfcomm_dlc_close(dlc, err);
-}
-
-/*
- * process Non Supported Command command/response
- */
-static void
-rfcomm_session_recv_mcc_nsc(struct rfcomm_session *rs,
- int cr, struct mbuf *m)
-{
- struct rfcomm_dlc *dlc, *next;
-
- /*
- * Since we did nothing that is not mandatory,
- * we just abort the whole session..
- */
-
- next = LIST_FIRST(&rs->rs_dlcs);
- while ((dlc = next) != NULL) {
- next = LIST_NEXT(dlc, rd_next);
- rfcomm_dlc_close(dlc, ECONNABORTED);
- }
-
- rfcomm_session_free(rs);
-}
-
-/***********************************************************************
- *
- * RFCOMM Session outward frame/uih/mcc building
- */
-
-/*
- * SABM/DISC/DM/UA frames are all minimal and mostly identical.
- */
-int
-rfcomm_session_send_frame(struct rfcomm_session *rs, int type, int dlci)
-{
- struct rfcomm_cmd_hdr *hdr;
- struct rfcomm_credit *credit;
- struct mbuf *m;
- uint8_t fcs, cr;
-
- credit = pool_get(&rfcomm_credit_pool, PR_NOWAIT);
- if (credit == NULL)
- return ENOMEM;
-
- m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- pool_put(&rfcomm_credit_pool, credit);
- return ENOMEM;
- }
-
- /*
- * The CR (command/response) bit identifies the frame either as a
- * commmand or a response and is used along with the DLCI to form
- * the address. Commands contain the non-initiator address, whereas
- * responses contain the initiator address, so the CR value is
- * also dependent on the session direction.
- */
- if (type == RFCOMM_FRAME_UA || type == RFCOMM_FRAME_DM)
- cr = IS_INITIATOR(rs) ? 0 : 1;
- else
- cr = IS_INITIATOR(rs) ? 1 : 0;
-
- hdr = mtod(m, struct rfcomm_cmd_hdr *);
- hdr->address = RFCOMM_MKADDRESS(cr, dlci);
- hdr->control = RFCOMM_MKCONTROL(type, 1); /* PF = 1 */
- hdr->length = (0x00 << 1) | 0x01; /* len = 0x00, EA = 1 */
-
- fcs = 0xff;
- fcs = FCS(fcs, hdr->address);
- fcs = FCS(fcs, hdr->control);
- fcs = FCS(fcs, hdr->length);
- fcs = 0xff - fcs; /* ones complement */
- hdr->fcs = fcs;
-
- m->m_pkthdr.len = m->m_len = sizeof(struct rfcomm_cmd_hdr);
-
- /* empty credit note */
- credit->rc_dlc = NULL;
- credit->rc_len = m->m_pkthdr.len;
- SIMPLEQ_INSERT_TAIL(&rs->rs_credits, credit, rc_next);
-
- DPRINTFN(5, "dlci %d type %2.2x (%d bytes, fcs=%#2.2x)\n",
- dlci, type, m->m_pkthdr.len, fcs);
-
- return l2cap_send(rs->rs_l2cap, m);
-}
-
-/*
- * rfcomm_session_send_uih(rfcomm_session, rfcomm_dlc, credits, mbuf)
- *
- * UIH frame is per DLC data or Multiplexer Control Commands
- * when no DLC is given. Data mbuf is optional (just credits
- * will be sent in that case)
- */
-int
-rfcomm_session_send_uih(struct rfcomm_session *rs, struct rfcomm_dlc *dlc,
- int credits, struct mbuf *m)
-{
- struct rfcomm_credit *credit;
- struct mbuf *m0 = NULL;
- int err, len;
- uint8_t fcs, *hdr;
-
- KASSERT(rs != NULL);
-
- len = (m == NULL) ? 0 : m->m_pkthdr.len;
- KASSERT(!(credits == 0 && len == 0));
-
- /*
- * Make a credit note for the completion notification
- */
- credit = pool_get(&rfcomm_credit_pool, PR_NOWAIT);
- if (credit == NULL)
- goto nomem;
-
- credit->rc_len = len;
- credit->rc_dlc = dlc;
-
- /*
- * Wrap UIH frame information around payload.
- *
- * [ADDRESS] [CONTROL] [LENGTH] [CREDITS] [...] [FCS]
- *
- * Address is one octet.
- * Control is one octet.
- * Length is one or two octets.
- * Credits may be one octet.
- *
- * FCS is one octet and calculated on address and
- * control octets only.
- *
- * If there are credits to be sent, we will set the PF
- * flag and include them in the frame.
- */
- m0 = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m0 == NULL)
- goto nomem;
-
- MH_ALIGN(m0, 5); /* (max 5 header octets) */
- hdr = mtod(m0, uint8_t *);
-
- /* CR bit is set according to the initiator of the session */
- *hdr = RFCOMM_MKADDRESS((IS_INITIATOR(rs) ? 1 : 0),
- (dlc ? dlc->rd_dlci : 0));
- fcs = FCS(0xff, *hdr);
- hdr++;
-
- /* PF bit is set if credits are being sent */
- *hdr = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, (credits > 0 ? 1 : 0));
- fcs = FCS(fcs, *hdr);
- hdr++;
-
- if (len < (1 << 7)) {
- *hdr++ = ((len << 1) & 0xfe) | 0x01; /* 7 bits, EA = 1 */
- } else {
- *hdr++ = ((len << 1) & 0xfe); /* 7 bits, EA = 0 */
- *hdr++ = ((len >> 7) & 0xff); /* 8 bits, no EA */
- }
-
- if (credits > 0)
- *hdr++ = (uint8_t)credits;
-
- m0->m_len = hdr - mtod(m0, uint8_t *);
-
- /* Append payload */
- m0->m_next = m;
- m = NULL;
-
- m0->m_pkthdr.len = m0->m_len + len;
-
- /* Append FCS */
- fcs = 0xff - fcs; /* ones complement */
- len = m0->m_pkthdr.len;
- m_copyback(m0, len, sizeof(fcs), &fcs, M_NOWAIT);
- if (m0->m_pkthdr.len != len + sizeof(fcs))
- goto nomem;
-
- DPRINTFN(10, "dlci %d, pktlen %d (%d data, %d credits), fcs=%#2.2x\n",
- dlc ? dlc->rd_dlci : 0, m0->m_pkthdr.len, credit->rc_len,
- credits, fcs);
-
- /*
- * UIH frame ready to go..
- */
- err = l2cap_send(rs->rs_l2cap, m0);
- if (err)
- goto fail;
-
- SIMPLEQ_INSERT_TAIL(&rs->rs_credits, credit, rc_next);
- return 0;
-
-nomem:
- err = ENOMEM;
-
- if (m0 != NULL)
- m_freem(m0);
-
- if (m != NULL)
- m_freem(m);
-
-fail:
- if (credit != NULL)
- pool_put(&rfcomm_credit_pool, credit);
-
- return err;
-}
-
-/*
- * send Multiplexer Control Command (or Response) on session
- */
-int
-rfcomm_session_send_mcc(struct rfcomm_session *rs, int cr,
- uint8_t type, void *data, int len)
-{
- struct mbuf *m;
- uint8_t *hdr;
- int hlen;
-
- m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return ENOMEM;
-
- hdr = mtod(m, uint8_t *);
-
- /*
- * Technically the type field can extend past one octet, but none
- * currently defined will do that.
- */
- *hdr++ = RFCOMM_MKMCC_TYPE(cr, type);
-
- /*
- * In the frame, the max length size is 2 octets (15 bits) whereas
- * no max length size is specified for MCC commands. We must allow
- * for 3 octets since for MCC frames we use 7 bits + EA in each.
- *
- * Only test data can possibly be that big.
- *
- * XXX Should we check this against the MTU?
- */
- if (len < (1 << 7)) {
- *hdr++ = ((len << 1) & 0xfe) | 0x01; /* 7 bits, EA = 1 */
- } else if (len < (1 << 14)) {
- *hdr++ = ((len << 1) & 0xfe); /* 7 bits, EA = 0 */
- *hdr++ = ((len >> 6) & 0xfe) | 0x01; /* 7 bits, EA = 1 */
- } else if (len < (1 << 15)) {
- *hdr++ = ((len << 1) & 0xfe); /* 7 bits, EA = 0 */
- *hdr++ = ((len >> 6) & 0xfe); /* 7 bits, EA = 0 */
- *hdr++ = ((len >> 13) & 0x02) | 0x01; /* 1 bit, EA = 1 */
- } else {
- DPRINTF("incredible length! (%d)\n", len);
- m_freem(m);
- return EMSGSIZE;
- }
-
- /*
- * add command data (to same mbuf if possible)
- */
- hlen = hdr - mtod(m, uint8_t *);
-
- if (len > 0) {
- m->m_pkthdr.len = m->m_len = MHLEN;
- m_copyback(m, hlen, len, data, M_NOWAIT);
- if (m->m_pkthdr.len != max(MHLEN, hlen + len)) {
- m_freem(m);
- return ENOMEM;
- }
- }
-
- m->m_pkthdr.len = hlen + len;
- m->m_len = min(MHLEN, m->m_pkthdr.len);
-
- DPRINTFN(5, "%s type %2.2x len %d\n",
- (cr ? "command" : "response"), type, m->m_pkthdr.len);
-
- return rfcomm_session_send_uih(rs, NULL, 0, m);
-}
diff --git a/sys/netbt/rfcomm_socket.c b/sys/netbt/rfcomm_socket.c
deleted file mode 100644
index 951d15fe5dc..00000000000
--- a/sys/netbt/rfcomm_socket.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/* $OpenBSD: rfcomm_socket.c,v 1.5 2009/11/21 13:05:32 guenther Exp $ */
-/* $NetBSD: rfcomm_socket.c,v 1.10 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* load symbolic names */
-#ifdef BLUETOOTH_DEBUG
-#define PRUREQUESTS
-#define PRCOREQUESTS
-#endif
-
-#include <sys/param.h>
-#include <sys/domain.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h> /* XXX for EPASSTHROUGH */
-#include <netbt/rfcomm.h>
-
-/****************************************************************************
- *
- * RFCOMM SOCK_STREAM Sockets - serial line emulation
- *
- */
-
-static void rfcomm_connecting(void *);
-static void rfcomm_connected(void *);
-static void rfcomm_disconnected(void *, int);
-static void *rfcomm_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
-static void rfcomm_complete(void *, int);
-static void rfcomm_linkmode(void *, int);
-static void rfcomm_input(void *, struct mbuf *);
-
-static const struct btproto rfcomm_proto = {
- rfcomm_connecting,
- rfcomm_connected,
- rfcomm_disconnected,
- rfcomm_newconn,
- rfcomm_complete,
- rfcomm_linkmode,
- rfcomm_input,
-};
-
-/* sysctl variables */
-int rfcomm_sendspace = 4096;
-int rfcomm_recvspace = 4096;
-
-/*
- * User Request.
- * up is socket
- * m is either
- * optional mbuf chain containing message
- * ioctl command (PRU_CONTROL)
- * nam is either
- * optional mbuf chain containing an address
- * ioctl data (PRU_CONTROL)
- * optionally protocol number (PRU_ATTACH)
- * message flags (PRU_RCVD)
- * ctl is either
- * optional mbuf chain containing socket options
- * optional interface pointer (PRU_CONTROL, PRU_PURGEIF)
- * l is pointer to process requesting action (if any)
- *
- * we are responsible for disposing of m and ctl if
- * they are mbuf chains
- */
-int
-rfcomm_usrreq(struct socket *up, int req, struct mbuf *m,
- struct mbuf *nam, struct mbuf *ctl, struct proc *p)
-{
- struct rfcomm_dlc *pcb = up->so_pcb;
- struct sockaddr_bt *sa;
- struct mbuf *m0;
- int err = 0;
-
-#ifdef notyet /* XXX */
- DPRINTFN(2, "%s\n", prurequests[req]);
-#endif
-
- switch (req) {
- case PRU_CONTROL:
- return EPASSTHROUGH;
-
-#ifdef notyet /* XXX */
- case PRU_PURGEIF:
- return EOPNOTSUPP;
-#endif
-
- case PRU_ATTACH:
- /* XXX solock() and bt_lock fiddling in NetBSD */
- if (pcb != NULL)
- return EINVAL;
- /*
- * Since we have nothing to add, we attach the DLC
- * structure directly to our PCB pointer.
- */
- err = soreserve(up, rfcomm_sendspace, rfcomm_recvspace);
- if (err)
- return err;
-
- err = rfcomm_attach((struct rfcomm_dlc **)&up->so_pcb,
- &rfcomm_proto, up);
- if (err)
- return err;
-
- err = rfcomm_rcvd(up->so_pcb, sbspace(&up->so_rcv));
- if (err) {
- rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb);
- return err;
- }
-
- return 0;
- }
-
- if (pcb == NULL) {
- err = EINVAL;
- goto release;
- }
-
- switch(req) {
- case PRU_DISCONNECT:
- soisdisconnecting(up);
- return rfcomm_disconnect(pcb, up->so_linger);
-
- case PRU_ABORT:
- rfcomm_disconnect(pcb, 0);
- soisdisconnected(up);
- /* fall through to */
- case PRU_DETACH:
- return rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb);
-
- case PRU_BIND:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- return rfcomm_bind(pcb, sa);
-
- case PRU_CONNECT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- soisconnecting(up);
- return rfcomm_connect(pcb, sa);
-
- case PRU_PEERADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return rfcomm_peeraddr(pcb, sa);
-
- case PRU_SOCKADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return rfcomm_sockaddr(pcb, sa);
-
- case PRU_SHUTDOWN:
- socantsendmore(up);
- break;
-
- case PRU_SEND:
- KASSERT(m != NULL);
-
- if (ctl) /* no use for that */
- m_freem(ctl);
-
- m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
- if (m0 == NULL)
- return ENOMEM;
-
- sbappendstream(&up->so_snd, m);
-
- return rfcomm_send(pcb, m0);
-
- case PRU_SENSE:
- return 0; /* (no release) */
-
- case PRU_RCVD:
- return rfcomm_rcvd(pcb, sbspace(&up->so_rcv));
-
- case PRU_RCVOOB:
- return EOPNOTSUPP; /* (no release) */
-
- case PRU_LISTEN:
- return rfcomm_listen(pcb);
-
- case PRU_ACCEPT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return rfcomm_peeraddr(pcb, sa);
-
- case PRU_CONNECT2:
- case PRU_SENDOOB:
- case PRU_FASTTIMO:
- case PRU_SLOWTIMO:
- case PRU_PROTORCV:
- case PRU_PROTOSEND:
- err = EOPNOTSUPP;
- break;
-
- default:
- UNKNOWN(req);
- err = EOPNOTSUPP;
- break;
- }
-
-release:
- if (m) m_freem(m);
- if (ctl) m_freem(ctl);
- return err;
-}
-
-/*
- * rfcomm_ctloutput(request, socket, level, optname, opt)
- *
- */
-int
-rfcomm_ctloutput(int req, struct socket *so, int level,
- int optname, struct mbuf **opt)
-{
- struct rfcomm_dlc *pcb = so->so_pcb;
- struct mbuf *m;
- int err = 0;
-
-#ifdef notyet /* XXX */
- DPRINTFN(2, "%s\n", prcorequests[req]);
-#endif
-
- if (pcb == NULL)
- return EINVAL;
-
- if (level != BTPROTO_RFCOMM) {
- err = EINVAL;
- if (req == PRCO_SETOPT && *opt)
- m_free(*opt);
- } else switch(req) {
- case PRCO_GETOPT:
- m = m_get(M_WAIT, MT_SOOPTS);
- m->m_len = rfcomm_getopt(pcb, optname, mtod(m, void *));
- if (m->m_len == 0) {
- m_freem(m);
- m = NULL;
- err = ENOPROTOOPT;
- }
- *opt = m;
- break;
-
- case PRCO_SETOPT:
- m = *opt;
- err = rfcomm_setopt(pcb, optname, m);
- m_freem(m);
- break;
-
- default:
- err = ENOPROTOOPT;
- break;
- }
-
- return err;
-}
-
-/**********************************************************************
- *
- * RFCOMM callbacks
- */
-
-static void
-rfcomm_connecting(void *arg)
-{
- /* struct socket *so = arg; */
-
- KASSERT(arg != NULL);
- DPRINTF("Connecting\n");
-}
-
-static void
-rfcomm_connected(void *arg)
-{
- struct socket *so = arg;
-
- KASSERT(so != NULL);
- DPRINTF("Connected\n");
- soisconnected(so);
-}
-
-static void
-rfcomm_disconnected(void *arg, int err)
-{
- struct socket *so = arg;
-
- KASSERT(so != NULL);
- DPRINTF("Disconnected\n");
-
- so->so_error = err;
- soisdisconnected(so);
-}
-
-static void *
-rfcomm_newconn(void *arg, struct sockaddr_bt *laddr,
- struct sockaddr_bt *raddr)
-{
- struct socket *so = arg;
-
- DPRINTF("New Connection\n");
- so = sonewconn(so, 0);
- if (so == NULL)
- return NULL;
-
- soisconnecting(so);
-
- return so->so_pcb;
-}
-
-/*
- * rfcomm_complete(rfcomm_dlc, length)
- *
- * length bytes are sent and may be removed from socket buffer
- */
-static void
-rfcomm_complete(void *arg, int length)
-{
- struct socket *so = arg;
-
- sbdrop(&so->so_snd, length);
- sowwakeup(so);
-}
-
-/*
- * rfcomm_linkmode(rfcomm_dlc, new)
- *
- * link mode change notification.
- */
-static void
-rfcomm_linkmode(void *arg, int new)
-{
- struct socket *so = arg;
- int mode;
-
- DPRINTF("auth %s, encrypt %s, secure %s\n",
- (new & RFCOMM_LM_AUTH ? "on" : "off"),
- (new & RFCOMM_LM_ENCRYPT ? "on" : "off"),
- (new & RFCOMM_LM_SECURE ? "on" : "off"));
-
- (void)rfcomm_getopt(so->so_pcb, SO_RFCOMM_LM, &mode);
- if (((mode & RFCOMM_LM_AUTH) && !(new & RFCOMM_LM_AUTH))
- || ((mode & RFCOMM_LM_ENCRYPT) && !(new & RFCOMM_LM_ENCRYPT))
- || ((mode & RFCOMM_LM_SECURE) && !(new & RFCOMM_LM_SECURE)))
- rfcomm_disconnect(so->so_pcb, 0);
-}
-
-/*
- * rfcomm_input(rfcomm_dlc, mbuf)
- */
-static void
-rfcomm_input(void *arg, struct mbuf *m)
-{
- struct socket *so = arg;
-
- KASSERT(so != NULL);
-
- if (m->m_pkthdr.len > sbspace(&so->so_rcv)) {
- printf("%s: %d bytes dropped (socket buffer full)\n",
- __func__, m->m_pkthdr.len);
- m_freem(m);
- return;
- }
-
- DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len);
-
- sbappendstream(&so->so_rcv, m);
- sorwakeup(so);
-}
diff --git a/sys/netbt/rfcomm_upper.c b/sys/netbt/rfcomm_upper.c
deleted file mode 100644
index 19635350362..00000000000
--- a/sys/netbt/rfcomm_upper.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* $OpenBSD: rfcomm_upper.c,v 1.7 2009/11/21 13:05:32 guenther Exp $ */
-/* $NetBSD: rfcomm_upper.c,v 1.11 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/l2cap.h>
-#include <netbt/rfcomm.h>
-
-/****************************************************************************
- *
- * RFCOMM DLC - Upper Protocol API
- *
- * Currently the only 'Port Emulation Entity' is the RFCOMM socket code
- * but it is should be possible to provide a pseudo-device for a direct
- * tty interface.
- */
-
-/*
- * rfcomm_attach(handle, proto, upper)
- *
- * attach a new RFCOMM DLC to handle, populate with reasonable defaults
- */
-int
-rfcomm_attach(struct rfcomm_dlc **handle,
- const struct btproto *proto, void *upper)
-{
- struct rfcomm_dlc *dlc;
-
- KASSERT(handle != NULL);
- KASSERT(proto != NULL);
- KASSERT(upper != NULL);
-
- dlc = malloc(sizeof(*dlc), M_BLUETOOTH, M_NOWAIT | M_ZERO);
- if (dlc == NULL)
- return ENOMEM;
-
- dlc->rd_state = RFCOMM_DLC_CLOSED;
- dlc->rd_mtu = rfcomm_mtu_default;
-
- dlc->rd_proto = proto;
- dlc->rd_upper = upper;
-
- dlc->rd_laddr.bt_len = sizeof(struct sockaddr_bt);
- dlc->rd_laddr.bt_family = AF_BLUETOOTH;
- dlc->rd_laddr.bt_psm = L2CAP_PSM_RFCOMM;
-
- dlc->rd_raddr.bt_len = sizeof(struct sockaddr_bt);
- dlc->rd_raddr.bt_family = AF_BLUETOOTH;
- dlc->rd_raddr.bt_psm = L2CAP_PSM_RFCOMM;
-
- dlc->rd_lmodem = RFCOMM_MSC_RTC | RFCOMM_MSC_RTR | RFCOMM_MSC_DV;
-
- timeout_set(&dlc->rd_timeout, rfcomm_dlc_timeout, dlc);
-
- *handle = dlc;
- return 0;
-}
-
-/*
- * rfcomm_bind(dlc, sockaddr)
- *
- * bind DLC to local address
- */
-int
-rfcomm_bind(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
-{
-
- memcpy(&dlc->rd_laddr, addr, sizeof(struct sockaddr_bt));
- return 0;
-}
-
-/*
- * rfcomm_sockaddr(dlc, sockaddr)
- *
- * return local address
- */
-int
-rfcomm_sockaddr(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
-{
-
- memcpy(addr, &dlc->rd_laddr, sizeof(struct sockaddr_bt));
- return 0;
-}
-
-/*
- * rfcomm_connect(dlc, sockaddr)
- *
- * Initiate connection of RFCOMM DLC to remote address.
- */
-int
-rfcomm_connect(struct rfcomm_dlc *dlc, struct sockaddr_bt *dest)
-{
- struct rfcomm_session *rs;
- int err = 0;
-
- if (dlc->rd_state != RFCOMM_DLC_CLOSED)
- return EISCONN;
-
- memcpy(&dlc->rd_raddr, dest, sizeof(struct sockaddr_bt));
-
- if (dlc->rd_raddr.bt_channel < RFCOMM_CHANNEL_MIN
- || dlc->rd_raddr.bt_channel > RFCOMM_CHANNEL_MAX
- || bdaddr_any(&dlc->rd_raddr.bt_bdaddr))
- return EDESTADDRREQ;
-
- if (dlc->rd_raddr.bt_psm == L2CAP_PSM_ANY)
- dlc->rd_raddr.bt_psm = L2CAP_PSM_RFCOMM;
- else if (dlc->rd_raddr.bt_psm != L2CAP_PSM_RFCOMM
- && (dlc->rd_raddr.bt_psm < 0x1001
- || L2CAP_PSM_INVALID(dlc->rd_raddr.bt_psm)))
- return EINVAL;
-
- /*
- * We are allowed only one RFCOMM session between any 2 Bluetooth
- * devices, so see if there is a session already otherwise create
- * one and set it connecting.
- */
- rs = rfcomm_session_lookup(&dlc->rd_laddr, &dlc->rd_raddr);
- if (rs == NULL) {
- rs = rfcomm_session_alloc(&rfcomm_session_active,
- &dlc->rd_laddr);
- if (rs == NULL)
- return ENOMEM;
-
- rs->rs_flags |= RFCOMM_SESSION_INITIATOR;
- rs->rs_state = RFCOMM_SESSION_WAIT_CONNECT;
-
- err = l2cap_connect(rs->rs_l2cap, &dlc->rd_raddr);
- if (err) {
- rfcomm_session_free(rs);
- return err;
- }
-
- /*
- * This session will start up automatically when its
- * L2CAP channel is connected.
- */
- }
-
- /* construct DLC */
- dlc->rd_dlci = RFCOMM_MKDLCI(IS_INITIATOR(rs) ? 0:1, dest->bt_channel);
- if (rfcomm_dlc_lookup(rs, dlc->rd_dlci))
- return EBUSY;
-
- l2cap_sockaddr(rs->rs_l2cap, &dlc->rd_laddr);
-
- /*
- * attach the DLC to the session and start it off
- */
- dlc->rd_session = rs;
- dlc->rd_state = RFCOMM_DLC_WAIT_SESSION;
- LIST_INSERT_HEAD(&rs->rs_dlcs, dlc, rd_next);
-
- if (rs->rs_state == RFCOMM_SESSION_OPEN)
- err = rfcomm_dlc_connect(dlc);
-
- return err;
-}
-
-/*
- * rfcomm_peeraddr(dlc, sockaddr)
- *
- * return remote address
- */
-int
-rfcomm_peeraddr(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
-{
-
- memcpy(addr, &dlc->rd_raddr, sizeof(struct sockaddr_bt));
- return 0;
-}
-
-/*
- * rfcomm_disconnect(dlc, linger)
- *
- * disconnect RFCOMM DLC
- */
-int
-rfcomm_disconnect(struct rfcomm_dlc *dlc, int linger)
-{
- struct rfcomm_session *rs = dlc->rd_session;
- int err = 0;
-
- KASSERT(dlc != NULL);
-
- switch (dlc->rd_state) {
- case RFCOMM_DLC_CLOSED:
- case RFCOMM_DLC_LISTEN:
- return EINVAL;
-
- case RFCOMM_DLC_WAIT_SEND_UA:
- err = rfcomm_session_send_frame(rs,
- RFCOMM_FRAME_DM, dlc->rd_dlci);
-
- /* fall through */
- case RFCOMM_DLC_WAIT_SESSION:
- case RFCOMM_DLC_WAIT_CONNECT:
- case RFCOMM_DLC_WAIT_SEND_SABM:
- rfcomm_dlc_close(dlc, 0);
- break;
-
- case RFCOMM_DLC_OPEN:
- if (dlc->rd_txbuf != NULL && linger != 0) {
- dlc->rd_flags |= RFCOMM_DLC_SHUTDOWN;
- break;
- }
-
- /* else fall through */
- case RFCOMM_DLC_WAIT_RECV_UA:
- dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
- err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
- dlc->rd_dlci);
- timeout_add_sec(&dlc->rd_timeout, rfcomm_ack_timeout);
- break;
-
- case RFCOMM_DLC_WAIT_DISCONNECT:
- err = EALREADY;
- break;
-
- default:
- UNKNOWN(dlc->rd_state);
- break;
- }
-
- return err;
-}
-
-/*
- * rfcomm_detach(handle)
- *
- * detach RFCOMM DLC from handle
- */
-int
-rfcomm_detach(struct rfcomm_dlc **handle)
-{
- struct rfcomm_dlc *dlc = *handle;
-
- if (dlc->rd_state != RFCOMM_DLC_CLOSED)
- rfcomm_dlc_close(dlc, 0);
-
- if (dlc->rd_txbuf != NULL) {
- m_freem(dlc->rd_txbuf);
- dlc->rd_txbuf = NULL;
- }
-
- dlc->rd_upper = NULL;
- *handle = NULL;
-
- /*
- * If callout is invoking we can't free the DLC so
- * mark it and let the callout release it.
- */
- if (timeout_triggered(&dlc->rd_timeout))
- dlc->rd_flags |= RFCOMM_DLC_DETACH;
- else
- free(dlc, M_BLUETOOTH);
-
- return 0;
-}
-
-/*
- * rfcomm_listen(dlc)
- *
- * This DLC is a listener. We look for an existing listening session
- * with a matching address to attach to or else create a new one on
- * the listeners list. If the ANY channel is given, allocate the first
- * available for the session.
- */
-int
-rfcomm_listen(struct rfcomm_dlc *dlc)
-{
- struct rfcomm_session *rs;
- struct rfcomm_dlc *used;
- struct sockaddr_bt addr;
- int err, channel;
-
- if (dlc->rd_state != RFCOMM_DLC_CLOSED)
- return EISCONN;
-
- if (dlc->rd_laddr.bt_channel != RFCOMM_CHANNEL_ANY
- && (dlc->rd_laddr.bt_channel < RFCOMM_CHANNEL_MIN
- || dlc->rd_laddr.bt_channel > RFCOMM_CHANNEL_MAX))
- return EADDRNOTAVAIL;
-
- if (dlc->rd_laddr.bt_psm == L2CAP_PSM_ANY)
- dlc->rd_laddr.bt_psm = L2CAP_PSM_RFCOMM;
- else if (dlc->rd_laddr.bt_psm != L2CAP_PSM_RFCOMM
- && (dlc->rd_laddr.bt_psm < 0x1001
- || L2CAP_PSM_INVALID(dlc->rd_laddr.bt_psm)))
- return EADDRNOTAVAIL;
-
- LIST_FOREACH(rs, &rfcomm_session_listen, rs_next) {
- l2cap_sockaddr(rs->rs_l2cap, &addr);
-
- if (addr.bt_psm != dlc->rd_laddr.bt_psm)
- continue;
-
- if (bdaddr_same(&dlc->rd_laddr.bt_bdaddr, &addr.bt_bdaddr))
- break;
- }
-
- if (rs == NULL) {
- rs = rfcomm_session_alloc(&rfcomm_session_listen,
- &dlc->rd_laddr);
- if (rs == NULL)
- return ENOMEM;
-
- rs->rs_state = RFCOMM_SESSION_LISTEN;
-
- err = l2cap_listen(rs->rs_l2cap);
- if (err) {
- rfcomm_session_free(rs);
- return err;
- }
- }
-
- if (dlc->rd_laddr.bt_channel == RFCOMM_CHANNEL_ANY) {
- channel = RFCOMM_CHANNEL_MIN;
- used = LIST_FIRST(&rs->rs_dlcs);
-
- while (used != NULL) {
- if (used->rd_laddr.bt_channel == channel) {
- if (channel++ == RFCOMM_CHANNEL_MAX)
- return EADDRNOTAVAIL;
-
- used = LIST_FIRST(&rs->rs_dlcs);
- } else {
- used = LIST_NEXT(used, rd_next);
- }
- }
-
- dlc->rd_laddr.bt_channel = channel;
- }
-
- dlc->rd_session = rs;
- dlc->rd_state = RFCOMM_DLC_LISTEN;
- LIST_INSERT_HEAD(&rs->rs_dlcs, dlc, rd_next);
-
- return 0;
-}
-
-/*
- * rfcomm_send(dlc, mbuf)
- *
- * Output data on DLC. This is streamed data, so we add it
- * to our buffer and start the DLC, which will assemble
- * packets and send them if it can.
- */
-int
-rfcomm_send(struct rfcomm_dlc *dlc, struct mbuf *m)
-{
-
- if (dlc->rd_txbuf != NULL) {
- dlc->rd_txbuf->m_pkthdr.len += m->m_pkthdr.len;
- m_cat(dlc->rd_txbuf, m);
- } else {
- dlc->rd_txbuf = m;
- }
-
- if (dlc->rd_state == RFCOMM_DLC_OPEN)
- rfcomm_dlc_start(dlc);
-
- return 0;
-}
-
-/*
- * rfcomm_rcvd(dlc, space)
- *
- * Indicate space now available in receive buffer
- *
- * This should be used to give an initial value of the receive buffer
- * size when the DLC is attached and anytime data is cleared from the
- * buffer after that.
- */
-int
-rfcomm_rcvd(struct rfcomm_dlc *dlc, size_t space)
-{
-
- KASSERT(dlc != NULL);
-
- dlc->rd_rxsize = space;
-
- /*
- * if we are using credit based flow control, we may
- * want to send some credits..
- */
- if (dlc->rd_state == RFCOMM_DLC_OPEN
- && (dlc->rd_session->rs_flags & RFCOMM_SESSION_CFC))
- rfcomm_dlc_start(dlc);
-
- return 0;
-}
-
-/*
- * rfcomm_setopt(dlc, option, m)
- *
- * set DLC options
- */
-int
-rfcomm_setopt(struct rfcomm_dlc *dlc, int opt, struct mbuf *m)
-{
- int mode, err = 0;
- uint16_t mtu;
-
- switch (opt) {
- case SO_RFCOMM_MTU:
- if (m == NULL || m->m_len != sizeof(uint16_t))
- err = EINVAL;
- else {
- mtu = *mtod(m, uint16_t *);
- if (mtu < RFCOMM_MTU_MIN || mtu > RFCOMM_MTU_MAX)
- err = EINVAL;
- else if (dlc->rd_state == RFCOMM_DLC_CLOSED)
- dlc->rd_mtu = mtu;
- else
- err = EBUSY;
- }
-
- break;
-
- case SO_RFCOMM_LM:
- if (m == NULL || m->m_len != sizeof(int))
- err = EINVAL;
- else {
- mode = *mtod(m, int *);
- mode &= (RFCOMM_LM_SECURE | RFCOMM_LM_ENCRYPT |
- RFCOMM_LM_AUTH);
-
- if (mode & RFCOMM_LM_SECURE)
- mode |= RFCOMM_LM_ENCRYPT;
-
- if (mode & RFCOMM_LM_ENCRYPT)
- mode |= RFCOMM_LM_AUTH;
-
- dlc->rd_mode = mode;
-
- if (dlc->rd_state == RFCOMM_DLC_OPEN)
- err = rfcomm_dlc_setmode(dlc);
- }
-
- break;
-
- default:
- err = ENOPROTOOPT;
- break;
- }
- return err;
-}
-
-/*
- * rfcomm_getopt(dlc, option, addr)
- *
- * get DLC options
- */
-int
-rfcomm_getopt(struct rfcomm_dlc *dlc, int opt, void *addr)
-{
- struct rfcomm_fc_info *fc;
-
- switch (opt) {
- case SO_RFCOMM_MTU:
- *(uint16_t *)addr = dlc->rd_mtu;
- return sizeof(uint16_t);
-
- case SO_RFCOMM_FC_INFO:
- fc = addr;
- memset(fc, 0, sizeof(*fc));
- fc->lmodem = dlc->rd_lmodem;
- fc->rmodem = dlc->rd_rmodem;
- fc->tx_cred = max(dlc->rd_txcred, 0xff);
- fc->rx_cred = max(dlc->rd_rxcred, 0xff);
- if (dlc->rd_session
- && (dlc->rd_session->rs_flags & RFCOMM_SESSION_CFC))
- fc->cfc = 1;
-
- return sizeof(*fc);
-
- case SO_RFCOMM_LM:
- *(int *)addr = dlc->rd_mode;
- return sizeof(int);
-
- default:
- break;
- }
-
- return 0;
-}
diff --git a/sys/netbt/sco.h b/sys/netbt/sco.h
deleted file mode 100644
index b93fee7f0f5..00000000000
--- a/sys/netbt/sco.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $OpenBSD: sco.h,v 1.5 2009/11/21 13:05:32 guenther Exp $ */
-/* $NetBSD: sco.h,v 1.3 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _NETBT_SCO_H_
-#define _NETBT_SCO_H_
-
-#define SO_SCO_MTU 1
-#define SO_SCO_HANDLE 2
-
-#ifdef _KERNEL
-/*
- * SCO protocol control block
- */
-struct sco_pcb {
- struct hci_link *sp_link; /* SCO link */
- unsigned int sp_flags; /* flags */
- bdaddr_t sp_laddr; /* local address */
- bdaddr_t sp_raddr; /* remote address */
- unsigned int sp_mtu; /* link MTU */
- int sp_pending; /* number of packets pending */
-
- const struct btproto *sp_proto; /* upper layer protocol */
- void *sp_upper; /* upper layer argument */
-
- LIST_ENTRY(sco_pcb) sp_next;
-};
-
-LIST_HEAD(sco_pcb_list, sco_pcb);
-extern struct sco_pcb_list sco_pcb;
-
-/* sp_flags */
-#define SP_LISTENING (1<<0) /* is listening pcb */
-
-/* sco_socket.c */
-struct socket;
-extern int sco_sendspace;
-extern int sco_recvspace;
-int sco_usrreq(struct socket *, int, struct mbuf *,
- struct mbuf *, struct mbuf *, struct proc *);
-int sco_ctloutput(int, struct socket *, int, int, struct mbuf **);
-
-/* sco_upper.c */
-int sco_attach(struct sco_pcb **, const struct btproto *, void *);
-int sco_bind(struct sco_pcb *, struct sockaddr_bt *);
-int sco_sockaddr(struct sco_pcb *, struct sockaddr_bt *);
-int sco_connect(struct sco_pcb *, struct sockaddr_bt *);
-int sco_peeraddr(struct sco_pcb *, struct sockaddr_bt *);
-int sco_disconnect(struct sco_pcb *, int);
-int sco_detach(struct sco_pcb **);
-int sco_listen(struct sco_pcb *);
-int sco_send(struct sco_pcb *, struct mbuf *);
-int sco_setopt(struct sco_pcb *, int, struct mbuf *);
-int sco_getopt(struct sco_pcb *, int, void *);
-
-#endif /* _KERNEL */
-
-#endif /* _NETBT_SCO_H_ */
diff --git a/sys/netbt/sco_socket.c b/sys/netbt/sco_socket.c
deleted file mode 100644
index 94a674041a8..00000000000
--- a/sys/netbt/sco_socket.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/* $OpenBSD: sco_socket.c,v 1.5 2012/12/05 23:20:23 deraadt Exp $ */
-/* $NetBSD: sco_socket.c,v 1.11 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* load symbolic names */
-#ifdef BLUETOOTH_DEBUG
-#define PRUREQUESTS
-#define PRCOREQUESTS
-#endif
-
-#include <sys/param.h>
-#include <sys/domain.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/sco.h>
-
-/*******************************************************************************
- *
- * SCO SOCK_SEQPACKET sockets - low latency audio data
- */
-
-static void sco_connecting(void *);
-static void sco_connected(void *);
-static void sco_disconnected(void *, int);
-static void *sco_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
-static void sco_complete(void *, int);
-static void sco_linkmode(void *, int);
-static void sco_input(void *, struct mbuf *);
-
-static const struct btproto sco_proto = {
- sco_connecting,
- sco_connected,
- sco_disconnected,
- sco_newconn,
- sco_complete,
- sco_linkmode,
- sco_input,
-};
-
-int sco_sendspace = 4096;
-int sco_recvspace = 4096;
-
-/*
- * User Request.
- * up is socket
- * m is either
- * optional mbuf chain containing message
- * ioctl command (PRU_CONTROL)
- * nam is either
- * optional mbuf chain containing an address
- * ioctl data (PRU_CONTROL)
- * optionally, protocol number (PRU_ATTACH)
- * ctl is optional mbuf chain containing socket options
- * l is pointer to process requesting action (if any)
- *
- * we are responsible for disposing of m and ctl if
- * they are mbuf chains
- */
-int
-sco_usrreq(struct socket *up, int req, struct mbuf *m,
- struct mbuf *nam, struct mbuf *ctl, struct proc *p)
-{
- struct sco_pcb *pcb = (struct sco_pcb *)up->so_pcb;
- struct sockaddr_bt *sa;
- struct mbuf *m0;
- int err = 0;
-
-#ifdef notyet /* XXX */
- DPRINTFN(2, "%s\n", prurequests[req]);
-#endif
-
- switch(req) {
- case PRU_CONTROL:
- return EOPNOTSUPP;
-
-#ifdef notyet /* XXX */
- case PRU_PURGEIF:
- return EOPNOTSUPP;
-#endif
-
- case PRU_ATTACH:
- /* XXX solock() and bt_lock fiddling in NetBSD */
- if (pcb)
- return EINVAL;
- err = soreserve(up, sco_sendspace, sco_recvspace);
- if (err)
- return err;
-
- return sco_attach((struct sco_pcb **)&up->so_pcb,
- &sco_proto, up);
- }
-
- /* anything after here *requires* a pcb */
- if (pcb == NULL) {
- err = EINVAL;
- goto release;
- }
-
- switch(req) {
- case PRU_DISCONNECT:
- soisdisconnecting(up);
- return sco_disconnect(pcb, up->so_linger);
-
- case PRU_ABORT:
- sco_disconnect(pcb, 0);
- soisdisconnected(up);
- /* fall through to */
- case PRU_DETACH:
- return sco_detach((struct sco_pcb **)&up->so_pcb);
-
- case PRU_BIND:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- return sco_bind(pcb, sa);
-
- case PRU_CONNECT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- soisconnecting(up);
- return sco_connect(pcb, sa);
-
- case PRU_PEERADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return sco_peeraddr(pcb, sa);
-
- case PRU_SOCKADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return sco_sockaddr(pcb, sa);
-
- case PRU_SHUTDOWN:
- socantsendmore(up);
- break;
-
- case PRU_SEND:
- KASSERT(m != NULL);
- if (m->m_pkthdr.len == 0)
- break;
-
- if (m->m_pkthdr.len > pcb->sp_mtu) {
- err = EMSGSIZE;
- break;
- }
-
- m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
- if (m0 == NULL) {
- err = ENOMEM;
- break;
- }
-
- if (ctl) /* no use for that */
- m_freem(ctl);
-
- sbappendrecord(&up->so_snd, m);
- return sco_send(pcb, m0);
-
- case PRU_SENSE:
- return 0; /* (no sense - Doh!) */
-
- case PRU_RCVD:
- case PRU_RCVOOB:
- return EOPNOTSUPP; /* (no release) */
-
- case PRU_LISTEN:
- return sco_listen(pcb);
-
- case PRU_ACCEPT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return sco_peeraddr(pcb, sa);
-
- case PRU_CONNECT2:
- case PRU_SENDOOB:
- case PRU_FASTTIMO:
- case PRU_SLOWTIMO:
- case PRU_PROTORCV:
- case PRU_PROTOSEND:
- err = EOPNOTSUPP;
- break;
-
- default:
- UNKNOWN(req);
- err = EOPNOTSUPP;
- break;
- }
-
-release:
- if (m) m_freem(m);
- if (ctl) m_freem(ctl);
- return err;
-}
-
-/*
- * get/set socket options
- */
-int
-sco_ctloutput(int req, struct socket *so, int level,
- int optname, struct mbuf **opt)
-{
- struct sco_pcb *pcb = (struct sco_pcb *)so->so_pcb;
- struct mbuf *m;
- int err = 0;
-
-#ifdef notyet /* XXX */
- DPRINTFN(2, "req %s\n", prcorequests[req]);
-#endif
-
- if (pcb == NULL)
- return EINVAL;
-
- if (level != BTPROTO_SCO) {
- err = EINVAL;
- if (req == PRCO_SETOPT && *opt)
- m_free(*opt);
- } else switch(req) {
- case PRCO_GETOPT:
- m = m_get(M_WAIT, MT_SOOPTS);
- m->m_len = sco_getopt(pcb, optname, mtod(m, uint8_t *));
- if (m->m_len == 0) {
- m_freem(m);
- m = NULL;
- err = ENOPROTOOPT;
- }
- *opt = m;
- break;
-
- case PRCO_SETOPT:
- m = *opt;
- err = sco_setopt(pcb, optname, m);
- m_freem(m);
- break;
-
- default:
- err = ENOPROTOOPT;
- break;
- }
-
- return err;
-}
-
-/*****************************************************************************
- *
- * SCO Protocol socket callbacks
- *
- */
-static void
-sco_connecting(void *arg)
-{
- struct socket *so = arg;
-
- DPRINTF("Connecting\n");
- soisconnecting(so);
-}
-
-static void
-sco_connected(void *arg)
-{
- struct socket *so = arg;
-
- DPRINTF("Connected\n");
- soisconnected(so);
-}
-
-static void
-sco_disconnected(void *arg, int err)
-{
- struct socket *so = arg;
-
- DPRINTF("Disconnected (%d)\n", err);
-
- so->so_error = err;
- soisdisconnected(so);
-}
-
-static void *
-sco_newconn(void *arg, struct sockaddr_bt *laddr,
- struct sockaddr_bt *raddr)
-{
- struct socket *so = arg;
-
- DPRINTF("New Connection\n");
- so = sonewconn(so, 0);
- if (so == NULL)
- return NULL;
-
- soisconnecting(so);
- return so->so_pcb;
-}
-
-static void
-sco_complete(void *arg, int num)
-{
- struct socket *so = arg;
-
- while (num-- > 0)
- sbdroprecord(&so->so_snd);
-
- sowwakeup(so);
-}
-
-static void
-sco_linkmode(void *arg, int mode)
-{
-}
-
-static void
-sco_input(void *arg, struct mbuf *m)
-{
- struct socket *so = arg;
-
- /*
- * since this data is time sensitive, if the buffer
- * is full we just dump data until the latest one
- * will fit.
- */
-
- while (m->m_pkthdr.len > sbspace(&so->so_rcv))
- sbdroprecord(&so->so_rcv);
-
- DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len);
-
- sbappendrecord(&so->so_rcv, m);
- sorwakeup(so);
-}
diff --git a/sys/netbt/sco_upper.c b/sys/netbt/sco_upper.c
deleted file mode 100644
index d30e4bbc63d..00000000000
--- a/sys/netbt/sco_upper.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/* $OpenBSD: sco_upper.c,v 1.5 2012/12/05 23:20:23 deraadt Exp $ */
-/* $NetBSD: sco_upper.c,v 1.8 2008/08/06 15:01:24 plunky Exp $ */
-
-/*-
- * Copyright (c) 2006 Itronix Inc.
- * All rights reserved.
- *
- * Written by Iain Hibbert for Itronix Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of Itronix Inc. may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-
-#include <netbt/bluetooth.h>
-#include <netbt/hci.h>
-#include <netbt/sco.h>
-
-/****************************************************************************
- *
- * SCO - Upper Protocol API
- */
-
-struct sco_pcb_list sco_pcb = LIST_HEAD_INITIALIZER(sco_pcb);
-
-/*
- * sco_attach(handle, proto, upper)
- *
- * Attach a new instance of SCO pcb to handle
- */
-int
-sco_attach(struct sco_pcb **handle,
- const struct btproto *proto, void *upper)
-{
- struct sco_pcb *pcb;
-
- KASSERT(handle != NULL);
- KASSERT(proto != NULL);
- KASSERT(upper != NULL);
-
- pcb = malloc(sizeof(*pcb), M_BLUETOOTH, M_NOWAIT | M_ZERO);
- if (pcb == NULL)
- return ENOMEM;
-
- pcb->sp_proto = proto;
- pcb->sp_upper = upper;
-
- LIST_INSERT_HEAD(&sco_pcb, pcb, sp_next);
-
- *handle = pcb;
- return 0;
-}
-
-/*
- * sco_bind(pcb, sockaddr)
- *
- * Bind SCO pcb to local address
- */
-int
-sco_bind(struct sco_pcb *pcb, struct sockaddr_bt *addr)
-{
-
- bdaddr_copy(&pcb->sp_laddr, &addr->bt_bdaddr);
- return 0;
-}
-
-/*
- * sco_sockaddr(pcb, sockaddr)
- *
- * Copy local address of PCB to sockaddr
- */
-int
-sco_sockaddr(struct sco_pcb *pcb, struct sockaddr_bt *addr)
-{
-
- memset(addr, 0, sizeof(struct sockaddr_bt));
- addr->bt_len = sizeof(struct sockaddr_bt);
- addr->bt_family = AF_BLUETOOTH;
- bdaddr_copy(&addr->bt_bdaddr, &pcb->sp_laddr);
- return 0;
-}
-
-/*
- * sco_connect(pcb, sockaddr)
- *
- * Initiate a SCO connection to the destination address.
- */
-int
-sco_connect(struct sco_pcb *pcb, struct sockaddr_bt *dest)
-{
- hci_add_sco_con_cp cp;
- struct hci_unit *unit;
- struct hci_link *acl, *sco;
- int err;
-
- if (pcb->sp_flags & SP_LISTENING)
- return EINVAL;
-
- bdaddr_copy(&pcb->sp_raddr, &dest->bt_bdaddr);
-
- if (bdaddr_any(&pcb->sp_raddr))
- return EDESTADDRREQ;
-
- if (bdaddr_any(&pcb->sp_laddr)) {
- err = hci_route_lookup(&pcb->sp_laddr, &pcb->sp_raddr);
- if (err)
- return err;
- }
-
- unit = hci_unit_lookup(&pcb->sp_laddr);
- if (unit == NULL)
- return ENETDOWN;
-
- /*
- * We must have an already open ACL connection before we open the SCO
- * connection, and since SCO connections dont happen on their own we
- * will not open one, the application wanting this should have opened
- * it previously.
- */
- acl = hci_link_lookup_bdaddr(unit, &pcb->sp_raddr, HCI_LINK_ACL);
- if (acl == NULL || acl->hl_state != HCI_LINK_OPEN)
- return EHOSTUNREACH;
-
- sco = hci_link_alloc(unit, &pcb->sp_raddr, HCI_LINK_SCO);
- if (sco == NULL)
- return ENOMEM;
-
- sco->hl_link = hci_acl_open(unit, &pcb->sp_raddr);
- KASSERT(sco->hl_link == acl);
-
- cp.con_handle = htole16(acl->hl_handle);
- cp.pkt_type = htole16(0x00e0); /* HV1, HV2, HV3 */
- err = hci_send_cmd(unit, HCI_CMD_ADD_SCO_CON, &cp, sizeof(cp));
- if (err) {
- hci_link_free(sco, err);
- return err;
- }
-
- sco->hl_sco = pcb;
- pcb->sp_link = sco;
-
- pcb->sp_mtu = unit->hci_max_sco_size;
- return 0;
-}
-
-/*
- * sco_peeraddr(pcb, sockaddr)
- *
- * Copy remote address of SCO pcb to sockaddr
- */
-int
-sco_peeraddr(struct sco_pcb *pcb, struct sockaddr_bt *addr)
-{
-
- memset(addr, 0, sizeof(struct sockaddr_bt));
- addr->bt_len = sizeof(struct sockaddr_bt);
- addr->bt_family = AF_BLUETOOTH;
- bdaddr_copy(&addr->bt_bdaddr, &pcb->sp_raddr);
- return 0;
-}
-
-/*
- * sco_disconnect(pcb, linger)
- *
- * Initiate disconnection of connected SCO pcb
- */
-int
-sco_disconnect(struct sco_pcb *pcb, int linger)
-{
- hci_discon_cp cp;
- struct hci_link *sco;
- int err;
-
- sco = pcb->sp_link;
- if (sco == NULL)
- return EINVAL;
-
- cp.con_handle = htole16(sco->hl_handle);
- cp.reason = 0x13; /* "Remote User Terminated Connection" */
-
- err = hci_send_cmd(sco->hl_unit, HCI_CMD_DISCONNECT, &cp, sizeof(cp));
- if (err || linger == 0) {
- sco->hl_sco = NULL;
- pcb->sp_link = NULL;
- hci_link_free(sco, err);
- }
-
- return err;
-}
-
-/*
- * sco_detach(handle)
- *
- * Detach SCO pcb from handle and clear up
- */
-int
-sco_detach(struct sco_pcb **handle)
-{
- struct sco_pcb *pcb;
-
- KASSERT(handle != NULL);
- pcb = *handle;
- *handle = NULL;
-
- if (pcb == NULL)
- return EINVAL;
-
- if (pcb->sp_link != NULL) {
- sco_disconnect(pcb, 0);
- pcb->sp_link = NULL;
- }
-
- LIST_REMOVE(pcb, sp_next);
- free(pcb, M_BLUETOOTH);
- return 0;
-}
-
-/*
- * sco_listen(pcb)
- *
- * Mark pcb as a listener.
- */
-int
-sco_listen(struct sco_pcb *pcb)
-{
-
- if (pcb->sp_link != NULL)
- return EINVAL;
-
- pcb->sp_flags |= SP_LISTENING;
- return 0;
-}
-
-/*
- * sco_send(pcb, mbuf)
- *
- * Send data on SCO pcb.
- *
- * Gross hackage, we just output the packet directly onto the unit queue.
- * This will work fine for one channel per unit, but for more channels it
- * really needs fixing. We set the context so that when the packet is sent,
- * we can drop a record from the socket buffer.
- */
-int
-sco_send(struct sco_pcb *pcb, struct mbuf *m)
-{
- hci_scodata_hdr_t *hdr;
- int plen;
-
- if (pcb->sp_link == NULL) {
- m_freem(m);
- return EINVAL;
- }
-
- plen = m->m_pkthdr.len;
- DPRINTFN(10, "%d bytes\n", plen);
-
- /*
- * This is a temporary limitation, as USB devices cannot
- * handle SCO packet sizes that are not an integer number
- * of Isochronous frames. See ubt(4)
- */
- if (plen != pcb->sp_mtu) {
- m_freem(m);
- return EMSGSIZE;
- }
-
- M_PREPEND(m, sizeof(hci_scodata_hdr_t), M_DONTWAIT);
- if (m == NULL)
- return ENOMEM;
-
- hdr = mtod(m, hci_scodata_hdr_t *);
- hdr->type = HCI_SCO_DATA_PKT;
- hdr->con_handle = htole16(pcb->sp_link->hl_handle);
- hdr->length = plen;
-
- pcb->sp_pending++;
- M_SETCTX(m, pcb->sp_link);
- hci_output_sco(pcb->sp_link->hl_unit, m);
-
- return 0;
-}
-
-/*
- * sco_setopt(pcb, option, m)
- *
- * Set SCO pcb options
- */
-int
-sco_setopt(struct sco_pcb *pcb, int opt, struct mbuf *m)
-{
- int err = 0;
-
- switch (opt) {
- default:
- err = ENOPROTOOPT;
- break;
- }
-
- return err;
-}
-
-/*
- * sco_getopt(pcb, option, addr)
- *
- * Get SCO pcb options
- */
-int
-sco_getopt(struct sco_pcb *pcb, int opt, void *addr)
-{
-
- switch (opt) {
- case SO_SCO_MTU:
- *(uint16_t *)addr = pcb->sp_mtu;
- return sizeof(uint16_t);
-
- case SO_SCO_HANDLE:
- if (pcb->sp_link) {
- *(uint16_t *)addr = pcb->sp_link->hl_handle;
- return sizeof(uint16_t);
- }
- break;
-
- default:
- break;
- }
- return 0;
-}