我有一个与BLE设备通信的应用程序。它运作良好,但一段时间后我得到错误:
qt.bluetooth.bluez: void QBluetoothSocketPrivate::_q_readNotify() 22
error: -1 "Function not implemented"
Controller
Error: 1 Remote device disconnected
我的设备已断开连接。 从设备接收值时会发生此错误
我找不到问题。我在Ubuntu 16.04(Qt 5.4)下的两台计算机上运行应用程序。该问题仅发生在第二台计算机上。我比较了两台计算机的包装,但没有发现任何差异。
我的bluez版本是:5.37-0ubuntu5
#include "myapp.h"
#include <QCoreApplication>
MyApp::MyApp()
: m_deviceDiscoveryAgent(0)
, m_controller(0)
, m_service(0)
, num(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(deviceScanError(QBluetoothDeviceDiscoveryAgent::Error)));
connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));
connect(m_deviceDiscoveryAgent, SIGNAL(canceled()), this, SLOT(scanCancel()));
qDebug()<<("Scanning for devices...");
m_deviceDiscoveryAgent->start();
}
MyApp::~MyApp()
{
delete m_deviceDiscoveryAgent;
delete m_controller;
delete m_service;
}
void MyApp::addDevice(const QBluetoothDeviceInfo &device)
{
if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
qDebug()<<device.address().toString();
}
}
void MyApp::scanServices(const QString &address)
{
qDebug()<<"scan service"<<address;
QBluetoothDeviceInfo device;
for(int i=0; i<m_deviceDiscoveryAgent->discoveredDevices().length(); i++) {
if(m_deviceDiscoveryAgent->discoveredDevices().at(i).address().toString()
== address) {
qDebug()<<"I find my service";
device = m_deviceDiscoveryAgent->discoveredDevices().at(i);
}
}
if (m_controller) {
qDebug()<<m_controller<<m_controller->remoteAddress() <<device.address();
if(m_controller->remoteAddress() != device.address()) {
m_controller->disconnectFromDevice();
delete m_controller;
m_controller = 0;
}
}
if (!m_controller) {
// Connecting signals and slots for connec DeviceInfo m_currentDevice;
m_controller = new QLowEnergyController(device.address());
connect(m_controller, SIGNAL(connected()),
this, SLOT(deviceConnected()));
connect(m_controller, SIGNAL(error(QLowEnergyController::Error)),
this, SLOT(controllerError(QLowEnergyController::Error)));
connect(m_controller, SIGNAL(disconnected()),
this, SLOT(deviceDisconnected()));
connect(m_controller, SIGNAL(serviceDiscovered(QBluetoothUuid)),
this, SLOT(serviceDiscovered(QBluetoothUuid)));
connect(m_controller, SIGNAL(discoveryFinished()),
this, SLOT(serviceScanDone()));
}
m_controller->connectToDevice();
}
void MyApp::scanFinished()
{
qDebug()<<"scanFinished()";
scanServices("xx:xx:xx:xx:xx:xx");
}
void MyApp::scanCancel()
{
qDebug()<<"scan cancel";
}
void MyApp::deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error)
{
if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
qDebug()<<("The Bluetooth adaptor is powered off, power it on before doing discovery.");
else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
qDebug()<<("Writing or reading from the device resulted in an error.");
else
qDebug()<<("An unknown error has occurred.");
}
void MyApp::serviceDiscovered(const QBluetoothUuid &gatt)
{
qDebug()<<"serviceDiscovered"<<gatt<<UUID_AUDIO_SERVICE;
if (gatt.toString().contains(UUID_AUDIO_SERVICE) ){
qDebug()<<("Audio service discovered. Waiting for service scan to be done...");
m_service = m_controller->createServiceObject(gatt);
}
}
void MyApp::serviceScanDone()
{
qDebug()<<"service scan done";
if (!m_service) {
qDebug()<<("Service not found.");
return;
}
connect(m_service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
this, SLOT(serviceDetailsDiscovered(QLowEnergyService::ServiceState)));
connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)),
this, SLOT(updateAudioValue(QLowEnergyCharacteristic,QByteArray)));
connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByteArray)),
this, SLOT(confirmedDescriptorWrite(QLowEnergyDescriptor,QByteArray)));
qDebug()<<"start discover details";
m_service->discoverDetails();
}
void MyApp::controllerError(QLowEnergyController::Error error)
{
qDebug()<<("Cannot connect to remote device.");
qWarning() << "Controller Error:" << error;
}
void MyApp::deviceConnected()
{
qDebug()<<"deviceConnected, request discoverServices";
m_controller->discoverServices();
}
void MyApp::deviceDisconnected()
{
qWarning() << "Remote device disconnected";
}
void MyApp::serviceDetailsDiscovered(QLowEnergyService::ServiceState s)
{
qDebug()<<"service state changed"<<s;
if (s != QLowEnergyService::ServiceDiscovered) {
return;
}
QLowEnergyService *service = qobject_cast<QLowEnergyService *>(sender());
if (!service) {
qDebug()<<"service not found";
return;
}
qDebug()<<"service found"<<service->serviceUuid()<<m_service->serviceUuid();
const QList<QLowEnergyCharacteristic> chars = service->characteristics();
foreach (const QLowEnergyCharacteristic &ch, chars) {
if(ch.uuid().toString() == UUID_CHARACT_1) {
foreach (const QLowEnergyDescriptor &d, ch.descriptors()) {
qDebug()<<"\tdescriptor"<<d.name()<<d.uuid();
if(d.uuid().toString() == UUID_DESC_1) {
qDebug()<<"j'écris sur mon descriptor";
service->writeDescriptor(d, QByteArray::fromHex("0100"));
}
}
}
if(ch.uuid().toString() == UUID_CHARACT_2) {
foreach (const QLowEnergyDescriptor &d, ch.descriptors()) {
qDebug()<<"\tdescriptor"<<d.name()<<d.uuid();
if(d.uuid().toString() == UUID_DESC_2) {
qDebug()<<"j'écris sur mon descriptor";
service->writeDescriptor(d, QByteArray::fromHex("0100"));
}
}
}
}
}
void MyApp::updateAudioValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
{
qDebug()<<"updateAudioValue"<<c.uuid()<<value<<"->"<<num;
}
void MyApp::confirmedDescriptorWrite(const QLowEnergyDescriptor &d, const QByteArray &value)
{
qDebug()<<"confirmedDescriptorWrite();";
}
void MyApp::serviceError(QLowEnergyService::ServiceError e)
{
switch (e) {
case QLowEnergyService::DescriptorWriteError:
qDebug()<<("Cannot obtain HR notifications");
break;
default:
qWarning() << "HR service error:" << e;
}
}
void MyApp::connectDevice(const QBluetoothDeviceInfo& device)
{
qDebug()<<"connectDevice";
if (m_controller!=NULL) {
m_controller->disconnectFromDevice();
delete m_controller;
m_controller = 0;
}
m_controller = new QLowEnergyController(device.address(),
this);
connect(m_controller, SIGNAL(error(QLowEnergyController::Error)),
this, SLOT(controllerError(QLowEnergyController::Error)));
connect(m_controller, SIGNAL(connected()),
this, SLOT(deviceConnected()));
connect(m_controller, SIGNAL(disconnected()),
this, SLOT(deviceDisconnected()));
connect(m_controller, SIGNAL(serviceDiscovered(QBluetoothUuid)),
this, SLOT(serviceDiscovered(QBluetoothUuid)));
connect(m_controller, SIGNAL(discoveryFinished()),
this, SLOT(serviceScanDone()));
m_controller->connectToDevice();
}