mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-36590: Add Bluetooth RFCOMM and support for Windows. (GH-12767)
Support for RFCOMM, L2CAP, HCI, SCO is based on the BTPROTO_* macros being defined. Winsock only supports RFCOMM, even though it has a BTHPROTO_L2CAP macro. L2CAP support would build on windows, but not necessarily work. This also adds some basic unittests for constants (all of which existed prior to this commit, just not on windows) and creating sockets. pair: Nate Duarte <slacknate@gmail.com>
This commit is contained in:
parent
cb65b3a4f4
commit
8fbece135d
4 changed files with 158 additions and 6 deletions
65
Modules/socketmodule.c
Normal file → Executable file
65
Modules/socketmodule.c
Normal file → Executable file
|
@ -520,6 +520,15 @@ remove_unusable_flags(PyObject *m)
|
|||
#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))
|
||||
|
||||
|
@ -1256,12 +1265,23 @@ setbdaddr(const char *name, bdaddr_t *bdaddr)
|
|||
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");
|
||||
|
@ -1278,9 +1298,23 @@ makebdaddr(bdaddr_t *bdaddr)
|
|||
{
|
||||
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
|
||||
|
@ -1378,6 +1412,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
|
|||
case AF_BLUETOOTH:
|
||||
switch (proto) {
|
||||
|
||||
#ifdef BTPROTO_L2CAP
|
||||
case BTPROTO_L2CAP:
|
||||
{
|
||||
struct sockaddr_l2 *a = (struct sockaddr_l2 *) addr;
|
||||
|
@ -1392,6 +1427,8 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#endif /* BTPROTO_L2CAP */
|
||||
|
||||
case BTPROTO_RFCOMM:
|
||||
{
|
||||
struct sockaddr_rc *a = (struct sockaddr_rc *) addr;
|
||||
|
@ -1406,6 +1443,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef BTPROTO_HCI
|
||||
case BTPROTO_HCI:
|
||||
{
|
||||
struct sockaddr_hci *a = (struct sockaddr_hci *) addr;
|
||||
|
@ -1425,6 +1463,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
|
|||
return makebdaddr(&_BT_SCO_MEMB(a, bdaddr));
|
||||
}
|
||||
#endif /* !__FreeBSD__ */
|
||||
#endif /* BTPROTO_HCI */
|
||||
|
||||
default:
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
|
@ -1879,6 +1918,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
|||
case AF_BLUETOOTH:
|
||||
{
|
||||
switch (s->sock_proto) {
|
||||
#ifdef BTPROTO_L2CAP
|
||||
case BTPROTO_L2CAP:
|
||||
{
|
||||
struct sockaddr_l2 *addr;
|
||||
|
@ -1899,6 +1939,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
|||
*len_ret = sizeof *addr;
|
||||
return 1;
|
||||
}
|
||||
#endif /* BTPROTO_L2CAP */
|
||||
case BTPROTO_RFCOMM:
|
||||
{
|
||||
struct sockaddr_rc *addr;
|
||||
|
@ -1918,6 +1959,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
|||
*len_ret = sizeof *addr;
|
||||
return 1;
|
||||
}
|
||||
#ifdef BTPROTO_HCI
|
||||
case BTPROTO_HCI:
|
||||
{
|
||||
struct sockaddr_hci *addr = (struct sockaddr_hci *)addr_ret;
|
||||
|
@ -1964,6 +2006,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
|||
return 1;
|
||||
}
|
||||
#endif /* !__FreeBSD__ */
|
||||
#endif /* BTPROTO_HCI */
|
||||
default:
|
||||
PyErr_Format(PyExc_OSError,
|
||||
"%s(): unknown Bluetooth protocol", caller);
|
||||
|
@ -2385,12 +2428,15 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
|
|||
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;
|
||||
|
@ -2399,6 +2445,7 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
|
|||
*len_ret = sizeof (struct sockaddr_sco);
|
||||
return 1;
|
||||
#endif /* !__FreeBSD__ */
|
||||
#endif /* BTPROTO_HCI */
|
||||
default:
|
||||
PyErr_SetString(PyExc_OSError, "getsockaddrlen: "
|
||||
"unknown BT protocol");
|
||||
|
@ -7273,23 +7320,29 @@ PyInit__socket(void)
|
|||
|
||||
#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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue