You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
7.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Security.Cryptography;
using System.Diagnostics;
namespace BluetoothLibrary
{
public enum BlueStatus
{
DisConnected, // 未连接
Connecting, // 正在连接
Connected // 已连接
};
public enum MsgType
{
NotifyTxt,
BleDevice,
BleSendData,
BleRecData,
}
public class BleCore
{
private BluetoothLEDevice _currentDevice;
private GattDeviceService _currentService;
private GattCharacteristic _writeCharacteristic;
private GattCharacteristic _notifyCharacteristic;
private List<BluetoothLEDevice> _discoveredDevices = new List<BluetoothLEDevice>();
public event Action<MsgType, string, byte[]> MessageChanged;
public async Task StartDeviceDiscoveryAsync()
{
try
{
string selector = BluetoothLEDevice.GetDeviceSelectorFromPairingState(false);
var devices = await DeviceInformation.FindAllAsync(selector);
foreach (var deviceInfo in devices)
{
var device = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);
if (device != null && !_discoveredDevices.Any(d => d.DeviceId == device.DeviceId))
{
_discoveredDevices.Add(device);
OnMessageChanged(MsgType.BleDevice, $"Discovered device: {device.Name}", null);
}
}
}
catch (Exception ex)
{
OnMessageChanged(MsgType.NotifyTxt, $"Error during device discovery: {ex.Message}", null);
}
}
public async Task ConnectToDeviceAsync(string deviceId)
{
try
{
_currentDevice = await BluetoothLEDevice.FromIdAsync(deviceId);
if (_currentDevice != null)
{
_currentDevice.ConnectionStatusChanged += OnConnectionStatusChanged;
OnMessageChanged(MsgType.NotifyTxt, $"Connecting to device: {_currentDevice.Name}", null);
await DiscoverServicesAsync();
}
else
{
OnMessageChanged(MsgType.NotifyTxt, "Device not found", null);
}
}
catch (Exception ex)
{
OnMessageChanged(MsgType.NotifyTxt, $"Error connecting to device: {ex.Message}", null);
}
}
private async Task DiscoverServicesAsync()
{
try
{
var services = await _currentDevice.GetGattServicesAsync();
foreach (var service in services.Services)
{
if (service.Uuid.ToString() == "your-service-uuid-here") // Replace with your service UUID
{
_currentService = service;
await DiscoverCharacteristicsAsync();
break;
}
}
}
catch (Exception ex)
{
OnMessageChanged(MsgType.NotifyTxt, $"Error discovering services: {ex.Message}", null);
}
}
private async Task DiscoverCharacteristicsAsync()
{
try
{
var characteristics = await _currentService.GetCharacteristicsAsync();
foreach (var characteristic in characteristics.Characteristics)
{
if (characteristic.Uuid.ToString() == "your-write-uuid-here") // Replace with your write UUID
{
_writeCharacteristic = characteristic;
}
else if (characteristic.Uuid.ToString() == "your-notify-uuid-here") // Replace with your notify UUID
{
_notifyCharacteristic = characteristic;
await EnableNotificationsAsync(characteristic);
}
}
}
catch (Exception ex)
{
OnMessageChanged(MsgType.NotifyTxt, $"Error discovering characteristics: {ex.Message}", null);
}
}
private async Task EnableNotificationsAsync(GattCharacteristic characteristic)
{
try
{
await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.Notify);
characteristic.ValueChanged += OnCharacteristicValueChanged;
OnMessageChanged(MsgType.NotifyTxt, "Notifications enabled", null);
}
catch (Exception ex)
{
OnMessageChanged(MsgType.NotifyTxt, $"Error enabling notifications: {ex.Message}", null);
}
}
private void OnCharacteristicValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
byte[] data;
CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
OnMessageChanged(MsgType.BleRecData, "Data received", data);
}
public async Task WriteDataAsync(byte[] data)
{
try
{
if (_writeCharacteristic != null)
{
await _writeCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(data));
OnMessageChanged(MsgType.BleSendData, "Data sent", data);
}
else
{
OnMessageChanged(MsgType.NotifyTxt, "Write characteristic not found", null);
}
}
catch (Exception ex)
{
OnMessageChanged(MsgType.NotifyTxt, $"Error writing data: {ex.Message}", null);
}
}
private void OnConnectionStatusChanged(BluetoothLEDevice sender, object args)
{
if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected)
{
OnMessageChanged(MsgType.NotifyTxt, "Device disconnected", null);
}
else
{
OnMessageChanged(MsgType.NotifyTxt, "Device connected", null);
}
}
private void OnMessageChanged(MsgType type, string message, byte[] data)
{
MessageChanged?.Invoke(type, message, data);
}
public void Dispose()
{
// 不需要调用 Dispose 方法
_currentDevice?.Dispose(); // 如果 BluetoothLEDevice 实现了 IDisposable则可以调用 Dispose
_currentService = null;
_writeCharacteristic = null;
_notifyCharacteristic = null;
_discoveredDevices.Clear();
}
}
}