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 services = new HashSet(); private readonly HashSet pendingServices = new HashSet(); public override string Name { get => peripheralInfo.Name; protected set => base.Name = value; } public string Address { get { return peripheralInfo.Address; } } public List Characteristics { get; protected set; } = new List(); 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 && this.State != DeviceState.Connecting)) { 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> response) { //Debug.Log("搜索service"); if(!response.IsSuccess || !response.Data.Any()) { this.Disconnect(); return; } this.CreateServices(response.Data); } protected abstract void CreateServices(List discoveredServices); //private void CreateServices(List 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; } } }