diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 25ea5ae..1b00b84 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -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: diff --git a/common/gattlib_callback_connected_device.c b/common/gattlib_callback_connected_device.c index 282c9fe..a4982cc 100644 --- a/common/gattlib_callback_connected_device.c +++ b/common/gattlib_callback_connected_device.c @@ -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 */, diff --git a/common/gattlib_callback_disconnected_device.c b/common/gattlib_callback_disconnected_device.c index 7fb6b21..84acbce 100644 --- a/common/gattlib_callback_disconnected_device.c +++ b/common/gattlib_callback_disconnected_device.c @@ -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); diff --git a/common/gattlib_callback_discovered_device.c b/common/gattlib_callback_discovered_device.c index 4a13020..9306843 100644 --- a/common/gattlib_callback_discovered_device.c +++ b/common/gattlib_callback_discovered_device.c @@ -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 */, diff --git a/common/gattlib_callback_notification_device.c b/common/gattlib_callback_notification_device.c index 86e19fc..abe622d 100644 --- a/common/gattlib_callback_notification_device.c +++ b/common/gattlib_callback_notification_device.c @@ -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; diff --git a/common/gattlib_common.c b/common/gattlib_common.c index 4f626bf..f1f6e86 100644 --- a/common/gattlib_common.c +++ b/common/gattlib_common.c @@ -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; diff --git a/common/gattlib_internal_defs.h b/common/gattlib_internal_defs.h index e11eb52..148542b 100644 --- a/common/gattlib_internal_defs.h +++ b/common/gattlib_internal_defs.h @@ -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 { diff --git a/dbus/CMakeLists.txt b/dbus/CMakeLists.txt index 1df82af..0aa2106 100644 --- a/dbus/CMakeLists.txt +++ b/dbus/CMakeLists.txt @@ -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()