Skip to content

[3.13] gh-132429: Fix support of Bluetooth sockets on NetBSD and DragonFly BSD #132458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix support of Bluetooth sockets on NetBSD and DragonFly BSD.
121 changes: 62 additions & 59 deletions Modules/socketmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,37 +473,42 @@ remove_unusable_flags(PyObject *m)
# define SOCKETCLOSE close
#endif

#if (defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)) && !defined(__NetBSD__) && !defined(__DragonFly__)
#define USE_BLUETOOTH 1
#if defined(__FreeBSD__)
#define BTPROTO_L2CAP BLUETOOTH_PROTO_L2CAP
#define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM
#define BTPROTO_HCI BLUETOOTH_PROTO_HCI
#define SOL_HCI SOL_HCI_RAW
#define HCI_FILTER SO_HCI_RAW_FILTER
#define sockaddr_l2 sockaddr_l2cap
#define sockaddr_rc sockaddr_rfcomm
#define hci_dev hci_node
#define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb)
#define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb)
#define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb)
#elif defined(__NetBSD__) || defined(__DragonFly__)
#define sockaddr_l2 sockaddr_bt
#define sockaddr_rc sockaddr_bt
#define sockaddr_hci sockaddr_bt
#define sockaddr_sco sockaddr_bt
#define SOL_HCI BTPROTO_HCI
#define HCI_DATA_DIR SO_HCI_DIRECTION
#define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb)
#define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb)
#define _BT_HCI_MEMB(sa, memb) ((sa)->bt_##memb)
#define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb)
#else
#define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb)
#define _BT_RC_MEMB(sa, memb) ((sa)->rc_##memb)
#define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb)
#define _BT_SCO_MEMB(sa, memb) ((sa)->sco_##memb)
#endif
#if defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)
# define USE_BLUETOOTH 1
# if defined(HAVE_BLUETOOTH_BLUETOOTH_H) // Linux
# define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb)
# define _BT_RC_MEMB(sa, memb) ((sa)->rc_##memb)
# define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb)
# define _BT_SCO_MEMB(sa, memb) ((sa)->sco_##memb)
# elif defined(__FreeBSD__)
# define BTPROTO_L2CAP BLUETOOTH_PROTO_L2CAP
# define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM
# define BTPROTO_HCI BLUETOOTH_PROTO_HCI
# define SOL_HCI SOL_HCI_RAW
# define HCI_FILTER SO_HCI_RAW_FILTER
# define sockaddr_l2 sockaddr_l2cap
# define sockaddr_rc sockaddr_rfcomm
# define hci_dev hci_node
# define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb)
# define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb)
# define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb)
# else // NetBSD, DragonFly BSD
# define sockaddr_l2 sockaddr_bt
# define sockaddr_rc sockaddr_bt
# define sockaddr_hci sockaddr_bt
# define sockaddr_sco sockaddr_bt
# define bt_l2 bt
# define bt_rc bt
# define bt_sco bt
# define bt_hci bt
# define bt_cid bt_channel
# define SOL_HCI BTPROTO_HCI
# define HCI_DATA_DIR SO_HCI_DIRECTION
# define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb)
# define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb)
# define _BT_HCI_MEMB(sa, memb) ((sa)->bt_##memb)
# define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb)
# endif
#endif

#ifdef MS_WINDOWS_DESKTOP
Expand Down Expand Up @@ -1483,16 +1488,16 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
case BTPROTO_HCI:
{
struct sockaddr_hci *a = (struct sockaddr_hci *) addr;
#if defined(__NetBSD__) || defined(__DragonFly__)
return makebdaddr(&_BT_HCI_MEMB(a, bdaddr));
#if defined(HAVE_BLUETOOTH_BLUETOOTH_H)
PyObject *ret = NULL;
ret = Py_BuildValue("i", _BT_HCI_MEMB(a, dev));
return ret;
#elif defined(__FreeBSD__)
char *node = _BT_HCI_MEMB(a, node);
const char *node = _BT_HCI_MEMB(a, node);
size_t len = strnlen(node, sizeof(_BT_HCI_MEMB(a, node)));
return PyBytes_FromStringAndSize(node, (Py_ssize_t)len);
#else
PyObject *ret = NULL;
ret = Py_BuildValue("i", _BT_HCI_MEMB(a, dev));
return ret;
return makebdaddr(&_BT_HCI_MEMB(a, bdaddr));
#endif
}

