blob: 03da12630eb3a2125bea862e3922929c83f87ebb [file] [log] [blame]
Scott James Remnantfc5a3f72013-08-01 14:39:40 -07001/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
Scott James Remnant96927a42013-07-17 18:27:57 -07002 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6#include <Python.h>
7
8#include <sys/types.h>
9#include <sys/socket.h>
10#include <poll.h>
11
12#include "bluetooth.h"
Scott James Remnantfc5a3f72013-08-01 14:39:40 -070013#include "l2cap.h"
14#include "rfcomm.h"
Scott James Remnant96927a42013-07-17 18:27:57 -070015#include "hci.h"
Scott James Remnantfc5a3f72013-08-01 14:39:40 -070016#include "sco.h"
Scott James Remnant96927a42013-07-17 18:27:57 -070017
Yu-Hsuan Hsue1cb3b92020-02-13 23:16:02 +080018#if PY_MAJOR_VERSION < 3
19 #define MOD_ERROR_VAL
20 #define MOD_SUCCESS_VAL(val)
21 #define MOD_INIT(name) void init##name(void)
22 #define MOD_DEF(ob, name, doc, methods) \
23 ob = Py_InitModule3(name, methods, doc);
24#else
25 #define PyInt_AS_LONG PyLong_AS_LONG
26 #define PyInt_Check PyLong_Check
27 #define MOD_ERROR_VAL NULL
28 #define MOD_SUCCESS_VAL(val) val
29 #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
30 #define MOD_DEF(ob, name, doc, methods) \
31 static struct PyModuleDef moduledef = { \
32 PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
33 ob = PyModule_Create(&moduledef);
34#endif
35
Scott James Remnant96927a42013-07-17 18:27:57 -070036static PyObject *_btsocket_error;
37static PyObject *_btsocket_timeout;
38
Scott James Remnantffa6f742013-11-19 12:10:07 -080039union bt_sockaddr {
40 struct sockaddr_l2 l2;
41 struct sockaddr_rc rc;
42 struct sockaddr_hci hci;
43 struct sockaddr_sco sco;
44};
45
Scott James Remnant96927a42013-07-17 18:27:57 -070046static int _get_fileno(PyObject *socket) {
47 PyObject *fileno_object;
48 long fileno;
49
50 fileno_object = PyObject_CallMethod(socket, "fileno", "", NULL);
51 if (!fileno_object)
52 return -1;
53
54 if (!PyInt_Check(fileno_object))
55 return -1;
56
Yu-Hsuan Hsue1cb3b92020-02-13 23:16:02 +080057 /* PyInt are longer than your average int, truncate back to an int */
Scott James Remnant96927a42013-07-17 18:27:57 -070058 fileno = PyInt_AS_LONG(fileno_object);
59 Py_DECREF(fileno_object);
60 return (int)fileno;
61}
62
63static int _get_timeout(PyObject *socket, double *timeout) {
64 PyObject *timeout_object;
65
66 timeout_object = PyObject_CallMethod(socket, "gettimeout", "", NULL);
67 if (!timeout_object)
68 return 0;
69
70 if (!PyFloat_Check(timeout_object))
71 return 0;
72
73 *timeout = PyFloat_AS_DOUBLE(timeout_object);
74 Py_DECREF(timeout_object);
75 return 1;
76}
77
Scott James Remnantfc5a3f72013-08-01 14:39:40 -070078static int _setbdaddr(const char *straddr, bdaddr_t *bdaddr) {
79 unsigned int b0, b1, b2, b3, b4, b5;
80 int n;
81
82 n = sscanf(straddr, "%X:%X:%X:%X:%X:%X", &b5, &b4, &b3, &b2, &b1, &b0);
83 if (n == 6) {
84 bdaddr->b[0] = b0;
85 bdaddr->b[1] = b1;
86 bdaddr->b[2] = b2;
87 bdaddr->b[3] = b3;
88 bdaddr->b[4] = b4;
89 bdaddr->b[5] = b5;
90 return 1;
91 } else {
92 PyErr_SetString(_btsocket_error, "bad bluetooth address for bind()");
93 return 0;
94 }
95}
96
Scott James Remnantffa6f742013-11-19 12:10:07 -080097static PyObject *parsesocketargs(PyObject *self, PyObject *args,
98 union bt_sockaddr *addr, size_t *addrlen) {
Scott James Remnantfc5a3f72013-08-01 14:39:40 -070099 PyObject *socket_object, *tuple;
Scott James Remnantffa6f742013-11-19 12:10:07 -0800100 int proto;
Scott James Remnant96927a42013-07-17 18:27:57 -0700101
Scott James Remnantffa6f742013-11-19 12:10:07 -0800102 if (!PyArg_ParseTuple(args, "OiO:_btsocket.parsesocketargs",
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700103 &socket_object, &proto, &tuple))
Scott James Remnant96927a42013-07-17 18:27:57 -0700104 return NULL;
105
Scott James Remnantffa6f742013-11-19 12:10:07 -0800106 memset(addr, 0, sizeof (union bt_sockaddr));
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700107
108 switch (proto) {
109 case BTPROTO_L2CAP: {
110 char *straddr;
111
Scott James Remnantffa6f742013-11-19 12:10:07 -0800112 addr->l2.l2_family = AF_BLUETOOTH;
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700113
Scott James Remnantffa6f742013-11-19 12:10:07 -0800114 if (!PyArg_ParseTuple(tuple, "si:_btsocket.parsesocketargs",
115 &straddr, &addr->l2.l2_psm))
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700116 return NULL;
Scott James Remnantffa6f742013-11-19 12:10:07 -0800117 if (!_setbdaddr(straddr, &addr->l2.l2_bdaddr))
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700118 return NULL;
119
Scott James Remnantffa6f742013-11-19 12:10:07 -0800120 *addrlen = sizeof (struct sockaddr_l2);
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700121 break;
122 }
123 case BTPROTO_RFCOMM: {
124 char *straddr;
125
Scott James Remnantffa6f742013-11-19 12:10:07 -0800126 addr->rc.rc_family = AF_BLUETOOTH;
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700127
Scott James Remnantffa6f742013-11-19 12:10:07 -0800128 if (!PyArg_ParseTuple(tuple, "si:_btsocket.parsesocketargs",
129 &straddr, &addr->rc.rc_channel))
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700130 return NULL;
Scott James Remnantffa6f742013-11-19 12:10:07 -0800131 if (!_setbdaddr(straddr, &addr->rc.rc_bdaddr))
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700132 return NULL;
133
Scott James Remnantffa6f742013-11-19 12:10:07 -0800134 *addrlen = sizeof (struct sockaddr_rc);
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700135 break;
136 }
137 case BTPROTO_HCI: {
Scott James Remnantffa6f742013-11-19 12:10:07 -0800138 addr->hci.hci_family = AF_BLUETOOTH;
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700139
Scott James Remnantffa6f742013-11-19 12:10:07 -0800140 if (!PyArg_ParseTuple(tuple, "HH:_btsocket.parsesocketargs",
141 &addr->hci.hci_dev, &addr->hci.hci_channel))
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700142 return NULL;
143
Scott James Remnantffa6f742013-11-19 12:10:07 -0800144 *addrlen = sizeof (struct sockaddr_hci);
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700145 break;
146 }
147 case BTPROTO_SCO: {
148 char *straddr;
149
Scott James Remnantffa6f742013-11-19 12:10:07 -0800150 addr->sco.sco_family = AF_BLUETOOTH;
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700151
Scott James Remnantffa6f742013-11-19 12:10:07 -0800152 if (!PyArg_ParseTuple(tuple, "s:_btsocket.parsesocketargs",
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700153 &straddr))
154 return NULL;
Scott James Remnantffa6f742013-11-19 12:10:07 -0800155 if (!_setbdaddr(straddr, &addr->sco.sco_bdaddr))
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700156 return NULL;
157
Scott James Remnantffa6f742013-11-19 12:10:07 -0800158 *addrlen = sizeof (struct sockaddr_sco);
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700159 break;
160 }
161 default:
Scott James Remnantffa6f742013-11-19 12:10:07 -0800162 PyErr_SetString(_btsocket_error, "unknown protocol");
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700163 return NULL;
164 }
165
Scott James Remnantffa6f742013-11-19 12:10:07 -0800166 return socket_object;
167}
168
169static PyObject *_btsocket_bind(PyObject *self, PyObject *args) {
170 PyObject *socket_object;
171 union bt_sockaddr addr;
172 size_t addrlen;
173 int fd, result;
174
175 socket_object = parsesocketargs(self, args, &addr, &addrlen);
176 if (!socket_object)
177 return NULL;
178
179 fd = _get_fileno(socket_object);
180 if (fd < 0)
181 return NULL;
182
Scott James Remnant96927a42013-07-17 18:27:57 -0700183 Py_BEGIN_ALLOW_THREADS;
Scott James Remnantfc5a3f72013-08-01 14:39:40 -0700184 result = bind(fd, (struct sockaddr *)&addr, addrlen);
Scott James Remnant96927a42013-07-17 18:27:57 -0700185 Py_END_ALLOW_THREADS;
186
187 if (result < 0)
188 return PyErr_SetFromErrno(_btsocket_error);
189
190 Py_INCREF(Py_None);
191 return Py_None;
192}
193
Scott James Remnantffa6f742013-11-19 12:10:07 -0800194static PyObject *_btsocket_connect(PyObject *self, PyObject *args) {
195 PyObject *socket_object;
196 union bt_sockaddr addr;
197 size_t addrlen;
198 int fd, timeout = 0, did_timeout = 0, result;
199 double timeout_secs;
200
201 socket_object = parsesocketargs(self, args, &addr, &addrlen);
202 if (!socket_object)
203 return NULL;
204
205 fd = _get_fileno(socket_object);
206 if (fd < 0)
207 return NULL;
208
209 timeout = _get_timeout(socket_object, &timeout_secs);
210
211 Py_BEGIN_ALLOW_THREADS;
212 result = connect(fd, (struct sockaddr *)&addr, addrlen);
213
214 if (timeout) {
215 struct pollfd pollfd;
216 int timeout_ms;
217 int n;
218
219 pollfd.fd = fd;
220 pollfd.events = POLLIN;
221
222 /* timeout limits are set by Python */
223 timeout_ms = (int)(timeout_secs * 1000);
224 n = poll(&pollfd, 1, timeout_ms);
225 if (n == 0) {
226 did_timeout = 1;
227 } else if (n < 0) {
228 result = n;
229 } else {
230 /* result from connect() is EINPROGRESS, get the real error */
231 socklen_t resultlen = sizeof result;
232 (void)getsockopt(fd, SOL_SOCKET, SO_ERROR, &result, &resultlen);
233 if (result == EISCONN)
234 result = 0;
235 else {
236 errno = result;
237 result = -1;
238 }
239 }
240 }
241 Py_END_ALLOW_THREADS;
242
243 if (did_timeout) {
244 PyErr_SetString(_btsocket_timeout, "timed out");
245 return NULL;
246 }
247 if (result < 0) {
248 PyErr_SetFromErrno(_btsocket_error);
249 return NULL;
250 }
251
252 Py_INCREF(Py_None);
253 return Py_None;
254}
255
Scott James Remnant96927a42013-07-17 18:27:57 -0700256static PyObject *_btsocket_recvmsg(PyObject *self, PyObject *args) {
257 PyObject *socket_object, *buffers, *iterator, *cmsg_list = NULL, *addrval;
258 PyObject *retval = NULL;
259 Py_ssize_t controllen = 0, nbuffers, buf_index = 0;
260 int flags = 0, fd, i, timeout = 0, did_timeout = 0;
261 double timeout_secs;
262 struct iovec *iovs = NULL;
263 Py_buffer *bufs = NULL;
264 void *controlbuf = NULL;
265 struct sockaddr_hci addr;
266 struct msghdr msg = {0};
267 ssize_t len;
268 struct cmsghdr *cmsgh;
269
270 /* Parse arguments, allocating an iovec array matching the incoming buffers
271 list and a matching PyBuffer for each one that we can fetch the incoming
272 buffer into for receiving. */
273 if (!PyArg_ParseTuple(args, "OO|ni:_btsocket.recvmsg_into",
274 &socket_object, &buffers, &controllen, &flags))
275 return NULL;
276
277 fd = _get_fileno(socket_object);
278 if (fd < 0)
279 return NULL;
280
281 timeout = _get_timeout(socket_object, &timeout_secs);
282
283 iterator = PySequence_Fast(buffers, ("recvmsg_into() argument 1 must be an "
284 "iterable"));
285 if (!iterator)
286 return NULL;
287
288 nbuffers = PySequence_Fast_GET_SIZE(iterator);
289 if (nbuffers > INT_MAX) {
290 PyErr_SetString(_btsocket_error, "recvmsg_into() argument 1 is too long");
291 goto finally;
292 }
293
294 if (nbuffers > 0) {
295 iovs = PyMem_New(struct iovec, nbuffers);
296 bufs = PyMem_New(Py_buffer, nbuffers);
297
298 if (!iovs || !bufs) {
299 PyErr_NoMemory();
300 goto finally;
301 }
302 }
303
304 for (buf_index = 0; buf_index < nbuffers; ++buf_index) {
305 if (!PyArg_Parse(PySequence_Fast_GET_ITEM(iterator, buf_index),
306 ("w*;recvmsg_into() argument 1 must be an iterable "
307 "of single-segment read-write buffers"),
308 &bufs[buf_index]))
309 goto finally;
310
311 iovs[buf_index].iov_base = bufs[buf_index].buf;
312 iovs[buf_index].iov_len = bufs[buf_index].len;
313 }
314
315 /* Allocate a control buffer large enough to receive ancillary data. */
316 if (controllen < 0 || controllen > INT_MAX) {
317 PyErr_SetString(_btsocket_error, "recvmsg_into() argument 2 invalid");
318 goto finally;
319 }
320
321 if (controllen > 0) {
322 controlbuf = PyMem_Malloc(controllen);
323 if (!controlbuf) {
324 PyErr_NoMemory();
325 goto finally;
326 }
327 }
328
329 /* Receive data on the socket. */
330 Py_BEGIN_ALLOW_THREADS;
331 msg.msg_name = (struct sockaddr *)&addr;
332 msg.msg_namelen = sizeof addr;
333 msg.msg_iov = iovs;
334 msg.msg_iovlen = nbuffers;
335 msg.msg_control = controlbuf;
336 msg.msg_controllen = controllen;
337
338 if (timeout) {
339 struct pollfd pollfd;
340 int timeout_ms;
341 int n;
342
343 pollfd.fd = fd;
344 pollfd.events = POLLIN;
345
346 /* timeout limits are set by Python */
347 timeout_ms = (int)(timeout_secs * 1000);
348 n = poll(&pollfd, 1, timeout_ms);
349 if (n <= 0)
350 did_timeout = 1;
351 }
352
353 if (!did_timeout)
354 len = recvmsg(fd, &msg, flags);
355 Py_END_ALLOW_THREADS;
356
357 if (did_timeout) {
358 PyErr_SetString(_btsocket_timeout, "timed out");
359 goto finally;
360 }
361 if (len < 0) {
362 PyErr_SetFromErrno(_btsocket_error);
363 goto finally;
364 }
365
366 /* Parse control message data into a list we pass in the return value. */
367 cmsg_list = PyList_New(0);
368 if (!cmsg_list)
369 goto finally;
370
371 for (cmsgh = CMSG_FIRSTHDR(&msg); cmsgh != NULL;
372 cmsgh = CMSG_NXTHDR(&msg, cmsgh)) {
373 size_t cmsgdatalen;
374 PyObject *bytes, *tuple;
375 int tmp;
376
377 /* cmsg_len includes the length of the 'struct cmsghdr' and any padding
378 the kernel sees fit to add. CMSG_LEN(0) gives the value that cmsg_len
379 would have if there were 0 bytes of additional data. Thus by doing
380 cmsg_len - CMSG_LEN(0) we get the actual length of data.
381
382 Never let kernel engineers design APIs. */
383 cmsgdatalen = cmsgh->cmsg_len - CMSG_LEN(0);
384 /* bytes is refcounted, if NULL the Py_BuildValue will fail and tuple will
385 be NULL too - which we catch. If it succeeds, the refcount will be 0
386 until Py_BuildValue succeeds. So there's no need to explicitly free or
387 decref bytes. */
388 bytes = PyBytes_FromStringAndSize((char *)CMSG_DATA(cmsgh), cmsgdatalen);
389 tuple = Py_BuildValue("iiN",
390 (int)cmsgh->cmsg_level, (int)cmsgh->cmsg_type, bytes);
391 if (tuple == NULL)
392 goto finally;
393
394 tmp = PyList_Append(cmsg_list, tuple);
395 Py_DECREF(tuple);
396 if (tmp != 0)
397 goto finally;
398 }
399
400 /* Build the rest of the return value. */
401 addrval = Py_BuildValue("ii", addr.hci_dev, addr.hci_channel);
402 if (!addrval)
403 goto finally;
404
405 retval = Py_BuildValue("NOiN",
406 PyLong_FromSsize_t(len),
407 cmsg_list,
408 (int)msg.msg_flags,
409 addrval);
410
411 /* Clean up in success cases as well as error. */
412finally:
413 Py_XDECREF(cmsg_list);
414 PyMem_Free(controlbuf);
415 /* We can abort out of the allocation loop only, so buffers will only be
416 allocated up to buf_index not nbuffers. */
417 for (i = 0; i < buf_index; ++i)
418 PyBuffer_Release(&bufs[i]);
419 PyMem_Free(bufs);
420 PyMem_Free(iovs);
421 Py_DECREF(iterator);
422 return retval;
423}
424
Artem Rakhov1b654492015-01-21 00:40:44 -0800425static PyObject *_btsocket_listen_and_accept() {
426 int sk, nsk, result;
427 struct sockaddr_l2 srcaddr, addr;
428 socklen_t optlen;
429 struct bt_security btsec;
430 bdaddr_t *ba;
431 char str[18];
432
433 Py_BEGIN_ALLOW_THREADS;
434 sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
435 Py_END_ALLOW_THREADS;
436 if (sk < 0)
437 goto fail;
438
439 /* Set up source address */
440 memset(&srcaddr, 0, sizeof(srcaddr));
441 srcaddr.l2_family = AF_BLUETOOTH;
442 srcaddr.l2_cid = htobs(ATT_CID);
443 srcaddr.l2_bdaddr_type = BDADDR_LE_PUBLIC;
444
445 Py_BEGIN_ALLOW_THREADS;
446 result = bind(sk, (struct sockaddr *) &srcaddr, sizeof(srcaddr));
447 Py_END_ALLOW_THREADS;
448
449 if (result < 0)
450 goto fail;
451
452 /* Set the security level */
453 memset(&btsec, 0, sizeof(btsec));
454 btsec.level = BT_SECURITY_LOW;
455
456 Py_BEGIN_ALLOW_THREADS;
457 result = setsockopt(sk, SOL_BLUETOOTH, BT_SECURITY, &btsec, sizeof(btsec));
458 Py_END_ALLOW_THREADS;
459
460 if (result != 0)
461 goto fail;
462
463 Py_BEGIN_ALLOW_THREADS;
464 result = listen(sk, 10);
465 Py_END_ALLOW_THREADS;
466
467 if (result < 0)
468 goto fail;
469
470 memset(&addr, 0, sizeof(addr));
471 optlen = sizeof(addr);
472
473 Py_BEGIN_ALLOW_THREADS;
474 nsk = accept(sk, (struct sockaddr *) &addr, &optlen);
475 Py_END_ALLOW_THREADS;
476
477 if (nsk < 0)
478 goto fail;
479
480 ba = &addr.l2_bdaddr;
481 sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
482 ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]);
483
484 close(sk);
485 return Py_BuildValue("(i,s)", nsk, str);
486
487fail:
488 if (sk >= 0)
489 close(sk);
490
491 return PyErr_SetFromErrno(_btsocket_error);
492}
Scott James Remnant96927a42013-07-17 18:27:57 -0700493
494static PyMethodDef _btsocket_methods[] = {
495 { "bind", _btsocket_bind, METH_VARARGS,
496 "Bind a Bluetooth socket to a device and channel" },
Scott James Remnantffa6f742013-11-19 12:10:07 -0800497 { "connect", _btsocket_connect, METH_VARARGS,
498 "Connect a Bluetooth socket to a remote address" },
Scott James Remnant96927a42013-07-17 18:27:57 -0700499 { "recvmsg", _btsocket_recvmsg, METH_VARARGS,
500 "Receive normal and ancillary data from a Bluetooth socket" },
Artem Rakhov1b654492015-01-21 00:40:44 -0800501 { "listen_and_accept", _btsocket_listen_and_accept, METH_NOARGS,
502 "Create a socket for incoming BLE connection" },
Scott James Remnant96927a42013-07-17 18:27:57 -0700503
504 { NULL, NULL, 0, NULL }
505};
506
Yu-Hsuan Hsue1cb3b92020-02-13 23:16:02 +0800507MOD_INIT(_btsocket)
Scott James Remnant96927a42013-07-17 18:27:57 -0700508{
509 PyObject *m;
510
Yu-Hsuan Hsue1cb3b92020-02-13 23:16:02 +0800511 MOD_DEF(m, "_btsocket", "Bluetooth socket API", _btsocket_methods);
Scott James Remnant96927a42013-07-17 18:27:57 -0700512 if (!m)
Yu-Hsuan Hsue1cb3b92020-02-13 23:16:02 +0800513 return MOD_ERROR_VAL;
Scott James Remnant96927a42013-07-17 18:27:57 -0700514
515 _btsocket_error = PyErr_NewException("btsocket.error",
516 PyExc_OSError, NULL);
517 Py_INCREF(_btsocket_error);
518 PyModule_AddObject(m, "error", _btsocket_error);
519
520 _btsocket_timeout = PyErr_NewException("btsocket.timeout",
521 PyExc_OSError, NULL);
522 Py_INCREF(_btsocket_timeout);
523 PyModule_AddObject(m, "timeout", _btsocket_timeout);
Yu-Hsuan Hsue1cb3b92020-02-13 23:16:02 +0800524
525 return MOD_SUCCESS_VAL(m);
Scott James Remnant96927a42013-07-17 18:27:57 -0700526}