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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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();
}
}
}