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: sudo apt install libbluetooth-dev
- run: mkdir build && pushd build && cmake -DGATTLIB_FORCE_DBUS=TRUE -DCMAKE_BUILD_TYPE=Release .. && make - 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: generate-python-binary-packages:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

View File

@ -6,6 +6,7 @@
#include "gattlib_internal.h" #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) { 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; struct gattlib_python_args* args = user_data;
PyObject *result; PyObject *result;
@ -43,6 +44,7 @@ void gattlib_connected_device_python_callback(void *adapter, const char *dst, ga
ON_ERROR: ON_ERROR:
PyGILState_Release(d_gstate); PyGILState_Release(d_gstate);
} }
#endif
static gpointer _gattlib_connected_device_thread(gpointer data) { static gpointer _gattlib_connected_device_thread(gpointer data) {
gatt_connection_t* connection = 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) { void gattlib_on_connected_device(gatt_connection_t* connection) {
gattlib_handler_dispatch_to_thread( gattlib_handler_dispatch_to_thread(
&connection->on_connection, &connection->on_connection,
#if defined(WITH_PYTHON)
gattlib_connected_device_python_callback /* python_callback */, 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 /* thread_func */,
"gattlib_connected_device" /* thread_name */, "gattlib_connected_device" /* thread_name */,
_connected_device_thread_args_allocator /* thread_args_allocator */, _connected_device_thread_args_allocator /* thread_args_allocator */,

View File

@ -6,6 +6,7 @@
#include "gattlib_internal.h" #include "gattlib_internal.h"
#if defined(WITH_PYTHON)
void gattlib_disconnected_device_python_callback(gatt_connection_t* connection, void *user_data) { void gattlib_disconnected_device_python_callback(gatt_connection_t* connection, void *user_data) {
struct gattlib_python_args* args = user_data; struct gattlib_python_args* args = user_data;
PyObject *result; PyObject *result;
@ -27,6 +28,7 @@ void gattlib_disconnected_device_python_callback(gatt_connection_t* connection,
PyGILState_Release(d_gstate); PyGILState_Release(d_gstate);
} }
#endif
void gattlib_on_disconnected_device(gatt_connection_t* connection) { void gattlib_on_disconnected_device(gatt_connection_t* connection) {
if (connection->on_disconnection.callback.callback == NULL) { if (connection->on_disconnection.callback.callback == NULL) {
@ -35,11 +37,13 @@ void gattlib_on_disconnected_device(gatt_connection_t* connection) {
return; 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 // 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. // once we are done with the handler.
if ((gattlib_disconnection_handler_t)connection->on_disconnection.callback.callback == gattlib_disconnected_device_python_callback) { 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; 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. // 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); connection->on_disconnection.callback.disconnection_handler(connection, connection->on_disconnection.user_data);

View File

@ -6,6 +6,7 @@
#include "gattlib_internal.h" #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) { void gattlib_discovered_device_python_callback(void *adapter, const char* addr, const char* name, void *user_data) {
struct gattlib_python_args* args = user_data; struct gattlib_python_args* args = user_data;
PyObject *result; PyObject *result;
@ -42,6 +43,7 @@ void gattlib_discovered_device_python_callback(void *adapter, const char* addr,
ON_ERROR: ON_ERROR:
PyGILState_Release(d_gstate); PyGILState_Release(d_gstate);
} }
#endif
struct gattlib_discovered_device_thread_args { struct gattlib_discovered_device_thread_args {
struct gattlib_adapter* gattlib_adapter; 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) { void gattlib_on_discovered_device(struct gattlib_adapter* gattlib_adapter, OrgBluezDevice1* device1) {
gattlib_handler_dispatch_to_thread( gattlib_handler_dispatch_to_thread(
&gattlib_adapter->ble_scan.discovered_device_callback, &gattlib_adapter->ble_scan.discovered_device_callback,
#if defined(WITH_PYTHON)
gattlib_discovered_device_python_callback /* python_callback */, 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 /* thread_func */,
"gattlib_discovered_device" /* thread_name */, "gattlib_discovered_device" /* thread_name */,
_discovered_device_thread_args_allocator /* thread_args_allocator */, _discovered_device_thread_args_allocator /* thread_args_allocator */,

View File

@ -6,6 +6,7 @@
#include "gattlib_internal.h" #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) { 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; struct gattlib_python_args* args = user_data;
char uuid_str[MAX_LEN_UUID_STR + 1]; 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); PyGILState_Release(d_gstate);
} }
#endif
struct gattlib_notification_device_thread_args { struct gattlib_notification_device_thread_args {
gatt_connection_t* connection; 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 // Reset callback to stop calling it after we stopped
handler->callback.callback = NULL; handler->callback.callback = NULL;
#if defined(WITH_PYTHON)
if (handler->python_args != NULL) { if (handler->python_args != NULL) {
struct gattlib_python_args* args = handler->python_args; struct gattlib_python_args* args = handler->python_args;
Py_DECREF(args->callback); Py_DECREF(args->callback);
@ -155,6 +156,7 @@ void gattlib_handler_free(struct gattlib_handler* handler) {
free(handler->python_args); free(handler->python_args);
handler->python_args = NULL; handler->python_args = NULL;
} }
#endif
if (handler->thread_pool != NULL) { if (handler->thread_pool != NULL) {
g_thread_pool_free(handler->thread_pool, FALSE /* immediate */, TRUE /* wait */); 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; 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 // 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. // once we are done with the handler.
if (handler->callback.callback == python_callback) { if (handler->callback.callback == python_callback) {
handler->python_args = handler->user_data; handler->python_args = handler->user_data;
} }
#endif
// We create a thread to ensure the callback is not blocking the mainloop // We create a thread to ensure the callback is not blocking the mainloop
va_list args; va_list args;

View File

@ -16,10 +16,12 @@
#include "gattlib.h" #include "gattlib.h"
#if defined(WITH_PYTHON)
struct gattlib_python_args { struct gattlib_python_args {
PyObject* callback; PyObject* callback;
PyObject* args; PyObject* args;
}; };
#endif
struct gattlib_handler { struct gattlib_handler {
union { union {
@ -35,8 +37,10 @@ struct gattlib_handler {
GThread *thread; GThread *thread;
// Thread pool // Thread pool
GThreadPool *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 // In case of Python callback and argument, we keep track to free it when we stopped to discover BLE devices
void* python_args; void* python_args;
#endif
}; };
struct _gatt_connection_t { 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_disconnected_device.c
${CMAKE_CURRENT_LIST_DIR}/../common/gattlib_callback_discovered_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_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/logging_backend/${GATTLIB_LOG_BACKEND}/gattlib_logging.c
${CMAKE_CURRENT_LIST_DIR}/../common/mainloop/gattlib_glib_mainloop.c ${CMAKE_CURRENT_LIST_DIR}/../common/mainloop/gattlib_glib_mainloop.c
${CMAKE_CURRENT_BINARY_DIR}/org-bluez-adaptater1.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-gattdescriptor1.c
${CMAKE_CURRENT_BINARY_DIR}/org-bluez-gattservice1.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) if (BLUEZ_VERSION_MINOR GREATER 40)
list(APPEND gattlib_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org-bluez-battery1.c) list(APPEND gattlib_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org-bluez-battery1.c)
endif() endif()