diff -Naur PyBluez-0.23/bluez/btmodule.c PyBluez-0.23.new/bluez/btmodule.c --- PyBluez-0.23/bluez/btmodule.c 2019-12-28 01:54:22.000000000 +0100 +++ PyBluez-0.23.new/bluez/btmodule.c 2022-12-11 16:47:52.974915482 +0100 @@ -16,10 +16,13 @@ - names starting with bt_ are module-level functions */ - +#define PY_SSIZE_T_CLEAN 1 +#include "Python.h" #include "btmodule.h" #include "structmember.h" +#include "pythoncapi_compat.h" + #include #include #include @@ -41,7 +44,6 @@ #include #include -#include #include #include #include "btsdp.h" @@ -212,7 +214,7 @@ switch(s->sock_proto) { case BTPROTO_HCI: { - return Py_BuildValue("H", + return Py_BuildValue("H", ((struct sockaddr_hci*)(addr))->hci_dev ); } case BTPROTO_L2CAP: @@ -234,7 +236,7 @@ return Py_BuildValue("s", ba_name); } default: - PyErr_SetString(bluetooth_error, + PyErr_SetString(bluetooth_error, "getsockaddrarg: unknown Bluetooth protocol"); return 0; } @@ -329,7 +331,7 @@ } default: { - PyErr_SetString(bluetooth_error, + PyErr_SetString(bluetooth_error, "getsockaddrarg: unknown Bluetooth protocol"); return 0; } @@ -418,7 +420,6 @@ /* get ba */ if(getsockname(socko->sock_fd, &addr, &alen) < 0) return -1; - switch(socko->sock_proto) { case BTPROTO_L2CAP: @@ -480,7 +481,7 @@ *len_ret = sizeof (struct sockaddr_hci); return 1; default: - PyErr_SetString(bluetooth_error, + PyErr_SetString(bluetooth_error, "getsockaddrlen: unknown bluetooth protocol"); return 0; } @@ -544,18 +545,14 @@ int pyunicode2uuid( PyObject *item, uuid_t *uuid ) { -#if PY_MAJOR_VERSION >= 3 PyObject* ascii = PyUnicode_AsASCIIString( item ); int ret = str2uuid( PyBytes_AsString( ascii ), uuid ); Py_XDECREF( ascii ); return ret; -#else - return str2uuid( PyString_AsString( item ), NULL ); -#endif } void -uuid2str( const uuid_t *uuid, char *dest ) +uuid2str( const uuid_t *uuid, char *dest ) { if( uuid->type == SDP_UUID16 ) { sprintf(dest, "%04X", uuid->value.uuid16 ); @@ -564,11 +561,11 @@ } else if( uuid->type == SDP_UUID128 ) { uint32_t *data = (uint32_t*)(&uuid->value.uuid128); sprintf(dest, "%08X-%04X-%04X-%04X-%04X%08X", - ntohl(data[0]), - ntohl(data[1])>>16, + ntohl(data[0]), + ntohl(data[1])>>16, (ntohl(data[1])<<16)>>16, - ntohl(data[2])>>16, - (ntohl(data[2])<<16)>>16, + ntohl(data[2])>>16, + (ntohl(data[2])<<16)>>16, ntohl(data[3])); } } @@ -649,7 +646,7 @@ { int block; - block = PyInt_AsLong(arg); + block = PyLong_AsLong(arg); if (block == -1 && PyErr_Occurred()) return NULL; @@ -677,7 +674,7 @@ { double timeout; - if (arg == Py_None) + if (Py_IsNone(arg)) timeout = -1.0; else { timeout = PyFloat_AsDouble(arg); @@ -732,7 +729,7 @@ int optname; int res; void *buf; - int buflen; + Py_ssize_t buflen; int flag; if (PyArg_ParseTuple(args, "iii:setsockopt", &level, &optname, &flag)) { @@ -779,21 +776,21 @@ res = getsockopt(s->sock_fd, level, optname, (void *)&flag, &flagsize); if (res < 0) return s->errorhandler(); - return PyInt_FromLong(flag); + return PyLong_FromLong(flag); } else if (buflen <= 0 || buflen > 1024) { PyErr_SetString(bluetooth_error, "getsockopt buflen out of range"); return NULL; } else { - PyObject *buf = PyString_FromStringAndSize((char *)NULL, buflen); + PyObject *buf = PyBytes_FromStringAndSize((char *)NULL, buflen); if (buf == NULL) return NULL; res = getsockopt(s->sock_fd, level, optname, - (void *)PyString_AS_STRING(buf), &buflen); + (void *)PyBytes_AS_STRING(buf), &buflen); if (res < 0) { Py_DECREF(buf); return s->errorhandler(); } - _PyString_Resize(&buf, buflen); + _PyBytes_Resize(&buf, buflen); return buf; } return NULL; @@ -982,7 +979,7 @@ res = internal_connect(s, &addr, addrlen, &timeout); Py_END_ALLOW_THREADS - return PyInt_FromLong((long) res); + return PyLong_FromLong((long) res); } PyDoc_STRVAR(connect_ex_doc, @@ -997,7 +994,7 @@ static PyObject * sock_fileno(PySocketSockObject *s) { - return PyInt_FromLong((long) s->sock_fd); + return PyLong_FromLong((long) s->sock_fd); } PyDoc_STRVAR(fileno_doc, @@ -1098,7 +1095,7 @@ int backlog; int res; - backlog = PyInt_AsLong(arg); + backlog = PyLong_AsLong(arg); if (backlog == -1 && PyErr_Occurred()) return NULL; Py_BEGIN_ALLOW_THREADS @@ -1147,13 +1144,7 @@ close(fd); return s->errorhandler(); } -#if PY_MAJOR_VERSION >= 3 f = PyFile_FromFd(fd, "", mode, bufsize, NULL, NULL, NULL, 1); -#else - f = PyFile_FromFile(fp, "", mode, fclose); - if (f != NULL) - PyFile_SetBufSize(f, bufsize); -#endif return f; } @@ -1182,14 +1173,14 @@ return NULL; } - buf = PyString_FromStringAndSize((char *) 0, len); + buf = PyBytes_FromStringAndSize((char *) 0, len); if (buf == NULL) return NULL; Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 0); if (!timeout) - n = recv(s->sock_fd, PyString_AS_STRING(buf), len, flags); + n = recv(s->sock_fd, PyBytes_AS_STRING(buf), len, flags); Py_END_ALLOW_THREADS if (timeout) { @@ -1202,7 +1193,7 @@ return s->errorhandler(); } if (n != len) - _PyString_Resize(&buf, n); + _PyBytes_Resize(&buf, n); return buf; } @@ -1232,7 +1223,7 @@ if (!getsockaddrlen(s, &addrlen)) return NULL; - buf = PyString_FromStringAndSize((char *) 0, len); + buf = PyUnicode_FromStringAndSize((char *) 0, len); if (buf == NULL) return NULL; @@ -1240,7 +1231,7 @@ memset(addrbuf, 0, addrlen); timeout = internal_select(s, 0); if (!timeout) - n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags, + n = recvfrom(s->sock_fd, PyBytes_AS_STRING(buf), len, flags, (void *)addrbuf, &addrlen ); Py_END_ALLOW_THREADS @@ -1255,7 +1246,7 @@ return s->errorhandler(); } - if (n != len && _PyString_Resize(&buf, n) < 0) + if (n != len && _PyBytes_Resize(&buf, n) < 0) return NULL; if (!(addr = makesockaddr(s, (struct sockaddr *)addrbuf, addrlen))) @@ -1279,17 +1270,18 @@ static PyObject * sock_send(PySocketSockObject *s, PyObject *args) { - char *buf; - int len, n = 0, flags = 0, timeout; + Py_buffer buf; + int n = 0, flags = 0, timeout; - if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags)) + if (!PyArg_ParseTuple(args, "s*|i:send", &buf, &flags)) return NULL; Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 1); if (!timeout) - n = send(s->sock_fd, buf, len, flags); + n = send(s->sock_fd, buf.buf, buf.len, flags); Py_END_ALLOW_THREADS + PyBuffer_Release(&buf); if (timeout) { PyErr_SetString(socket_timeout, "timed out"); @@ -1297,7 +1289,7 @@ } if (n < 0) return s->errorhandler(); - return PyInt_FromLong((long)n); + return PyLong_FromLong((long)n); } PyDoc_STRVAR(send_doc, @@ -1313,24 +1305,29 @@ static PyObject * sock_sendall(PySocketSockObject *s, PyObject *args) { - char *buf; + Py_buffer buf; + char *raw_buf; int len, n = 0, flags = 0, timeout; - if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags)) + if (!PyArg_ParseTuple(args, "s*|i:sendall", &buf, &flags)) return NULL; Py_BEGIN_ALLOW_THREADS + raw_buf = buf.buf; + len = buf.len; do { timeout = internal_select(s, 1); if (timeout) break; - n = send(s->sock_fd, buf, len, flags); + n = send(s->sock_fd, raw_buf, len, flags); if (n < 0) break; - buf += n; + raw_buf += n; len -= n; } while (len > 0); + raw_buf = NULL; Py_END_ALLOW_THREADS + PyBuffer_Release(&buf); if (timeout) { PyErr_SetString(socket_timeout, "timed out"); @@ -1357,14 +1354,14 @@ sock_sendto(PySocketSockObject *s, PyObject *args) { PyObject *addro; - char *buf; + Py_buffer buf; struct sockaddr addr = { 0 }; - int addrlen, len, n = 0, flags, timeout; + int addrlen, n = 0, flags, timeout; flags = 0; - if (!PyArg_ParseTuple(args, "s#O:sendto", &buf, &len, &addro)) { + if (!PyArg_ParseTuple(args, "s*O:sendto", &buf, &addro)) { PyErr_Clear(); - if (!PyArg_ParseTuple(args, "s#iO:sendto", &buf, &len, &flags, &addro)) + if (!PyArg_ParseTuple(args, "s*iO:sendto", &buf, &flags, &addro)) return NULL; } @@ -1374,8 +1371,9 @@ Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 1); if (!timeout) - n = sendto(s->sock_fd, buf, len, flags, &addr, addrlen); + n = sendto(s->sock_fd, buf.buf, buf.len, flags, &addr, addrlen); Py_END_ALLOW_THREADS + PyBuffer_Release(&buf); if (timeout) { PyErr_SetString(socket_timeout, "timed out"); @@ -1383,7 +1381,7 @@ } if (n < 0) return s->errorhandler(); - return PyInt_FromLong((long)n); + return PyLong_FromLong((long)n); } PyDoc_STRVAR(sendto_doc, @@ -1401,7 +1399,7 @@ int how; int res; - how = PyInt_AsLong(arg); + how = PyLong_AsLong(arg); if (how == -1 && PyErr_Occurred()) return NULL; Py_BEGIN_ALLOW_THREADS @@ -1512,7 +1510,7 @@ close(s->sock_fd); Py_END_ALLOW_THREADS } - + if( s->sdp_session ) { sdp_close( s->sdp_session ); s->sdp_record_handle = 0; @@ -1544,7 +1542,7 @@ (long)s->sock_fd, s->sock_family, s->sock_type, s->sock_proto); - return PyString_FromString(buf); + return PyUnicode_FromString(buf); } @@ -1617,12 +1615,7 @@ /* Type object for socket objects. */ PyTypeObject sock_type = { -#if PY_MAJOR_VERSION < 3 - PyObject_HEAD_INIT(0) /* Must fill in type value later */ - 0, /* ob_size */ -#else PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */ -#endif "_bluetooth.btsocket", /* tp_name */ sizeof(PySocketSockObject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -1708,7 +1701,7 @@ return NULL; } x2 = (int)btohs((short)x1); - return PyInt_FromLong(x2); + return PyLong_FromLong(x2); } PyDoc_STRVAR(bt_btohs_doc, @@ -1722,13 +1715,13 @@ { unsigned long x; PyObject *arg; - + if (!PyArg_ParseTuple(args, "O:btohl", &arg)) { return NULL; } - if (PyInt_Check(arg)) { - x = PyInt_AS_LONG(arg); + if (PyLong_Check(arg)) { + x = PyLong_AS_LONG(arg); if (x == (unsigned long) -1 && PyErr_Occurred()) return NULL; } @@ -1751,10 +1744,10 @@ else return PyErr_Format(PyExc_TypeError, "expected int/long, %s found", - arg->ob_type->tp_name); + Py_TYPE(arg)->tp_name); if (x == (unsigned long) -1 && PyErr_Occurred()) return NULL; - return PyInt_FromLong(btohl(x)); + return PyLong_FromLong(btohl(x)); } PyDoc_STRVAR(bt_btohl_doc, @@ -1772,7 +1765,7 @@ return NULL; } x2 = (int)htobs((short)x1); - return PyInt_FromLong(x2); + return PyLong_FromLong(x2); } PyDoc_STRVAR(bt_htobs_doc, @@ -1791,8 +1784,8 @@ return NULL; } - if (PyInt_Check(arg)) { - x = PyInt_AS_LONG(arg); + if (PyLong_Check(arg)) { + x = PyLong_AS_LONG(arg); if (x == (unsigned long) -1 && PyErr_Occurred()) return NULL; } @@ -1815,8 +1808,8 @@ else return PyErr_Format(PyExc_TypeError, "expected int/long, %s found", - arg->ob_type->tp_name); - return PyInt_FromLong(htobl(x)); + Py_TYPE(arg)->tp_name); + return PyLong_FromLong(htobl(x)); } //static PyObject * @@ -1825,7 +1818,7 @@ // int protocol = -1; // int s; // -// protocol = PyInt_AsLong(arg); +// protocol = PyLong_AsLong(arg); // // if (protocol == -1 && PyErr_Occurred()) // return NULL; @@ -1838,7 +1831,7 @@ // s = socket( AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM ); // // sockaddr.rc_family = AF_BLUETOOTH; -// bacppy( &sockaddr.rc_bdaddr, BDADDR_ANY +// bacppy( &sockaddr.rc_bdaddr, BDADDR_ANY // } // break; // case BTPROTO_L2CAP: @@ -1851,7 +1844,7 @@ // break; // default: // { -// PyErr_SetString( PyExc_ValueError, +// PyErr_SetString( PyExc_ValueError, // "protocol must be either RFCOMM or L2CAP" ); // return 0; // } @@ -1888,7 +1881,7 @@ { double timeout; - if (arg == Py_None) + if (Py_IsNone(arg)) timeout = -1.0; else { timeout = PyFloat_AsDouble(arg); @@ -1914,13 +1907,13 @@ /* * ---------------------------------------------------------------------- * HCI Section (Calvin) - * + * * This section provides the socket methods for calling HCI commands. * These commands may be called statically, and implementation is * independent from the rest of the module (except for bt_methods[]). * * ---------------------------------------------------------------------- - * + * */ /* @@ -1933,7 +1926,7 @@ { int dev = -1, fd; PySocketSockObject *s = NULL; - + if ( !PyArg_ParseTuple(args, "|i", &dev) ) { return NULL; @@ -1948,7 +1941,7 @@ PyErr_SetString(bluetooth_error, "no available bluetoot devices"); return 0; } - + Py_BEGIN_ALLOW_THREADS fd = hci_open_dev(dev); Py_END_ALLOW_THREADS @@ -1969,7 +1962,7 @@ bt_hci_close_dev(PyObject *self, PyObject *args) { int dev, err; - + if ( !PyArg_ParseTuple(args, "i", &dev) ) { return NULL; @@ -1980,11 +1973,11 @@ Py_END_ALLOW_THREADS if( err < 0 ) return set_error(); - + Py_RETURN_NONE; } -PyDoc_STRVAR(bt_hci_close_dev_doc, +PyDoc_STRVAR(bt_hci_close_dev_doc, "hci_close_dev(dev_id)\n\ \n\ Closes the specified device id. Note: device id is NOT a btoscket.\n\ @@ -2001,11 +1994,12 @@ bt_hci_send_cmd(PyObject *self, PyObject *args) { PySocketSockObject *socko = NULL; - int err, plen = 0; + int err; + Py_ssize_t plen = 0; uint16_t ogf, ocf; char *param = NULL; int dd = 0; - + if ( !PyArg_ParseTuple(args, "OHH|s#", &socko, &ogf, &ocf, ¶m, &plen)) { return NULL; } @@ -2021,7 +2015,7 @@ return Py_BuildValue("i", err); } -PyDoc_STRVAR(bt_hci_send_cmd_doc, +PyDoc_STRVAR(bt_hci_send_cmd_doc, "hci_send_cmd(sock, ogf, ocf, params)\n\ \n\ Transmits the specified HCI command to the socket.\n\ @@ -2036,6 +2030,7 @@ int err; int to=0; char rparam[256]; + Py_ssize_t req_clen; struct hci_request req = { 0 }; int dd = 0; @@ -2043,9 +2038,10 @@ "timeout", 0 }; if( !PyArg_ParseTupleAndKeywords(args, kwds, "OHHii|s#i", keywords, - &socko, &req.ogf, &req.ocf, &req.event, &req.rlen, - &req.cparam, &req.clen, &to) ) + &socko, &req.ogf, &req.ocf, &req.event, &req.rlen, + &req.cparam, &req_clen, &to) ) return 0; + req.clen = req_clen; req.rparam = rparam; dd = socko->sock_fd; @@ -2056,7 +2052,7 @@ if( err< 0 ) return socko->errorhandler(); - return PyString_FromStringAndSize(rparam, req.rlen); + return PyUnicode_FromStringAndSize(rparam, req.rlen); } PyDoc_STRVAR(bt_hci_send_req_doc, "hci_send_req(sock, ogf, ocf, event, rlen, params=None, timeout=0)\n\ @@ -2128,8 +2124,8 @@ int err; ba2str( &(info+i)->bdaddr, ba_name ); - - addr_entry = PyString_FromString( ba_name ); + + addr_entry = PyUnicode_FromString( ba_name ); if (lookup_class) { PyObject *item_tuple = PyTuple_New(2); @@ -2137,7 +2133,7 @@ int dev_class = (info+i)->dev_class[2] << 16 | (info+i)->dev_class[1] << 8 | (info+i)->dev_class[0]; - PyObject *class_entry = PyInt_FromLong( dev_class ); + PyObject *class_entry = PyLong_FromLong( dev_class ); err = PyTuple_SetItem( item_tuple, 0, addr_entry ); if (err) { @@ -2173,7 +2169,7 @@ return rtn_list; } -PyDoc_STRVAR(bt_hci_inquiry_doc, +PyDoc_STRVAR(bt_hci_inquiry_doc, "hci_inquiry(dev_id=0, duration=8, flush_cache=True\n\ \n\ Performs a device inquiry using the specified device (usually 0 or 1).\n\ @@ -2203,14 +2199,14 @@ memset( name, 0, sizeof(name) ); Py_BEGIN_ALLOW_THREADS - err = hci_read_remote_name( socko->sock_fd, &ba, sizeof(name)-1, + err = hci_read_remote_name( socko->sock_fd, &ba, sizeof(name)-1, name, timeout ); Py_END_ALLOW_THREADS - if( err < 0) + if( err < 0) return PyErr_SetFromErrno(bluetooth_error); - return PyString_FromString( name ); + return PyUnicode_FromString( name ); } PyDoc_STRVAR(bt_hci_read_remote_name_doc, "hci_read_remote_name(sock, bdaddr, timeout=5192)\n\ @@ -2232,7 +2228,7 @@ // DPRINTF("opcode = %x\n", opcode); const char* cmd_name = opcode2str (opcode); - return PyString_FromString( cmd_name ); + return PyUnicode_FromString( cmd_name ); } PyDoc_STRVAR(bt_hci_opcode_name_doc, "hci_opcode_name(opcode)\n\ @@ -2258,7 +2254,7 @@ return 0; } const char* event_name = event_str[eventNum]; - return PyString_FromString( event_name ); + return PyUnicode_FromString( event_name ); } PyDoc_STRVAR(bt_hci_event_name_doc, "hci_event_name(eventNum)\n\ @@ -2274,7 +2270,8 @@ static PyObject * bt_hci_filter_ ## name (PyObject *self, PyObject *args )\ { \ char *param; \ - int len, arg; \ + Py_ssize_t len; \ + int arg; \ if( !PyArg_ParseTuple(args,"s#i", ¶m, &len, &arg) ) \ return 0; \ if( len != sizeof(struct hci_filter) ) { \ @@ -2282,7 +2279,7 @@ return 0; \ } \ hci_filter_ ## name ( arg, (struct hci_filter*)param ); \ - return PyString_FromStringAndSize(param, len); \ + return PyUnicode_FromStringAndSize(param, len); \ } \ PyDoc_STRVAR(bt_hci_filter_ ## name ## _doc, docstring); @@ -2303,7 +2300,7 @@ static PyObject * bt_hci_filter_ ## name (PyObject *self, PyObject *args )\ { \ char *param; \ - int len; \ + Py_ssize_t len; \ if( !PyArg_ParseTuple(args,"s#", ¶m, &len) ) \ return 0; \ if( len != sizeof(struct hci_filter) ) { \ @@ -2311,7 +2308,7 @@ return 0; \ } \ hci_filter_ ## name ( (struct hci_filter*)param ); \ - return PyString_FromStringAndSize(param, len); \ + return PyUnicode_FromStringAndSize(param, len); \ } \ PyDoc_STRVAR(bt_hci_filter_ ## name ## _doc, docstring); @@ -2323,7 +2320,7 @@ #undef DECL_HCI_FILTER_OP_2 static PyObject * -bt_cmd_opcode_pack(PyObject *self, PyObject *args ) +bt_cmd_opcode_pack(PyObject *self, PyObject *args ) { uint16_t opcode, ogf, ocf; if (!PyArg_ParseTuple(args, "HH", &ogf, &ocf )) return 0; @@ -2364,18 +2361,18 @@ bt_ba2str(PyObject *self, PyObject *args) { char *data=NULL; - int len=0; + Py_ssize_t len=0; char ba_str[19] = {0}; if (!PyArg_ParseTuple(args, "s#", &data, &len)) return 0; ba2str((bdaddr_t*)data, ba_str); - return PyString_FromString( ba_str ); + return PyUnicode_FromString( ba_str ); // return Py_BuildValue("s#", ba_str, 18); } PyDoc_STRVAR(bt_ba2str_doc, "ba2str(data)\n\ \n\ Converts a packed bluetooth address to a human readable string"); - + static PyObject * bt_str2ba(PyObject *self, PyObject *args) { @@ -2383,14 +2380,14 @@ bdaddr_t ba; if (!PyArg_ParseTuple(args, "s", &ba_str)) return 0; str2ba( ba_str, &ba ); - return Py_BuildValue(BYTES_FORMAT_CHR, (char*)(&ba), sizeof(ba)); + return Py_BuildValue("y#", (char*)(&ba), sizeof(ba)); } PyDoc_STRVAR(bt_str2ba_doc, "str2ba(string)\n\ \n\ Converts a bluetooth address string into a packed bluetooth address.\n\ The string should be of the form \"XX:XX:XX:XX:XX:XX\""); - + /* * params: (string) device address * effect: - @@ -2462,7 +2459,7 @@ int which; int timeout; uint32_t btclock; - uint16_t accuracy; + uint16_t accuracy; int res; if ( !PyArg_ParseTuple(args, "iiii", &fd, &handle, &which, &timeout) ) @@ -2502,7 +2499,7 @@ if (dev_id < 0) { return PyErr_SetFromErrno(PyExc_OSError); } - return PyInt_FromLong(dev_id); + return PyLong_FromLong(dev_id); } PyDoc_STRVAR( bt_hci_get_route_doc, "hci_get_route(address)\n\ @@ -2561,6 +2558,85 @@ methods, and for passing to getsockopt and setsockopt. The filter is\n\ initially cleared"); + +static PyObject * +bt_hci_le_add_white_list(PyObject *self, PyObject *args) +{ + PySocketSockObject *socko = NULL; + int err = 0; + int to = 0; + char *addr = NULL; + bdaddr_t ba; + int dd = 0; + uint8_t type; + + if ( !PyArg_ParseTuple(args, "OsHi", &socko, &addr, &type, &to) ) { + return NULL; + } + if ( addr && strlen(addr) ){ + str2ba( addr, &ba ); + } + else { + return NULL; + } + + dd = socko->sock_fd; + err = hci_le_add_white_list(dd, &ba, type, to); + if ( err < 0 ) { + return NULL; + } + + return Py_BuildValue("i", err); +} + +PyDoc_STRVAR(bt_hci_le_add_white_list_doc, +"hci_le_add_white_list( dd, btaddr, type, to )\n\ +\n\ +Add the given MAC to the LE scan white list"); + +static PyObject * +bt_hci_le_read_white_list_size(PyObject *self, PyObject *args) +{ + PySocketSockObject *socko = NULL; + int err = 0; + int to = 0; + uint8_t ret; + int dd; + if ( !PyArg_ParseTuple(args, "Oi", &socko, &to) ) { + return NULL; + } + dd = socko->sock_fd; + err = hci_le_read_white_list_size(dd, &ret, to); + if ( err < 0 ) { + return NULL; + } + return Py_BuildValue("i", ret); +} +PyDoc_STRVAR(bt_hci_le_read_white_list_size_doc, +"hci_le_read_white_list_size( dd, size, to )\n\ +\n\ +Read the total length of the LE scan white list. This is the length of the\n\ +empty list, not the total entries in the list"); + +static PyObject * +bt_hci_le_clear_white_list(PyObject *self, PyObject *args) +{ + PySocketSockObject *socko = NULL; + int err = 0; + int to = 0; + int dd; + if ( !PyArg_ParseTuple(args, "Oi", &socko, &to) ) { + return NULL; + } + dd = socko->sock_fd; + err = hci_le_clear_white_list(dd, to); + return Py_BuildValue("i", err); +} +PyDoc_STRVAR(bt_hci_le_clear_white_list_doc, +"hci_le_clear_white_list( dd, to )\n\ +\n\ +Clears the LE scan white list"); + /* * ------------------- * End of HCI section @@ -2574,12 +2650,12 @@ bt_sdp_advertise_service( PyObject *self, PyObject *args ) { PySocketSockObject *socko = NULL; - char *name = NULL, - *service_id_str = NULL, - *provider = NULL, + char *name = NULL, + *service_id_str = NULL, + *provider = NULL, *description = NULL; PyObject *service_classes, *profiles, *protocols; - int namelen = 0, provlen = 0, desclen = 0; + Py_ssize_t namelen = 0, provlen = 0, desclen = 0; uuid_t svc_uuid = { 0 }; int i; char addrbuf[256] = { 0 }; @@ -2587,10 +2663,10 @@ socklen_t addrlen; struct sockaddr *sockaddr; uuid_t root_uuid, l2cap_uuid, rfcomm_uuid; - sdp_list_t *l2cap_list = 0, + sdp_list_t *l2cap_list = 0, *rfcomm_list = 0, *root_list = 0, - *proto_list = 0, + *proto_list = 0, *profile_list = 0, *svc_class_list = 0, *access_proto_list = 0; @@ -2601,7 +2677,7 @@ int err = 0; if (!PyArg_ParseTuple(args, "O!s#sOOs#s#O", &sock_type, &socko, &name, - &namelen, &service_id_str, &service_classes, + &namelen, &service_id_str, &service_classes, &profiles, &provider, &provlen, &description, &desclen, &protocols)) { return 0; @@ -2635,7 +2711,7 @@ for(i = 0; i < PySequence_Length(service_classes); ++i) { PyObject *item = PySequence_GetItem(service_classes, i); if( ! pyunicode2uuid( item, NULL ) ) { - PyErr_SetString(PyExc_ValueError, + PyErr_SetString(PyExc_ValueError, "service_classes must be a list of " "strings, each either of the form XXXX or " "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); @@ -2653,17 +2729,17 @@ char *profile_uuid_str = NULL; uint16_t version; PyObject *tuple = PySequence_GetItem(profiles, i); - if ( ( ! PySequence_Check(tuple) ) || - ( ! PyArg_ParseTuple(tuple, "sH", - &profile_uuid_str, &version)) || - ( ! str2uuid( profile_uuid_str, NULL ) ) + if ( ( ! PySequence_Check(tuple) ) || + ( ! PyArg_ParseTuple(tuple, "sH", + &profile_uuid_str, &version)) || + ( ! str2uuid( profile_uuid_str, NULL ) ) ) { - PyErr_SetString(PyExc_ValueError, + PyErr_SetString(PyExc_ValueError, "Each profile must be a ('uuid', version) tuple"); return 0; } } - + // protocols must be a list / sequence if (! PySequence_Check(protocols)) { PyErr_SetString(PyExc_ValueError, "protocols must be a sequence"); @@ -2673,7 +2749,7 @@ for(i = 0; i < PySequence_Length(protocols); ++i) { PyObject *item = PySequence_GetItem(protocols, i); if( ! pyunicode2uuid( item, NULL ) ) { - PyErr_SetString(PyExc_ValueError, + PyErr_SetString(PyExc_ValueError, "protocols must be a list of " "strings, each either of the form XXXX or " "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); @@ -2683,7 +2759,7 @@ // verify that the socket is bound and listening if( ! socko->is_listening_socket ) { - PyErr_SetString(bluetooth_error, + PyErr_SetString(bluetooth_error, "must have already called socket.listen()"); return 0; } @@ -2709,9 +2785,9 @@ sockaddr = (struct sockaddr *)addrbuf; // can only deal with L2CAP and RFCOMM sockets - if( socko->sock_proto != BTPROTO_L2CAP && + if( socko->sock_proto != BTPROTO_L2CAP && socko->sock_proto != BTPROTO_RFCOMM ) { - PyErr_SetString(bluetooth_error, + PyErr_SetString(bluetooth_error, "Sorry, can only advertise L2CAP and RFCOMM sockets for now"); return 0; } @@ -2726,7 +2802,7 @@ // okay, now construct the SDP service record. memset( &record, 0, sizeof(sdp_record_t) ); - + record.handle = 0xffffffff; // make the service record publicly browsable @@ -2756,7 +2832,7 @@ psm = sdp_data_alloc(SDP_UINT16, &l2cap_psm); sdp_list_append(l2cap_list, psm); } - + // add additional protocols, if any sdp_list_t *extra_protos_array[PySequence_Length(protocols)]; if (PySequence_Length(protocols) > 0) { @@ -2764,16 +2840,16 @@ uuid_t *proto_uuid = (uuid_t*) malloc( sizeof( uuid_t ) ); PyObject *item = PySequence_GetItem(protocols, i); pyunicode2uuid( item, proto_uuid ); - + sdp_list_t *new_list; new_list = sdp_list_append( 0, proto_uuid ); proto_list = sdp_list_append( proto_list, new_list ); - + // keep track, to free the list later extra_protos_array[i] = new_list; } } - + access_proto_list = sdp_list_append( 0, proto_list ); sdp_set_access_protos( &record, access_proto_list ); @@ -2789,10 +2865,10 @@ // add profiles, if any for(i = 0; i < PySequence_Length(profiles); i++) { char *profile_uuid_str; - sdp_profile_desc_t *profile_desc = + sdp_profile_desc_t *profile_desc = (sdp_profile_desc_t*)malloc(sizeof(sdp_profile_desc_t)); PyObject *tuple = PySequence_GetItem(profiles, i); - PyArg_ParseTuple(tuple, "sH", &profile_uuid_str, + PyArg_ParseTuple(tuple, "sH", &profile_uuid_str, &profile_desc->version); str2uuid( profile_uuid_str, &profile_desc->uuid ); profile_list = sdp_list_append( profile_list, profile_desc ); @@ -2805,7 +2881,7 @@ // set the general service ID, if needed if( strlen(service_id_str) ) sdp_set_service_id( &record, svc_uuid ); - // connect to the local SDP server, register the service record, and + // connect to the local SDP server, register the service record, and // disconnect Py_BEGIN_ALLOW_THREADS session = sdp_connect( BDADDR_ANY, BDADDR_LOCAL, 0 ); @@ -2840,7 +2916,7 @@ Py_RETURN_NONE; } -PyDoc_STRVAR( bt_sdp_advertise_service_doc, +PyDoc_STRVAR( bt_sdp_advertise_service_doc, "sdp_advertise_service( socket, name )\n\ \n\ Registers a service with the local SDP server.\n\ @@ -2866,7 +2942,7 @@ // verify that we got a real socket object if( ! socko || (Py_TYPE(socko) != &sock_type) ) { // TODO change this to a more accurate exception type - PyErr_SetString(bluetooth_error, + PyErr_SetString(bluetooth_error, "must pass in _bluetooth.socket object"); return 0; } @@ -2888,11 +2964,9 @@ \n\ Stop advertising services associated with this socket"); - /* List of functions exported by this module. */ -#define DECL_BT_METHOD(name, argtype) \ -{ #name, (PyCFunction)bt_ ##name, argtype, bt_ ## name ## _doc } +#define DECL_BT_METHOD(name, argtype){ #name, (PyCFunction)bt_ ##name, argtype, bt_ ## name ## _doc } static PyMethodDef bt_methods[] = { DECL_BT_METHOD( hci_devid, METH_VARARGS ), @@ -2937,6 +3011,9 @@ DECL_BT_METHOD( setdefaulttimeout, METH_O ), DECL_BT_METHOD( sdp_advertise_service, METH_VARARGS ), DECL_BT_METHOD( sdp_stop_advertising, METH_VARARGS ), + DECL_BT_METHOD( hci_le_add_white_list, METH_VARARGS ), + DECL_BT_METHOD( hci_le_read_white_list_size, METH_VARARGS ), + DECL_BT_METHOD( hci_le_clear_white_list, METH_VARARGS ), // DECL_BT_METHOD( advertise_service, METH_VARARGS | METH_KEYWORDS ), {NULL, NULL} /* Sentinel */ }; @@ -2951,7 +3028,6 @@ \n\ See the bluetooth module for documentation."); -#if PY_MAJOR_VERSION >= 3 #define INITERROR return NULL static struct PyModuleDef moduledef = { @@ -2968,20 +3044,10 @@ PyMODINIT_FUNC PyInit__bluetooth(void) -#else -#define INITERROR return - -PyMODINIT_FUNC -init_bluetooth(void) -#endif { - Py_TYPE(&sock_type) = &PyType_Type; - Py_TYPE(&sdp_session_type) = &PyType_Type; -#if PY_MAJOR_VERSION >= 3 + Py_SET_TYPE(&sock_type, &PyType_Type); + Py_SET_TYPE(&sdp_session_type, &PyType_Type); PyObject *m = PyModule_Create(&moduledef); -#else - PyObject *m = Py_InitModule3("_bluetooth", bt_methods, socket_doc); -#endif if (m == NULL) INITERROR; @@ -3026,7 +3092,7 @@ // PyModule_AddIntMacro(m, SOCK_DGRAM); // PyModule_AddIntMacro(m, SOCK_RAW); // PyModule_AddIntMacro(m, SOCK_SEQPACKET); - + /* HCI Constants */ /* HCI OGF values */ @@ -3695,23 +3761,21 @@ #endif PyModule_AddIntMacro(m, SOL_BLUETOOTH); -#if PY_MAJOR_VERSION >= 3 return m; -#endif } /* - * Affix socket module + * Affix socket module * Socket module for python based in the original socket module for python * This code is a copy from socket.c source code from python2.2 with - * updates/modifications to support affix socket interface * - * AAA FFFFFFF FFFFFFF IIIIIII X X + * updates/modifications to support affix socket interface * + * AAA FFFFFFF FFFFFFF IIIIIII X X * A A F F I X X * A A F F I X X * AAAAAAA FFFF FFFF I X X * A A F F I X X * A A F F IIIIIII X X - * + * * Any modifications of this sourcecode must keep this information !!!!! * * by Carlos Chinea diff -Naur PyBluez-0.23/bluez/pythoncapi_compat.h PyBluez-0.23.new/bluez/pythoncapi_compat.h --- PyBluez-0.23/bluez/pythoncapi_compat.h 1970-01-01 01:00:00.000000000 +0100 +++ PyBluez-0.23.new/bluez/pythoncapi_compat.h 2022-12-11 16:31:25.093057950 +0100 @@ -0,0 +1,364 @@ +// Header file providing new functions of the Python C API to old Python +// versions. +// +// File distributed under the MIT license. +// Copyright Contributors to the pythoncapi_compat project. +// +// Homepage: +// https://github.com/pythoncapi/pythoncapi_compat +// +// Latest version: +// https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h +// +// SPDX-License-Identifier: MIT + +#ifndef PYTHONCAPI_COMPAT +#define PYTHONCAPI_COMPAT + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "frameobject.h" // PyFrameObject, PyFrame_GetBack() + + +// Compatibility with Visual Studio 2013 and older which don't support +// the inline keyword in C (only in C++): use __inline instead. +#if (defined(_MSC_VER) && _MSC_VER < 1900 \ + && !defined(__cplusplus) && !defined(inline)) +# define inline __inline +# define PYTHONCAPI_COMPAT_MSC_INLINE + // These two macros are undefined at the end of this file +#endif + + +// Cast argument to PyObject* type. +#ifndef _PyObject_CAST +# define _PyObject_CAST(op) ((PyObject*)(op)) +#endif +#ifndef _PyObject_CAST_CONST +# define _PyObject_CAST_CONST(op) ((const PyObject*)(op)) +#endif + + +// bpo-42262 added Py_NewRef() to Python 3.10.0a3 +#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef) +static inline PyObject* _Py_NewRef(PyObject *obj) +{ + Py_INCREF(obj); + return obj; +} +#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) +#endif + + +// bpo-42262 added Py_XNewRef() to Python 3.10.0a3 +#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef) +static inline PyObject* _Py_XNewRef(PyObject *obj) +{ + Py_XINCREF(obj); + return obj; +} +#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj)) +#endif + + +// See https://bugs.python.org/issue42522 +#if !defined(_Py_StealRef) +static inline PyObject* __Py_StealRef(PyObject *obj) +{ + Py_DECREF(obj); + return obj; +} +#define _Py_StealRef(obj) __Py_StealRef(_PyObject_CAST(obj)) +#endif + + +// See https://bugs.python.org/issue42522 +#if !defined(_Py_XStealRef) +static inline PyObject* __Py_XStealRef(PyObject *obj) +{ + Py_XDECREF(obj); + return obj; +} +#define _Py_XStealRef(obj) __Py_XStealRef(_PyObject_CAST(obj)) +#endif + + +// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4 +#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT) +static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) +{ + ob->ob_refcnt = refcnt; +} +#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) +#endif + + +// Py_SETREF() and Py_XSETREF() were added to Python 3.5.2. +// It is excluded from the limited C API. +#if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && !defined(Py_LIMITED_API) +#define Py_SETREF(op, op2) \ + do { \ + PyObject *_py_tmp = _PyObject_CAST(op); \ + (op) = (op2); \ + Py_DECREF(_py_tmp); \ + } while (0) + +#define Py_XSETREF(op, op2) \ + do { \ + PyObject *_py_tmp = _PyObject_CAST(op); \ + (op) = (op2); \ + Py_XDECREF(_py_tmp); \ + } while (0) +#endif + + +// bpo-43753 added Py_Is(), Py_IsNone(), Py_IsTrue() and Py_IsFalse() +// to Python 3.10.0b1. +#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_Is) +# define Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsNone) +# define Py_IsNone(x) Py_Is(x, Py_None) +#endif +#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsTrue) +# define Py_IsTrue(x) Py_Is(x, Py_True) +#endif +#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsFalse) +# define Py_IsFalse(x) Py_Is(x, Py_False) +#endif + + +// bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4 +#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE) +static inline void +_Py_SET_TYPE(PyObject *ob, PyTypeObject *type) +{ + ob->ob_type = type; +} +#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) +#endif + + +// bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4 +#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) +static inline void +_Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) +{ + ob->ob_size = size; +} +#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size) +#endif + + +// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 +#if PY_VERSION_HEX < 0x030900B1 +static inline PyCodeObject* +PyFrame_GetCode(PyFrameObject *frame) +{ + assert(frame != NULL); + assert(frame->f_code != NULL); + return (PyCodeObject*)Py_NewRef(frame->f_code); +} +#endif + +static inline PyCodeObject* +_PyFrame_GetCodeBorrow(PyFrameObject *frame) +{ + return (PyCodeObject *)_Py_StealRef(PyFrame_GetCode(frame)); +} + + +// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 +#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) +static inline PyFrameObject* +PyFrame_GetBack(PyFrameObject *frame) +{ + assert(frame != NULL); + return (PyFrameObject*)Py_XNewRef(frame->f_back); +} +#endif + +#if !defined(PYPY_VERSION) +static inline PyFrameObject* +_PyFrame_GetBackBorrow(PyFrameObject *frame) +{ + return (PyFrameObject *)_Py_XStealRef(PyFrame_GetBack(frame)); +} +#endif + + +// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5 +#if PY_VERSION_HEX < 0x030900A5 +static inline PyInterpreterState * +PyThreadState_GetInterpreter(PyThreadState *tstate) +{ + assert(tstate != NULL); + return tstate->interp; +} +#endif + + +// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1 +#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) +static inline PyFrameObject* +PyThreadState_GetFrame(PyThreadState *tstate) +{ + assert(tstate != NULL); + return (PyFrameObject *)Py_XNewRef(tstate->frame); +} +#endif + +#if !defined(PYPY_VERSION) +static inline PyFrameObject* +_PyThreadState_GetFrameBorrow(PyThreadState *tstate) +{ + return (PyFrameObject *)_Py_XStealRef(PyThreadState_GetFrame(tstate)); +} +#endif + + +// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5 +#if PY_VERSION_HEX < 0x030900A5 +static inline PyInterpreterState * +PyInterpreterState_Get(void) +{ + PyThreadState *tstate; + PyInterpreterState *interp; + + tstate = PyThreadState_GET(); + if (tstate == NULL) { + Py_FatalError("GIL released (tstate is NULL)"); + } + interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("no current interpreter"); + } + return interp; +} +#endif + + +// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6 +#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) +static inline uint64_t +PyThreadState_GetID(PyThreadState *tstate) +{ + assert(tstate != NULL); + return tstate->id; +} +#endif + + +// bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1 +#if PY_VERSION_HEX < 0x030900A1 +static inline PyObject* +PyObject_CallNoArgs(PyObject *func) +{ + return PyObject_CallFunctionObjArgs(func, NULL); +} +#endif + + +// bpo-39245 made PyObject_CallOneArg() public (previously called +// _PyObject_CallOneArg) in Python 3.9.0a4 +#if PY_VERSION_HEX < 0x030900A4 +static inline PyObject* +PyObject_CallOneArg(PyObject *func, PyObject *arg) +{ + return PyObject_CallFunctionObjArgs(func, arg, NULL); +} +#endif + + +// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3 +#if PY_VERSION_HEX < 0x030A00A3 +static inline int +PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value) +{ + Py_XINCREF(value); + int res = PyModule_AddObject(module, name, value); + if (res < 0) { + Py_XDECREF(value); + } + return res; +} +#endif + + +// bpo-40024 added PyModule_AddType() to Python 3.9.0a5 +#if PY_VERSION_HEX < 0x030900A5 +static inline int +PyModule_AddType(PyObject *module, PyTypeObject *type) +{ + const char *name, *dot; + + if (PyType_Ready(type) < 0) { + return -1; + } + + // inline _PyType_Name() + name = type->tp_name; + assert(name != NULL); + dot = strrchr(name, '.'); + if (dot != NULL) { + name = dot + 1; + } + + return PyModule_AddObjectRef(module, name, (PyObject *)type); +} +#endif + + +// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6. +// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2. +#if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) +static inline int +PyObject_GC_IsTracked(PyObject* obj) +{ + return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)); +} +#endif + +// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6. +// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final. +#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION) +static inline int +PyObject_GC_IsFinalized(PyObject *obj) +{ + return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1)); +} +#endif + + +// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4 +#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE) +static inline int +_Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { + return ob->ob_type == type; +} +#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type) +#endif + + +// Py_UNUSED() was added to Python 3.4.0b2. +#if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED) +# if defined(__GNUC__) || defined(__clang__) +# define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) +# else +# define Py_UNUSED(name) _unused_ ## name +# endif +#endif + + +#ifdef PYTHONCAPI_COMPAT_MSC_INLINE +# undef inline +# undef PYTHONCAPI_COMPAT_MSC_INLINE +#endif + +#ifdef __cplusplus +} +#endif +#endif // PYTHONCAPI_COMPAT