Skip to content

gh-132734: Add new constants for Bluetooth sockets #132735

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
53 changes: 50 additions & 3 deletions Doc/library/socket.rst
Original file line number Diff line number Diff line change
Expand Up @@ -677,15 +677,62 @@ Constants
These constants describe the Bluetooth address type when binding or
connecting a :const:`BTPROTO_L2CAP` socket.

.. availability:: Linux, FreeBSD

.. versionadded:: 3.14

.. data:: SOL_RFCOMM
SOL_L2CAP
SOL_HCI
SOL_SCO
SOL_BLUETOOTH

Used in the level argument to the :meth:`~socket.setsockopt` and
:meth:`~socket.getsockopt` methods of Bluetooth socket objects.

:const:`SOL_BLUETOOTH` is only available on Linux, other constants
are available if the corresponding protocol is supported.

.. data:: SO_L2CAP_*
L2CAP_LM
L2CAP_LM_*
SO_RFCOMM_*
RFCOMM_LM_*
SO_SCO_*
SO_BTH_*
BT_*

Used in the option name and value argument to the :meth:`~socket.setsockopt`
and :meth:`~socket.getsockopt` methods of Bluetooth socket objects.

:const:`!BT_*` and :const:`L2CAP_LM` are only available on Linux.
:const:`!SO_BTH_*` are only available on Windows.
Other constants may be available on Linux and varios BSD platforms.

.. versionadded:: next

.. data:: HCI_FILTER
HCI_TIME_STAMP
HCI_DATA_DIR
SO_HCI_EVT_FILTER
SO_HCI_PKT_FILTER

For use with :const:`BTPROTO_HCI`. :const:`!HCI_FILTER` is only
available on Linux and FreeBSD. :const:`!HCI_TIME_STAMP` and
:const:`!HCI_DATA_DIR` are only available on Linux.
Options names for use with :const:`BTPROTO_HCI`.
Availability and format of the option value depend on platform.

.. versionchanged:: next
Added :const:`!SO_HCI_EVT_FILTER` and :const:`!SO_HCI_PKT_FILTER`
on NetBSD and DragonFly BSD.
Added :const:`!HCI_DATA_DIR` on FreeBSD, NetBSD and DragonFly BSD.
Comment on lines +725 to +726
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
on NetBSD and DragonFly BSD.
Added :const:`!HCI_DATA_DIR` on FreeBSD, NetBSD and DragonFly BSD.
for NetBSD and DragonFly BSD.
Added :const:`!HCI_DATA_DIR` for FreeBSD, NetBSD and DragonFly BSD.

I think for is more fitting here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it so? I thought that it is more common to write "on platform" than "for platform". There are many examples of the former, and not many of the latter.


.. data:: HCI_DEV_NONE

The ``device_id`` value used to create an HCI socket that isn't specific
to a single Bluetooth adapter.

.. availability:: Linux

.. versionadded:: next

.. data:: HCI_CHANNEL_RAW
HCI_CHANNEL_USER
Expand Down
26 changes: 26 additions & 0 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,32 @@ pydoc
(Contributed by Jelle Zijlstra in :gh:`101552`.)


socket
------

* Fix and improve support for Bluetooth sockets.

* Fix support of Bluetooth sockets on NetBSD and DragonFly BSD.
(Contributed by Serhiy Storchaka in :gh:`132429`.)
* Fix support for :const:`~socket.BTPROTO_HCI` on FreeBSD.
(Contributed by Victor Stinner in :gh:`111178`.)
* Add support for :const:`~socket.BTPROTO_SCO` on FreeBSD.
(Contributed by Serhiy Storchaka in :gh:`85302`.)
* Add support for *cid* and *bdaddr_type* in the address for
:const:`~socket.BTPROTO_L2CAP` on FreeBSD.
(Contributed by Serhiy Storchaka in :gh:`132429`.)
* Add support for *channel* in the address for
:const:`~socket.BTPROTO_HCI` on Linux.
(Contributed by Serhiy Storchaka in :gh:`70145`.)
* Accept an integer as the address for
:const:`~socket.BTPROTO_HCI` on Linux
(Contributed by Serhiy Storchaka in :gh:`132099`.)
* Return *cid* in :meth:`~socket.socket.getsockname` for
:const:`~socket.BTPROTO_L2CAP`.
(Contributed by Serhiy Storchaka in :gh:`132429`.)
* Add many new constants.
(Contributed by Serhiy Storchaka in :gh:`132734`.)

ssl
---

Expand Down
62 changes: 61 additions & 1 deletion Lib/test/test_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -2606,7 +2606,7 @@ def testSocketBufferSize(self):
socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE))


