/* **************************************************************************** * Copyright 2019 Open Systems Development BV * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the "Software"), * * to deal in the Software without restriction, including without limitation * * the rights to use, copy, modify, merge, publish, distribute, sublicense, * * and/or sell copies of the Software, and to permit persons to whom the * * Software is furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included in * * all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * * DEALINGS IN THE SOFTWARE. * * ***************************************************************************/ // osdev::components::bluetooth #include "devicefinder.h" #include "devicehandler.h" #include "deviceinfo.h" using namespace osdev::components::bluetooth; DeviceFinder::DeviceFinder( DeviceHandler *handler, QObject *parent ) : BluetoothBaseClass( parent ) , m_pDeviceHandler( handler ) , m_pDeviceDiscoveryAgent( new QBluetoothDeviceDiscoveryAgent() ) , m_devices() { //! [devicediscovery-1] m_pDeviceDiscoveryAgent->setLowEnergyDiscoveryTimeout( 5000 ); connect( m_pDeviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &DeviceFinder::slotAddDevice ); connect( m_pDeviceDiscoveryAgent, static_cast(&QBluetoothDeviceDiscoveryAgent::error), this, &DeviceFinder::slotScanError ); connect( m_pDeviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &DeviceFinder::slotScanFinished ); connect( m_pDeviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &DeviceFinder::slotScanFinished ); connect( m_pDeviceHandler, &DeviceHandler::signalReceivedValue, this, &DeviceFinder::signalSendData ); } DeviceFinder::~DeviceFinder() { qDeleteAll( m_devices ); m_devices.clear(); } void DeviceFinder::slotStartSearch() { clearMessages(); m_pDeviceHandler->setDevice( nullptr ); qDeleteAll( m_devices ); m_devices.clear(); emit signalDevicesChanged(); m_pDeviceDiscoveryAgent->start( QBluetoothDeviceDiscoveryAgent::LowEnergyMethod ); emit signalScanningChanged(); setInfo( tr( "Scanning for devices..." ) ); } void DeviceFinder::slotAddDevice( const QBluetoothDeviceInfo &device ) { // If device is LowEnergy-device and its services contain the one we're looking for, add it to the list. if( device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration ) { qInfo() << device.serviceUuids() << " : Looking for : " << m_pDeviceHandler->requestedServiceUuid(); m_devices.append( new DeviceInfo( device ) ); setInfo( tr( "Low Energy Device Found. Scanning for more...." ) ); emit signalDevicesChanged(); } } void DeviceFinder::slotScanError( QBluetoothDeviceDiscoveryAgent::Error error ) { if( error == QBluetoothDeviceDiscoveryAgent::PoweredOffError ) { setError( tr( "The Bluetooth adapter 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 occured." ) ); } } void DeviceFinder::slotScanFinished() { if( m_devices.isEmpty() ) setError( tr( "No Low Energy devices found." ) ); else setInfo( tr( "Scanning done." ) ); emit signalScanningChanged(); emit signalDevicesChanged(); emit signalScanFinished(); } void DeviceFinder::slotConnectToService( const QString &address ) { m_pDeviceDiscoveryAgent->stop(); DeviceInfo *currentDevice = nullptr; for( auto entry : qAsConst( m_devices ) ) { if( entry && entry->getAddress() == address ) { currentDevice = entry; break; } } if( currentDevice ) m_pDeviceHandler->setDevice( currentDevice ); clearMessages(); } bool DeviceFinder::scanning() const { return m_pDeviceDiscoveryAgent->isActive(); } QList DeviceFinder::devices() { return m_devices; } QString DeviceFinder::getAddressByName( const QString &name ) { if( name.isEmpty() || name.isNull() ) return QString(); for( const auto &device : qAsConst( m_devices ) ) { if( device->getName() == name ) return device->getAddress(); } return QString(); } void DeviceFinder::slotDisconnect() { m_pDeviceHandler->slotDisconnectService(); }