Skip to content

Commit 8cb177d

Browse files
gh-132099: Accept an integer as the address for BTPROTO_HCI on Linux (GH-132525)
Previously only an integer packed in a tuple was accepted, while getsockname() could return a raw integer. Now the result of getsockname() is always acceptable as an address.
1 parent 82f74eb commit 8cb177d

File tree

4 files changed

+19
-5
lines changed

4 files changed

+19
-5
lines changed

Diff for: Doc/library/socket.rst

+4-2
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,9 @@ created. Socket addresses are represented as follows:
156156

157157
- :const:`BTPROTO_HCI` accepts a format that depends on your OS.
158158

159-
- On Linux it accepts a tuple ``(device_id, [channel])`` where ``device_id``
160-
is an integer specifying the number of the Bluetooth device,
159+
- On Linux it accepts an integer ``device_id`` or a tuple
160+
``(device_id, [channel])`` where ``device_id``
161+
specifies the number of the Bluetooth device,
161162
and ``channel`` is an optional integer specifying the HCI channel
162163
(:const:`HCI_CHANNEL_RAW` by default).
163164
- On FreeBSD, NetBSD and DragonFly BSD it accepts ``bdaddr``
@@ -171,6 +172,7 @@ created. Socket addresses are represented as follows:
171172

172173
.. versionchanged:: next
173174
Added ``channel`` field.
175+
``device_id`` not packed in a tuple is now accepted.
174176

175177
- :const:`BTPROTO_SCO` accepts ``bdaddr`` where ``bdaddr`` is
176178
the Bluetooth address as a string or a :class:`bytes` object.

Diff for: Lib/test/test_socket.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -2745,6 +2745,12 @@ def testBindHciSocket(self):
27452745
addr = s.getsockname()
27462746
self.assertEqual(addr, dev)
27472747

2748+
with (self.subTest('integer'),
2749+
socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) as s):
2750+
s.bind(dev)
2751+
addr = s.getsockname()
2752+
self.assertEqual(addr, dev)
2753+
27482754
with (self.subTest('channel=HCI_CHANNEL_RAW'),
27492755
socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) as s):
27502756
channel = socket.HCI_CHANNEL_RAW
@@ -2789,8 +2795,6 @@ def testBadHciAddr(self):
27892795
s.bind(())
27902796
with self.assertRaises(OSError):
27912797
s.bind((dev, socket.HCI_CHANNEL_RAW, 0, 0))
2792-
with self.assertRaises(OSError):
2793-
s.bind(dev)
27942798
with self.assertRaises(OSError):
27952799
s.bind(socket.BDADDR_ANY)
27962800
with self.assertRaises(OSError):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The Bluetooth socket with the :data:`~socket.BTPROTO_HCI` protocol on Linux
2+
now accepts an address in the format of an integer ``device_id``, not only a
3+
tuple ``(device_id,)``.

Diff for: Modules/socketmodule.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -2147,7 +2147,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
21472147
#if defined(HAVE_BLUETOOTH_BLUETOOTH_H)
21482148
unsigned short dev;
21492149
unsigned short channel = HCI_CHANNEL_RAW;
2150-
if (!PyArg_ParseTuple(args, "H|H", &dev, &channel)) {
2150+
if (PyLong_Check(args)) {
2151+
if (!PyArg_Parse(args, "H", &dev)) {
2152+
return 0;
2153+
}
2154+
}
2155+
else if (!PyArg_ParseTuple(args, "H|H", &dev, &channel)) {
21512156
PyErr_Format(PyExc_OSError,
21522157
"%s(): wrong format", caller);
21532158
return 0;

0 commit comments

Comments
 (0)