Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Getting - Controller Error: QLowEnergyController::ConectionError



  • HI,
    I am new in the Qt Desktop App Development. I am using the QtBluetooth library in my desktop app but when i am trying to connect my BLE device I am getting the error (Controller Error: QLowEnergyController::ConectionError). And I am able to connect my BLE device with other desktop apps. So please help me with this.



  • @sarthak031

    Since we are not clairvoyant, you need to provide some more information.



  • @Pl45m4 I have a BLE-based Hardware device for which I want to make the Desktop app to connect the BLE device and read the data through it. I am using visual studio 2019 for the app development using the Qt opensource Bluetooth library.

    So I write this code

    BLEInterface::BLEInterface(QObject* parent) : QObject(parent),
    m_currentDevice(0),
    m_control(0),
    m_service(0),
    m_readTimer(0),
    m_connected(false),
    m_currentService(0)
    {
    m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);

    connect(m_deviceDiscoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
    	this, SLOT(addDevice(const QBluetoothDeviceInfo&)));
    connect(m_deviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
    	this, SLOT(onDeviceScanError(QBluetoothDeviceDiscoveryAgent::Error)));
    connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(onScanFinished()));
    

    }

    BLEInterface::~BLEInterface()
    {
    qDeleteAll(m_devices);
    m_devices.clear();
    }

    void BLEInterface::scanDevices()
    {
    m_devicesNames.clear();
    qDeleteAll(m_devices);
    m_devices.clear();
    emit devicesNamesChanged(m_devicesNames);
    m_deviceDiscoveryAgent->start();
    m_deviceDiscoveryAgent->setLowEnergyDiscoveryTimeout(10000);
    //emit statusInfoChanged("Scanning for devices...", true);
    }

    void BLEInterface::read() {
    if (m_service && m_readCharacteristic.isValid())
    m_service->readCharacteristic(m_readCharacteristic);
    }

    void BLEInterface::waitForWrite() {
    QEventLoop loop;
    connect(m_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic, QByteArray)),
    &loop, SLOT(quit()));
    loop.exec();
    }

    void BLEInterface::write(const QByteArray& data)
    {
    qDebug() << "BLEInterface::write: " << data;
    if (m_service && m_writeCharacteristic.isValid()) {
    if (data.length() > CHUNK_SIZE) {
    int sentBytes = 0;
    while (sentBytes < data.length()) {
    m_service->writeCharacteristic(m_writeCharacteristic,
    data.mid(sentBytes, CHUNK_SIZE),
    m_writeMode);
    sentBytes += CHUNK_SIZE;
    if (m_writeMode == QLowEnergyService::WriteWithResponse) {
    waitForWrite();
    if (m_service->error() != QLowEnergyService::NoError)
    return;
    }
    }

    	}
    	else
    		m_service->writeCharacteristic(m_writeCharacteristic, data, m_writeMode);
    }
    

    }

    void BLEInterface::addDevice(const QBluetoothDeviceInfo& device)
    {
    if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration)
    {
    qWarning() << "Discovered LE Device name: " << device.name() << " Address: "
    << device.address().toString();
    m_devicesNames.append(device.name());
    DeviceInfo* dev = new DeviceInfo(device);
    m_devices.append(dev);
    emit devicesNamesChanged(m_devicesNames);
    //emit printf("Low Energy device found. Scanning for more...");
    }
    //...
    }

    void BLEInterface::onScanFinished()
    {
    if (m_devicesNames.size() == 0)
    /emit/ printf("No Low Energy devices found");
    }

    void BLEInterface::onDeviceScanError(QBluetoothDeviceDiscoveryAgent::Error error)
    {
    if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
    /emit/ printf("The Bluetooth adaptor is powered off, power it on before doing discovery.");
    else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
    /emit/ printf("Writing or reading from the device resulted in an error.");
    else
    /emit/ printf("An unknown error has occurred.");
    }

    void BLEInterface::connectCurrentDevice()
    {
    if (m_devices.isEmpty())
    return;

    if (m_control)
    {
    	m_control->disconnectFromDevice();
    	delete m_control;
    	m_control = 0;
    
    }
    m_control = new QLowEnergyController(m_devices[m_currentDevice]->getDevice(), this);
    connect(m_control, SIGNAL(connected()),
    	this, SLOT(onDeviceConnected()));
    connect(m_control, SIGNAL(error(QLowEnergyController::Error)),
    	this, SLOT(onControllerError(QLowEnergyController::Error)));
    connect(m_control, SIGNAL(disconnected()),
    	this, SLOT(onDeviceDisconnected()));
    connect(m_control, SIGNAL(serviceDiscovered(QBluetoothUuid)),
    	this, SLOT(onServiceDiscovered(QBluetoothUuid)));
    connect(m_control, SIGNAL(discoveryFinished()),
    	this, SLOT(onServiceScanDone()));
    
    
    m_control->connectToDevice();
    

    }

    void BLEInterface::onDeviceConnected()
    {
    m_servicesUuid.clear();
    m_services.clear();
    setCurrentService(-1);
    emit servicesChanged(m_services);
    m_control->discoverServices();
    }

    void BLEInterface::onDeviceDisconnected()
    {
    update_connected(false);
    // emit statusInfoChanged("Service disconnected", false);
    qWarning() << "Remote device disconnected";
    }

    void BLEInterface::onServiceDiscovered(const QBluetoothUuid& gatt)
    {
    Q_UNUSED(gatt)
    /* emit*/ printf("Service discovered. Waiting for service scan to be done...");
    }

    void BLEInterface::onServiceScanDone()
    {
    m_servicesUuid = m_control->services();
    if (m_servicesUuid.isEmpty())
    /* emit*/ printf("Can't find any services.");
    else {
    m_services.clear();
    foreach(auto uuid, m_servicesUuid)
    m_services.append(uuid.toString());
    emit servicesChanged(m_services);
    m_currentService = -1;// to force call update_currentService(once)
    setCurrentService(0);
    /* emit*/ printf("All services discovered.");
    }
    }

    void BLEInterface::disconnectDevice()
    {
    m_readTimer->deleteLater();
    m_readTimer = NULL;

    if (m_devices.isEmpty()) {
    	return;
    }
    
    //disable notifications
    if (m_notificationDesc.isValid() && m_service) {
    	m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0000"));
    }
    else {
    	m_control->disconnectFromDevice();
    	delete m_service;
    	m_service = 0;
    }
    

    }

    void BLEInterface::onControllerError(QLowEnergyController::Error error)
    {
    /* emit*/ printf("Cannot connect to remote device.");
    qWarning() << "Controller Error:" << error;
    }

    void BLEInterface::onCharacteristicChanged(const QLowEnergyCharacteristic& c,
    const QByteArray& value)
    {
    Q_UNUSED(c)
    qDebug() << "Characteristic Changed: " << value;
    // emit dataReceived(value);
    }
    void BLEInterface::onCharacteristicWrite(const QLowEnergyCharacteristic& c,
    const QByteArray& value)
    {
    Q_UNUSED(c)
    qDebug() << "Characteristic Written: " << value;
    }

    void BLEInterface::update_currentService(int indx)
    {
    delete m_service;
    m_service = 0;

    if (indx >= 0 && m_servicesUuid.count() > indx) {
    	m_service = m_control->createServiceObject(
    		m_servicesUuid.at(indx), this);
    }
    
    if (!m_service) {
    	/* emit*/ printf("Service not found.");
    	return;
    }
    
    connect(m_service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
    	this, SLOT(onServiceStateChanged(QLowEnergyService::ServiceState)));
    connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic, QByteArray)),
    	this, SLOT(onCharacteristicChanged(QLowEnergyCharacteristic, QByteArray)));
    connect(m_service, SIGNAL(characteristicRead(QLowEnergyCharacteristic, QByteArray)),
    	this, SLOT(onCharacteristicRead(QLowEnergyCharacteristic, QByteArray)));
    connect(m_service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic, QByteArray)),
    	this, SLOT(onCharacteristicWrite(QLowEnergyCharacteristic, QByteArray)));
    connect(m_service, SIGNAL(error(QLowEnergyService::ServiceError)),
    	this, SLOT(serviceError(QLowEnergyService::ServiceError)));
    
    if (m_service->state() == QLowEnergyService::DiscoveryRequired) {
    	/* emit*/ printf("Connecting to service...");
    	m_service->discoverDetails();
    }
    else
    	searchCharacteristic();
    

    }
    void BLEInterface::onCharacteristicRead(const QLowEnergyCharacteristic& c,
    const QByteArray& value) {
    Q_UNUSED(c)
    qDebug() << "Characteristic Read: " << value;
    //emit dataReceived(value);
    }

    void BLEInterface::searchCharacteristic() {
    if (m_service) {
    foreach(QLowEnergyCharacteristic c, m_service->characteristics()) {
    if (c.isValid()) {
    if (c.properties() & QLowEnergyCharacteristic::WriteNoResponse ||
    c.properties() & QLowEnergyCharacteristic::Write) {
    m_writeCharacteristic = c;
    update_connected(true);
    if (c.properties() & QLowEnergyCharacteristic::WriteNoResponse)
    m_writeMode = QLowEnergyService::WriteWithoutResponse;
    else
    m_writeMode = QLowEnergyService::WriteWithResponse;

    			}
    			if (c.properties() & QLowEnergyCharacteristic::Read) {
    				m_readCharacteristic = c;
    				if (!m_readTimer) {
    					m_readTimer = new QTimer(this);
    					connect(m_readTimer, &QTimer::timeout, this, &BLEInterface::read);
    					m_readTimer->start(
    					);
    				}
    			}
    			m_notificationDesc = c.descriptor(
    				QBluetoothUuid::ClientCharacteristicConfiguration);
    			if (m_notificationDesc.isValid()) {
    				m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
    			}
    		}
    	}
    }
    

    }

    void BLEInterface::onServiceStateChanged(QLowEnergyService::ServiceState s)
    {
    qDebug() << "serviceStateChanged, state: " << s;
    if (s == QLowEnergyService::ServiceDiscovered) {
    searchCharacteristic();
    }
    }
    void BLEInterface::serviceError(QLowEnergyService::ServiceError e)
    {
    qWarning() << "Service error:" << e;
    }

    but I am getting the Controller Error: QLowEnergyController::ConectionError while I am trying to connect my BLE Device.



  • @sarthak031 said in Getting - Controller Error: QLowEnergyController::ConectionError:

    but I am getting the Controller Error: QLowEnergyController::ConectionError while I am trying to connect my BLE Device.

    Where exactly? The deviceDiscovery works?



  • @Pl45m4
    yes, Device discovery is working correctly but when I am trying to connect the device I get this error.



  • @sarthak031

    You are using this example (https://github.com/Gawhary/BLE-Tester), aren't you?
    Where exactly the error occurs (use debugger)? Is your device BLE ready?

    Test your connection using the official BTLE examples


Log in to reply