@unittest.skipUnless(HAVE_SOCKET_BLUETOOTH,
@unittest.skipUnless(hasattr(socket, 'AF_BLUETOOTH'),
'Bluetooth sockets required for this test.')
class BasicBluetoothTest(unittest.TestCase):

Expand All @@ -2615,19 +2615,79 @@ def testBluetoothConstants(self):
socket.BDADDR_LOCAL
socket.AF_BLUETOOTH
socket.BTPROTO_RFCOMM
socket.SOL_RFCOMM

if sys.platform == "win32":
socket.SO_BTH_ENCRYPT
socket.SO_BTH_MTU
socket.SO_BTH_MTU_MAX
socket.SO_BTH_MTU_MIN

if sys.platform != "win32":
socket.BTPROTO_HCI
socket.SOL_HCI
socket.BTPROTO_L2CAP
socket.SOL_L2CAP
socket.BTPROTO_SCO
socket.SOL_SCO
socket.HCI_DATA_DIR

if sys.platform == "linux":
socket.SOL_BLUETOOTH
socket.HCI_DEV_NONE
socket.HCI_CHANNEL_RAW
socket.HCI_CHANNEL_USER
socket.HCI_CHANNEL_MONITOR
socket.HCI_CHANNEL_CONTROL
socket.HCI_CHANNEL_LOGGING
socket.HCI_TIME_STAMP
socket.BT_SECURITY
socket.BT_SECURITY_SDP
socket.BT_FLUSHABLE
socket.BT_POWER
socket.BT_CHANNEL_POLICY
socket.BT_CHANNEL_POLICY_BREDR_ONLY
socket.BT_PHY
socket.BT_PHY_BR_1M_1SLOT
socket.BT_MODE
socket.BT_MODE_BASIC
socket.BT_VOICE
socket.BT_VOICE_TRANSPARENT
socket.BT_VOICE_CVSD_16BIT
socket.BT_CODEC
socket.L2CAP_LM
socket.L2CAP_LM_MASTER
socket.L2CAP_LM_AUTH

if sys.platform in ("linux", "freebsd"):
socket.BDADDR_BREDR
socket.BDADDR_LE_PUBLIC
socket.BDADDR_LE_RANDOM
socket.HCI_FILTER

if sys.platform.startswith(("freebsd", "netbsd", "dragonfly")):
socket.SO_L2CAP_IMTU
socket.SO_L2CAP_FLUSH
socket.SO_RFCOMM_MTU
socket.SO_RFCOMM_FC_INFO
socket.SO_SCO_MTU

if sys.platform == "freebsd":
socket.SO_SCO_CONNINFO

if sys.platform.startswith(("netbsd", "dragonfly")):
socket.SO_HCI_EVT_FILTER
socket.SO_HCI_PKT_FILTER
socket.SO_L2CAP_IQOS
socket.SO_L2CAP_LM
socket.L2CAP_LM_AUTH
socket.SO_RFCOMM_LM
socket.RFCOMM_LM_AUTH
socket.SO_SCO_HANDLE

@unittest.skipUnless(HAVE_SOCKET_BLUETOOTH,
'Bluetooth sockets required for this test.')
class BluetoothTest(unittest.TestCase):

def testCreateRfcommSocket(self):
with socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM) as s:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add new constants for Bluetooth :mod:`sockets <socket>`.
137 changes: 133 additions & 4 deletions Modules/socketmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ shutdown(how) -- shut down traffic in one or both directions\n\
# include <sys/ioctl.h>
#endif

#ifdef HAVE_BLUETOOTH_H
# include <netbt/l2cap.h>
# include <netbt/rfcomm.h>
# include <netbt/hci.h>
# include <netbt/sco.h>
#endif