Expand Down Expand Up @@ -2061,19 +2066,16 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
{
struct sockaddr_hci *addr = &addrbuf->bt_hci;
memset(addr, 0, sizeof(struct sockaddr_hci));
#if defined(__NetBSD__) || defined(__DragonFly__)
const char *straddr;
_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
if (!PyBytes_Check(args)) {
PyErr_Format(PyExc_OSError, "%s: "
"wrong format", caller);
#if defined(HAVE_BLUETOOTH_BLUETOOTH_H)
unsigned short dev = _BT_HCI_MEMB(addr, dev);
if (!PyArg_ParseTuple(args, "H", &dev)) {
PyErr_Format(PyExc_OSError,
"%s(): wrong format", caller);
return 0;
}
straddr = PyBytes_AS_STRING(args);
if (setbdaddr(straddr, &_BT_HCI_MEMB(addr, bdaddr)) < 0)
return 0;
_BT_HCI_MEMB(addr, dev) = dev;
#elif defined(__FreeBSD__)
_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
if (!PyBytes_Check(args)) {
PyErr_Format(PyExc_OSError, "%s: "
"wrong node format", caller);
Expand All @@ -2094,14 +2096,15 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
strncpy(_BT_HCI_MEMB(addr, node), straddr,
sizeof(_BT_HCI_MEMB(addr, node)));
#else
_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
unsigned short dev = _BT_HCI_MEMB(addr, dev);
if (!PyArg_ParseTuple(args, "H", &dev)) {
PyErr_Format(PyExc_OSError,
"%s(): wrong format", caller);
const char *straddr;
if (!PyBytes_Check(args)) {
PyErr_Format(PyExc_OSError, "%s: "
"wrong format", caller);
return 0;
}
_BT_HCI_MEMB(addr, dev) = dev;
straddr = PyBytes_AS_STRING(args);
if (setbdaddr(straddr, &_BT_HCI_MEMB(addr, bdaddr)) < 0)
return 0;
#endif
*len_ret = sizeof *addr;
return 1;
Expand Down Expand Up @@ -2679,12 +2682,12 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
case BTPROTO_HCI:
*len_ret = sizeof (struct sockaddr_hci);
return 1;
#if !defined(__FreeBSD__)
#endif /* BTPROTO_HCI */
#ifdef BTPROTO_SCO
case BTPROTO_SCO:
*len_ret = sizeof (struct sockaddr_sco);
return 1;
#endif /* !__FreeBSD__ */
#endif /* BTPROTO_HCI */
#endif /* BTPROTO_SCO */
default:
PyErr_SetString(PyExc_OSError, "getsockaddrlen: "
"unknown BT protocol");
Expand Down Expand Up @@ -7724,13 +7727,13 @@ socket_exec(PyObject *m)
#ifdef BTPROTO_HCI
ADD_INT_MACRO(m, BTPROTO_HCI);
ADD_INT_MACRO(m, SOL_HCI);
#if !defined(__NetBSD__) && !defined(__DragonFly__)
#if defined(HCI_FILTER)
ADD_INT_MACRO(m, HCI_FILTER);
#if !defined(__FreeBSD__)
#endif
#if defined(HCI_TIME_STAMP)
ADD_INT_MACRO(m, HCI_TIME_STAMP);
ADD_INT_MACRO(m, HCI_DATA_DIR);
#endif /* !__FreeBSD__ */
#endif /* !__NetBSD__ && !__DragonFly__ */
#endif
#endif /* BTPROTO_HCI */
#ifdef BTPROTO_RFCOMM
ADD_INT_MACRO(m, BTPROTO_RFCOMM);
Expand Down
23 changes: 15 additions & 8 deletions Modules/socketmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ typedef int socklen_t;
#endif

#ifdef HAVE_BLUETOOTH_H
#ifdef __FreeBSD__
#define L2CAP_SOCKET_CHECKED
#endif
#include <bluetooth.h>
#endif

Expand Down Expand Up @@ -270,18 +273,22 @@ typedef union sock_addr {
struct sockaddr_in6 in6;
struct sockaddr_storage storage;
#endif
#if defined(HAVE_BLUETOOTH_H) && defined(__FreeBSD__)
struct sockaddr_l2cap bt_l2;
struct sockaddr_rfcomm bt_rc;
struct sockaddr_sco bt_sco;
struct sockaddr_hci bt_hci;
#elif defined(HAVE_BLUETOOTH_BLUETOOTH_H)
#if defined(MS_WINDOWS)
struct SOCKADDR_BTH_REDEF bt_rc;
#elif defined(HAVE_BLUETOOTH_BLUETOOTH_H) // Linux
struct sockaddr_l2 bt_l2;
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;
#elif defined(HAVE_BLUETOOTH_H)
# if defined(__FreeBSD__)
struct sockaddr_l2cap bt_l2;
struct sockaddr_rfcomm bt_rc;
struct sockaddr_sco bt_sco;
struct sockaddr_hci bt_hci;
# else // NetBSD, DragonFly BSD
struct sockaddr_bt bt;
# endif
#endif
#ifdef HAVE_NETPACKET_PACKET_H
struct sockaddr_ll ll;
Expand Down
Loading