返回

蓝牙低能耗特性通知时有时不工作?原因竟是这个?

Linux

蓝牙低能耗特性通知时有时不工作

问题概述

在使用蓝牙低能耗(BLE)在 Qt Android 应用程序和树莓派之间交换数据时,我们遇到了一个间歇性问题:特征的通知有时无法启用,导致数据交换中断。具体来说,涉及数据交换的特征的通知符无法正确写入,从而阻止了手机接收有关特征数据更改的通知。

故障分析

我们仔细检查了调试日志,发现了 Bluez DBUS 消息中的以下差异:

  • 通知正常工作时:特征的 StartNotify 方法被调用,发送值为 0x0100 的通知。
  • 通知不工作时:通知符的 WriteValue 方法被调用,发送未知数据。

解决方案

经过进一步调查,我们发现 Bluez DBUS API 中存在一个错误,导致在某些情况下 WriteValue 方法被错误地调用。为了解决这个问题,我们修改了 Qt 应用程序的代码,以便始终调用 StartNotify 方法,即使对于通知描述符。

修改后的代码

void DeviceHandlerBase::onServiceStateChangedUwb(QLowEnergyService::ServiceState s)
{
    if (s == QLowEnergyService::RemoteServiceDiscovered)
    {
        if (m_service == nullptr)
        {
            LOGE("UWB SERVICE POINTER IS NULL");
            return;
        }

        // To be moved to CONFIG.H
        txCharacteristic = m_service->characteristic(UWB::UWB_TX_CHARACTERISTIC_UUID);
        rxCharacteristic = m_service->characteristic(UWB::UWB_RX_CHARACTERISTIC_UUID);

        if (txCharacteristic.isValid() && rxCharacteristic.isValid())
        {
            LOGI("The RX and TX Characteristics were found and are valid");

            // Always call StartNotify, even for notification descriptor
            m_service->startNotify(txCharacteristic);
            m_service->startNotify(rxCharacteristic);
        }
        else
            LOGE("THE RX AND TX CHARACTERISTICS ARE NOT VALID");
    }
}

结论

通过修改 Qt 应用程序的代码以始终调用 StartNotify 方法,我们能够解决 BLE 特征通知时有时不工作的问题。这确保了即使在 Bluez DBUS API 出现错误的情况下,通知也能正确启用,从而确保了数据交换的可靠性。

常见问题解答

  1. 为什么通知有时会工作,有时又会失败?
    由于 Bluez DBUS API 中的错误,WriteValue 方法有时会被错误地调用,这会干扰通知。

  2. 修改后的代码是否解决了所有 BLE 通知问题?
    修改后的代码解决了由 Bluez DBUS API 错误引起的特定问题,但可能无法解决所有 BLE 通知问题。

  3. 如何确保通知的可靠性?
    通过使用可靠的 BLE 库和定期重新建立连接,可以提高通知的可靠性。

  4. 除了修改代码之外,还有其他解决方法吗?
    可以尝试更新 Bluez DBUS API 或使用不同的 BLE 库。

  5. 此问题对我的应用程序有什么影响?
    通知中断可能会导致数据丢失或应用程序功能不正确。