diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index deab037321dd27..4e4e853ccdc69f 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -42,7 +42,7 @@ #include #include -#include "bluez/Helper.h" +#include "bluez/BluezEndpoint.h" using namespace ::nl; using namespace ::chip::Ble; diff --git a/src/platform/Linux/BLEManagerImpl.h b/src/platform/Linux/BLEManagerImpl.h index 23e182f2281b31..2cc764b742cf13 100644 --- a/src/platform/Linux/BLEManagerImpl.h +++ b/src/platform/Linux/BLEManagerImpl.h @@ -23,9 +23,12 @@ #pragma once +#include + #include #include +#include "bluez/BluezEndpoint.h" #include "bluez/ChipDeviceScanner.h" #include "bluez/Types.h" diff --git a/src/platform/Linux/BUILD.gn b/src/platform/Linux/BUILD.gn index 56324ff5c4a494..9d10caf9b381d1 100644 --- a/src/platform/Linux/BUILD.gn +++ b/src/platform/Linux/BUILD.gn @@ -88,10 +88,12 @@ static_library("Linux") { "BlePlatformConfig.h", "bluez/AdapterIterator.cpp", "bluez/AdapterIterator.h", + "bluez/BluezConnection.cpp", + "bluez/BluezConnection.h", + "bluez/BluezEndpoint.cpp", + "bluez/BluezEndpoint.h", "bluez/ChipDeviceScanner.cpp", "bluez/ChipDeviceScanner.h", - "bluez/Helper.cpp", - "bluez/Helper.h", "bluez/Types.h", ] } diff --git a/src/platform/Linux/bluez/AdapterIterator.h b/src/platform/Linux/bluez/AdapterIterator.h index 2908c7a28e51d3..85697b5d544c9a 100644 --- a/src/platform/Linux/bluez/AdapterIterator.h +++ b/src/platform/Linux/bluez/AdapterIterator.h @@ -21,7 +21,8 @@ #include -#include "lib/core/CHIPError.h" +#include +#include #include "Types.h" diff --git a/src/platform/Linux/bluez/BluezConnection.cpp b/src/platform/Linux/bluez/BluezConnection.cpp new file mode 100644 index 00000000000000..142df8f1317202 --- /dev/null +++ b/src/platform/Linux/bluez/BluezConnection.cpp @@ -0,0 +1,241 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BluezConnection.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "BluezEndpoint.h" +#include "Types.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +static CHIP_ERROR BluezC2Indicate(BluezConnection::ConnectionDataBundle * closure) +{ + BluezConnection * conn = nullptr; + GAutoPtr error; + GIOStatus status; + const char * buf; + size_t len, written; + + VerifyOrExit(closure != nullptr, ChipLogError(DeviceLayer, "ConnectionDataBundle is NULL in %s", __func__)); + + conn = closure->mpConn; + VerifyOrExit(conn != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); + VerifyOrExit(conn->mpC2 != nullptr, ChipLogError(DeviceLayer, "FAIL: C2 Indicate: %s", "NULL C2")); + + if (bluez_gatt_characteristic1_get_notify_acquired(conn->mpC2) == TRUE) + { + buf = (char *) g_variant_get_fixed_array(closure->mpVal, &len, sizeof(uint8_t)); + VerifyOrExit(len <= static_cast(std::numeric_limits::max()), + ChipLogError(DeviceLayer, "FAIL: buffer too large in %s", __func__)); + status = g_io_channel_write_chars(conn->mC2Channel.mpChannel, buf, static_cast(len), &written, + &MakeUniquePointerReceiver(error).Get()); + g_variant_unref(closure->mpVal); + closure->mpVal = nullptr; + + VerifyOrExit(status == G_IO_STATUS_NORMAL, ChipLogError(DeviceLayer, "FAIL: C2 Indicate: %s", error->message)); + } + else + { + bluez_gatt_characteristic1_set_value(conn->mpC2, closure->mpVal); + closure->mpVal = nullptr; + } + +exit: + if (closure != nullptr) + { + g_free(closure); + } + + return CHIP_NO_ERROR; +} + +static BluezConnection::ConnectionDataBundle * MakeConnectionDataBundle(BLE_CONNECTION_OBJECT apConn, + const chip::System::PacketBufferHandle & apBuf) +{ + auto * bundle = g_new(BluezConnection::ConnectionDataBundle, 1); + bundle->mpConn = static_cast(apConn); + bundle->mpVal = + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, apBuf->Start(), apBuf->DataLength() * sizeof(uint8_t), sizeof(uint8_t)); + return bundle; +} + +CHIP_ERROR SendBluezIndication(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf) +{ + VerifyOrReturnError(!apBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(DeviceLayer, "apBuf is NULL in %s", __func__)); + return PlatformMgrImpl().GLibMatterContextInvokeSync(BluezC2Indicate, MakeConnectionDataBundle(apConn, apBuf)); +} + +static CHIP_ERROR BluezDisconnect(BluezConnection * conn) +{ + GAutoPtr error; + gboolean success; + + VerifyOrExit(conn != nullptr, ChipLogError(DeviceLayer, "conn is NULL in %s", __func__)); + VerifyOrExit(conn->mpDevice != nullptr, ChipLogError(DeviceLayer, "FAIL: Disconnect: %s", "NULL Device")); + + ChipLogDetail(DeviceLayer, "%s peer=%s", __func__, bluez_device1_get_address(conn->mpDevice)); + + success = bluez_device1_call_disconnect_sync(conn->mpDevice, nullptr, &MakeUniquePointerReceiver(error).Get()); + VerifyOrExit(success == TRUE, ChipLogError(DeviceLayer, "FAIL: Disconnect: %s", error->message)); + +exit: + return CHIP_NO_ERROR; +} + +CHIP_ERROR CloseBluezConnection(BLE_CONNECTION_OBJECT apConn) +{ + return PlatformMgrImpl().GLibMatterContextInvokeSync(BluezDisconnect, static_cast(apConn)); +} + +// BluezSendWriteRequest callbacks + +static void SendWriteRequestDone(GObject * aObject, GAsyncResult * aResult, gpointer apConnection) +{ + BluezGattCharacteristic1 * c1 = BLUEZ_GATT_CHARACTERISTIC1(aObject); + GAutoPtr error; + gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c1, aResult, &MakeUniquePointerReceiver(error).Get()); + + VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: BluezSendWriteRequest : %s", error->message)); + BLEManagerImpl::HandleWriteComplete(static_cast(apConnection)); +} + +static CHIP_ERROR SendWriteRequestImpl(BluezConnection::ConnectionDataBundle * data) +{ + GVariant * options = nullptr; + GVariantBuilder optionsBuilder; + + VerifyOrExit(data != nullptr, ChipLogError(DeviceLayer, "ConnectionDataBundle is NULL in %s", __func__)); + VerifyOrExit(data->mpConn != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); + VerifyOrExit(data->mpConn->mpC1 != nullptr, ChipLogError(DeviceLayer, "C1 is NULL in %s", __func__)); + + g_variant_builder_init(&optionsBuilder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add(&optionsBuilder, "{sv}", "type", g_variant_new_string("request")); + options = g_variant_builder_end(&optionsBuilder); + + bluez_gatt_characteristic1_call_write_value(data->mpConn->mpC1, data->mpVal, options, nullptr, SendWriteRequestDone, + data->mpConn); + +exit: + g_free(data); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BluezSendWriteRequest(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf) +{ + VerifyOrReturnError(!apBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(DeviceLayer, "apBuf is NULL in %s", __func__)); + return PlatformMgrImpl().GLibMatterContextInvokeSync(SendWriteRequestImpl, MakeConnectionDataBundle(apConn, apBuf)); +} + +// BluezSubscribeCharacteristic callbacks + +static void OnCharacteristicChanged(GDBusProxy * aInterface, GVariant * aChangedProperties, const gchar * const * aInvalidatedProps, + gpointer apConnection) +{ + BLE_CONNECTION_OBJECT connection = static_cast(apConnection); + GAutoPtr dataValue(g_variant_lookup_value(aChangedProperties, "Value", G_VARIANT_TYPE_BYTESTRING)); + VerifyOrReturn(dataValue != nullptr); + + size_t bufferLen; + auto buffer = g_variant_get_fixed_array(dataValue.get(), &bufferLen, sizeof(uint8_t)); + VerifyOrReturn(buffer != nullptr, ChipLogError(DeviceLayer, "Characteristic value has unexpected type")); + + BLEManagerImpl::HandleTXCharChanged(connection, static_cast(buffer), bufferLen); +} + +static void SubscribeCharacteristicDone(GObject * aObject, GAsyncResult * aResult, gpointer apConnection) +{ + BluezGattCharacteristic1 * c2 = BLUEZ_GATT_CHARACTERISTIC1(aObject); + GAutoPtr error; + gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c2, aResult, &MakeUniquePointerReceiver(error).Get()); + + VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: BluezSubscribeCharacteristic : %s", error->message)); + + BLEManagerImpl::HandleSubscribeOpComplete(static_cast(apConnection), true); +} + +static CHIP_ERROR SubscribeCharacteristicImpl(BluezConnection * connection) +{ + BluezGattCharacteristic1 * c2 = nullptr; + VerifyOrExit(connection != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); + VerifyOrExit(connection->mpC2 != nullptr, ChipLogError(DeviceLayer, "C2 is NULL in %s", __func__)); + c2 = BLUEZ_GATT_CHARACTERISTIC1(connection->mpC2); + + // Get notifications on the TX characteristic change (e.g. indication is received) + g_signal_connect(c2, "g-properties-changed", G_CALLBACK(OnCharacteristicChanged), connection); + bluez_gatt_characteristic1_call_start_notify(connection->mpC2, nullptr, SubscribeCharacteristicDone, connection); + +exit: + return CHIP_NO_ERROR; +} + +CHIP_ERROR BluezSubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn) +{ + return PlatformMgrImpl().GLibMatterContextInvokeSync(SubscribeCharacteristicImpl, static_cast(apConn)); +} + +// BluezUnsubscribeCharacteristic callbacks + +static void UnsubscribeCharacteristicDone(GObject * aObject, GAsyncResult * aResult, gpointer apConnection) +{ + BluezGattCharacteristic1 * c2 = BLUEZ_GATT_CHARACTERISTIC1(aObject); + GAutoPtr error; + gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c2, aResult, &MakeUniquePointerReceiver(error).Get()); + + VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: BluezUnsubscribeCharacteristic : %s", error->message)); + + // Stop listening to the TX characteristic changes + g_signal_handlers_disconnect_by_data(c2, apConnection); + BLEManagerImpl::HandleSubscribeOpComplete(static_cast(apConnection), false); +} + +static CHIP_ERROR UnsubscribeCharacteristicImpl(BluezConnection * connection) +{ + VerifyOrExit(connection != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); + VerifyOrExit(connection->mpC2 != nullptr, ChipLogError(DeviceLayer, "C2 is NULL in %s", __func__)); + + bluez_gatt_characteristic1_call_stop_notify(connection->mpC2, nullptr, UnsubscribeCharacteristicDone, connection); + +exit: + return CHIP_NO_ERROR; +} + +CHIP_ERROR BluezUnsubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn) +{ + return PlatformMgrImpl().GLibMatterContextInvokeSync(UnsubscribeCharacteristicImpl, static_cast(apConn)); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Linux/bluez/BluezConnection.h b/src/platform/Linux/bluez/BluezConnection.h new file mode 100644 index 00000000000000..7375fbe79d915d --- /dev/null +++ b/src/platform/Linux/bluez/BluezConnection.h @@ -0,0 +1,79 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +struct BluezEndpoint; + +struct BluezConnection +{ + + struct IOChannel + { + GIOChannel * mpChannel; + GSource * mWatchSource; + }; + + struct ConnectionDataBundle + { + BluezConnection * mpConn; + GVariant * mpVal; + }; + + char * mpPeerAddress; + BluezDevice1 * mpDevice; + BluezGattService1 * mpService; + BluezGattCharacteristic1 * mpC1; + BluezGattCharacteristic1 * mpC2; + // additional data characteristics + BluezGattCharacteristic1 * mpC3; + + bool mIsNotify; + uint16_t mMtu; + struct IOChannel mC1Channel; + struct IOChannel mC2Channel; + BluezEndpoint * mpEndpoint; +}; + +CHIP_ERROR SendBluezIndication(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf); +CHIP_ERROR CloseBluezConnection(BLE_CONNECTION_OBJECT apConn); + +/// Write to the CHIP RX characteristic on the remote peripheral device +CHIP_ERROR BluezSendWriteRequest(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf); +/// Subscribe to the CHIP TX characteristic on the remote peripheral device +CHIP_ERROR BluezSubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn); +/// Unsubscribe from the CHIP TX characteristic on the remote peripheral device +CHIP_ERROR BluezUnsubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn); + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Linux/bluez/Helper.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp similarity index 86% rename from src/platform/Linux/bluez/Helper.cpp rename to src/platform/Linux/bluez/BluezEndpoint.cpp index 47bfb51452b123..066a5730042eea 100644 --- a/src/platform/Linux/bluez/Helper.cpp +++ b/src/platform/Linux/bluez/BluezEndpoint.cpp @@ -43,43 +43,33 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/** - * @file - * Provides Bluez dbus implementation for BLE - */ +#include "BluezEndpoint.h" #include +#include #include -#include -#include -#include +#include +#include #include -#include #include #include +#include #include -#include -#include #include #include -#include #include -#include -#include +#include +#include +#include #include -#include -#include +#include +#include #include -#include - -#include "BluezObjectIterator.h" -#include "Helper.h" +#include -using namespace ::nl; -using namespace chip::Protocols; -using chip::Platform::CopyString; +#include "BluezConnection.h" namespace chip { namespace DeviceLayer { @@ -1214,84 +1204,6 @@ static CHIP_ERROR StartupEndpointBindings(BluezEndpoint * endpoint) return CHIP_NO_ERROR; } -static CHIP_ERROR BluezC2Indicate(ConnectionDataBundle * closure) -{ - BluezConnection * conn = nullptr; - GAutoPtr error; - GIOStatus status; - const char * buf; - size_t len, written; - - VerifyOrExit(closure != nullptr, ChipLogError(DeviceLayer, "ConnectionDataBundle is NULL in %s", __func__)); - - conn = closure->mpConn; - VerifyOrExit(conn != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); - VerifyOrExit(conn->mpC2 != nullptr, ChipLogError(DeviceLayer, "FAIL: C2 Indicate: %s", "NULL C2")); - - if (bluez_gatt_characteristic1_get_notify_acquired(conn->mpC2) == TRUE) - { - buf = (char *) g_variant_get_fixed_array(closure->mpVal, &len, sizeof(uint8_t)); - VerifyOrExit(len <= static_cast(std::numeric_limits::max()), - ChipLogError(DeviceLayer, "FAIL: buffer too large in %s", __func__)); - status = g_io_channel_write_chars(conn->mC2Channel.mpChannel, buf, static_cast(len), &written, - &MakeUniquePointerReceiver(error).Get()); - g_variant_unref(closure->mpVal); - closure->mpVal = nullptr; - - VerifyOrExit(status == G_IO_STATUS_NORMAL, ChipLogError(DeviceLayer, "FAIL: C2 Indicate: %s", error->message)); - } - else - { - bluez_gatt_characteristic1_set_value(conn->mpC2, closure->mpVal); - closure->mpVal = nullptr; - } - -exit: - if (closure != nullptr) - { - g_free(closure); - } - - return CHIP_NO_ERROR; -} - -static ConnectionDataBundle * MakeConnectionDataBundle(BLE_CONNECTION_OBJECT apConn, const chip::System::PacketBufferHandle & apBuf) -{ - ConnectionDataBundle * bundle = g_new(ConnectionDataBundle, 1); - bundle->mpConn = static_cast(apConn); - bundle->mpVal = - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, apBuf->Start(), apBuf->DataLength() * sizeof(uint8_t), sizeof(uint8_t)); - return bundle; -} - -CHIP_ERROR SendBluezIndication(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf) -{ - VerifyOrReturnError(!apBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(DeviceLayer, "apBuf is NULL in %s", __func__)); - return PlatformMgrImpl().GLibMatterContextInvokeSync(BluezC2Indicate, MakeConnectionDataBundle(apConn, apBuf)); -} - -static CHIP_ERROR BluezDisconnect(BluezConnection * conn) -{ - GAutoPtr error; - gboolean success; - - VerifyOrExit(conn != nullptr, ChipLogError(DeviceLayer, "conn is NULL in %s", __func__)); - VerifyOrExit(conn->mpDevice != nullptr, ChipLogError(DeviceLayer, "FAIL: Disconnect: %s", "NULL Device")); - - ChipLogDetail(DeviceLayer, "%s peer=%s", __func__, bluez_device1_get_address(conn->mpDevice)); - - success = bluez_device1_call_disconnect_sync(conn->mpDevice, nullptr, &MakeUniquePointerReceiver(error).Get()); - VerifyOrExit(success == TRUE, ChipLogError(DeviceLayer, "FAIL: Disconnect: %s", error->message)); - -exit: - return CHIP_NO_ERROR; -} - -CHIP_ERROR CloseBluezConnection(BLE_CONNECTION_OBJECT apConn) -{ - return PlatformMgrImpl().GLibMatterContextInvokeSync(BluezDisconnect, static_cast(apConn)); -} - CHIP_ERROR StartBluezAdv(BluezEndpoint * apEndpoint) { CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(BluezAdvStart, apEndpoint); @@ -1402,123 +1314,6 @@ CHIP_ERROR ShutdownBluezBleLayer(BluezEndpoint * apEndpoint) return CHIP_NO_ERROR; } -// BluezSendWriteRequest callbacks - -static void SendWriteRequestDone(GObject * aObject, GAsyncResult * aResult, gpointer apConnection) -{ - BluezGattCharacteristic1 * c1 = BLUEZ_GATT_CHARACTERISTIC1(aObject); - GAutoPtr error; - gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c1, aResult, &MakeUniquePointerReceiver(error).Get()); - - VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: BluezSendWriteRequest : %s", error->message)); - BLEManagerImpl::HandleWriteComplete(static_cast(apConnection)); -} - -static CHIP_ERROR SendWriteRequestImpl(ConnectionDataBundle * data) -{ - GVariant * options = nullptr; - GVariantBuilder optionsBuilder; - - VerifyOrExit(data != nullptr, ChipLogError(DeviceLayer, "ConnectionDataBundle is NULL in %s", __func__)); - VerifyOrExit(data->mpConn != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); - VerifyOrExit(data->mpConn->mpC1 != nullptr, ChipLogError(DeviceLayer, "C1 is NULL in %s", __func__)); - - g_variant_builder_init(&optionsBuilder, G_VARIANT_TYPE_ARRAY); - g_variant_builder_add(&optionsBuilder, "{sv}", "type", g_variant_new_string("request")); - options = g_variant_builder_end(&optionsBuilder); - - bluez_gatt_characteristic1_call_write_value(data->mpConn->mpC1, data->mpVal, options, nullptr, SendWriteRequestDone, - data->mpConn); - -exit: - g_free(data); - return CHIP_NO_ERROR; -} - -CHIP_ERROR BluezSendWriteRequest(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf) -{ - VerifyOrReturnError(!apBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(DeviceLayer, "apBuf is NULL in %s", __func__)); - return PlatformMgrImpl().GLibMatterContextInvokeSync(SendWriteRequestImpl, MakeConnectionDataBundle(apConn, apBuf)); -} - -// BluezSubscribeCharacteristic callbacks - -static void OnCharacteristicChanged(GDBusProxy * aInterface, GVariant * aChangedProperties, const gchar * const * aInvalidatedProps, - gpointer apConnection) -{ - BLE_CONNECTION_OBJECT connection = static_cast(apConnection); - GAutoPtr dataValue(g_variant_lookup_value(aChangedProperties, "Value", G_VARIANT_TYPE_BYTESTRING)); - VerifyOrReturn(dataValue != nullptr); - - size_t bufferLen; - auto buffer = g_variant_get_fixed_array(dataValue.get(), &bufferLen, sizeof(uint8_t)); - VerifyOrReturn(buffer != nullptr, ChipLogError(DeviceLayer, "Characteristic value has unexpected type")); - - BLEManagerImpl::HandleTXCharChanged(connection, static_cast(buffer), bufferLen); -} - -static void SubscribeCharacteristicDone(GObject * aObject, GAsyncResult * aResult, gpointer apConnection) -{ - BluezGattCharacteristic1 * c2 = BLUEZ_GATT_CHARACTERISTIC1(aObject); - GAutoPtr error; - gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c2, aResult, &MakeUniquePointerReceiver(error).Get()); - - VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: BluezSubscribeCharacteristic : %s", error->message)); - - BLEManagerImpl::HandleSubscribeOpComplete(static_cast(apConnection), true); -} - -static CHIP_ERROR SubscribeCharacteristicImpl(BluezConnection * connection) -{ - BluezGattCharacteristic1 * c2 = nullptr; - VerifyOrExit(connection != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); - VerifyOrExit(connection->mpC2 != nullptr, ChipLogError(DeviceLayer, "C2 is NULL in %s", __func__)); - c2 = BLUEZ_GATT_CHARACTERISTIC1(connection->mpC2); - - // Get notifications on the TX characteristic change (e.g. indication is received) - g_signal_connect(c2, "g-properties-changed", G_CALLBACK(OnCharacteristicChanged), connection); - bluez_gatt_characteristic1_call_start_notify(connection->mpC2, nullptr, SubscribeCharacteristicDone, connection); - -exit: - return CHIP_NO_ERROR; -} - -CHIP_ERROR BluezSubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn) -{ - return PlatformMgrImpl().GLibMatterContextInvokeSync(SubscribeCharacteristicImpl, static_cast(apConn)); -} - -// BluezUnsubscribeCharacteristic callbacks - -static void UnsubscribeCharacteristicDone(GObject * aObject, GAsyncResult * aResult, gpointer apConnection) -{ - BluezGattCharacteristic1 * c2 = BLUEZ_GATT_CHARACTERISTIC1(aObject); - GAutoPtr error; - gboolean success = bluez_gatt_characteristic1_call_write_value_finish(c2, aResult, &MakeUniquePointerReceiver(error).Get()); - - VerifyOrReturn(success == TRUE, ChipLogError(DeviceLayer, "FAIL: BluezUnsubscribeCharacteristic : %s", error->message)); - - // Stop listening to the TX characteristic changes - g_signal_handlers_disconnect_by_data(c2, apConnection); - BLEManagerImpl::HandleSubscribeOpComplete(static_cast(apConnection), false); -} - -static CHIP_ERROR UnsubscribeCharacteristicImpl(BluezConnection * connection) -{ - VerifyOrExit(connection != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); - VerifyOrExit(connection->mpC2 != nullptr, ChipLogError(DeviceLayer, "C2 is NULL in %s", __func__)); - - bluez_gatt_characteristic1_call_stop_notify(connection->mpC2, nullptr, UnsubscribeCharacteristicDone, connection); - -exit: - return CHIP_NO_ERROR; -} - -CHIP_ERROR BluezUnsubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn) -{ - return PlatformMgrImpl().GLibMatterContextInvokeSync(UnsubscribeCharacteristicImpl, static_cast(apConn)); -} - // ConnectDevice callbacks struct ConnectParams diff --git a/src/platform/Linux/bluez/Helper.h b/src/platform/Linux/bluez/BluezEndpoint.h similarity index 69% rename from src/platform/Linux/bluez/Helper.h rename to src/platform/Linux/bluez/BluezEndpoint.h index 687e9a166c4b72..1500b55a370215 100644 --- a/src/platform/Linux/bluez/Helper.h +++ b/src/platform/Linux/bluez/BluezEndpoint.h @@ -43,39 +43,72 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/** - * @file - * Provides Bluez dbus implementation for BLE - */ - #pragma once +#include + +#include +#include + +#include #include -#include +#include "BluezConnection.h" #include "Types.h" namespace chip { namespace DeviceLayer { namespace Internal { +struct BLEAdvConfig; + +struct BluezEndpoint +{ + char * mpOwningName; // Bus owning name + + // Adapter properties + char * mpAdapterName; + char * mpAdapterAddr; + + // Paths for objects published by this service + char * mpRootPath; + char * mpAdvPath; + char * mpServicePath; + + // Objects (interfaces) subscibed to by this service + GDBusObjectManager * mpObjMgr = nullptr; + BluezAdapter1 * mpAdapter = nullptr; + BluezDevice1 * mpDevice = nullptr; + + // Objects (interfaces) published by this service + GDBusObjectManagerServer * mpRoot; + BluezGattService1 * mpService; + BluezGattCharacteristic1 * mpC1; + BluezGattCharacteristic1 * mpC2; + // additional data characteristics + BluezGattCharacteristic1 * mpC3; + + // map device path to the connection + GHashTable * mpConnMap; + uint32_t mAdapterId; + bool mIsCentral; + char * mpAdvertisingUUID; + chip::Ble::ChipBLEDeviceIdentificationInfo mDeviceIdInfo; + ChipAdvType mType; ///< Advertisement type. + uint16_t mDuration; ///< Advertisement interval (in ms). + bool mIsAdvertising; + char * mpPeerDevicePath; + GCancellable * mpConnectCancellable = nullptr; +}; + CHIP_ERROR InitBluezBleLayer(bool aIsCentral, const char * apBleAddr, const BLEAdvConfig & aBleAdvConfig, BluezEndpoint *& apEndpoint); CHIP_ERROR ShutdownBluezBleLayer(BluezEndpoint * apEndpoint); -CHIP_ERROR SendBluezIndication(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf); -CHIP_ERROR CloseBluezConnection(BLE_CONNECTION_OBJECT apConn); CHIP_ERROR StartBluezAdv(BluezEndpoint * apEndpoint); CHIP_ERROR StopBluezAdv(BluezEndpoint * apEndpoint); CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint); CHIP_ERROR BluezAdvertisementSetup(BluezEndpoint * apEndpoint); -/// Write to the CHIP RX characteristic on the remote peripheral device -CHIP_ERROR BluezSendWriteRequest(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf); -/// Subscribe to the CHIP TX characteristic on the remote peripheral device -CHIP_ERROR BluezSubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn); -/// Unsubscribe from the CHIP TX characteristic on the remote peripheral device -CHIP_ERROR BluezUnsubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn); - CHIP_ERROR ConnectDevice(BluezDevice1 & aDevice, BluezEndpoint * apEndpoint); void CancelConnect(BluezEndpoint * apEndpoint); diff --git a/src/platform/Linux/bluez/Types.h b/src/platform/Linux/bluez/Types.h index df1485a5104989..d96d4b1524febb 100644 --- a/src/platform/Linux/bluez/Types.h +++ b/src/platform/Linux/bluez/Types.h @@ -49,13 +49,6 @@ #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE -#include -#include -#include - -#include -#include - namespace chip { namespace DeviceLayer { namespace Internal { @@ -109,88 +102,6 @@ enum ChipAdvType #define BLUEZ_ADV_FLAGS_LE_EDR_CONTROLLER (1 << 3) #define BLUEZ_ADV_FLAGS_LE_EDR_HOST (1 << 4) -enum BluezAddressType -{ - BLUEZ_ADDRESS_TYPE_PUBLIC = 0, ///< Bluetooth public device address. - BLUEZ_ADDRESS_TYPE_RANDOM_STATIC = 1, ///< Bluetooth random static address. - BLUEZ_ADDRESS_TYPE_RANDOM_PRIVATE_RESOLVABLE = 2, ///< Bluetooth random private resolvable address. - BLUEZ_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = 3, ///< Bluetooth random private non-resolvable address. -}; - -struct BluezAddress -{ - BluezAddressType mType; ///< Bluetooth device address type. - uint8_t mAddress[BLUEZ_ADDRESS_SIZE]; ///< A 48-bit address of Bluetooth device in LSB format. -}; - -struct IOChannel -{ - GIOChannel * mpChannel; - GSource * mWatchSource; -}; - -struct BluezEndpoint -{ - char * mpOwningName; // Bus owning name - - // Adapter properties - char * mpAdapterName; - char * mpAdapterAddr; - - // Paths for objects published by this service - char * mpRootPath; - char * mpAdvPath; - char * mpServicePath; - - // Objects (interfaces) subscibed to by this service - GDBusObjectManager * mpObjMgr = nullptr; - BluezAdapter1 * mpAdapter = nullptr; - BluezDevice1 * mpDevice = nullptr; - - // Objects (interfaces) published by this service - GDBusObjectManagerServer * mpRoot; - BluezGattService1 * mpService; - BluezGattCharacteristic1 * mpC1; - BluezGattCharacteristic1 * mpC2; - // additional data characteristics - BluezGattCharacteristic1 * mpC3; - - // map device path to the connection - GHashTable * mpConnMap; - uint32_t mAdapterId; - bool mIsCentral; - char * mpAdvertisingUUID; - chip::Ble::ChipBLEDeviceIdentificationInfo mDeviceIdInfo; - ChipAdvType mType; ///< Advertisement type. - uint16_t mDuration; ///< Advertisement interval (in ms). - bool mIsAdvertising; - char * mpPeerDevicePath; - GCancellable * mpConnectCancellable = nullptr; -}; - -struct BluezConnection -{ - char * mpPeerAddress; - BluezDevice1 * mpDevice; - BluezGattService1 * mpService; - BluezGattCharacteristic1 * mpC1; - BluezGattCharacteristic1 * mpC2; - // additional data characteristics - BluezGattCharacteristic1 * mpC3; - - bool mIsNotify; - uint16_t mMtu; - struct IOChannel mC1Channel; - struct IOChannel mC2Channel; - BluezEndpoint * mpEndpoint; -}; - -struct ConnectionDataBundle -{ - BluezConnection * mpConn; - GVariant * mpVal; -}; - } // namespace Internal } // namespace DeviceLayer } // namespace chip