Index: sources/bluetooth/BluetoothInterface.cpp =================================================================== diff -u -r028cb1403e8fcb2d2e9ab2aa1562f660124015b1 -r93cb2e56782aa64aafb2b69ec526a5e49ffdf1c7 --- sources/bluetooth/BluetoothInterface.cpp (.../BluetoothInterface.cpp) (revision 028cb1403e8fcb2d2e9ab2aa1562f660124015b1) +++ sources/bluetooth/BluetoothInterface.cpp (.../BluetoothInterface.cpp) (revision 93cb2e56782aa64aafb2b69ec526a5e49ffdf1c7) @@ -1,4 +1,4 @@ -/*! + /*! * \copyright * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN @@ -21,6 +21,7 @@ // Project #include "Logger.h" +#include "types.h" // namespace using namespace Bluetooth; @@ -95,12 +96,6 @@ void BluetoothInterface::initConnections() { // Local connections - connect(_local , &QBluetoothLocalDevice :: pairingFinished , - this , &BluetoothInterface ::onLocalPairingFinish ); - connect(_local , &QBluetoothLocalDevice :: pairingDisplayConfirmation , - this , &BluetoothInterface ::onLocalPairingDisplayConfirmation ); - connect(_local , &QBluetoothLocalDevice :: pairingDisplayPinCode , - this , &BluetoothInterface ::onLocalPairingDisplayPinCode ); connect(_local , &QBluetoothLocalDevice :: deviceConnected , this , &BluetoothInterface ::onLocalDeviceConnect ); connect(_local , &QBluetoothLocalDevice :: deviceDisconnected , @@ -160,9 +155,10 @@ // ~~~~~~~~~~~ Local #define NOTIFY_LOCAL_INIT notifyStateChange(MBluetooth(MBluetooth::eIS_Local_Init , \ _local->address().toString() , \ - _local->name() )); + _local->name(),0,1 )); + #define NOTIFY_LOCAL_CONNECT notifyStateChange(MBluetooth(MBluetooth::eIS_Local_Connect , vAddress.toString()) ); -#define NOTIFY_LOCAL_ERROR notifyStateChange(MBluetooth(MBluetooth::eIS_Local_Error_Unknown )); +#define NOTIFY_LOCAL_ERROR notifyStateChange(MBluetooth(MBluetooth::eIS_Local_Error )); #define NOTIFY_LOCAL_ERROR_IO notifyStateChange(MBluetooth(MBluetooth::eIS_Local_Error_IO )); #define NOTIFY_LOCAL_ERROR_OFF notifyStateChange(MBluetooth(MBluetooth::eIS_Local_Error_Off )); #define NOTIFY_LOCAL_ERROR_INVALID notifyStateChange(MBluetooth(MBluetooth::eIS_Local_Error_Invalid )); @@ -175,51 +171,77 @@ #define NOTIFY_PAIR_ERROR notifyStateChange(MBluetooth(MBluetooth::eIS_Pair_Error )); // ~~~~~~~~~~~ Scan #define NOTIFY_SCAN_DISCOVER notifyStateChange(MBluetooth(MBluetooth::eIS_Scan_Discover , \ - vInfo.address().toString() , \ - vInfo.name(), "" , \ - _local->pairingStatus(vInfo.address()) , \ - 0 , \ - vInfo.isValid() , \ - vInfo.deviceUuid().toString() )); -#define NOTIFY_SCAN_FOUND _model = MBluetooth(MBluetooth::eIS_Scan_Found , \ - _info.address().toString() , \ - _info.name(), "" , \ - _local->pairingStatus(vInfo.address()) , \ - 0 , \ - _info.isValid() , \ - _info.deviceUuid().toString() );\ - notifyStateChange(_model ); + vInfo.address().toString() , \ + vInfo.name(), "" , \ + _local->pairingStatus(vInfo.address()) , \ + 0 , \ + vInfo.isValid() , \ + vInfo.deviceUuid().toString() )); +#define NOTIFY_SCAN_FOUND notifyStateChange(MBluetooth(MBluetooth::eIS_Scan_Found , \ + _temp.address().toString() , \ + _temp.name(), "" , \ + _local->pairingStatus(_temp.address()) , \ + 0 , \ + _temp.isValid() , \ + _temp.deviceUuid().toString() )); #define NOTIFY_SCAN_START notifyStateChange(MBluetooth(MBluetooth::eIS_Scan_Start )); #define NOTIFY_SCAN_REJECT notifyStateChange(MBluetooth(MBluetooth::eIS_Scan_Reject )); #define NOTIFY_SCAN_NOTFOUND notifyStateChange(MBluetooth(MBluetooth::eIS_Scan_NotFound ,"", "" )); #define NOTIFY_SCAN_STOP notifyStateChange(MBluetooth(MBluetooth::eIS_Scan_Stop )); #define NOTIFY_SCAN_DONE notifyStateChange(MBluetooth(MBluetooth::eIS_Scan_Done )); -#define NOTIFY_SCAN_DETAIL notifyStateChange(MBluetooth(MBluetooth::eIS_Scan_Detail , \ - _info.address().toString() , \ - _info.name() )); // ~~~~~~~~~ Device #define NOTIFY_DEVICE_INIT_ERROR notifyStateChange(MBluetooth(MBluetooth::eIS_Device_Error_Init )); #define NOTIFY_DEVICE_INIT notifyStateChange(MBluetooth(MBluetooth::eIS_Device_Init , \ - _info.address().toString() , \ - _info.name() )); + _device->remoteAddress().toString() , \ + _device->remoteName() )); #define NOTIFY_DEVICE_START notifyStateChange(MBluetooth(MBluetooth::eIS_Device_Start , \ - _info.address().toString() , \ - _info.name() )); + _device->remoteAddress().toString() , \ + _device->remoteName() )); #define NOTIFY_DEVICE_CONNECT notifyStateChange(MBluetooth(MBluetooth::eIS_Device_Connect , \ - _info.address().toString() , \ - _info.name() )); + _device->remoteAddress().toString() , \ + _device->remoteName() )); #define NOTIFY_DEVICE_DONE notifyStateChange(MBluetooth(MBluetooth::eIS_Device_Done , \ - _info.address().toString() , \ - _info.name() )); + _device->remoteAddress().toString() , \ + _device->remoteName() )); #define NOTIFY_DEVICE_ERROR notifyStateChange(MBluetooth(MBluetooth::eIS_Device_Error , \ - _info.address().toString() , \ - _info.name() , \ - "",0, vError, false )); + _device->remoteAddress().toString() , \ + _device->remoteName() , \ + "",0, vError, false )); #define NOTIFY_DEVICE_DISCONNECT notifyStateChange(MBluetooth(MBluetooth::eIS_Device_Disconnect , \ - _info.address().toString() , \ - _info.name() )); + _device->remoteAddress().toString() , \ + _device->remoteName() )); #define NOTIFY_SERVICE_START notifyStateChange(MBluetooth(MBluetooth::eIS_Service_Start )); +#define NOTIFY_SERVICE_DISCOVER notifyStateChange(MBluetooth(MBluetooth::eIS_Service_Discover )); +#define NOTIFY_SERVICE_DETAILS(vS) notifyStateChange(MBluetooth(MBluetooth::eIS_Service_Detail , \ + _device->remoteAddress().toString() , \ + _device->remoteName(), "" , \ + _local->pairingStatus(_device->remoteAddress()), 0, 1 , \ + vS->serviceUuid().toString() , \ + vS->serviceName() )); +#define NOTIFY_SERVICE_ERROR notifyStateChange(MBluetooth(MBluetooth::eIS_Service_Error , \ + _device->remoteAddress().toString() , \ + _device->remoteName(), "" , \ + _local->pairingStatus(_device->remoteAddress()), vError, 0 , \ + service->serviceUuid().toString() , \ + service->serviceName() )); +#define NOTIFY_SERVICE_DONE notifyStateChange(MBluetooth(MBluetooth::eIS_Service_Done )); + +#define NOTIFY_DETAILS_ERROR notifyStateChange(MBluetooth(MBluetooth::eIS_Service_Detail_Error , \ + _device->remoteAddress().toString() , \ + _device->remoteName(), "" , \ + _local->pairingStatus(_device->remoteAddress()), vState, 0 , \ + service->serviceUuid().toString() , \ + service->serviceName() )); +#define NOTIFY_DETAILS_INVALID notifyStateChange(MBluetooth(MBluetooth::eIS_Service_Detail_Invalid )); +#define NOTIFY_SERVICE_DETAILS_DONE notifyStateChange(MBluetooth(MBluetooth::eIS_Service_Detail_Done , \ + _device->remoteAddress().toString() , \ + _device->remoteName(), "" , \ + _local->pairingStatus(_device->remoteAddress()), vState, 0 , \ + service->serviceUuid().toString() , \ + service->serviceName() )); + + /* #define NOTIFY_SERVICE_DISCOVER notifyStateChange(MBluetooth(MBluetooth::eIS_Service_Discover , \ _service->serviceUuid().toString() , \ @@ -237,13 +259,8 @@ void BluetoothInterface::onstart() { _local->powerOn(); - if (! _local->isValid() ) { - NOTIFY_LOCAL_ERROR_INVALID - return; - } - - resetDevice(); - + if ( ! isLocalValid() ) return; + quitDevice(); _agent->setLowEnergyDiscoveryTimeout(5000); NOTIFY_LOCAL_INIT NOTIFY_IDLE @@ -288,50 +305,13 @@ } /*! - * \brief BluetoothInterface::onLocalPairingDisplayConfirmation - * \details Notifies the observers (view: VBluetooth) that the user needs to confirm paring. - * \param vAddress - remote device address - * \param vPin - remote device requested pin code - * \note Not used for now just logged for later use. - */ -void BluetoothInterface::onLocalPairingDisplayConfirmation (const QBluetoothAddress &vAddress, const QString &vPin ) { - NOTIFY_PAIR_CONFIRM -} - -/*! - * \brief BluetoothInterface::onLocalPairingDisplayPinCode - * \details Notifies the observers (view: VBluetooth) the pin code to make sure this is the device it intends to connect. - * Signal by some platforms to display the pin to the user for address. - * The pin is automatically generated, and does not need to be confirmed. - * \param vAddress - * \param vPin - * \note Not used for now just logged for later use. - */ -void BluetoothInterface::onLocalPairingDisplayPinCode (const QBluetoothAddress &vAddress, const QString &vPin ) { - NOTIFY_PAIR_PINCODE -} - -/*! - * \brief BluetoothInterface::onLocalPairingFinish - * \details Notifies the observers (view: VBluetooth) that the paring is successfully done - * \param vAddress - Paired remote address - * \param vPairing - The Paring status/Type - */ -void BluetoothInterface::onLocalPairingFinish (const QBluetoothAddress &vAddress, QBluetoothLocalDevice::Pairing vPairing ) { - NOTIFY_PAIR_DONE -} - -/*! * \brief BluetoothInterface::onLocalError * \details Notifies the observers (view: VBluetooth) that the local adapter has error * \param vError - The error */ -void BluetoothInterface::onLocalError ( QBluetoothLocalDevice::Error vError) { - switch (vError) { - case QBluetoothLocalDevice::PairingError: NOTIFY_PAIR_ERROR break; - default : NOTIFY_LOCAL_ERROR break; - } - if ( _device ) _device->disconnectFromDevice(); +void BluetoothInterface::onLocalError ( QBluetoothLocalDevice::Error /*vError*/ ) { + NOTIFY_LOCAL_ERROR + quitDevice(); } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -350,7 +330,7 @@ NOTIFY_SCAN_DISCOVER if (vInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) { if ( isDeviceSupported( vInfo.name() ) ) { - _info = QBluetoothDeviceInfo(vInfo.address(), vInfo.name(), QBluetoothDeviceInfo::HealthBloodPressureMonitor); + _temp = QBluetoothDeviceInfo(vInfo.address(), vInfo.name(), QBluetoothDeviceInfo::HealthBloodPressureMonitor); NOTIFY_SCAN_FOUND if (_agent->isActive()) _agent->stop(); @@ -400,8 +380,9 @@ * \brief BluetoothInterface::connectToDevice * \return false if * the local Bluetooth device _local is not valid - * the device info _info is not valid - * + * the device info _temp is not valid. + * notifies the observers (view: VBluetooth) that the state is MBluetooth::eIS_Device_Start, + * on successfully connecting initializing the remove Bluetooth device _device. */ bool BluetoothInterface::connectToDevice() { @@ -415,103 +396,250 @@ return true; } +/*! + * \brief BluetoothInterface::discoverServices + * \details The function to be called to start retrieving the remote Bluetooth device _device's services, and + * notifies the observers (view: VBluetooth) that the state is MBluetooth::eIS_Service_Start. + */ +void BluetoothInterface::discoverServices() +{ + NOTIFY_SERVICE_START + _device->discoverServices(); +} + +/*! + * \brief BluetoothInterface::onDeviceConnect + * \details The slot to be called when the remote Bluetooth device _device is connected to start to retrieve its services, + * by calling discoverServices(). + * notifies the observers (view: VBluetooth) that the state is MBluetooth::eIS_Device_Connect. + */ void BluetoothInterface::onDeviceConnect() { NOTIFY_DEVICE_CONNECT - _device->discoverServices(); - NOTIFY_SERVICE_START + discoverServices(); } +/*! + * \brief BluetoothInterface::onDeviceDisconnect + * \details The slot to be called when the remote Bluetooth device _device is disconnected, and + * notifies the observers (view: VBluetooth) that the state is MBluetooth::eIS_Device_Disconnect. + */ void BluetoothInterface::onDeviceDisconnect() { NOTIFY_DEVICE_DISCONNECT } -void BluetoothInterface::onDeviceError(QLowEnergyController::Error vError) +void BluetoothInterface::onDeviceDiscoverService(const QBluetoothUuid &vService) { - NOTIFY_DEVICE_ERROR + initServices(vService); } -void BluetoothInterface::onDeviceStateChanged(QLowEnergyController::ControllerState vState) +void BluetoothInterface::onDeviceDiscoverFinish() { - // qDebug() << "Device State Changed" << vState; + NOTIFY_SERVICE_DISCOVER + discoverServicesDetails(); } -void BluetoothInterface::onDeviceConnectionUpdated(const QLowEnergyConnectionParameters &/*vParameters*/) +void BluetoothInterface::discoverServicesDetails() { - // qDebug() << "Device Connection Changed"; + if ( _serviceDeviceInformation ) { + NOTIFY_SERVICE_DETAILS (_serviceDeviceInformation ) + _serviceDeviceInformation ->discoverDetails(); + } + if ( _serviceCurrentTime ) { + NOTIFY_SERVICE_DETAILS (_serviceCurrentTime ) + qDebug() << _serviceCurrentTime ->type(); + _serviceCurrentTime ->discoverDetails(); + } + if ( _serviceBloodPressure ) { + NOTIFY_SERVICE_DETAILS (_serviceBloodPressure ) + qDebug() << _serviceBloodPressure ->type(); + _serviceBloodPressure ->discoverDetails(); + } + if ( _serviceBattery ) { + NOTIFY_SERVICE_DETAILS (_serviceBattery ) + qDebug() << _serviceBattery ->type(); + _serviceBattery ->discoverDetails(); + } } -bool BluetoothInterface::initDevice() +/*! + * \brief BluetoothInterface::onDeviceError + * \details The slot to be called when the remote Bluetooth device _device has an error vError, and + * notifies the observers (view: VBluetooth) that the state is MBluetooth::eIS_Device_Error. + * \param vError + */ +void BluetoothInterface::onDeviceError(QLowEnergyController::Error vError) { - if ( _device ) { - _device->disconnectFromDevice(); - delete _device; - _device = nullptr; + NOTIFY_DEVICE_ERROR +} + +void BluetoothInterface::onServiceCharacteristicChanged(const QLowEnergyCharacteristic &vCharacteristic, const QByteArray &vValue) { + qDebug() << " ..... Service Charc C:" << vCharacteristic.name() << vValue; + if (vCharacteristic.uuid() == QBluetoothUuid(QBluetoothUuid::BloodPressureMeasurement)) + { + parseMeasurement(vValue); } - _device = QLowEnergyController::createCentral(_info, this); - if ( _device ) NOTIFY_DEVICE_INIT - else { NOTIFY_DEVICE_INIT_ERROR - return false; - } +} +void BluetoothInterface::parseMeasurement(const QByteArray &byteArray) +{ + MeasurementData measurement; +// const uint8_t *d = reinterpret_cast(byteArray.constData()); + const uchar *d = reinterpret_cast(byteArray.constData()); + + measurement.flags = *d; + measurement.systolic = d[1]; + measurement.diastolic = d[3]; + measurement.mean_arterial_pressure_value= d[5]; + measurement.year = d[7]; + measurement.month = d[9]; + measurement.day = d[10]; + measurement.hour = d[11]; + measurement.minute = d[12]; + measurement.second = d[13]; + measurement.pulse_rate = d[14]; + measurement.user_id = d[16]; + measurement.measurement_status = d[17]; + + qDebug() << measurement.flags + << measurement.systolic + << measurement.diastolic + << measurement.mean_arterial_pressure_value + << measurement.year + << measurement.month + << measurement.day + << measurement.hour + << measurement.minute + << measurement.second + << measurement.pulse_rate + << measurement.user_id + << measurement.measurement_status ; + // emit didReceiveBPMeasurement(measurement); +} + +/*! + * \brief BluetoothInterface::initConnectionsDevice + * \details sets up the remote Bluetooth device _device connections. + */ +void BluetoothInterface::initConnectionsDevice() { // Device controller connect( _device, SIGNAL( connected ( )), this , SLOT(onDeviceConnect ( ))); connect( _device, SIGNAL( error (QLowEnergyController::Error )), this , SLOT(onDeviceError (QLowEnergyController::Error ))); connect( _device, SIGNAL( disconnected ( )), this , SLOT(onDeviceDisconnect ( ))); - connect( _device, SIGNAL( stateChanged(QLowEnergyController::ControllerState )), - this , SLOT(onDeviceStateChanged(QLowEnergyController::ControllerState ))); - connect( _device, SIGNAL( connectionUpdated(QLowEnergyConnectionParameters )), - this , SLOT(onDeviceConnectionUpdated(QLowEnergyConnectionParameters ))); // Device Services - connect( _device, &QLowEnergyController::serviceDiscovered, [=](const QBluetoothUuid &vService){ - if (vService == QBluetoothUuid (QBluetoothUuid::DeviceInformation )) { - if ( _serviceDeviceInformation )S - delete _serviceDeviceInformation ; - _serviceDeviceInformation = _device->createServiceObject(vService, this); - qDebug() << " ~~~~~ Inf Service Found" << vService; - return; + connect( _device, SIGNAL(serviceDiscovered (const QBluetoothUuid &)), + this , SLOT(onDeviceDiscoverService(const QBluetoothUuid &))); + connect( _device, SIGNAL(discoveryFinished ()), + this , SLOT(onDeviceDiscoverFinish ())); +} + +void BluetoothInterface::initConnectionsService(QLowEnergyService *vService) +{ + if ( ! vService ) return; + + connect(vService, SIGNAL( characteristicChanged (const QLowEnergyCharacteristic &, const QByteArray &)), + this , SLOT(onServiceCharacteristicChanged (const QLowEnergyCharacteristic &, const QByteArray &))); + + connect(vService, SIGNAL( characteristicChanged (const QLowEnergyCharacteristic &, const QByteArray &)), + this , SLOT(onServiceCharacteristicChanged (const QLowEnergyCharacteristic &, const QByteArray &))); + connect(vService, SIGNAL( characteristicRead (const QLowEnergyCharacteristic &, const QByteArray &)), + this , SLOT(onServiceCharacteristicRead (const QLowEnergyCharacteristic &, const QByteArray &))); + connect(vService, SIGNAL( characteristicWritten (const QLowEnergyCharacteristic &, const QByteArray &)), + this , SLOT(onServiceCharacteristicWritten (const QLowEnergyCharacteristic &, const QByteArray &))); + + connect(vService, SIGNAL( descriptorRead (const QLowEnergyDescriptor &, const QByteArray &)), + this , SLOT(onServiceDescriptorRead (const QLowEnergyDescriptor &, const QByteArray &))); + connect(vService, SIGNAL( descriptorWritten (const QLowEnergyDescriptor &, const QByteArray &)), + this , SLOT(onServiceDescriptorWritten (const QLowEnergyDescriptor &, const QByteArray &))); + + connect(vService, SIGNAL( error ( QLowEnergyService::ServiceError )), + this , SLOT(onServiceError ( QLowEnergyService::ServiceError ))); + connect(vService, SIGNAL( stateChanged ( QLowEnergyService::ServiceState )), + this , SLOT(onServiceStateChanged ( QLowEnergyService::ServiceState ))); +} + +void BluetoothInterface::onServiceError(QLowEnergyService::ServiceError vError) { + QLowEnergyService *service = reinterpret_cast(sender()); + NOTIFY_SERVICE_ERROR +} + +void BluetoothInterface::onServiceStateChanged(QLowEnergyService::ServiceState vState) { + QLowEnergyService *service = reinterpret_cast(sender()); + qDebug() << "Service State:" << service->serviceUuid() << service->serviceName() << vState; + switch (vState) { + case QLowEnergyService::InvalidService : + NOTIFY_DETAILS_ERROR + break; + + case QLowEnergyService::ServiceDiscovered : + NOTIFY_SERVICE_DETAILS_DONE + for ( auto const &detail: service->characteristics()) { + qDebug() << " ~~~~~ " << detail.name() << detail.uuid() << detail.value(); } - if (vService == QBluetoothUuid (QBluetoothUuid::CurrentTimeService )) { - if ( _serviceCurrentTime ) - delete _serviceCurrentTime ; - _serviceCurrentTime = _device->createServiceObject(vService, this); - qDebug() << " ~~~~~ TDt Service Found" << vService; - return; + if ( service->serviceUuid() == QBluetoothUuid (QBluetoothUuid::BloodPressure)) { + // blood pressure measurements + const QLowEnergyCharacteristic detailBPMeas = service->characteristic(QBluetoothUuid(QBluetoothUuid::BloodPressureMeasurement)); + QLowEnergyDescriptor configBPMeas = detailBPMeas.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (configBPMeas.isValid()) service->writeDescriptor(configBPMeas, QByteArray::fromHex("0100")); + + // blood pressure feature + const QLowEnergyCharacteristic detailBPFeat = service->characteristic(QBluetoothUuid(QBluetoothUuid::BloodPressureFeature)); + if (!detailBPFeat.isValid()) { + qDebug() << "Blood pressure feature not found."; + return; + } + service->readCharacteristic(detailBPFeat); + _connectionActive = true; } - if (vService == QBluetoothUuid (QBluetoothUuid::BloodPressure )) { - if ( _serviceBloodPressure ) - delete _serviceBloodPressure ; - _serviceBloodPressure = _device->createServiceObject(vService, this); - qDebug() << " ~~~~~ BPr Service Found" << vService; - return; - } - if (vService == QBluetoothUuid (QBluetoothUuid::BatteryService )) { - if ( _serviceBattery ) - delete _serviceBattery ; - _serviceBattery = _device->createServiceObject(vService, this); - qDebug() << " ~~~~~ Bat Service Found" << vService; - return; - } - }); - connect(_device, &QLowEnergyController::discoveryFinished, [=](){ - // _serviceInformation->discoverDetails(); - NOTIFY_DEVICE_DONE - _device->disconnectFromDevice(); - }); + break; + + default: + break; + + } +} +/*! + * \brief BluetoothInterface::initDevice + * \return Initializes the device by making a new device and initializes its connections + */ +bool BluetoothInterface::initDevice() +{ + if ( ! makeDevice() ) return false; + initConnectionsDevice(); return true; } /*! + * \brief BluetoothInterface::makeDevice + * \details Makes a device by disconnect and delete the old one and create a new one, and + * validates if the device was created successfully, and + * notifies the observers (view: VBluetooth) that the state is + * MBluetooth::eIS_Device_Init if succeeded, or the state is + * MBluetooth::eIS_Device_Error_Init if failed. + * \return returns true if the remote Bluetooth device _device is created successfully, false otherwise. + */ +bool BluetoothInterface::makeDevice() +{ + quitDevice(); + _device = QLowEnergyController::createCentral(_temp, this); + _temp = QBluetoothDeviceInfo(); + if ( _device ) NOTIFY_DEVICE_INIT + else { NOTIFY_DEVICE_INIT_ERROR + return false; + } + return true; +} + +/*! * \brief BluetoothInterface::notifyStateChange * \details sends a notification signal to the observers (view: VBluetooth) on any reported state changes. * \param vData - the Bluetooth data model containing information about the current state and device. */ void BluetoothInterface::notifyStateChange(const BluetoothData &vData) { - _state = vData.state; emit didStateChange(vData); } @@ -522,7 +650,10 @@ */ void BluetoothInterface::timerEvent(QTimerEvent *) { - if ( _bpRead ) { } + if ( _connectionActive ) { + if ( _device ) + _device->connectToDevice(); + } } /*! @@ -553,15 +684,15 @@ /*! * \brief BluetoothInterface::isInfoValid - * \details checks if the device info _info is valid. + * \details checks if the device info _temp is valid. * notifies the observers (view: VBluetooth) that the device info is not valid. * \return false if the device info _local is not valid - * \note the device info _info is set to a default QBluetoothDeviceInfo which is invalid by default, + * \note the device info _temp is set to a default QBluetoothDeviceInfo which is invalid by default, * when the interface initialized (onStart), and * when a scan started (ondoScan) */ bool BluetoothInterface::isInfoValid() { - if ( ! _info.isValid() ) { + if ( ! _temp.isValid() ) { NOTIFY_SCAN_NOTFOUND // not a valid device found return false; } @@ -581,15 +712,92 @@ return true; } +// bool BluetoothInterface::isServiceValid(QLowEnergyService *vService) +// { +// if ( vService ) { NOTIFY_SERVICE_INIT } +// else { NOTIFY_SERVICE_INIT_ERROR +// return false; +// } +// return true; +// } + +bool BluetoothInterface::isDetailValid(const QLowEnergyCharacteristic &vDetail) +{ + if ( ! vDetail.isValid() ) { + NOTIFY_DETAILS_INVALID + return false; + } + return true; +} + /*! - * \brief BluetoothInterface::resetDevice - * \details resets the remote device _device and the device info _info. + * \brief BluetoothInterface::quitDevice + * \details quits and deletes the old remote device _device and the device info _temp. */ -void BluetoothInterface::resetDevice() { - _info = QBluetoothDeviceInfo(); // reset the found info +void BluetoothInterface::quitDevice() { + _connectionActive = false; if ( _device ) { + NOTIFY_DEVICE_DONE + quitServices(); // it seems safe to delete all the services when the device is deleted because the current discovered service may not apply to the next device. _device->disconnectFromDevice(); delete _device; _device = nullptr; } } + +/*! + * \brief BluetoothInterface::initService + * \details + */ +void BluetoothInterface::initServices(const QBluetoothUuid &vService) +{ + makeServices(vService); +} + +void BluetoothInterface::makeServices(const QBluetoothUuid &vService) +{ + if (vService == QBluetoothUuid (QBluetoothUuid::DeviceInformation )) { + _serviceDeviceInformation = _device->createServiceObject(vService, this); + initConnectionsService (_serviceDeviceInformation ); + return; + } + if (vService == QBluetoothUuid (QBluetoothUuid::CurrentTimeService )) { + _serviceCurrentTime = _device->createServiceObject(vService, this); + initConnectionsService (_serviceCurrentTime ); + return; + } + if (vService == QBluetoothUuid (QBluetoothUuid::BloodPressure )) { + _serviceBloodPressure = _device->createServiceObject(vService, this); + initConnectionsService (_serviceBloodPressure ); + return; + } + if (vService == QBluetoothUuid (QBluetoothUuid::BatteryService )) { + _serviceBattery = _device->createServiceObject(vService, this); + initConnectionsService (_serviceBattery ); + return; + } +} + +/*! + * \brief BluetoothInterface::quitServices + * \details quits and deletes the old remote services. + */ +void BluetoothInterface::quitServices() { + NOTIFY_SERVICE_DONE + if ( _serviceDeviceInformation ) { + delete _serviceDeviceInformation ; + _serviceDeviceInformation = nullptr; + } + if ( _serviceCurrentTime ) { + delete _serviceCurrentTime ; + _serviceCurrentTime = nullptr; + } + if ( _serviceBloodPressure ) { + delete _serviceBloodPressure ; + _serviceBloodPressure = nullptr; + } + if ( _serviceBattery ) { + delete _serviceBattery ; + _serviceBattery = nullptr; + } +}