当前位置:   article > 正文

c/c++ windows ble 蓝牙_windows 蓝牙广播通信

windows 蓝牙广播通信

前言:

在使用c/c++ 通过winrt 操作ble蓝牙之前,本身采用了qt的ble蓝牙库去操作,但是最后发现qt的ble只能使用在msvc+qt中使用,其他的使用的时候就会在扫描的时候没有反应,最终又只能在比较了解ble的同事帮助之下去研究 微软的使用c/c++ 通过winrt 操作ble蓝牙,另外如果不用通过广播过滤设备可以使用第三方库 WCHBleLib_MultiOS 或者是BleWinrtDll ,如果想多深入了解的话也可以参考微软写的demo BluetoothLE,关于微软操作ble接口说明文档地址是bluetoothleadvertisement

注意事项:

1.使用该方式的时候c++的版本要设置为 c++17

2.引用的头文件为:

  1. #include <windows.h>
  2. #include <iostream>
  3. #include <sstream>
  4. #include <iomanip>
  5. #include <mutex> 
  6. #include <winrt/Windows.Foundation.h>
  7. #include <winrt/Windows.Foundation.Collections.h> 
  8. #include <winrt/Windows.Devices.Bluetooth.h>
  9. #include <winrt/Windows.Devices.Enumeration.h>
  10. #include <winrt/Windows.Devices.Bluetooth.Advertisement.h>
  11. #include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
  12. #include <winrt/Windows.Storage.Streams.h>
  13. #include <winrt/Windows.Foundation.Collections.h>
  14. #include <winrt/Windows.Devices.Radios.h>
  15. #include <winrt/Windows.Web.Syndication.h>
  16. #include <windows.devices.bluetooth.h>
  17. #include <windows.foundation.h>
  18. #include<coroutine>
  19. using namespace winrt;
  20. using namespace Windows::Devices::Bluetooth;
  21. using namespace Windows::Devices::Bluetooth::Advertisement;
  22. using namespace Windows::Devices::Bluetooth::GenericAttributeProfile;
  23. using namespace winrt::Windows::Devices::Radios;
  24. using namespace Windows::Foundation;
  25. #pragma comment(lib, "windowsapp")
  26. #pragma comment(lib, "WindowsApp.lib")
  27. using namespace std;

1.获取电脑是否支持ble蓝牙和蓝牙是否打开

  1. bool BLEIsLowEnergySupported() {
  2.     auto getadapter_op = Windows::Devices::Bluetooth::BluetoothAdapter::GetDefaultAsync();
  3.     auto adapter = getadapter_op.get();
  4.     auto  supported = adapter.IsLowEnergySupported(); // 获取windows电脑是否支持ble
  5.     if (supported == false) return false;
  6.     auto async = adapter.GetRadioAsync(); //获取本地蓝牙信息
  7.     auto radio = async.get();
  8.     auto t = radio.State(); // 获取电脑蓝牙状态 0未知,1打开,2关闭,3硬件关闭或禁用
  9.     if (t != winrt::Windows::Devices::Radios::RadioState::On) {
  10.         return false;
  11.     }
  12.     return  true;
  13. }

LPWSTRT 与char 互转

  1. LPWSTR ConvertCharToLPWSTR(char* szString, WCHAR* addrchar)
  2. {
  3.     int dwLen = strlen(szString) + 1;
  4.     int nwLen = MultiByteToWideChar(CP_ACP, 0, szString, dwLen, NULL, 0);//算出合适的长度
  5.     MultiByteToWideChar(CP_ACP, 0, szString, dwLen, addrchar, nwLen);
  6.     return addrchar;
  7. }
  8. unsigned char* ConvertLPWSTRToChar(LPCTSTR widestr, unsigned char* addrchar)
  9. {
  10.     int num = WideCharToMultiByte(CP_OEMCP, NULL, widestr, -1, NULL, 0, NULL, FALSE);
  11.     WideCharToMultiByte(CP_OEMCP, NULL, widestr, -1, (char*)addrchar, num, NULL, FALSE);
  12.     return addrchar;
  13. }


 

