devicefinder.cpp Example File

heartrate-game/devicefinder.cpp

  /***************************************************************************
  **
  ** Copyright (C) 2017 The Qt Company Ltd.
  ** Contact: http://www.qt.io/licensing/
  **
  ** This file is part of the examples of the QtBluetooth module of the Qt Toolkit.
  **
  ** $QT_BEGIN_LICENSE:BSD$
  ** You may use this file under the terms of the BSD license as follows:
  **
  ** "Redistribution and use in source and binary forms, with or without
  ** modification, are permitted provided that the following conditions are
  ** met:
  **   * Redistributions of source code must retain the above copyright
  **     notice, this list of conditions and the following disclaimer.
  **   * Redistributions in binary form must reproduce the above copyright
  **     notice, this list of conditions and the following disclaimer in
  **     the documentation and/or other materials provided with the
  **     distribution.
  **   * Neither the name of The Qt Company Ltd nor the names of its
  **     contributors may be used to endorse or promote products derived
  **     from this software without specific prior written permission.
  **
  **
  ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  **
  ** $QT_END_LICENSE$
  **
  ****************************************************************************/

  #include "devicefinder.h"
  #include "devicehandler.h"
  #include "deviceinfo.h"

  DeviceFinder::DeviceFinder(DeviceHandler *handler, QObject *parent):
      BluetoothBaseClass(parent),
      m_deviceHandler(handler)
  {
      m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
      m_deviceDiscoveryAgent->setLowEnergyDiscoveryTimeout(5000);

      connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &DeviceFinder::addDevice);
      connect(m_deviceDiscoveryAgent, static_cast<void (QBluetoothDeviceDiscoveryAgent::*)(QBluetoothDeviceDiscoveryAgent::Error)>(&QBluetoothDeviceDiscoveryAgent::error),
              this, &DeviceFinder::scanError);

      connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &DeviceFinder::scanFinished);
      connect(m_deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &DeviceFinder::scanFinished);

  #ifdef SIMULATOR
      m_demoTimer.setSingleShot(true);
      m_demoTimer.setInterval(2000);
      connect(&m_demoTimer, &QTimer::timeout, this, &DeviceFinder::scanFinished);
  #endif
  }

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

  void DeviceFinder::startSearch()
  {
      clearMessages();
      m_deviceHandler->setDevice(0);
      qDeleteAll(m_devices);
      m_devices.clear();

      emit devicesChanged();

  #ifdef SIMULATOR
      m_demoTimer.start();
  #else
      m_deviceDiscoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
  #endif
      emit scanningChanged();
      setInfo(tr("Scanning for devices..."));
  }

  void DeviceFinder::addDevice(const QBluetoothDeviceInfo &device)
  {
      // If device is LowEnergy-device, add it to the list
      if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
          m_devices.append(new DeviceInfo(device));
          setInfo(tr("Low Energy device found. Scanning more..."));
          emit devicesChanged();
      }
      //...
  }

  void DeviceFinder::scanError(QBluetoothDeviceDiscoveryAgent::Error error)
  {
      if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
          setError(tr("The Bluetooth adaptor is powered off."));
      else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
          setError(tr("Writing or reading from the device resulted in an error."));
      else
          setError(tr("An unknown error has occurred."));
  }

  void DeviceFinder::scanFinished()
  {
  #ifdef SIMULATOR
      // Only for testing
      for (int i = 0; i < 4; i++)
          m_devices.append(new DeviceInfo(QBluetoothDeviceInfo()));
  #endif

      if (m_devices.size() == 0)
          setError(tr("No Low Energy devices found."));
      else
          setInfo(tr("Scanning done."));

      emit scanningChanged();
      emit devicesChanged();
  }

  void DeviceFinder::connectToService(const QString &address)
  {
      m_deviceDiscoveryAgent->stop();

      DeviceInfo *currentDevice = 0;
      for (int i = 0; i < m_devices.size(); i++) {
          if (((DeviceInfo*)m_devices.at(i))->getAddress() == address ) {
              currentDevice = (DeviceInfo*)m_devices.at(i);
              break;
          }
      }

      if (currentDevice)
          m_deviceHandler->setDevice(currentDevice);

      clearMessages();
  }

  bool DeviceFinder::scanning() const
  {
  #ifdef SIMULATOR
      return m_demoTimer.isActive();
  #else
      return m_deviceDiscoveryAgent->isActive();
  #endif
  }

  QVariant DeviceFinder::devices()
  {
      return QVariant::fromValue(m_devices);
  }