https://github.com/python/cpython/commit/e84624450dc0494271119018c699372245d724d9
commit: e84624450dc0494271119018c699372245d724d9
branch: main
author: Serhiy Storchaka <storch...@gmail.com>
committer: serhiy-storchaka <storch...@gmail.com>
date: 2025-04-22T11:02:13Z
summary:

gh-132734: Add new constants for Bluetooth sockets (GH-132735)

files:
A Misc/NEWS.d/next/Library/2025-04-19-19-58-27.gh-issue-132734.S6F9Cs.rst
M Doc/library/socket.rst
M Doc/whatsnew/3.14.rst
M Lib/test/test_socket.py
M Modules/socketmodule.c

diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index 2b1fae57c668de..d3f94016937a24 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -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 various 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.
+   Option names for use with :const:`BTPROTO_HCI`.
+   Availability and format of the option values 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.
+
+.. 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
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 373708763ac027..904a3ce6d597e9 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -1088,6 +1088,32 @@ pydoc
   (Contributed by Jelle Zijlstra in :gh:`101552`.)
 
 
+socket
+------
+
+* Improve and fix 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
 ---
 
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 8a3793b9072b78..ed45180a5f7d99 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -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):
 
@@ -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:
diff --git 
a/Misc/NEWS.d/next/Library/2025-04-19-19-58-27.gh-issue-132734.S6F9Cs.rst 
b/Misc/NEWS.d/next/Library/2025-04-19-19-58-27.gh-issue-132734.S6F9Cs.rst
new file mode 100644
index 00000000000000..e0825227d6ed01
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-04-19-19-58-27.gh-issue-132734.S6F9Cs.rst
@@ -0,0 +1 @@
+Add new constants for Bluetooth :mod:`sockets <socket>`.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index f55a9583b8586a..22b94e4b03a27c 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -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)
@@ -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
@@ -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)
@@ -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

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to