2.扫描ble蓝牙

  1. void Scanblebackfun(BluetoothLEAdvertisementWatcher w, BluetoothLEAdvertisementReceivedEventArgs e) // 扫描到的ble蓝牙设备通过此回调方式返回{
  2.     if (e.AdvertisementType() == BluetoothLEAdvertisementType::ConnectableUndirected)
  3.     {
  4.         uint64_t address = e.BluetoothAddress(); //获取蓝牙地址,建议不用转字符串太麻烦
  5.         auto Rssi = e.RawSignalStrengthInDBm(); //获取蓝牙信号强度
  6.         //保存有效地址
  7.         BluetoothLEDevice dev = BluetoothLEDevice::FromBluetoothAddressAsync(address).get();
  8.         int cid = 0;
  9.         auto id = dev.BluetoothDeviceId(); //获取蓝牙唯一id
  10.         auto name = dev.Name(); //获取蓝牙名称
  11. char ID[50] = {0};
  12. char Name[50] = {0};
  13. ConvertLPWSTRToChar(id.Id().c_str(), (unsigned char*)ID);
  14. ConvertLPWSTRToChar(name.c_str(), (unsigned char*)Name);
  15.         auto advertisement = e.Advertisement();  //获取蓝牙广播
  16.         auto serviceUuids = advertisement.ServiceUuids(); //获取广播的服务器的uuid
  17.         auto view = serviceUuids.GetView();
  18.         bool Isfindguid = false;
  19.         for (size_t i = 0; i < view.Size(); i++)
  20.         {
  21.             auto guid = view.GetAt(i);
  22.             if (guid.Data1 == 0xf801 ) { //获取自己需要的广播
  23.                 Isfindguid = true;
  24.             }
  25.         }
  26.         dev.Close();
  27.         if (Isfindguid == false) return;
  28. }
  29. void ScanBLEDevice(int timeout) {
  30.     BluetoothLEAdvertisementWatcher m_btWatcher;
  31.     m_btWatcher.ScanningMode(BluetoothLEScanningMode::Passive); //扫描所有此时没有连接的蓝牙
  32.     m_btWatcher.Received(Scanblebackfun); // 注册扫描到的蓝牙回调
  33.     Pens.clear();
  34.     m_btWatcher.Start(); //开始扫描
  35.     Sleep(timeout);
  36.     m_btWatcher.Stop();//结束扫描
  37. }

3.连接蓝牙获取服务和特征

  1. void Characteristic_ValueChanged(GattCharacteristic const& characteristic, GattValueChangedEventArgs args){//订阅回传的数据
  2. }
  3. BLEHandle ConnectBLEDevice(char * id) {
  4.     WCHAR ID[255] = { 0 };
  5.     ConvertCharToLPWSTR(id, ID);
  6.     hstring hst(ID);
  7.     auto device =  BluetoothLEDevice::FromIdAsync(hst).get();
  8.     auto result =  device.GetGattServicesAsync(BluetoothCacheMode::Uncached).get();//连接蓝牙服务
  9.     auto services = result.Services();
  10.     for (size_t i = 0; i < services.Size(); i++)
  11.     {
  12.         auto service = services.GetAt(i);
  13.         auto uuid = service.Uuid(); //获取服务uuid
  14.         auto charact = service.GetCharacteristicsAsync().get();
  15.         auto characts = charact.Characteristics();
  16.         for (size_t j = 0; j < characts.Size(); j++)
  17.         {
  18.             auto charact = characts.GetAt(j);
  19.             auto uuid = charact.Uuid(); //获取子服务的uuid
  20.             auto GAttpro = charact.CharacteristicProperties(); //获取每个子服务特征值
  21.             if (GAttpro == GattCharacteristicProperties::Notify) {                 charact.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue::Notify);//注册订阅
  22.                 charact.ValueChanged(auto_revoke, &Characteristic_ValueChanged); //设置订阅数据回传的回调
  23.             }
  24.             if (GAttpro == GattCharacteristicProperties::Write) {
  25.                 //写入数据
  26.                 unsigned char* buff = "123456";
  27.                 unsigned int lenght = 6;
  28.                 winrt::Windows::Storage::Streams::DataWriter writer;
  29.                 writer.WriteBytes(array_view<uint8_t const>(buff, buff + lenght));
  30.                 winrt::Windows::Storage::Streams::IBuffer buffer = writer.DetachBuffer();
  31.                 charact.WriteValueAsync(buffer);
  32.             }
  33.             if (GAttpro == GattCharacteristicProperties::Read) {
  34.                 
  35.             }
  36.             if (GAttpro == (GattCharacteristicProperties::Write | GattCharacteristicProperties::WriteWithoutResponse)) {
  37.                
  38.             }
  39.             if (GAttpro == (GattCharacteristicProperties::Notify | GattCharacteristicProperties::Write)) {
  40.              
  41.             }
  42.             if (GAttpro == (GattCharacteristicProperties::Notify | GattCharacteristicProperties::Read)) {
  43.                 
  44.             }
  45.             if (GAttpro == (GattCharacteristicProperties::Write | GattCharacteristicProperties::Read)) {
  46.                 
  47.             }
  48.             return;
  49.         }
  50.     }
  51. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/483737
推荐阅读
相关标签
  

闽ICP备14008679号