269 lines
9.4 KiB
C#
Raw Normal View History

2021-05-19 14:38:48 +08:00
using Assets.Scripts.Ble;
using Assets.Scripts.Ble.HeartRate;
using Assets.Scripts.Ble.Service;
using Assets.Scripts.Ble.Win;
2021-05-19 14:38:48 +08:00
using Assets.Scripts.Devices.Ant;
2021-06-04 10:35:58 +08:00
using Assets.Scripts.Devices.Ble.Characteristic;
using Assets.Scripts.Devices.Ble.Interfaces;
2021-05-19 14:38:48 +08:00
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
{
2021-08-19 18:03:25 +08:00
protected IBleWinHwInterface hwInterface;
2021-05-19 14:38:48 +08:00
protected BlePeripheralInfo peripheralInfo;
2022-06-09 14:51:03 +08:00
protected Action<string> connectCallBack;
2021-05-19 14:38:48 +08:00
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;
}
}
2021-06-04 10:35:58 +08:00
public List<ICharacteristic> Characteristics { get; protected set; } = new List<ICharacteristic>();
2021-08-19 18:03:25 +08:00
public BleDevice(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface, SensorType sensor) : base(peripheralInfo.Address, NetworkType.BLE)
2021-05-19 14:38:48 +08:00
{
this.hwInterface = bleWinHwInterface;
this.hwInterface.BluetoothStateChangedEvent += BluetoothStateChangedEvent;
this.hwInterface.PeripheralDisconnectedEvent += HwInterface_PeripheralDisconnectedEvent;
2021-05-19 14:38:48 +08:00
this.peripheralInfo = peripheralInfo;
base.Sensor = sensor;
2021-06-04 10:35:58 +08:00
2021-05-19 14:38:48 +08:00
//base.Name = this.peripheralInfo.Name;
2021-06-08 10:30:26 +08:00
Debug.Log(base.Name + "," + sensor.ToString() + "," + this.Address);
2021-06-04 10:35:58 +08:00
Characteristics.Add(new BatteryLevel());
Characteristics.Add(new ManufacturerNameCharacteristic());
Characteristics.Add(new ModelNumberCharacteristic());
2021-05-19 14:38:48 +08:00
}
2021-08-19 18:03:25 +08:00
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();
}
}
//
}
2021-06-08 10:30:26 +08:00
private void ConnectToPeripheralIfPossible()
2021-05-19 14:38:48 +08:00
{
if(this.peripheralInfo == null)
{
return;
}
2021-09-13 18:21:43 +08:00
if(!this.hwInterface.BleState.Equals(BleState.On) || (this.State != DeviceState.Disconnected && this.State != DeviceState.Connecting))
{
return;
}
this.State = DeviceState.Connecting;
try
{
2021-06-08 10:30:26 +08:00
Debug.Log("连接设备");
this.hwInterface.ConnectPeripheral(this.peripheralInfo, PeripheralConnectedAction);
}
2021-06-08 10:30:26 +08:00
catch (Exception ex)
{
2021-06-08 10:30:26 +08:00
Debug.LogError(ex);
this.State = DeviceState.Disconnected;
}
2021-05-19 14:38:48 +08:00
}
2021-08-19 18:03:25 +08:00
private void PeripheralConnectedAction(IBleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse response)
2021-05-19 14:38:48 +08:00
{
2021-06-08 10:30:26 +08:00
Debug.Log($"连接{ this.Name }"+response.IsSuccess);
2021-05-19 14:38:48 +08:00
if (response.IsSuccess)
{
2022-06-09 14:51:03 +08:00
ErrorMsg = string.Empty;
2021-05-19 14:38:48 +08:00
State = DeviceState.Connected;
2021-06-08 10:30:26 +08:00
//Debug.Log("连接成功"+this.Name);
2021-05-19 14:38:48 +08:00
hwInterface.DiscoverServices(this.peripheralInfo, ServicesDiscoveredAction);//, this.ServicesDiscoveredAction);
2021-06-08 10:30:26 +08:00
return;
2021-05-19 14:38:48 +08:00
}
if (response.Error != null)
{
2022-06-09 14:51:03 +08:00
ErrorMsg = App.GetLocalString("connect failed");
2022-06-08 13:05:56 +08:00
this.State = DeviceState.Disconnected;
if (response.Error.Code == WclBleErrors.WCL_E_BLUETOOTH_LE_DEVICE_NOT_FOUND)
{
Debug.Log("未找到设备");
App.MainDeviceAdapter.ClearDevice(this.peripheralInfo.Address);
}
}
2022-06-09 14:51:03 +08:00
//无法与xx连接请检查后重拾
var errorMsg = App.GetLocalLanguage() == "zh" ? $"无法与设备{Name}-{DeviceNumber}连接,请检查后重试。": $"failed to connect {Name}-{DeviceNumber},please check and retry.";
connectCallBack?.Invoke(response.IsSuccess ? string.Empty : errorMsg);
2021-05-19 14:38:48 +08:00
}
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;
});
}
}
2021-08-19 18:03:25 +08:00
private void ServicesDiscoveredAction(IBleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse<List<BleServiceInfo>> response)
2021-05-19 14:38:48 +08:00
{
2021-06-08 10:30:26 +08:00
//Debug.Log("搜索service");
if(!response.IsSuccess || !response.Data.Any())
{
this.Disconnect();
return;
}
2021-05-19 14:38:48 +08:00
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);
// }
//}
2021-05-19 14:38:48 +08:00
protected bool CheckPendingServiceCharacteristicsResponse(BleServiceInfo serviceInfo, BleResponse bleResponse)
2021-05-19 14:38:48 +08:00
{
if (bleResponse.IsSuccess)
{
return true;
}
//this.pendingServices.Remove(serviceInfo);
2021-05-19 14:38:48 +08:00
this.CheckAndSetConnectionStatus();
return false;
}
public void SendCommand()
{
}
private void CheckAndSetConnectionStatus()
{
}
2021-05-19 14:38:48 +08:00
2021-08-19 18:03:25 +08:00
private void BluetoothStateChangedEvent(IBleWinHwInterface hwInterface, BleState state)
2021-05-19 14:38:48 +08:00
{
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;
}
}
2022-06-09 14:51:03 +08:00
public override void Connect(Action<string> callback = null)
2021-05-19 14:38:48 +08:00
{
2022-06-09 14:51:03 +08:00
this.connectCallBack = callback;
2021-05-19 14:38:48 +08:00
this.ConnectToPeripheralIfPossible();
}
public override void Disconnect(bool save = true)
{
//throw new NotImplementedException();
//this.hwInterface.DisconnectPeripheral(this.peripheralInfo, null);
this.Disconnect();
2021-05-19 14:38:48 +08:00
}
2021-06-08 10:30:26 +08:00
public void Dispose()
{
if(this.State == DeviceState.Connected)
{
this.Disconnect();
}
this.services.Clear();
this.pendingServices.Clear();
this.Characteristics.Clear();
this.hwInterface.BluetoothStateChangedEvent -= BluetoothStateChangedEvent;
}
2021-05-19 14:38:48 +08:00
}
}