return ret
+def _have_socket_bluetooth():
+ """Check whether AF_BLUETOOTH sockets are supported on this host."""
+ try:
+ # RFCOMM is supported by all platforms with bluetooth support. Windows
+ # does not support omitting the protocol.
+ s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
+ except (AttributeError, OSError):
+ return False
+ else:
+ s.close()
+ return True
+
+
@contextlib.contextmanager
def socket_setdefaulttimeout(timeout):
old_timeout = socket.getdefaulttimeout()
HAVE_SOCKET_UDPLITE = hasattr(socket, "IPPROTO_UDPLITE")
+HAVE_SOCKET_BLUETOOTH = _have_socket_bluetooth()
+
# Size in bytes of the int type
SIZEOF_INT = array.array("i").itemsize
socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE))
+@unittest.skipUnless(HAVE_SOCKET_BLUETOOTH,
+ 'Bluetooth sockets required for this test.')
+class BasicBluetoothTest(unittest.TestCase):
+
+ def testBluetoothConstants(self):
+ socket.BDADDR_ANY
+ socket.BDADDR_LOCAL
+ socket.AF_BLUETOOTH
+ socket.BTPROTO_RFCOMM
+
+ if sys.platform != "win32":
+ socket.BTPROTO_HCI
+ socket.SOL_HCI
+ socket.BTPROTO_L2CAP
+
+ if not sys.platform.startswith("freebsd"):
+ socket.BTPROTO_SCO
+
+ def testCreateRfcommSocket(self):
+ with socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM) as s:
+ pass
+
+ @unittest.skipIf(sys.platform == "win32", "windows does not support L2CAP sockets")
+ def testCreateL2capSocket(self):
+ with socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP) as s:
+ pass
+
+ @unittest.skipIf(sys.platform == "win32", "windows does not support HCI sockets")
+ def testCreateHciSocket(self):
+ with socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) as s:
+ pass
+
+ @unittest.skipIf(sys.platform == "win32" or sys.platform.startswith("freebsd"),
+ "windows and freebsd do not support SCO sockets")
+ def testCreateScoSocket(self):
+ with socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_SCO) as s:
+ pass
+
+
class BasicTCPTest(SocketConnectedTest):
def __init__(self, methodName='runTest'):
BasicVSOCKTest,
ThreadedVSOCKSocketStreamTest,
])
+ tests.append(BasicBluetoothTest)
tests.extend([
CmsgMacroTests,
SendmsgUDPTest,
#endif
#endif
+#ifdef MS_WINDOWS
+#define sockaddr_rc SOCKADDR_BTH_REDEF
+
+#define USE_BLUETOOTH 1
+#define AF_BLUETOOTH AF_BTH
+#define BTPROTO_RFCOMM BTHPROTO_RFCOMM
+#define _BT_RC_MEMB(sa, memb) ((sa)->memb)
+#endif
+
/* Convert "sock_addr_t *" to "struct sockaddr *". */
#define SAS2SA(x) (&((x)->sa))
n = sscanf(name, "%X:%X:%X:%X:%X:%X%c",
&b5, &b4, &b3, &b2, &b1, &b0, &ch);
if (n == 6 && (b0 | b1 | b2 | b3 | b4 | b5) < 256) {
+
+#ifdef MS_WINDOWS
+ *bdaddr = (ULONGLONG)(b0 & 0xFF);
+ *bdaddr |= ((ULONGLONG)(b1 & 0xFF) << 8);
+ *bdaddr |= ((ULONGLONG)(b2 & 0xFF) << 16);
+ *bdaddr |= ((ULONGLONG)(b3 & 0xFF) << 24);
+ *bdaddr |= ((ULONGLONG)(b4 & 0xFF) << 32);
+ *bdaddr |= ((ULONGLONG)(b5 & 0xFF) << 40);
+#else
bdaddr->b[0] = b0;
bdaddr->b[1] = b1;
bdaddr->b[2] = b2;
bdaddr->b[3] = b3;
bdaddr->b[4] = b4;
bdaddr->b[5] = b5;
+#endif
+
return 6;
} else {
PyErr_SetString(PyExc_OSError, "bad bluetooth address");
{
char buf[(6 * 2) + 5 + 1];
+#ifdef MS_WINDOWS
+ int i;
+ unsigned int octets[6];
+
+ for (i = 0; i < 6; ++i) {
+ octets[i] = ((*bdaddr) >> (8 * i)) & 0xFF;
+ }
+
+ sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+ octets[5], octets[4], octets[3],
+ octets[2], octets[1], octets[0]);
+#else
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+#endif
+
return PyUnicode_FromString(buf);
}
#endif
case AF_BLUETOOTH:
switch (proto) {
+#ifdef BTPROTO_L2CAP
case BTPROTO_L2CAP:
{
struct sockaddr_l2 *a = (struct sockaddr_l2 *) addr;
return ret;
}
+#endif /* BTPROTO_L2CAP */
+
case BTPROTO_RFCOMM:
{
struct sockaddr_rc *a = (struct sockaddr_rc *) addr;
return ret;
}
+#ifdef BTPROTO_HCI
case BTPROTO_HCI:
{
struct sockaddr_hci *a = (struct sockaddr_hci *) addr;
return makebdaddr(&_BT_SCO_MEMB(a, bdaddr));
}
#endif /* !__FreeBSD__ */
+#endif /* BTPROTO_HCI */
default:
PyErr_SetString(PyExc_ValueError,
case AF_BLUETOOTH:
{
switch (s->sock_proto) {
+#ifdef BTPROTO_L2CAP
case BTPROTO_L2CAP:
{
struct sockaddr_l2 *addr;
*len_ret = sizeof *addr;
return 1;
}
+#endif /* BTPROTO_L2CAP */
case BTPROTO_RFCOMM:
{
struct sockaddr_rc *addr;
*len_ret = sizeof *addr;
return 1;
}
+#ifdef BTPROTO_HCI
case BTPROTO_HCI:
{
struct sockaddr_hci *addr = (struct sockaddr_hci *)addr_ret;
return 1;
}
#endif /* !__FreeBSD__ */
+#endif /* BTPROTO_HCI */
default:
PyErr_Format(PyExc_OSError,
"%s(): unknown Bluetooth protocol", caller);
switch(s->sock_proto)
{
+#ifdef BTPROTO_L2CAP
case BTPROTO_L2CAP:
*len_ret = sizeof (struct sockaddr_l2);
return 1;
+#endif /* BTPROTO_L2CAP */
case BTPROTO_RFCOMM:
*len_ret = sizeof (struct sockaddr_rc);
return 1;
+#ifdef BTPROTO_HCI
case BTPROTO_HCI:
*len_ret = sizeof (struct sockaddr_hci);
return 1;
*len_ret = sizeof (struct sockaddr_sco);
return 1;
#endif /* !__FreeBSD__ */
+#endif /* BTPROTO_HCI */
default:
PyErr_SetString(PyExc_OSError, "getsockaddrlen: "
"unknown BT protocol");
#ifdef USE_BLUETOOTH
PyModule_AddIntMacro(m, AF_BLUETOOTH);
+#ifdef BTPROTO_L2CAP
PyModule_AddIntMacro(m, BTPROTO_L2CAP);
+#endif /* BTPROTO_L2CAP */
+#ifdef BTPROTO_HCI
PyModule_AddIntMacro(m, BTPROTO_HCI);
PyModule_AddIntMacro(m, SOL_HCI);
#if !defined(__NetBSD__) && !defined(__DragonFly__)
PyModule_AddIntMacro(m, HCI_FILTER);
-#endif
#if !defined(__FreeBSD__)
-#if !defined(__NetBSD__) && !defined(__DragonFly__)
PyModule_AddIntMacro(m, HCI_TIME_STAMP);
-#endif
PyModule_AddIntMacro(m, HCI_DATA_DIR);
- PyModule_AddIntMacro(m, BTPROTO_SCO);
-#endif
+#endif /* !__FreeBSD__ */
+#endif /* !__NetBSD__ && !__DragonFly__ */
+#endif /* BTPROTO_HCI */
+#ifdef BTPROTO_RFCOMM
PyModule_AddIntMacro(m, BTPROTO_RFCOMM);
+#endif /* BTPROTO_RFCOMM */
PyModule_AddStringConstant(m, "BDADDR_ANY", "00:00:00:00:00:00");
PyModule_AddStringConstant(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF");
-#endif
+#ifdef BTPROTO_SCO
+ PyModule_AddIntMacro(m, BTPROTO_SCO);
+#endif /* BTPROTO_SCO */
+#endif /* USE_BLUETOOTH */
#ifdef AF_CAN
/* Controller Area Network */
#else /* MS_WINDOWS */
# include <winsock2.h>
+
+/*
+ * If Windows has bluetooth support, include bluetooth constants.
+ */
+#ifdef AF_BTH
+# include <ws2bth.h>
+# include <pshpack1.h>
+
+/*
+ * The current implementation assumes the bdaddr in the sockaddr structs
+ * will be a bdaddr_t. We treat this as an opaque type: on *nix systems, it
+ * will be a struct with a single member (an array of six bytes). On windows,
+ * we typedef this to ULONGLONG to match the Windows definition.
+ */
+typedef ULONGLONG bdaddr_t;
+
+/*
+ * Redefine SOCKADDR_BTH to provide names compatible with _BT_RC_MEMB() macros.
+ */
+struct SOCKADDR_BTH_REDEF {
+ union {
+ USHORT addressFamily;
+ USHORT family;
+ };
+
+ union {
+ ULONGLONG btAddr;
+ bdaddr_t bdaddr;
+ };
+
+ GUID serviceClassId;
+
+ union {
+ ULONG port;
+ ULONG channel;
+ };
+
+};
+# include <poppack.h>
+#endif
+
/* Windows 'supports' CMSG_LEN, but does not follow the POSIX standard
* interface at all, so there is no point including the code that
* attempts to use it.
struct sockaddr_rc bt_rc;
struct sockaddr_sco bt_sco;
struct sockaddr_hci bt_hci;
+#elif defined(MS_WINDOWS)
+ struct SOCKADDR_BTH_REDEF bt_rc;
#endif
#ifdef HAVE_NETPACKET_PACKET_H
struct sockaddr_ll ll;