Bluetooth, discovering devices' services never ends.



  • Hi,

    I'm developing an android app that communicate with a data acquisition device through a Bluetooth connection.

    Almost everything works fine. I can discover my device, its SPP service, open a socket and communicate with it.

    But, to speed-up the initialization procedure I try to filter on which device I want to discover the available services. But when I set a filter, the discovery service agent never ends.

    Here's the procedure that discover what services are available.
    @bool Device::initialize()
    {
    QBluetoothServiceInfo tServiceInfo;
    QEventLoop tEventLoop;
    bool bResult = false;

    if( false != m_bIsInitialized )
    return true;

    // Create the discovery agent to get the service object
    connect( m_ptDiscoveryAgent, SIGNAL( finished() ), &tEventLoop, SLOT( quit() ) );
    connect( m_ptDiscoveryAgent, SIGNAL( canceled() ), &tEventLoop, SLOT( quit() ) );
    connect( this, SIGNAL( quitLoop() ), &tEventLoop, SLOT( quit() ) ); /* DEBUG TEST /
    connect( m_ptDiscoveryAgent, SIGNAL( error(QBluetoothServiceDiscoveryAgent::Error)), this, SLOT( onServiceError(QBluetoothServiceDiscoveryAgent::Error)) );
    connect( m_ptDiscoveryAgent, SIGNAL( serviceDiscovered(QBluetoothServiceInfo)), this, SLOT( onServiceDiscovered(QBluetoothServiceInfo)) ); /
    DEBUG TEST */

    // FIXME: When filtering it never ends
    m_ptDiscoveryAgent->setRemoteAddress( QBluetoothAddress( m_tAddress ) ); /* DEBUG TEST */

    // Start
    m_ptDiscoveryAgent->start();
    tEventLoop.exec();

    foreach( tServiceInfo, m_ptDiscoveryAgent->discoveredServices() )
    {
    // Search for our device
    if( tServiceInfo.device().address().toString() == m_tAddress )
    {
    // Some code to store the service object
    ...

    bResult = true;
    }
    }

    return bResult;
    }@

    And here's some code I added to try to fix this issue.
    @void Device::onServiceDiscovered(const QBluetoothServiceInfo &info)
    {
    Q_UNUSED(info);
    qDebug() << "service discovered";
    emit quitLoop(); /* DEBUG TEST */
    qDebug() << "signal emitted";
    }@

    If I remove all the lines that contain /* DEBUG TEST */, tEventLoop.exec() exits when the discovery agent ends and I can filter what services I have to use. But the procedure takes a long time cause the discovery agent try to discover all of the services available on all the devices around the tablet (even those which are not paired with the tablet).

    To speed this up, I tried to use a signal quitLoop() when the discovery agent has discovered the service. The signal is emitted but the tEventLoop.exec() never exits.

    If I try to call ptDiscoveryAgent->stop() instead of emitting a signal, a segmentation fault occurs.

    Does anyone have an idea, if this is a bug in the QT Bluetooth API or a mistake I made ?

    Thanks.
    Alex.


  • Lifetime Qt Champion

    Hi,

    You should also add which version of Qt you are using and which OS you are targeting



  • [quote author="SGaist" date="1403899777"]Hi,

    You should also add which version of Qt you are using and which OS you are targeting [/quote]
    Yes sorry, Qt 5.3.1 and android os


  • Lifetime Qt Champion

    Can you create a minimal compilable example that reproduce the behavior ?



  • I made two tests on two different tablets.

    1. Samsung galalxy tab2 with cyanogenmod android 4.2.2
    2. Motoral XOOM with android 4.0.2

    The issue is present with both of them.

    You can download the apk there : https://dl.dropboxusercontent.com/u/1628289/QtApp-debug.apk

    you'll see the main window
    !https://dl.dropboxusercontent.com/u/1628289/main.png!

    If you click on "Create device list", after a while is might display a message with the list of device available nearby the tablet.
    !https://dl.dropboxusercontent.com/u/1628289/device_list.png!

    If you click on 'open device', it will try to initialize the first device in the list. Even an error message box is displayed that means the initialization function is not blocking. If you click 'filter devices', the initialization function will get stuck and no message box with be displayed.

    you don't have a create device list before opening the device. If no device list has been created, a default device will be created using the address entered in the line edit control.

    Thanks for your help.


  • Lifetime Qt Champion

    Can you share the code so I can built it with my version of Qt ?





  • Hi SGaist,

    Did you have time to try to reproduce the issue ?
    If so, did you succeed in it ?

    Alex.


  • Lifetime Qt Champion

    Hi,

    Sorry for the delay

    Indeed there's a loop going on when filtering. However you have some typos in your code, at least in BluePort you have quitConnectionLoop rather than quitLoop.

    You should simplify your example and open a report on the "bug report system":http://bugreports.qt-project.org



  • [quote author="SGaist" date="1404423551"]Sorry for the delay[/quote]No worries.

    [quote author="SGaist" date="1404423551"]Indeed there's a loop going on when filtering. However you have some typos in your code, at least in BluePort you have quitConnectionLoop rather than quitLoop.[/quote]Shoot, I forgot to rename the slot at this line...

    [quote author="SGaist" date="1404423551"]You should simplify your example and open a report on the "bug report system":http://bugreports.qt-project.org[/quote]I will.

    Thank you very much for your help.



  • Based on my debugging the signals are emitted but QEventLoop is not waking up. If there is a bug in here then it's QEventLoop. I lack the knowledge to determine the cause.

    In any case (as suggested in my bug comment) I suggest to rewrite your app to not use QEventLoop as it can be a very destablising factor in the app and your app can be written without it.



  • [quote author="Alex Blasche" date="1404728740"]Based on my debugging the signals are emitted but QEventLoop is not waking up. If there is a bug in here then it's QEventLoop. I lack the knowledge to determine the cause.
    In any case (as suggested in my bug comment) I suggest to rewrite your app to not use QEventLoop as it can be a very destablising factor in the app and your app can be written without it.[/quote]

    QEventLoop works fine when discovering bluetooth devices with QBluetoothDeviceDiscoveryAgent. The function is similar to the one searching for bluetooth services with QBluetoothServiceDiscoveryAgent which never ends.



  • That might be a conincedence or just pure luck. The device discovery uses completely different Android API's.

    My main point is that QBluetoothServiceDiscoveryAgent is working as expected, QEventLoop is not at all recommended to be used if avoidable (which it is here) and can cause spourious crashes. It shouldn't be too difficult to change the relevant code pieces in your application. Believe me when I telll you that I have been where you are with your QEventLoop based implementation and I taking those experiences into account I strongly discourage its use.

    I leave it up to you if you want to file a bug against QEventLoop on Android.



  • [quote author="Alex Blasche" date="1404736574"][...]I strongly discourage its use.[/quote]
    So how can I wait for the end of an asynchronous function. I open a new thread on the forum for those who could help me.
    "Waiting for an asynchronous function":https://qt-project.org/forums/viewthread/44795/

    Thanks for having checked why the service discovery never ends.



  • I posted a small toy example in the other thread.

    Mind you threads won't help as the Bluetooth classes are not thread safe unless. You can use them in different threads but you have to build a lot of guards around them. This would make the code more complicated than it should be.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.