263 lines
8.8 KiB
C#
263 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;
|
|
}
|
|
this.State = DeviceState.Disconnected;
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|