using Assets.Scripts.Ble; using Assets.Scripts.Ble.HeartRate; using Assets.Scripts.Ble.Service; 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 BleWinHwInterface 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, BleWinHwInterface bleWinHwInterface, SensorType sensor) : base(peripheralInfo.Address, NetworkType.BLE) { this.hwInterface = bleWinHwInterface; this.hwInterface.BluetoothStateChangedEvent += BluetoothStateChangedEvent; 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 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(BleWinHwInterface 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; } private void ServicesDiscoveredAction(BleWinHwInterface 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); // } //} private void CreateFtmsService(BleServiceInfo serviceInfo) { this.hwInterface.DiscoverCharacteristic(serviceInfo, (hwInterface, bleServiceInfo, response) => { if (this.CheckPendingServiceCharacteristicsResponse(serviceInfo, response)) { this.CreateFtmsService(serviceInfo, response); } }); } private void CreateFtmsService(BleServiceInfo serviceInfo, BleResponse> response) { BleService service; //if (response.Data.Any((BleCharacteristicInfo characteristicInfo) => characteristicInfo.MatchGuid(BleApi.Characteristics.CycleOpsFtmsSystemWeight))) //{ //service = new CycleOpsFtmsService(serviceInfo, base.Settings, this.hwInterface, new ServiceStateChanged(this.ServiceStateChanged), new ServiceCapabilitiesUpdated(this.ServiceCapabilitiesUpdated)); //} //else //{ //FixType fixType = FixType.FtmsFeature7ByteResponse; //if (this.IsWattbike()) //{ // fixType |= FixType.WattbikeFeatureInconsistency; //} //service = new FtmsService(serviceInfo, base.Settings, this.hwInterface, new ServiceStateChanged(this.ServiceStateChanged), new ServiceCapabilitiesUpdated(this.ServiceCapabilitiesUpdated), fixType); //service = new Ftms.FtmsService(serviceInfo, hwInterface); //} //this.AddService(service, response); } private void CreateCyclingPowerService(BleServiceInfo serviceInfo) { this.pendingServices.Add(serviceInfo); this.hwInterface.DiscoverCharacteristic(serviceInfo, (hwInterface, service, response) => { if (this.CheckPendingServiceCharacteristicsResponse(serviceInfo, response)) { this.CreateCyclingPowerService(serviceInfo, response); } }); } private void CreateCyclingPowerService(BleServiceInfo serviceInfo, BleResponse> response) { //BleService service = null; //if (response.Data.Any((BleCharacteristicInfo characteristicInfo) => characteristicInfo.MatchGuid(ServiceUuids.Characteristics.WahooControlPoint))) //{ // //service = new WahooService(serviceInfo, base.Settings, this.hwInterface, new ServiceStateChanged(this.ServiceStateChanged), new ServiceCapabilitiesUpdated(this.ServiceCapabilitiesUpdated), fixType); //} //else //{ // service = new CyclingPowerService(serviceInfo, this.hwInterface); // this.AddService(service, response); //} } private void AddService(BleService service, BleResponse> scanCharacteristicsResponse = null) { if (service == null) { return; } this.services.Add(service); service.DiscoverCharacteristics(scanCharacteristicsResponse); } private 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 Disconnect() { if (this.State != DeviceState.Disconnected) { Debug.Log("断开设备" + this.Name); this.hwInterface.DisconnectPeripheral(this.peripheralInfo, ()=> { this.State = DeviceState.Disconnected; }); } } private void BluetoothStateChangedEvent(BleWinHwInterface 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; } } }