No signals wich BluetoothDiscoveryAgent
-
Hey I'm using the BluetoothdiscoveryAgent to find BT classic devices.
However sometimes a do not receive any finnish() events.
My (simplified) class looks like thisclass BluetoothClassicDiscoveryAgent : public QThread { Q_OBJECT public: BluetoothClassicDiscoveryAgent(); virtual ~BluetoothClassicDiscoveryAgent(); public slots: void deviceDiscovered(QBluetoothDeviceInfo device); void agentFinished(); signals: void audioDeviceListChanged(const std::vector<BTAudioDevice>& vecAudioDevices); protected: void run() override; private: bool BTClassicThreadFunction(); std::vector<BTAudioDevice> m_AudioDevices; ///Instance to the BT connect std::unique_ptr<QBluetoothDeviceDiscoveryAgent> m_pDiscoveryAgent = nullptr; };
BluetoothClassicDiscoveryAgent::BluetoothClassicDiscoveryAgent() { qRegisterMetaType<QBluetoothDeviceInfo>(); } BluetoothClassicDiscoveryAgent::~BluetoothClassicDiscoveryAgent() { if (isRunning()) { exit(-1); wait(); } } bool BluetoothClassicDiscoveryAgent::BTClassicThreadFunction() { m_AudioDevices.clear(); QBluetoothLocalDevice localDevice; QString localDeviceName; bool bRes = false; // Check if Bluetooth is available on this device if (!localDevice.isValid()) { //log Device Invalid } else { // Turn Bluetooth on localDevice.powerOn(); // Read local device name localDeviceName = localDevice.name(); // Make it visible to others localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable); // /////////////////////////////////////////////// m_pDiscoveryAgent = std::make_unique<QBluetoothDeviceDiscoveryAgent>(); const bool bConnectRes1 = connect(m_pDiscoveryAgent.get(), SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)), this, SLOT(deviceDiscovered(QBluetoothDeviceInfo))); const bool bConnectRes2 = connect(m_pDiscoveryAgent.get(), SIGNAL(finished()), this, SLOT(agentFinished())); const bool bConnectRes3 = connect(m_pDiscoveryAgent.get(), QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(&QBluetoothDeviceDiscoveryAgent::error), [=](QBluetoothDeviceDiscoveryAgent::Error error) { qDebug() << "An Error Ocurred while scanning devices: " << error; }); if (!bConnectRes1 || !bConnectRes2 || !bConnectRes3) { //log print error signal connection failed } else { /* start scanning for bt classic devices */ m_pDiscoveryAgent->start(QBluetoothDeviceDiscoveryAgent::ClassicMethod); QString qstrError = m_pDiscoveryAgent->errorString(); if (!qstrError.isEmpty()) { //print out error agentFinished(); } bRes = true; } } return bRes; } // In your local slot, read information about the found devices void BluetoothClassicDiscoveryAgent::deviceDiscovered(QBluetoothDeviceInfo device) { if (device.majorDeviceClass() == QBluetoothDeviceInfo::AudioVideoDevice) { //print out valid device found BTAudioDevice btAudioDevice(device.name().toStdString(), device.address().toString().toStdString(), device); m_AudioDevices.push_back(btAudioDevice); } else { //print out warning no valid audio device } } void BluetoothClassicDiscoveryAgent::agentFinished() { //print agent finnished and print out all found devices emit audioDeviceListChanged(m_AudioDevices); } void BluetoothClassicDiscoveryAgent::run() { //log start scan if (!BTClassicThreadFunction()) { //log failure agentFinished(); } else { const int iRes = exec(); //log finnish res m_pDiscoveryAgent->stop(); } m_pDiscoveryAgent = nullptr; }
Now in my case an outer class helds a uniqe_ptr<BluetoothClassicDiscoveryAgent>().
Unique Pointer is created via make_unique<BluetoothClassicDiscoveryAgent>()class OuterClass { std::unique_ptr<BluetoothClassicDiscoveryAgent> pDicoveryAgent = nullptr; void initAgent() { pDicoveryAgent = std::make_unique<BluetoothClassicDiscoveryAgent>(); } void startscan() { pDicoveryAgent->run(); } }
I have 2 other signals with are emitted directly after another. Both signals are calling initAgent() directly after another.
So there is a temporary instance of BluetoothClassicDiscoveryAgent which gets deleted when the second call hits.Later on (via a button click event) startScan() is executed.
However my slots deviceDiscovered() or agentFinished() are not called.I did try to following:
Add an instanceCounter to initAgent()int iInstanceCount = 0; void initAgent() { iInstanceCount++; if (iInstanceCount % 2 == 0) { //even count...skip return; } pDicoveryAgent = std::make_unique<BluetoothClassicDiscoveryAgent>(); }
In this case only the first signal is allowed to create a instance of BluetoothClassicDiscoveryAgent
=>in this case: all expected events are coming thoughwhen i change
if (iInstanceCount % 2 == 0)
to
if (iInstanceCount % 2 != 0)
no events are coming though.
So there seems to be something different what thread actual makes the constructor calls.
I tried with Qt 5.12.8 and Qt 5.15.1 for VS2019 64 bit.
I all so tried different connection types. Some of them returned false on connect() others produced the same behaviour as posted.Do you have any idea what I'm doing wrong? Could subclasing QThread be the problem? I thought it's still a valid method
greets Julian
-
First please read about QThread and why you must not call run directly. Second: no you don't need a thread since all the stuff you're doing is asynchronously and can be easily done with signals and slots.
-
Funny, I am having exactly opposite behavior. I am using Qt examples "btscanner" and it consistently returns "finished" signal each 20 seconds after "scan" signal is emitted.
.
It also returns "found device" immediately , not with up to 2 seconds delay, even on non existing devices.For what it is worth - I have found that "scan for nearby devices" results depends on type of local device "doing the scan".
I am not is position to actually check why is that - not until I get this "non-existent" devices discovery under control.
I am busy putting timers in to track the real time signals, it is lots of fun debugging Bluetooth "fixed" timing.
.