3 #include <QRegularExpression>
5 #define UARTSERVICEUUID "6e400001-b5a3-f393-e0a9-e50e24dcca9e"
6 #define RXUUID "6e400002-b5a3-f393-e0a9-e50e24dcca9e"
7 #define TXUUID "6e400003-b5a3-f393-e0a9-e50e24dcca9e"
11 _owner{&owner}, _mac{mac}
13 _timer = startTimer(std::chrono::milliseconds{10});
30 std::lock_guard guard(_cmdMutex);
31 _cmd += QString::fromStdString(cmd);
35 BLEProthesisInterfaceQtWorker::cleanup()
46 _control->disconnectFromDevice();
60 if (_deviceDiscoveryAgent)
62 delete _deviceDiscoveryAgent;
63 _deviceDiscoveryAgent =
nullptr;
72 qDebug() <<
'[' << _mac <<
']' <<
" Stopping NOW!";
80 _deviceDiscoveryAgent =
new QBluetoothDeviceDiscoveryAgent;
81 connect(_deviceDiscoveryAgent,
82 SIGNAL(deviceDiscovered(
const QBluetoothDeviceInfo&)),
84 SLOT(deviceDiscovered(
const QBluetoothDeviceInfo&)));
85 connect(_deviceDiscoveryAgent,
86 SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
88 SLOT(deviceDiscoverError(QBluetoothDeviceDiscoveryAgent::Error)));
89 connect(_deviceDiscoveryAgent, SIGNAL(finished()),
this, SLOT(deviceDiscoverFinished()));
90 connect(_deviceDiscoveryAgent, SIGNAL(canceled()),
this, SLOT(deviceDiscoverFinished()));
91 qDebug() <<
'[' << _mac <<
']' <<
" State DiscoveringDevices";
93 _deviceDiscoveryAgent->start();
97 if (!_deviceDiscovered)
99 qDebug() <<
'[' << _mac <<
']' <<
" Device discovering failed!";
103 qDebug() <<
'[' << _mac <<
']' <<
" State Disconnected";
118 _serviceDiscovered =
false;
119 _control =
new QLowEnergyController(_currentDevice);
120 _control->setRemoteAddressType(QLowEnergyController::RandomAddress);
123 SIGNAL(serviceDiscovered(QBluetoothUuid)),
125 SLOT(serviceDiscovered(QBluetoothUuid)));
126 connect(_control, SIGNAL(discoveryFinished()),
this, SLOT(serviceScanDone()));
128 SIGNAL(error(QLowEnergyController::Error)),
130 SLOT(controllerError(QLowEnergyController::Error)));
131 connect(_control, SIGNAL(connected()),
this, SLOT(deviceConnected()));
132 connect(_control, SIGNAL(disconnected()),
this, SLOT(deviceDisconnected()));
133 _control->connectToDevice();
134 qDebug() <<
'[' << _mac <<
']' <<
" State Connecting";
139 _control->discoverServices();
140 qDebug() <<
'[' << _mac <<
']' <<
" State DiscoveringServices";
145 if (!_serviceDiscovered)
147 qDebug() <<
'[' << _mac <<
']' <<
" Service discovering failed!";
151 _service = _control->createServiceObject(QBluetoothUuid(QUuid(
UARTSERVICEUUID)));
154 SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
156 SLOT(serviceStateChanged(QLowEnergyService::ServiceState)));
158 SIGNAL(characteristicChanged(QLowEnergyCharacteristic, QByteArray)),
160 SLOT(readData(QLowEnergyCharacteristic, QByteArray)));
162 SIGNAL(descriptorWritten(QLowEnergyDescriptor, QByteArray)),
164 SLOT(receiveDeviceDisconnec(QLowEnergyDescriptor, QByteArray)));
166 _service->discoverDetails();
168 qDebug() <<
'[' << _mac <<
']' <<
" State ConnectingService";
173 std::lock_guard g(_cmdMutex);
174 if (_service && _cmd.size() != 0)
176 const QLowEnergyCharacteristic RxChar =
177 _service->characteristic(QBluetoothUuid(QUuid(
RXUUID)));
180 _service->writeCharacteristic(RxChar,
data, QLowEnergyService::WriteWithoutResponse);
181 if (_owner->_verboseSend)
183 qDebug() <<
'[' << _mac <<
']' <<
" send: " << _cmd;
191 BLEProthesisInterfaceQtWorker::deviceDiscovered(
const QBluetoothDeviceInfo& device)
193 if (device.address().toString() == _mac)
195 qDebug() <<
'[' << _mac <<
']' <<
" Discovered target device "
196 << device.address().toString();
197 _currentDevice = device;
198 _deviceDiscovered =
true;
199 qDebug() <<
'[' << _mac <<
']' <<
" State DiscoveringDevicesDone";
201 _deviceDiscoveryAgent->stop();
205 qDebug() <<
'[' << _mac <<
']' <<
" Discovered device " << device.address().toString();
210 BLEProthesisInterfaceQtWorker::deviceDiscoverFinished()
212 qDebug() <<
'[' << _mac <<
']' <<
" Discovering of services done.";
217 BLEProthesisInterfaceQtWorker::deviceDiscoverError(QBluetoothDeviceDiscoveryAgent::Error error)
219 if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
221 qDebug() <<
'[' << _mac <<
']'
222 <<
"The Bluetooth adaptor is powered off, power it on before doing discovery.";
224 else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
226 qDebug() <<
'[' << _mac <<
']'
227 <<
"Writing or reading from the device resulted in an error.";
231 qDebug() <<
'[' << _mac <<
']' <<
"An unknown error has occurred.";
237 BLEProthesisInterfaceQtWorker::serviceDiscovered(
const QBluetoothUuid& gatt)
239 qDebug() <<
'[' << _mac <<
']' <<
" Discovered service " << gatt.toString();
242 qDebug() <<
'[' << _mac <<
']' <<
"Discovered UART service " << gatt.toString();
243 _serviceDiscovered =
true;
249 BLEProthesisInterfaceQtWorker::serviceDiscoverFinished()
251 qDebug() <<
'[' << _mac <<
']' <<
" State DiscoveringServicesDone";
256 BLEProthesisInterfaceQtWorker::controllerError(QLowEnergyController::Error error)
258 qDebug() <<
'[' << _mac <<
']' <<
" Cannot connect to remote device.";
259 qWarning() <<
'[' << _mac <<
']' <<
" Controller Error:" << error;
264 BLEProthesisInterfaceQtWorker::receiveDeviceDisconnec(
const QLowEnergyDescriptor& d,
265 const QByteArray&
value)
267 if (d.isValid() && d == _notificationDescTx &&
value == QByteArray(
"0000"))
269 qDebug() <<
'[' << _mac <<
']' <<
"Device requests disconnect.";
271 _control->disconnectFromDevice();
281 BLEProthesisInterfaceQtWorker::serviceStateChanged(QLowEnergyService::ServiceState
s)
284 qDebug() <<
'[' << _mac <<
']' <<
" serviceStateChanged -> " <<
s;
287 case QLowEnergyService::ServiceDiscovered:
291 const QLowEnergyCharacteristic TxChar =
292 _service->characteristic(QBluetoothUuid(QUuid(
TXUUID)));
293 if (!TxChar.isValid())
295 qDebug() <<
'[' << _mac <<
']' <<
" Tx characteristic not found";
300 const QLowEnergyCharacteristic RxChar =
301 _service->characteristic(QBluetoothUuid(QUuid(
RXUUID)));
302 if (!RxChar.isValid())
304 qDebug() <<
'[' << _mac <<
']' <<
" Rx characteristic not found";
311 _notificationDescTx =
312 TxChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
313 if (_notificationDescTx.isValid())
316 _service->writeDescriptor(_notificationDescTx, QByteArray::fromHex(
"0100"));
317 qDebug() <<
'[' << _mac <<
']' <<
" State Running";
328 BLEProthesisInterfaceQtWorker::deviceConnected()
330 qDebug() <<
'[' << _mac <<
']' <<
" State ConnectingDone";
335 BLEProthesisInterfaceQtWorker::deviceDisconnected()
337 qDebug() <<
'[' << _mac <<
']' <<
" State Disconnected";
343 BLEProthesisInterfaceQtWorker::consumeData<
346 if (!_valueAkk.contains(
'\n'))
348 if (_owner->_verboseReceive)
350 qDebug() <<
'[' << _mac <<
']'
351 <<
" data does not contain \\n -> no new sensor values\n Buffer:\n"
356 auto listPacks = _valueAkk.split(
'\n');
358 if (_owner->_verboseReceive)
360 qDebug() <<
'[' << _mac <<
']' <<
" parsing " << listPacks.at(listPacks.size() - 2);
363 auto listVals = listPacks.at(listPacks.size() - 2).split(
' ');
364 _owner->_thumbPos = listVals.at(0).toLong();
365 _owner->_thumbPWM = listVals.at(1).toLong();
366 _owner->_fingerPos = listVals.at(2).toLong();
367 _owner->_fingerPWM = listVals.at(3).toLong();
369 _valueAkk = listPacks.back();
374 BLEProthesisInterfaceQtWorker::consumeData<BLEProthesisInterface::SensorValueProtocol::mx_pos_pwm>()
376 if (!_valueAkk.contains(
'\n'))
378 if (_owner->_verboseReceive)
380 qDebug() <<
'[' << _mac <<
']'
381 <<
" data does not contain \\n -> no new sensor values\n Buffer:\n"
386 auto listPacks = _valueAkk.split(
'\n');
388 static const QRegularExpression m2(
389 R
"(^M2:[ \t]+Pos.:[ \t]+(-?[1-9][0-9]*|0)[ \t]+PWM:[ \t]+(-?[1-9][0-9]*|0)[ \t\n\r]+$)");
390 static const QRegularExpression m3(
391 R
"(^M3:[ \t]+Pos.:[ \t]+(-?[1-9][0-9]*|0)[ \t]+PWM:[ \t]+(-?[1-9][0-9]*|0)[ \t\n\r]+$)");
393 for (
int i = 0; i < listPacks.size() - 1; ++i)
395 if (listPacks.at(i).size() == 0)
399 if (_owner->_verboseReceive)
401 qDebug() <<
'[' << _mac <<
']' <<
" parsing " << listPacks.at(i);
403 if (
const auto matchM2 = m2.match(listPacks.at(i)); matchM2.hasMatch())
405 _owner->_thumbPos = matchM2.captured(1).toLong();
406 _owner->_thumbPWM = matchM2.captured(2).toLong();
407 if (_owner->_verboseReceive)
409 qDebug() <<
'[' << _mac <<
']' <<
" updated M2";
412 else if (
const auto matchM3 = m3.match(listPacks.at(i)); matchM3.hasMatch())
414 _owner->_fingerPos = matchM3.captured(1).toLong();
415 _owner->_fingerPWM = matchM3.captured(2).toLong();
416 if (_owner->_verboseReceive)
418 qDebug() <<
'[' << _mac <<
']' <<
" updated M3";
423 qWarning() <<
"unknown format for data: " << listPacks.at(i).toLocal8Bit()
427 _valueAkk = listPacks.back();
431 BLEProthesisInterfaceQtWorker::readData(
const QLowEnergyCharacteristic&
c,
const QByteArray&
value)
434 if (
c.uuid() != QBluetoothUuid(QUuid(
TXUUID)))
438 if (_owner->_verboseReceive)
440 qDebug() <<
'[' << _mac <<
']' <<
" received : " <<
value;
443 _valueAkk.append(
value.data());
445 switch (_owner->_protocol)
448 consumeData<BLEProthesisInterface::SensorValueProtocol::tpos_tpwm_fpos_fpwm>();
451 consumeData<BLEProthesisInterface::SensorValueProtocol::mx_pos_pwm>();