Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. No signals wich BluetoothDiscoveryAgent

No signals wich BluetoothDiscoveryAgent

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 3 Posters 206 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JuliusCaesar
    wrote on last edited by JuliusCaesar
    #1

    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 this

    class 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 though

    when 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

    1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by Christian Ehrlicher
      #2

      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.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Anonymous_Banned275
        wrote on last edited by
        #3

        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.

        .

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved