Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-109587

Refactor QLowEnergyController backend for Windows

    XMLWordPrintable

Details

    • Task
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.5.0 FF
    • None
    • Windows
    • 25
    • PM Spotted

    Description

      This task is a result of a discussion with vuokko .

      The modern Windows Bluetooth API is asynchronous, all the synchronous methods are now deprecated.
      In the current implementation we have two ways of working with these APIs:

      • Usual approach: allocate a resource (for example, GattDeviceService handle), perform some async call on it, and provide a callback.
      • When a lot of consecutive operations need to be done, we put the work in a helper thread and use QWinRTFunctions::await() call to wait for the result of an async call (see QWinRTLowEnergyServiceHandler and QWinRTLowEnergyConnectionHandler).

      Also note that Windows Bluetooth implementation does not seem to allow access to the same resource (service, or characteristic, or descriptor) using multiple handlers. The handler is successfully created, but any operation will fail while there is other operation in progress.

      With this limitation, both our approaches have a fundamental problem of proper resource cleanup:

      • With the code running in the main thread, we do the cleanup when disconnecting from the device. But if the user tries to disconnect while the async operation is in progress, the cleanup code will block until it's completed, so the UI will freeze (see QTBUG-108461).
      • For the resources acquired in helper threads the problem is different. When we disconnect during the async call, the thread is not finished immediately - it waits for the async operation to complete, and only after that the resource can be released and re-used. If we try to reconnect to the same device and perform some operations on the same service, it will fail, because the previous helper thread is still using the resource. This can also lead to various freezes under some conditions.

      One possible approach to fix it is to rewrite QLowEnergyController implementation in such a way that it does all the Bluetooth related operations in the background thread, so that the UI never freezes. Ideally we should also keep track of all the used resources, so that if we do connect() -> disconnect() -> connect(), we could delay the second connect until we're sure that the disconnect is completed. AFAIK, that is doable from the API point of view, because QLowEnergyController API is mostly async anyway.

      One other important point is that we should switch to C++/winrt instead of COM when doing the rewrite.

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              cnn Qt Core & Network
              ivan.solovev Ivan Solovev
              Vladimir Minenko Vladimir Minenko
              Alex Blasche Alex Blasche
              Votes:
              3 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes