Ensure gattlib can be built without Python support

pull/273/head
Olivier Martin 2024-03-25 12:19:52 +01:00 committed by Olivier Martin
parent 2a46780e96
commit 6cea2d37db
8 changed files with 37 additions and 1 deletions

View File

@ -22,6 +22,13 @@ jobs:
- run: sudo apt install libbluetooth-dev
- run: mkdir build && pushd build && cmake -DGATTLIB_FORCE_DBUS=TRUE -DCMAKE_BUILD_TYPE=Release .. && make
build-release-without-python-support:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: sudo apt install libbluetooth-dev
- run: mkdir build && pushd build && cmake -DCMAKE_BUILD_TYPE=Release -DGATTLIB_PYTHON_INTERFACE=OFF .. && make
generate-python-binary-packages:
runs-on: ubuntu-latest
steps:

View File

@ -6,6 +6,7 @@
#include "gattlib_internal.h"
#if defined(WITH_PYTHON)
void gattlib_connected_device_python_callback(void *adapter, const char *dst, gatt_connection_t* connection, int error, void* user_data) {
struct gattlib_python_args* args = user_data;
PyObject *result;
@ -43,6 +44,7 @@ void gattlib_connected_device_python_callback(void *adapter, const char *dst, ga
ON_ERROR:
PyGILState_Release(d_gstate);
}
#endif
static gpointer _gattlib_connected_device_thread(gpointer data) {
gatt_connection_t* connection = data;
@ -63,7 +65,11 @@ static void* _connected_device_thread_args_allocator(va_list args) {
void gattlib_on_connected_device(gatt_connection_t* connection) {
gattlib_handler_dispatch_to_thread(
&connection->on_connection,
#if defined(WITH_PYTHON)
gattlib_connected_device_python_callback /* python_callback */,
#else
NULL, // No Python support. So we do not need to check the callback against Python callback
#endif
_gattlib_connected_device_thread /* thread_func */,
"gattlib_connected_device" /* thread_name */,
_connected_device_thread_args_allocator /* thread_args_allocator */,

View File

@ -6,6 +6,7 @@
#include "gattlib_internal.h"
#if defined(WITH_PYTHON)
void gattlib_disconnected_device_python_callback(gatt_connection_t* connection, void *user_data) {
struct gattlib_python_args* args = user_data;
PyObject *result;
@ -27,6 +28,7 @@ void gattlib_disconnected_device_python_callback(gatt_connection_t* connection,
PyGILState_Release(d_gstate);
}
#endif
void gattlib_on_disconnected_device(gatt_connection_t* connection) {
if (connection->on_disconnection.callback.callback == NULL) {
@ -35,11 +37,13 @@ void gattlib_on_disconnected_device(gatt_connection_t* connection) {
return;
}
#if defined(WITH_PYTHON)
// Check if we are using the Python callback, in case of Python argument we keep track of the argument to free them
// once we are done with the handler.
if ((gattlib_disconnection_handler_t)connection->on_disconnection.callback.callback == gattlib_disconnected_device_python_callback) {
connection->on_disconnection.python_args = connection->on_disconnection.user_data;
}
#endif
// For GATT disconnection we do not use thread to ensure the callback is synchronous.
connection->on_disconnection.callback.disconnection_handler(connection, connection->on_disconnection.user_data);

View File

@ -6,6 +6,7 @@
#include "gattlib_internal.h"
#if defined(WITH_PYTHON)
void gattlib_discovered_device_python_callback(void *adapter, const char* addr, const char* name, void *user_data) {
struct gattlib_python_args* args = user_data;
PyObject *result;
@ -42,6 +43,7 @@ void gattlib_discovered_device_python_callback(void *adapter, const char* addr,
ON_ERROR:
PyGILState_Release(d_gstate);
}
#endif
struct gattlib_discovered_device_thread_args {
struct gattlib_adapter* gattlib_adapter;
@ -87,7 +89,11 @@ static void* _discovered_device_thread_args_allocator(va_list args) {
void gattlib_on_discovered_device(struct gattlib_adapter* gattlib_adapter, OrgBluezDevice1* device1) {
gattlib_handler_dispatch_to_thread(
&gattlib_adapter->ble_scan.discovered_device_callback,
#if defined(WITH_PYTHON)
gattlib_discovered_device_python_callback /* python_callback */,
#else
NULL, // No Python support. So we do not need to check the callback against Python callback
#endif
_gattlib_discovered_device_thread /* thread_func */,
"gattlib_discovered_device" /* thread_name */,
_discovered_device_thread_args_allocator /* thread_args_allocator */,

View File

@ -6,6 +6,7 @@
#include "gattlib_internal.h"
#if defined(WITH_PYTHON)
void gattlib_notification_device_python_callback(const uuid_t* uuid, const uint8_t* data, size_t data_length, void* user_data) {
struct gattlib_python_args* args = user_data;
char uuid_str[MAX_LEN_UUID_STR + 1];
@ -42,6 +43,7 @@ void gattlib_notification_device_python_callback(const uuid_t* uuid, const uint8
PyGILState_Release(d_gstate);
}
#endif
struct gattlib_notification_device_thread_args {
gatt_connection_t* connection;

View File

@ -147,6 +147,7 @@ void gattlib_handler_free(struct gattlib_handler* handler) {
// Reset callback to stop calling it after we stopped
handler->callback.callback = NULL;
#if defined(WITH_PYTHON)
if (handler->python_args != NULL) {
struct gattlib_python_args* args = handler->python_args;
Py_DECREF(args->callback);
@ -155,6 +156,7 @@ void gattlib_handler_free(struct gattlib_handler* handler) {
free(handler->python_args);
handler->python_args = NULL;
}
#endif
if (handler->thread_pool != NULL) {
g_thread_pool_free(handler->thread_pool, FALSE /* immediate */, TRUE /* wait */);
@ -175,11 +177,13 @@ void gattlib_handler_dispatch_to_thread(struct gattlib_handler* handler, void (*
return;
}
#if defined(WITH_PYTHON)
// Check if we are using the Python callback, in case of Python argument we keep track of the argument to free them
// once we are done with the handler.
if (handler->callback.callback == python_callback) {
handler->python_args = handler->user_data;
}
#endif
// We create a thread to ensure the callback is not blocking the mainloop
va_list args;

View File

@ -16,10 +16,12 @@
#include "gattlib.h"
#if defined(WITH_PYTHON)
struct gattlib_python_args {
PyObject* callback;
PyObject* args;
};
#endif
struct gattlib_handler {
union {
@ -35,8 +37,10 @@ struct gattlib_handler {
GThread *thread;
// Thread pool
GThreadPool *thread_pool;
#if defined(WITH_PYTHON)
// In case of Python callback and argument, we keep track to free it when we stopped to discover BLE devices
void* python_args;
#endif
};
struct _gatt_connection_t {

View File

@ -78,7 +78,6 @@ set(gattlib_SRCS gattlib.c
${CMAKE_CURRENT_LIST_DIR}/../common/gattlib_callback_disconnected_device.c
${CMAKE_CURRENT_LIST_DIR}/../common/gattlib_callback_discovered_device.c
${CMAKE_CURRENT_LIST_DIR}/../common/gattlib_callback_notification_device.c
${CMAKE_CURRENT_LIST_DIR}/../common/gattlib_callback_python.c
${CMAKE_CURRENT_LIST_DIR}/../common/logging_backend/${GATTLIB_LOG_BACKEND}/gattlib_logging.c
${CMAKE_CURRENT_LIST_DIR}/../common/mainloop/gattlib_glib_mainloop.c
${CMAKE_CURRENT_BINARY_DIR}/org-bluez-adaptater1.c
@ -87,6 +86,10 @@ set(gattlib_SRCS gattlib.c
${CMAKE_CURRENT_BINARY_DIR}/org-bluez-gattdescriptor1.c
${CMAKE_CURRENT_BINARY_DIR}/org-bluez-gattservice1.c)
if (GATTLIB_PYTHON_INTERFACE)
list(APPEND gattlib_SRCS ${CMAKE_CURRENT_LIST_DIR}/../common/gattlib_callback_python.c)
endif()
if (BLUEZ_VERSION_MINOR GREATER 40)
list(APPEND gattlib_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org-bluez-battery1.c)
endif()