262 lines
8.8 KiB
C#

using Assets.Scripts.Ble;
using Assets.Scripts.Ble.HeartRate;
using Assets.Scripts.Ble.Service;
using Assets.Scripts.Ble.Win;
using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Devices.Ble.Characteristic;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace Assets.Scripts.Devices.Ble
{
public abstract class BleDevice : AbstractDevice
{
protected IBleWinHwInterface hwInterface;
protected BlePeripheralInfo peripheralInfo;
private readonly HashSet<BleService> services = new HashSet<BleService>();
private readonly HashSet<BleServiceInfo> pendingServices = new HashSet<BleServiceInfo>();
public override string Name { get => peripheralInfo.Name; protected set => base.Name = value; }
public string Address {
get
{
return peripheralInfo.Address;
}
}
public List<ICharacteristic> Characteristics { get; protected set; } = new List<ICharacteristic>();
public BleDevice(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface, SensorType sensor) : base(peripheralInfo.Address, NetworkType.BLE)
{
this.hwInterface = bleWinHwInterface;
this.hwInterface.BluetoothStateChangedEvent += BluetoothStateChangedEvent;
this.hwInterface.PeripheralDisconnectedEvent += HwInterface_PeripheralDisconnectedEvent;
this.peripheralInfo = peripheralInfo;
base.Sensor = sensor;
//base.Name = this.peripheralInfo.Name;
Debug.Log(base.Name + "," + sensor.ToString() + "," + this.Address);
Characteristics.Add(new BatteryLevel());
Characteristics.Add(new ManufacturerNameCharacteristic());
Characteristics.Add(new ModelNumberCharacteristic());
}
private void HwInterface_PeripheralDisconnectedEvent(IBleWinHwInterface hwInterface, BlePeripheralInfo peripheral, BleResponse response, bool manualDisconnect)
{
if (!peripheral.MatchAddress(this.peripheralInfo.Address))
{
return;
}
Debug.Log("disconnected event");
if (this.State != DeviceState.Disconnected)
{
this.State = DeviceState.Disconnected;
if (!manualDisconnect)
{
this.ConnectToPeripheralIfPossible();
}
}
//
}
private void ConnectToPeripheralIfPossible()
{
if(this.peripheralInfo == null)
{
return;
}
if(!this.hwInterface.BleState.Equals(BleState.On) || this.State != DeviceState.Disconnected)
{
return;
}
this.State = DeviceState.Connecting;
try
{
Debug.Log("连接设备");
this.hwInterface.ConnectPeripheral(this.peripheralInfo, PeripheralConnectedAction);
}
catch (Exception ex)
{
Debug.LogError(ex);
this.State = DeviceState.Disconnected;
}
}
private void PeripheralConnectedAction(IBleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse response)
{
Debug.Log($"连接{ this.Name }"+response.IsSuccess);
if (response.IsSuccess)
{
State = DeviceState.Connected;
//Debug.Log("连接成功"+this.Name);
hwInterface.DiscoverServices(this.peripheralInfo, ServicesDiscoveredAction);//, this.ServicesDiscoveredAction);
return;
}
if (response.Error != null)
{
if (response.Error.Code == WclBleErrors.WCL_E_BLUETOOTH_LE_DEVICE_NOT_FOUND)
{
Debug.Log("未找到设备");
App.MainDeviceAdapter.ClearDevice(this.peripheralInfo.Address);
}
}
}
private void Disconnect()
{
if (this.State != DeviceState.Disconnected)
{
Debug.Log("断开设备" + this.Name);
//App.MainDeviceAdapter.PrintStatus();
this.State = DeviceState.Disconnected;
this.hwInterface.DisconnectPeripheral(this.peripheralInfo, () => {
//App.MainDeviceAdapter.PrintStatus();
this.State = DeviceState.Disconnected;
});
}
}
private void ServicesDiscoveredAction(IBleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse<List<BleServiceInfo>> response)
{
//Debug.Log("搜索service");
if(!response.IsSuccess || !response.Data.Any())
{
this.Disconnect();
return;
}
this.CreateServices(response.Data);
}
protected abstract void CreateServices(List<BleServiceInfo> discoveredServices);
//private void CreateServices(List<BleServiceInfo> discoveredServices)
//{
// foreach (var item in discoveredServices)
// {
//BleService service = null;
//if (item.MatchGuid(ServiceUuids.Services.Single(s => s.IdByteArray == ServiceUuids.DeviceInformation).IdGuid))
//{
// Debug.Log("device infomation");
//}
//else if (item.MatchGuid(ServiceUuids.Services.Single(s => s.IdByteArray == ServiceUuids.Battery).IdGuid))
//{
// Debug.Log("battery");
// //service = new BatteryService(item, this.hwInterface);
//}
//else if (item.MatchGuid(ServiceUuids.Get(ServiceUuids.HeartRate).IdGuid))
//{
// Debug.Log("发现 heartRate 服务");
// service = new HeartRateService(item, this.hwInterface);
//}
//else if (item.MatchGuid(ServiceUuids.Get(ServiceUuids.CyclingSpeedCadence).IdGuid))
//{
// //service = new CyclingSpeedCadence.CyclingSpeedCadenceService(item, this.hwInterface);
//}
//else if (item.MatchGuid(ServiceUuids.Get(ServiceUuids.CyclingPower).IdGuid))
//{
// Debug.Log("cycling power");
// this.CreateCyclingPowerService(item);
//}
//else if (item.MatchGuid(ServiceUuids.Services.Single(s => s.IdByteArray == ServiceUuids.Ftms).IdGuid))
//{
// Debug.Log("ftms");
// this.CreateFtmsService(item);
//}
//else if (item.MatchGuid(ServiceUuids.Services.Single(s => s.IdByteArray == ServiceUuids.TacxBle).IdGuid))
//{
// Debug.Log("tacx ble");
// //service = new TacxFecService(item, this.hwInterface);
//}
//this.AddService(service, null);
// }
//}
protected bool CheckPendingServiceCharacteristicsResponse(BleServiceInfo serviceInfo, BleResponse bleResponse)
{
if (bleResponse.IsSuccess)
{
return true;
}
//this.pendingServices.Remove(serviceInfo);
this.CheckAndSetConnectionStatus();
return false;
}
public void SendCommand()
{
}
private void CheckAndSetConnectionStatus()
{
}
private void BluetoothStateChangedEvent(IBleWinHwInterface hwInterface, BleState state)
{
switch (state)
{
case BleState.Unknown:
break;
case BleState.Unavailable:
break;
case BleState.Unauthorize:
break;
case BleState.Reseting:
break;
case BleState.Off:
this.Disconnect();
break;
case BleState.On:
break;
default:
break;
}
}
public override void Connect()
{
this.ConnectToPeripheralIfPossible();
}
public override void Disconnect(bool save = true)
{
//throw new NotImplementedException();
//this.hwInterface.DisconnectPeripheral(this.peripheralInfo, null);
this.Disconnect();
}
public void Dispose()
{
if(this.State == DeviceState.Connected)
{
this.Disconnect();
}
this.services.Clear();
this.pendingServices.Clear();
this.Characteristics.Clear();
this.hwInterface.BluetoothStateChangedEvent -= BluetoothStateChangedEvent;
}
}
}