2024-11-25 17:15:44 +08:00

228 lines
7.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ble.h"
BLE::BLE(QObject *parent) : QObject(parent)
{
init();
}
BLE::~BLE()
{
delete m_LowController;
delete m_DiscoveryAgent;
servicesList.clear();
characterList.clear();
bleDevicesList.clear();
}
void BLE::init()
{
m_DiscoveryAgent = new QBluetoothDeviceDiscoveryAgent();
m_DiscoveryAgent->setLowEnergyDiscoveryTimeout(5000);
connect(m_DiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered,[=](const QBluetoothDeviceInfo &info){
if (info.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration){
qDebug()<<info.name()<<info.address().toString();
bleDevicesList.append(info);
}
});
connect(m_DiscoveryAgent, QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(&QBluetoothDeviceDiscoveryAgent::error),[=](QBluetoothDeviceDiscoveryAgent::Error error){
if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError){
qDebug("The Bluetooth is powered off.");
}
else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError) {
qDebug("Writing or reading from the device resulted in an error.");
}
});
connect(m_DiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, [=]{
if (bleDevicesList.isEmpty())
qDebug("No Low Energy devices found...");
else
qDebug("Scan finished!");
emit signal_scanFinished();
isScanning = false;
});
}
//开始扫描设备
void BLE::startScanDevices()
{
//清空设备列表
bleDevicesList.clear();
//开始扫描
m_DiscoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
if(m_DiscoveryAgent->isActive()){
qDebug("Scanning.\n");
isScanning = true;
}
}
//连接设备
void BLE::connectDevice(QString address)
{
for(auto dev : bleDevicesList){
if(dev.address().toString() == address){
nowDevice = dev;
}
}
if(!nowDevice.isValid()){
qDebug("Not a valid device");
return;
}
servicesList.clear();
characterList.clear();
if (m_LowController && previousAddress != nowDevice.address().toString()) {
m_LowController->disconnectFromDevice();
delete m_LowController;
m_LowController = nullptr;
}
if (!m_LowController) {
m_LowController = QLowEnergyController::createCentral(nowDevice);
connect(m_LowController, &QLowEnergyController::connected,[=](){
qDebug("Device connect success.");
m_LowController->discoverServices();
});
connect(m_LowController, QOverload<QLowEnergyController::Error>::of(&QLowEnergyController::error),[=](QLowEnergyController::Error){
qDebug()<<"Error : "+m_LowController->errorString();
});
connect(m_LowController, &QLowEnergyController::disconnected,[=]{
qDebug("Device disconnected.");
});
connect(m_LowController, &QLowEnergyController::serviceDiscovered,[=]{
//
});
connect(m_LowController, &QLowEnergyController::discoveryFinished,[=]{
qDebug("Services scan finished.");
servicesUUIDList = m_LowController->services();
for(auto s : servicesUUIDList){
qDebug()<<s.toString();
}
emit signal_findservicesFinished();
});
}
m_LowController->connectToDevice();
previousAddress = nowDevice.address().toString();
}
void BLE::connectService(QString uuid)
{
QLowEnergyService *service = nullptr;
for(int i=0;i<servicesUUIDList.length();i++)
{
if(servicesUUIDList.at(i).toString() == uuid){
service = m_LowController->createServiceObject(servicesUUIDList.at(i));
}
}
if (!service)
return;
characterList.clear();
if (service->state() == QLowEnergyService::DiscoveryRequired) {
connect(service, &QLowEnergyService::stateChanged,this, &BLE::serviceDetailsDiscovered);
service->discoverDetails();
return;
}
}
void BLE::serviceDetailsDiscovered(QLowEnergyService::ServiceState newState)
{
qDebug()<<"State : "<<newState;
if (newState != QLowEnergyService::ServiceDiscovered) {
if (newState != QLowEnergyService::DiscoveringServices) {
}
return;
}
auto service = qobject_cast<QLowEnergyService *>(sender());
if (!service){
return;
}
//BLE设备特征值改变
connect(service, &QLowEnergyService::characteristicChanged,[=](const QLowEnergyCharacteristic &c, const QByteArray &value){
QString Charuuid = c.uuid().toString();
QString Value = value.toHex();
qDebug()<<"BLE设备-"+Charuuid+"特性值发生变化:"+ Value;
});
//当特征读取请求成功返回其值时,发出此信号。
connect(service,&QLowEnergyService::characteristicRead,[=](const QLowEnergyCharacteristic &c, const QByteArray &value){
QString Charname = c.uuid().toString();
QString Value = value.toHex();
qDebug()<<"BLE设备-"+Charname+"特性值读取到的值:"+ Value;
});
//当特性值成功更改为newValue时会发出此信号。
connect(service,&QLowEnergyService::characteristicWritten,[=](const QLowEnergyCharacteristic &c, const QByteArray &value){
QString Charname = c.uuid().toString();
QString Value = value.toHex();
qDebug()<<"BLE设备-"+Charname+"特性值成功写入值:"+ Value;
});
//描述符修改
connect(service,&QLowEnergyService::descriptorWritten,[=](const QLowEnergyDescriptor &descriptor, const QByteArray &newValue){
QString Charname = QString("%1").arg(descriptor.name());
qDebug()<<"BLE设备-"+Charname+"描述符成功写入值:"+ QString(newValue);
});
//各种错误信息
connect(service, static_cast<void(QLowEnergyService::*)(QLowEnergyService::ServiceError)>(&QLowEnergyService::error),
[=](QLowEnergyService::ServiceError newErrorr)
{
if(QLowEnergyService::NoError == newErrorr){
qDebug()<<"没有发生错误。\n";
}
if(QLowEnergyService::OperationError==newErrorr){
qDebug()<<"错误: 当服务没有准备好时尝试进行操作!\n";
}
if(QLowEnergyService::CharacteristicReadError==newErrorr){
qDebug()<<"尝试读取特征值失败!\n";
}
if(QLowEnergyService::CharacteristicWriteError==newErrorr){
qDebug()<<"尝试为特性写入新值失败!\n";
}
if(QLowEnergyService::DescriptorReadError==newErrorr){
qDebug()<<"尝试读取描述符值失败!\n";
}
if(QLowEnergyService::DescriptorWriteError==newErrorr){
qDebug()<<"尝试向描述符写入新值失败!\n";
}
if(QLowEnergyService::UnknownError==newErrorr){
qDebug()<<"与服务交互时发生未知错误!\n";
}
});
characterList = service->characteristics();
emit signal_findcharsFinished();
for(auto s : characterList){
qDebug()<<s.uuid();
}
for (const QLowEnergyCharacteristic &ch : characterList) {
if(ch.isValid()){
if(ch.properties() & QLowEnergyCharacteristic::Notify){
QLowEnergyDescriptor notice = ch.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
if(notice.isValid()){
service->writeDescriptor(notice,QByteArray::fromHex("0100"));
}
}
if(ch.properties() & QLowEnergyCharacteristic::WriteNoResponse || ch.properties() & QLowEnergyCharacteristic::Write){
QByteArray arr;
arr.resize(20);
for(int i=0;i<20;i++){
arr[i] = static_cast<char>(i);
}
service->writeCharacteristic(ch,arr);
}
if(ch.properties() & QLowEnergyCharacteristic::Read){
service->readCharacteristic(ch);
}
}
}
}