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. Getting - Controller Error: QLowEnergyController::ConectionError
Forum Updated to NodeBB v4.3 + New Features

Getting - Controller Error: QLowEnergyController::ConectionError

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 971 Views 1 Watching
  • 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.
  • S Offline
    S Offline
    sarthak031
    wrote on last edited by
    #1

    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.

    Pl45m4P 1 Reply Last reply
    0
    • S sarthak031

      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.

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by
      #2

      @sarthak031

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


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      1 Reply Last reply
      0
      • S Offline
        S Offline
        sarthak031
        wrote on last edited by
        #3

        @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.

        Pl45m4P 1 Reply Last reply
        0
        • S sarthak031

          @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.

          Pl45m4P Offline
          Pl45m4P Offline
          Pl45m4
          wrote on last edited by
          #4

          @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?


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          1 Reply Last reply
          1
          • S Offline
            S Offline
            sarthak031
            wrote on last edited by
            #5

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

            Pl45m4P 1 Reply Last reply
            0
            • S sarthak031

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

              Pl45m4P Offline
              Pl45m4P Offline
              Pl45m4
              wrote on last edited by Pl45m4
              #6

              @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

              • https://doc.qt.io/qt-5/qtbluetooth-le-overview.html#using-qt-bluetooth-low-energy-api
              • https://doc.qt.io/qt-5/qtbluetooth-lowenergyscanner-example.html

              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

              ~E. W. Dijkstra

              1 Reply Last reply
              1

              • Login

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