#if defined(__sgi) && _COMPILER_VERSION>700 && !_SGIAPI
/* make sure that the reentrant (gethostbyaddr_r etc)
Expand Down Expand Up @@ -474,6 +480,7 @@ remove_unusable_flags(PyObject *m)
# define BTPROTO_SCO BLUETOOTH_PROTO_SCO
# define SOL_HCI SOL_HCI_RAW
# define HCI_FILTER SO_HCI_RAW_FILTER
# define HCI_DATA_DIR SO_HCI_RAW_DIRECTION
# define sockaddr_l2 sockaddr_l2cap
# define sockaddr_rc sockaddr_rfcomm
# define hci_dev hci_node
Expand All @@ -491,7 +498,10 @@ remove_unusable_flags(PyObject *m)
# define bt_sco bt
# define bt_hci bt
# define bt_cid bt_channel
# define SOL_L2CAP BTPROTO_L2CAP
# define SOL_RFCOMM BTPROTO_RFCOMM
# define SOL_HCI BTPROTO_HCI
# define SOL_SCO BTPROTO_SCO
# 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)
Expand Down Expand Up @@ -7879,38 +7889,157 @@ socket_exec(PyObject *m)
ADD_INT_MACRO(m, AF_BLUETOOTH);
#ifdef BTPROTO_L2CAP
ADD_INT_MACRO(m, BTPROTO_L2CAP);
ADD_INT_MACRO(m, SOL_L2CAP);
#if defined(BDADDR_BREDR)
ADD_INT_MACRO(m, BDADDR_BREDR);
ADD_INT_MACRO(m, BDADDR_LE_PUBLIC);
ADD_INT_MACRO(m, BDADDR_LE_RANDOM);
#endif
#ifdef SO_L2CAP_IMTU
ADD_INT_MACRO(m, SO_L2CAP_IMTU);
ADD_INT_MACRO(m, SO_L2CAP_OMTU);
ADD_INT_MACRO(m, SO_L2CAP_FLUSH);
#endif
#ifdef SO_L2CAP_IQOS
ADD_INT_MACRO(m, SO_L2CAP_IQOS);
ADD_INT_MACRO(m, SO_L2CAP_OQOS);
#endif
#ifdef SO_L2CAP_ENCRYPTED
ADD_INT_MACRO(m, SO_L2CAP_ENCRYPTED);
#endif
#ifdef L2CAP_LM
ADD_INT_MACRO(m, L2CAP_LM);
ADD_INT_MACRO(m, L2CAP_LM_MASTER);
ADD_INT_MACRO(m, L2CAP_LM_AUTH);
ADD_INT_MACRO(m, L2CAP_LM_ENCRYPT);
ADD_INT_MACRO(m, L2CAP_LM_TRUSTED);
ADD_INT_MACRO(m, L2CAP_LM_RELIABLE);
ADD_INT_MACRO(m, L2CAP_LM_SECURE);
#endif
#ifdef SO_L2CAP_LM
ADD_INT_MACRO(m, SO_L2CAP_LM);
ADD_INT_MACRO(m, L2CAP_LM_AUTH);
ADD_INT_MACRO(m, L2CAP_LM_ENCRYPT);
ADD_INT_MACRO(m, L2CAP_LM_SECURE);
#endif
#endif /* BTPROTO_L2CAP */
#ifdef BTPROTO_HCI
ADD_INT_MACRO(m, BTPROTO_HCI);
ADD_INT_MACRO(m, SOL_HCI);
#if defined(HCI_CHANNEL_RAW)
#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
ADD_INT_MACRO(m, HCI_DEV_NONE);
ADD_INT_MACRO(m, HCI_CHANNEL_RAW);
ADD_INT_MACRO(m, HCI_CHANNEL_USER);
ADD_INT_MACRO(m, HCI_CHANNEL_MONITOR);
ADD_INT_MACRO(m, HCI_CHANNEL_CONTROL);
ADD_INT_MACRO(m, HCI_CHANNEL_LOGGING);
#endif
#if defined(HCI_FILTER)
#ifdef HCI_FILTER
ADD_INT_MACRO(m, HCI_FILTER);
#endif
#if defined(HCI_TIME_STAMP)
ADD_INT_MACRO(m, HCI_TIME_STAMP);
#ifdef HCI_DATA_DIR
ADD_INT_MACRO(m, HCI_DATA_DIR);
#endif
#ifdef HCI_TIME_STAMP
ADD_INT_MACRO(m, HCI_TIME_STAMP);
#endif
#ifdef SO_HCI_EVT_FILTER
ADD_INT_MACRO(m, SO_HCI_EVT_FILTER);
ADD_INT_MACRO(m, SO_HCI_PKT_FILTER);
#endif
#endif /* BTPROTO_HCI */
#ifdef BTPROTO_RFCOMM
ADD_INT_MACRO(m, BTPROTO_RFCOMM);
ADD_INT_MACRO(m, SOL_RFCOMM);
#ifdef SO_RFCOMM_MTU
ADD_INT_MACRO(m, SO_RFCOMM_MTU);
ADD_INT_MACRO(m, SO_RFCOMM_FC_INFO);
#endif
#ifdef SO_RFCOMM_LM
ADD_INT_MACRO(m, SO_RFCOMM_LM);
ADD_INT_MACRO(m, RFCOMM_LM_AUTH);
ADD_INT_MACRO(m, RFCOMM_LM_ENCRYPT);
ADD_INT_MACRO(m, RFCOMM_LM_SECURE);
#endif
#ifdef MS_WINDOWS_DESKTOP
ADD_INT_MACRO(m, SO_BTH_ENCRYPT);
ADD_INT_MACRO(m, SO_BTH_MTU);
ADD_INT_MACRO(m, SO_BTH_MTU_MAX);
ADD_INT_MACRO(m, SO_BTH_MTU_MIN);
#endif
#endif /* BTPROTO_RFCOMM */
ADD_STR_CONST(m, "BDADDR_ANY", "00:00:00:00:00:00");
ADD_STR_CONST(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF");
#ifdef BTPROTO_SCO
ADD_INT_MACRO(m, BTPROTO_SCO);
ADD_INT_MACRO(m, SOL_SCO);
#ifdef SO_SCO_MTU
ADD_INT_MACRO(m, SO_SCO_MTU);
#endif
#ifdef SO_SCO_CONNINFO
ADD_INT_MACRO(m, SO_SCO_CONNINFO);
#endif
#ifdef SO_SCO_HANDLE
ADD_INT_MACRO(m, SO_SCO_HANDLE);
#endif
#endif /* BTPROTO_SCO */
#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
ADD_INT_MACRO(m, SOL_BLUETOOTH);
ADD_INT_MACRO(m, BT_SECURITY);
ADD_INT_MACRO(m, BT_SECURITY_SDP);
ADD_INT_MACRO(m, BT_SECURITY_LOW);
ADD_INT_MACRO(m, BT_SECURITY_MEDIUM);
ADD_INT_MACRO(m, BT_SECURITY_HIGH);
#ifdef BT_SECURITY_FIPS
ADD_INT_MACRO(m, BT_SECURITY_FIPS);
#endif
#ifdef BT_DEFER_SETUP
ADD_INT_MACRO(m, BT_DEFER_SETUP);
#endif
ADD_INT_MACRO(m, BT_FLUSHABLE);
ADD_INT_MACRO(m, BT_FLUSHABLE_OFF);
ADD_INT_MACRO(m, BT_FLUSHABLE_ON);
ADD_INT_MACRO(m, BT_POWER);
ADD_INT_MACRO(m, BT_POWER_FORCE_ACTIVE_OFF);
ADD_INT_MACRO(m, BT_POWER_FORCE_ACTIVE_ON);
ADD_INT_MACRO(m, BT_CHANNEL_POLICY);
ADD_INT_MACRO(m, BT_CHANNEL_POLICY_BREDR_ONLY);
ADD_INT_MACRO(m, BT_CHANNEL_POLICY_BREDR_PREFERRED);
ADD_INT_MACRO(m, BT_CHANNEL_POLICY_BREDR_PREFERRED);
ADD_INT_MACRO(m, BT_VOICE);
ADD_INT_MACRO(m, BT_VOICE_TRANSPARENT);
ADD_INT_MACRO(m, BT_VOICE_CVSD_16BIT);
#ifdef BT_VOICE_TRANSPARENT_16BIT
ADD_INT_MACRO(m, BT_VOICE_TRANSPARENT_16BIT);
#endif
ADD_INT_MACRO(m, BT_SNDMTU);
ADD_INT_MACRO(m, BT_RCVMTU);
ADD_INT_MACRO(m, BT_PHY);
ADD_INT_MACRO(m, BT_PHY_BR_1M_1SLOT);
ADD_INT_MACRO(m, BT_PHY_BR_1M_3SLOT);
ADD_INT_MACRO(m, BT_PHY_BR_1M_5SLOT);
ADD_INT_MACRO(m, BT_PHY_EDR_2M_1SLOT);
ADD_INT_MACRO(m, BT_PHY_EDR_2M_3SLOT);
ADD_INT_MACRO(m, BT_PHY_EDR_2M_5SLOT);
ADD_INT_MACRO(m, BT_PHY_EDR_3M_1SLOT);
ADD_INT_MACRO(m, BT_PHY_EDR_3M_3SLOT);
ADD_INT_MACRO(m, BT_PHY_EDR_3M_5SLOT);
ADD_INT_MACRO(m, BT_PHY_LE_1M_TX);
ADD_INT_MACRO(m, BT_PHY_LE_1M_RX);
ADD_INT_MACRO(m, BT_PHY_LE_2M_TX);
ADD_INT_MACRO(m, BT_PHY_LE_2M_RX);
ADD_INT_MACRO(m, BT_PHY_LE_CODED_TX);
ADD_INT_MACRO(m, BT_PHY_LE_CODED_RX);
ADD_INT_MACRO(m, BT_MODE);
ADD_INT_MACRO(m, BT_MODE_BASIC);
ADD_INT_MACRO(m, BT_MODE_ERTM);
ADD_INT_MACRO(m, BT_MODE_STREAMING);
ADD_INT_MACRO(m, BT_MODE_LE_FLOWCTL);
ADD_INT_MACRO(m, BT_MODE_EXT_FLOWCTL);
ADD_INT_MACRO(m, BT_PKT_STATUS);
ADD_INT_MACRO(m, BT_ISO_QOS);
ADD_INT_MACRO(m, BT_CODEC);
#endif /* HAVE_BLUETOOTH_BLUETOOTH_H */
#endif /* USE_BLUETOOTH */

#ifdef AF_CAN
Expand Down
Loading