btsocket: support L2CAP, RFCOMM & SCO sockets
Python's socket module doesn't consistently provide these (depending
whether it saw bluetooth.h during build or not), and provides old
versions - so support bind() on them too.
BUG=chromium:256771
TEST=import btsocket, socket
s1 = btsocket.socket(btsocket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, btsocket.BTPROTO_L2CAP)
s1.bind((btsocket.BDADDR_ANY, 0))
s2 = btsocket.socket(btsocket.AF_BLUETOOTH, socket.SOCK_STREAM, btsocket.BTPROTO_RFCOMM)
s2.bind((btsocket.BDADDR_ANY, 1))
s3 = btsocket.socket(btsocket.AF_BLUETOOTH, socket.SOCK_RAW, btsocket.BTPROTO_HCI)
s3.bind((0, btsocket.HCI_CHANNEL_RAW))
s4 = btsocket.socket(btsocket.AF_BLUETOOTH, socket.SOCK_RAW, btsocket.BTPROTO_HCI)
s4.bind((btsocket.HCI_DEV_NONE, btsocket.HCI_CHANNEL_CONTROL))
s5 = btsocket.socket(btsocket.AF_BLUETOOTH, socket.SOCK_RAW, btsocket.BTPROTO_HCI)
s5.bind((btsocket.HCI_DEV_NONE, btsocket.HCI_CHANNEL_MONITOR))
s6 = btsocket.socket(btsocket.AF_BLUETOOTH, socket.SOCK_STREAM, btsocket.BTPROTO_SCO)
s6.bind((btsocket.BDADDR_ANY))
Change-Id: I6d44a11b667e96d7fa3334df80e383911d658405
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg
new file mode 100644
index 0000000..76b4df1
--- /dev/null
+++ b/PRESUBMIT.cfg
@@ -0,0 +1,9 @@
+# This sample config file disables all of the ChromiumOS source style checks.
+# Comment out the disable-flags for any checks you want to leave enabled.
+
+[Hook Overrides]
+#stray_whitespace_check: false
+#long_line_check: false
+cros_license_check: false
+tab_check: false
+
diff --git a/btsocket/btsocket.py b/btsocket/btsocket.py
index 4473830..0b38a77 100644
--- a/btsocket/btsocket.py
+++ b/btsocket/btsocket.py
@@ -6,6 +6,7 @@
import socket
import _btsocket
+import constants
class BluetoothSocket(socket._socketobject):
"""Socket wrapper class for Bluetooth sockets.
@@ -16,11 +17,11 @@
"""
- def __init__(self):
- # TODO(keybuk): do we want to support other BTPROTO_* ?
- super(BluetoothSocket, self).__init__(family=socket.AF_BLUETOOTH,
- type=socket.SOCK_RAW,
- proto=socket.BTPROTO_HCI)
+ def __init__(self,
+ family=constants.AF_BLUETOOTH,
+ type=socket.SOCK_RAW,
+ proto=constants.BTPROTO_HCI):
+ super(BluetoothSocket, self).__init__(family, type, proto)
def bind(self, *args):
"""Bind the socket.
@@ -31,10 +32,8 @@
@param channel channel to bind to, e.g. HCI_CHANNEL_RAW.
"""
- if (self.family == socket.AF_BLUETOOTH and
- self.type == socket.SOCK_RAW and
- self.proto == socket.BTPROTO_HCI):
- return _btsocket.bind(self, *args)
+ if self.family == constants.AF_BLUETOOTH:
+ return _btsocket.bind(self, self.proto, *args)
else:
return super(BluetoothSocket, self).bind(*args)
diff --git a/btsocket/constants.py b/btsocket/constants.py
index 31b8e2b..e1408e3 100644
--- a/btsocket/constants.py
+++ b/btsocket/constants.py
@@ -54,6 +54,121 @@
BDADDR_LE_PUBLIC = 0x01
BDADDR_LE_RANDOM = 0x02
+BDADDR_ANY = "00:00:00:00:00:00"
+BDADDR_ALL = "FF:FF:FF:FF:FF:FF"
+BDADDR_LOCAL = "00:00:00:FF:FF:FF"
+
+# Constants from src/l2cap.h
+L2CAP_DEFAULT_MTU = 672
+L2CAP_DEFAULT_FLUSH_TO = 0xFFFF
+L2CAP_OPTIONS = 0x01
+L2CAP_CONNINFO = 0x02
+L2CAP_LM = 0x03
+L2CAP_LM_MASTER = 0x0001
+L2CAP_LM_AUTH = 0x0002
+L2CAP_LM_ENCRYPT = 0x0004
+L2CAP_LM_TRUSTED = 0x0008
+L2CAP_LM_RELIABLE = 0x0010
+L2CAP_LM_SECURE = 0x0020
+L2CAP_COMMAND_REJ = 0x01
+L2CAP_CONN_REQ = 0x02
+L2CAP_CONN_RSP = 0x03
+L2CAP_CONF_REQ = 0x04
+L2CAP_CONF_RSP = 0x05
+L2CAP_DISCONN_REQ = 0x06
+L2CAP_DISCONN_RSP = 0x07
+L2CAP_ECHO_REQ = 0x08
+L2CAP_ECHO_RSP = 0x09
+L2CAP_INFO_REQ = 0x0a
+L2CAP_INFO_RSP = 0x0b
+L2CAP_CREATE_REQ = 0x0c
+L2CAP_CREATE_RSP = 0x0d
+L2CAP_MOVE_REQ = 0x0e
+L2CAP_MOVE_RSP = 0x0f
+L2CAP_MOVE_CFM = 0x10
+L2CAP_MOVE_CFM_RSP = 0x11
+L2CAP_FEAT_FLOWCTL = 0x00000001
+L2CAP_FEAT_RETRANS = 0x00000002
+L2CAP_FEAT_BIDIR_QOS = 0x00000004
+L2CAP_FEAT_ERTM = 0x00000008
+L2CAP_FEAT_STREAMING = 0x00000010
+L2CAP_FEAT_FCS = 0x00000020
+L2CAP_FEAT_EXT_FLOW = 0x00000040
+L2CAP_FEAT_FIXED_CHAN = 0x00000080
+L2CAP_FEAT_EXT_WINDOW = 0x00000100
+L2CAP_FEAT_UCD = 0x00000200
+L2CAP_FC_L2CAP = 0x02
+L2CAP_FC_CONNLESS = 0x04
+L2CAP_FC_A2MP = 0x08
+L2CAP_HDR_SIZE = 4
+L2CAP_CMD_HDR_SIZE = 4
+L2CAP_CMD_REJ_SIZE = 2
+L2CAP_CONN_REQ_SIZE = 4
+L2CAP_CONN_RSP_SIZE = 8
+L2CAP_CR_SUCCESS = 0x0000
+L2CAP_CR_PEND = 0x0001
+L2CAP_CR_BAD_PSM = 0x0002
+L2CAP_CR_SEC_BLOCK = 0x0003
+L2CAP_CR_NO_MEM = 0x0004
+L2CAP_CS_NO_INFO = 0x0000
+L2CAP_CS_AUTHEN_PEND = 0x0001
+L2CAP_CS_AUTHOR_PEND = 0x0002
+L2CAP_CONF_REQ_SIZE = 4
+L2CAP_CONF_RSP_SIZE = 6
+L2CAP_CONF_SUCCESS = 0x0000
+L2CAP_CONF_UNACCEPT = 0x0001
+L2CAP_CONF_REJECT = 0x0002
+L2CAP_CONF_UNKNOWN = 0x0003
+L2CAP_CONF_PENDING = 0x0004
+L2CAP_CONF_EFS_REJECT = 0x0005
+L2CAP_CONF_OPT_SIZE = 2
+L2CAP_CONF_MTU = 0x01
+L2CAP_CONF_FLUSH_TO = 0x02
+L2CAP_CONF_QOS = 0x03
+L2CAP_CONF_RFC = 0x04
+L2CAP_CONF_FCS = 0x05
+L2CAP_CONF_EFS = 0x06
+L2CAP_CONF_EWS = 0x07
+L2CAP_CONF_MAX_SIZE = 22
+L2CAP_MODE_BASIC = 0x00
+L2CAP_MODE_RETRANS = 0x01
+L2CAP_MODE_FLOWCTL = 0x02
+L2CAP_MODE_ERTM = 0x03
+L2CAP_MODE_STREAMING = 0x04
+L2CAP_SERVTYPE_NOTRAFFIC = 0x00
+L2CAP_SERVTYPE_BESTEFFORT = 0x01
+L2CAP_SERVTYPE_GUARANTEED = 0x02
+L2CAP_DISCONN_REQ_SIZE = 4
+L2CAP_DISCONN_RSP_SIZE = 4
+L2CAP_INFO_REQ_SIZE = 2
+L2CAP_INFO_RSP_SIZE = 4
+L2CAP_IT_CL_MTU = 0x0001
+L2CAP_IT_FEAT_MASK = 0x0002
+L2CAP_IR_SUCCESS = 0x0000
+L2CAP_IR_NOTSUPP = 0x0001
+L2CAP_CREATE_REQ_SIZE = 5
+L2CAP_CREATE_RSP_SIZE = 8
+L2CAP_MOVE_REQ_SIZE = 3
+L2CAP_MOVE_RSP_SIZE = 4
+L2CAP_MOVE_CFM_SIZE = 4
+L2CAP_MOVE_CFM_RSP_SIZE = 2
+
+# Constants from src/rfcomm.h
+RFCOMM_DEFAULT_MTU = 127
+RFCOMM_PSM = 3
+RFCOMM_CONNINFO = 0x02
+RFCOMM_LM = 0x03
+RFCOMM_LM_MASTER = 0x0001
+RFCOMM_LM_AUTH = 0x0002
+RFCOMM_LM_ENCRYPT = 0x0004
+RFCOMM_LM_TRUSTED = 0x0008
+RFCOMM_LM_RELIABLE = 0x0010
+RFCOMM_LM_SECURE = 0x0020
+RFCOMM_MAX_DEV = 256
+RFCOMM_REUSE_DLC = 0
+RFCOMM_RELEASE_ONHUP = 1
+RFCOMM_HANGUP_NOW = 2
+RFCOMM_TTY_ATTACHED = 3
# Constants from src/hci.h
HCI_MAX_DEV = 16
@@ -798,3 +913,9 @@
HCI_FLT_OGF_BITS = 63
HCI_FLT_OCF_BITS = 127
IREQ_CACHE_FLUSH = 0x0001
+
+# Constants from src/sco.h
+SCO_DEFAULT_MTU = 500
+SCO_DEFAULT_FLUSH_TO = 0xFFFF
+SCO_OPTIONS = 0x01
+SCO_CONNINFO = 0x02
diff --git a/src/btsocket.c b/src/btsocket.c
index 020c2ad..a4e4b62 100644
--- a/src/btsocket.c
+++ b/src/btsocket.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -10,7 +10,10 @@
#include <poll.h>
#include "bluetooth.h"
+#include "l2cap.h"
+#include "rfcomm.h"
#include "hci.h"
+#include "sco.h"
static PyObject *_btsocket_error;
static PyObject *_btsocket_timeout;
@@ -47,23 +50,106 @@
return 1;
}
+static int _setbdaddr(const char *straddr, bdaddr_t *bdaddr) {
+ unsigned int b0, b1, b2, b3, b4, b5;
+ int n;
+
+ n = sscanf(straddr, "%X:%X:%X:%X:%X:%X", &b5, &b4, &b3, &b2, &b1, &b0);
+ if (n == 6) {
+ bdaddr->b[0] = b0;
+ bdaddr->b[1] = b1;
+ bdaddr->b[2] = b2;
+ bdaddr->b[3] = b3;
+ bdaddr->b[4] = b4;
+ bdaddr->b[5] = b5;
+ return 1;
+ } else {
+ PyErr_SetString(_btsocket_error, "bad bluetooth address for bind()");
+ return 0;
+ }
+}
+
static PyObject *_btsocket_bind(PyObject *self, PyObject *args) {
- PyObject *socket_object;
- struct sockaddr_hci addr;
- int fd, result;
+ PyObject *socket_object, *tuple;
+ union {
+ struct sockaddr_l2 l2;
+ struct sockaddr_rc rc;
+ struct sockaddr_hci hci;
+ struct sockaddr_sco sco;
+ } addr;
+ size_t addrlen;
+ int proto, fd, result;
- addr.hci_family = AF_BLUETOOTH;
-
- if (!PyArg_ParseTuple(args, "O(HH):_btsocket.bind",
- &socket_object, &addr.hci_dev, &addr.hci_channel))
+ if (!PyArg_ParseTuple(args, "OiO:_btsocket.bind",
+ &socket_object, &proto, &tuple))
return NULL;
fd = _get_fileno(socket_object);
if (fd < 0)
return NULL;
+ memset(&addr, 0, sizeof addr);
+
+ switch (proto) {
+ case BTPROTO_L2CAP: {
+ char *straddr;
+
+ addr.l2.l2_family = AF_BLUETOOTH;
+
+ if (!PyArg_ParseTuple(tuple, "si:_btsocket.bind",
+ &straddr, &addr.l2.l2_psm))
+ return NULL;
+ if (!_setbdaddr(straddr, &addr.l2.l2_bdaddr))
+ return NULL;
+
+ addrlen = sizeof (struct sockaddr_l2);
+ break;
+ }
+ case BTPROTO_RFCOMM: {
+ char *straddr;
+
+ addr.rc.rc_family = AF_BLUETOOTH;
+
+ if (!PyArg_ParseTuple(tuple, "si:_btsocket.bind",
+ &straddr, &addr.rc.rc_channel))
+ return NULL;
+ if (!_setbdaddr(straddr, &addr.rc.rc_bdaddr))
+ return NULL;
+
+ addrlen = sizeof (struct sockaddr_rc);
+ break;
+ }
+ case BTPROTO_HCI: {
+ addr.hci.hci_family = AF_BLUETOOTH;
+
+ if (!PyArg_ParseTuple(tuple, "HH:_btsocket.bind",
+ &addr.hci.hci_dev, &addr.hci.hci_channel))
+ return NULL;
+
+ addrlen = sizeof (struct sockaddr_hci);
+ break;
+ }
+ case BTPROTO_SCO: {
+ char *straddr;
+
+ addr.sco.sco_family = AF_BLUETOOTH;
+
+ if (!PyArg_ParseTuple(tuple, "s:_btsocket.bind",
+ &straddr))
+ return NULL;
+ if (!_setbdaddr(straddr, &addr.sco.sco_bdaddr))
+ return NULL;
+
+ addrlen = sizeof (struct sockaddr_sco);
+ break;
+ }
+ default:
+ PyErr_SetString(_btsocket_error, "unknown protocol for bind()");
+ return NULL;
+ }
+
Py_BEGIN_ALLOW_THREADS;
- result = bind(fd, (struct sockaddr *)&addr, sizeof addr);
+ result = bind(fd, (struct sockaddr *)&addr, addrlen);
Py_END_ALLOW_THREADS;
if (result < 0)
diff --git a/src/l2cap.h b/src/l2cap.h
new file mode 100644
index 0000000..5ce94c4
--- /dev/null
+++ b/src/l2cap.h
@@ -0,0 +1,279 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2000-2001 Qualcomm Incorporated
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __L2CAP_H
+#define __L2CAP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/socket.h>
+
+/* L2CAP defaults */
+#define L2CAP_DEFAULT_MTU 672
+#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
+
+/* L2CAP socket address */
+struct sockaddr_l2 {
+ sa_family_t l2_family;
+ unsigned short l2_psm;
+ bdaddr_t l2_bdaddr;
+ unsigned short l2_cid;
+ uint8_t l2_bdaddr_type;
+};
+
+/* L2CAP socket options */
+#define L2CAP_OPTIONS 0x01
+struct l2cap_options {
+ uint16_t omtu;
+ uint16_t imtu;
+ uint16_t flush_to;
+ uint8_t mode;
+ uint8_t fcs;
+ uint8_t max_tx;
+ uint16_t txwin_size;
+};
+
+#define L2CAP_CONNINFO 0x02
+struct l2cap_conninfo {
+ uint16_t hci_handle;
+ uint8_t dev_class[3];
+};
+
+#define L2CAP_LM 0x03
+#define L2CAP_LM_MASTER 0x0001
+#define L2CAP_LM_AUTH 0x0002
+#define L2CAP_LM_ENCRYPT 0x0004
+#define L2CAP_LM_TRUSTED 0x0008
+#define L2CAP_LM_RELIABLE 0x0010
+#define L2CAP_LM_SECURE 0x0020
+
+/* L2CAP command codes */
+#define L2CAP_COMMAND_REJ 0x01
+#define L2CAP_CONN_REQ 0x02
+#define L2CAP_CONN_RSP 0x03
+#define L2CAP_CONF_REQ 0x04
+#define L2CAP_CONF_RSP 0x05
+#define L2CAP_DISCONN_REQ 0x06
+#define L2CAP_DISCONN_RSP 0x07
+#define L2CAP_ECHO_REQ 0x08
+#define L2CAP_ECHO_RSP 0x09
+#define L2CAP_INFO_REQ 0x0a
+#define L2CAP_INFO_RSP 0x0b
+#define L2CAP_CREATE_REQ 0x0c
+#define L2CAP_CREATE_RSP 0x0d
+#define L2CAP_MOVE_REQ 0x0e
+#define L2CAP_MOVE_RSP 0x0f
+#define L2CAP_MOVE_CFM 0x10
+#define L2CAP_MOVE_CFM_RSP 0x11
+
+/* L2CAP extended feature mask */
+#define L2CAP_FEAT_FLOWCTL 0x00000001
+#define L2CAP_FEAT_RETRANS 0x00000002
+#define L2CAP_FEAT_BIDIR_QOS 0x00000004
+#define L2CAP_FEAT_ERTM 0x00000008
+#define L2CAP_FEAT_STREAMING 0x00000010
+#define L2CAP_FEAT_FCS 0x00000020
+#define L2CAP_FEAT_EXT_FLOW 0x00000040
+#define L2CAP_FEAT_FIXED_CHAN 0x00000080
+#define L2CAP_FEAT_EXT_WINDOW 0x00000100
+#define L2CAP_FEAT_UCD 0x00000200
+
+/* L2CAP fixed channels */
+#define L2CAP_FC_L2CAP 0x02
+#define L2CAP_FC_CONNLESS 0x04
+#define L2CAP_FC_A2MP 0x08
+
+/* L2CAP structures */
+typedef struct {
+ uint16_t len;
+ uint16_t cid;
+} __attribute__ ((packed)) l2cap_hdr;
+#define L2CAP_HDR_SIZE 4
+
+typedef struct {
+ uint8_t code;
+ uint8_t ident;
+ uint16_t len;
+} __attribute__ ((packed)) l2cap_cmd_hdr;
+#define L2CAP_CMD_HDR_SIZE 4
+
+typedef struct {
+ uint16_t reason;
+} __attribute__ ((packed)) l2cap_cmd_rej;
+#define L2CAP_CMD_REJ_SIZE 2
+
+typedef struct {
+ uint16_t psm;
+ uint16_t scid;
+} __attribute__ ((packed)) l2cap_conn_req;
+#define L2CAP_CONN_REQ_SIZE 4
+
+typedef struct {
+ uint16_t dcid;
+ uint16_t scid;
+ uint16_t result;
+ uint16_t status;
+} __attribute__ ((packed)) l2cap_conn_rsp;
+#define L2CAP_CONN_RSP_SIZE 8
+
+/* connect result */
+#define L2CAP_CR_SUCCESS 0x0000
+#define L2CAP_CR_PEND 0x0001
+#define L2CAP_CR_BAD_PSM 0x0002
+#define L2CAP_CR_SEC_BLOCK 0x0003
+#define L2CAP_CR_NO_MEM 0x0004
+
+/* connect status */
+#define L2CAP_CS_NO_INFO 0x0000
+#define L2CAP_CS_AUTHEN_PEND 0x0001
+#define L2CAP_CS_AUTHOR_PEND 0x0002
+
+typedef struct {
+ uint16_t dcid;
+ uint16_t flags;
+ uint8_t data[0];
+} __attribute__ ((packed)) l2cap_conf_req;
+#define L2CAP_CONF_REQ_SIZE 4
+
+typedef struct {
+ uint16_t scid;
+ uint16_t flags;
+ uint16_t result;
+ uint8_t data[0];
+} __attribute__ ((packed)) l2cap_conf_rsp;
+#define L2CAP_CONF_RSP_SIZE 6
+
+#define L2CAP_CONF_SUCCESS 0x0000
+#define L2CAP_CONF_UNACCEPT 0x0001
+#define L2CAP_CONF_REJECT 0x0002
+#define L2CAP_CONF_UNKNOWN 0x0003
+#define L2CAP_CONF_PENDING 0x0004
+#define L2CAP_CONF_EFS_REJECT 0x0005
+
+typedef struct {
+ uint8_t type;
+ uint8_t len;
+ uint8_t val[0];
+} __attribute__ ((packed)) l2cap_conf_opt;
+#define L2CAP_CONF_OPT_SIZE 2
+
+#define L2CAP_CONF_MTU 0x01
+#define L2CAP_CONF_FLUSH_TO 0x02
+#define L2CAP_CONF_QOS 0x03
+#define L2CAP_CONF_RFC 0x04
+#define L2CAP_CONF_FCS 0x05
+#define L2CAP_CONF_EFS 0x06
+#define L2CAP_CONF_EWS 0x07
+
+#define L2CAP_CONF_MAX_SIZE 22
+
+#define L2CAP_MODE_BASIC 0x00
+#define L2CAP_MODE_RETRANS 0x01
+#define L2CAP_MODE_FLOWCTL 0x02
+#define L2CAP_MODE_ERTM 0x03
+#define L2CAP_MODE_STREAMING 0x04
+
+#define L2CAP_SERVTYPE_NOTRAFFIC 0x00
+#define L2CAP_SERVTYPE_BESTEFFORT 0x01
+#define L2CAP_SERVTYPE_GUARANTEED 0x02
+
+typedef struct {
+ uint16_t dcid;
+ uint16_t scid;
+} __attribute__ ((packed)) l2cap_disconn_req;
+#define L2CAP_DISCONN_REQ_SIZE 4
+
+typedef struct {
+ uint16_t dcid;
+ uint16_t scid;
+} __attribute__ ((packed)) l2cap_disconn_rsp;
+#define L2CAP_DISCONN_RSP_SIZE 4
+
+typedef struct {
+ uint16_t type;
+} __attribute__ ((packed)) l2cap_info_req;
+#define L2CAP_INFO_REQ_SIZE 2
+
+typedef struct {
+ uint16_t type;
+ uint16_t result;
+ uint8_t data[0];
+} __attribute__ ((packed)) l2cap_info_rsp;
+#define L2CAP_INFO_RSP_SIZE 4
+
+/* info type */
+#define L2CAP_IT_CL_MTU 0x0001
+#define L2CAP_IT_FEAT_MASK 0x0002
+
+/* info result */
+#define L2CAP_IR_SUCCESS 0x0000
+#define L2CAP_IR_NOTSUPP 0x0001
+
+typedef struct {
+ uint16_t psm;
+ uint16_t scid;
+ uint8_t id;
+} __attribute__ ((packed)) l2cap_create_req;
+#define L2CAP_CREATE_REQ_SIZE 5
+
+typedef struct {
+ uint16_t dcid;
+ uint16_t scid;
+ uint16_t result;
+ uint16_t status;
+} __attribute__ ((packed)) l2cap_create_rsp;
+#define L2CAP_CREATE_RSP_SIZE 8
+
+typedef struct {
+ uint16_t icid;
+ uint8_t id;
+} __attribute__ ((packed)) l2cap_move_req;
+#define L2CAP_MOVE_REQ_SIZE 3
+
+typedef struct {
+ uint16_t icid;
+ uint16_t result;
+} __attribute__ ((packed)) l2cap_move_rsp;
+#define L2CAP_MOVE_RSP_SIZE 4
+
+typedef struct {
+ uint16_t icid;
+ uint16_t result;
+} __attribute__ ((packed)) l2cap_move_cfm;
+#define L2CAP_MOVE_CFM_SIZE 4
+
+typedef struct {
+ uint16_t icid;
+} __attribute__ ((packed)) l2cap_move_cfm_rsp;
+#define L2CAP_MOVE_CFM_RSP_SIZE 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __L2CAP_H */
diff --git a/src/rfcomm.h b/src/rfcomm.h
new file mode 100644
index 0000000..ad6c0e1
--- /dev/null
+++ b/src/rfcomm.h
@@ -0,0 +1,99 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __RFCOMM_H
+#define __RFCOMM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/socket.h>
+
+/* RFCOMM defaults */
+#define RFCOMM_DEFAULT_MTU 127
+
+#define RFCOMM_PSM 3
+
+/* RFCOMM socket address */
+struct sockaddr_rc {
+ sa_family_t rc_family;
+ bdaddr_t rc_bdaddr;
+ uint8_t rc_channel;
+};
+
+/* RFCOMM socket options */
+#define RFCOMM_CONNINFO 0x02
+struct rfcomm_conninfo {
+ uint16_t hci_handle;
+ uint8_t dev_class[3];
+};
+
+#define RFCOMM_LM 0x03
+#define RFCOMM_LM_MASTER 0x0001
+#define RFCOMM_LM_AUTH 0x0002
+#define RFCOMM_LM_ENCRYPT 0x0004
+#define RFCOMM_LM_TRUSTED 0x0008
+#define RFCOMM_LM_RELIABLE 0x0010
+#define RFCOMM_LM_SECURE 0x0020
+
+/* RFCOMM TTY support */
+#define RFCOMM_MAX_DEV 256
+
+#define RFCOMMCREATEDEV _IOW('R', 200, int)
+#define RFCOMMRELEASEDEV _IOW('R', 201, int)
+#define RFCOMMGETDEVLIST _IOR('R', 210, int)
+#define RFCOMMGETDEVINFO _IOR('R', 211, int)
+
+struct rfcomm_dev_req {
+ int16_t dev_id;
+ uint32_t flags;
+ bdaddr_t src;
+ bdaddr_t dst;
+ uint8_t channel;
+};
+#define RFCOMM_REUSE_DLC 0
+#define RFCOMM_RELEASE_ONHUP 1
+#define RFCOMM_HANGUP_NOW 2
+#define RFCOMM_TTY_ATTACHED 3
+
+struct rfcomm_dev_info {
+ int16_t id;
+ uint32_t flags;
+ uint16_t state;
+ bdaddr_t src;
+ bdaddr_t dst;
+ uint8_t channel;
+};
+
+struct rfcomm_dev_list_req {
+ uint16_t dev_num;
+ struct rfcomm_dev_info dev_info[0];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RFCOMM_H */
diff --git a/src/sco.h b/src/sco.h
new file mode 100644
index 0000000..75336a5
--- /dev/null
+++ b/src/sco.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __SCO_H
+#define __SCO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* SCO defaults */
+#define SCO_DEFAULT_MTU 500
+#define SCO_DEFAULT_FLUSH_TO 0xFFFF
+
+#define SCO_CONN_TIMEOUT (HZ * 40)
+#define SCO_DISCONN_TIMEOUT (HZ * 2)
+#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
+
+/* SCO socket address */
+struct sockaddr_sco {
+ sa_family_t sco_family;
+ bdaddr_t sco_bdaddr;
+};
+
+/* set/get sockopt defines */
+#define SCO_OPTIONS 0x01
+struct sco_options {
+ uint16_t mtu;
+};
+
+#define SCO_CONNINFO 0x02
+struct sco_conninfo {
+ uint16_t hci_handle;
+ uint8_t dev_class[3];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SCO_H */