From aa75bb281f050e833839be59e3f07f577f6f3a31 Mon Sep 17 00:00:00 2001 From: suntao Date: Tue, 8 Jun 2021 10:30:26 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E8=93=9D=E7=89=99=E5=8D=A1?= =?UTF-8?q?=E9=A1=BF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/Devices/Ble/BleDevice.cs | 36 ++- .../Scripts/Devices/Ble/BleDeviceAdapter.cs | 27 ++ .../Scripts/Devices/Ble/Devices/HeartRate.cs | 5 +- .../Devices/Ble/Scan/BleAdvertisementInfo.cs | 2 +- .../Devices/Ble/Win/BleWinHwInterface.cs | 95 +++---- .../Devices/Ble/Win/WclBleGattClient.cs | 1 + .../Devices/Ble/Win/WclBleGattThread.cs | 221 +++++++-------- .../Devices/Ble/Win/WclBleMainThread.cs | 43 +-- .../Scripts/Devices/Ble/Win/WclBleManager.cs | 5 - .../Scripts/Devices/Ble/Win/WclBleWatcher.cs | 10 +- Assets/Scripts/Scenes/MainController.cs | 2 +- .../Scripts/UI/Prefab/Device/DeviceCache.cs | 18 +- Assets/Scripts/UI/Prefab/Device/DeviceView.cs | 12 +- Assets/Scripts/Utils/Loom.cs | 251 +++++++++--------- 14 files changed, 409 insertions(+), 319 deletions(-) diff --git a/Assets/Scripts/Devices/Ble/BleDevice.cs b/Assets/Scripts/Devices/Ble/BleDevice.cs index d06816d0..46374569 100644 --- a/Assets/Scripts/Devices/Ble/BleDevice.cs +++ b/Assets/Scripts/Devices/Ble/BleDevice.cs @@ -41,14 +41,14 @@ namespace Assets.Scripts.Devices.Ble //base.Name = this.peripheralInfo.Name; - //Debug.Log(base.Name + "," + sensor.ToString()); + Debug.Log(base.Name + "," + sensor.ToString() + "," + this.Address); Characteristics.Add(new BatteryLevel()); Characteristics.Add(new ManufacturerNameCharacteristic()); Characteristics.Add(new ModelNumberCharacteristic()); } - public void ConnectToPeripheralIfPossible() + private void ConnectToPeripheralIfPossible() { if(this.peripheralInfo == null) { @@ -61,28 +61,39 @@ namespace Assets.Scripts.Devices.Ble this.State = DeviceState.Connecting; try { + Debug.Log("连接设备"); this.hwInterface.ConnectPeripheral(this.peripheralInfo, PeripheralConnectedAction); } - catch (Exception) + 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("连接成功"); + //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("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); - + //Debug.Log("搜索service"); + if(!response.IsSuccess || !response.Data.Any()) + { + this.Disconnect(); + return; + } + this.CreateServices(response.Data); } @@ -263,5 +274,18 @@ namespace Assets.Scripts.Devices.Ble //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; + } } } diff --git a/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs b/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs index de47e3eb..c5ed1791 100644 --- a/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs +++ b/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs @@ -1,6 +1,7 @@ using Assets.Scripts.Ble; using Assets.Scripts.Ble.Service; using Assets.Scripts.Devices.Ble.Devices; +using Assets.Scripts.UI.Prefab.Device; using System; using System.Collections.Generic; using System.Linq; @@ -72,7 +73,24 @@ namespace Assets.Scripts.Devices.Ble var device1 = new SpeedCadence(device.Peripheral, hwInterface); discoveredDevices.Add(device.Peripheral.Address, device1); } + else + { + return; + } + + var device111 = discoveredDevices.Last().Value; + if (device111 != null && device111.State == Ant.DeviceState.Disconnected) + { + if (DeviceCache.Exist(device111)) + { + //TODO:取消注释,自动连接设备 + //Debug.Log("自动连接" + device111.Id); + //device111.Connect(); + } + } + //discoveredDevices.Add(device.Peripheral.Address, new BleDevice(device.Peripheral, hwInterface, device.SensorType)); + } if (discoveredDevices.ContainsKey(device.Peripheral.Address)) { @@ -89,8 +107,17 @@ namespace Assets.Scripts.Devices.Ble public override void Dispose() { + this.ReleaseDevices(); hwInterface.Dispose(); base.Dispose(); } + + public void ReleaseDevices() + { + foreach (var item in discoveredDevices) + { + item.Value.Dispose(); + } + } } } diff --git a/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs b/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs index 3f6183aa..06e2e18c 100644 --- a/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs +++ b/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs @@ -33,7 +33,6 @@ namespace Assets.Scripts.Devices.Ble.Devices foreach (var service in this.Services) { - //Debug.Log($"11111 "+ service.Id.ToString()); hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) => { foreach (var character in response.Data) @@ -47,7 +46,7 @@ namespace Assets.Scripts.Devices.Ble.Devices continue; } } - foreach (var item in Characteristics.Where(c=>c.IsOptional)) + foreach (var item in Characteristics.Where(c => c.IsOptional)) { //Debug.Log(item.GetType() + "服务可用"+ item.Uuid.ToString() +", service:" + item.ServiceUuid); var ccc = response.Data.FirstOrDefault(r => r.MatchGuid(item.Uuid)); @@ -58,7 +57,7 @@ namespace Assets.Scripts.Devices.Ble.Devices else { Debug.Log(item.GetType() + "服务可用"); - + GetBatteryLevel(ccc); } } diff --git a/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs b/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs index b2436be2..64093e43 100644 --- a/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs +++ b/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs @@ -40,7 +40,7 @@ namespace Assets.Scripts.Ble.Scan } public void TryAddService(Guid service) - { + { if (this.services.Contains(service)) return; this.services.Add(service); diff --git a/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs b/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs index 89d243ff..12090afa 100644 --- a/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs +++ b/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs @@ -99,29 +99,14 @@ namespace Assets.Scripts.Ble { //if(address != 224160707349234) //{ - //return; + //return; //} - if (service.HasValue) - { - //Debug.Log($"address:{ address }, name:{ name }, service:{ (service == null ? "" : service.Value.ToString()) }"); - } - if (!string.IsNullOrWhiteSpace(name)) - { - if (pCache.ContainsKey(address.ToString())) - { - (pCache[address.ToString()].Peripheral as WinBlePeripheralInfo).SetName(name); - } - } - //Debug.Log("service:" + service.ToString()+",name:" + name); - if (!service.HasValue || ServiceUuids.Services.Select(s => s.IdGuid).All(x => !x.Equals(service.Value))) - { - return; - } + //Debug.Log($"address:{ address }, name:{ name }, service:{ (service == null ? "" : service.Value.ToString()) }"); + SensorType sensor = SensorType.None; - List services = null; + List services = new List(); if (service != null) - { - + { services = new List { service.Value }; foreach(var item in ServiceUuids.Services) { @@ -152,36 +137,51 @@ namespace Assets.Scripts.Ble } } }; - - if (!pCache.ContainsKey(address.ToString())) + var addressStr = address.ToString("X12"); + if (!pCache.ContainsKey(addressStr)) { - var device = new BleAdvertisementInfo(new WinBlePeripheralInfo(address.ToString(), name), rssi, true, services, null, sensor); - pCache.Add(address.ToString(), device); + var device = new BleAdvertisementInfo(new WinBlePeripheralInfo(addressStr, name), rssi, true, services, null, sensor); + pCache.Add(addressStr, device); - WclBleGattThread gattClient = this.SetUpGattClient(device.Peripheral); + //WclBleGattThread gattClient = this.SetUpGattClient(device.Peripheral); //this.ConnectInternal(gattClient); } - else + if (!string.IsNullOrWhiteSpace(name)) { - //Debug.Log(sensor); - //pCache[address.ToString()].SensorType = sensor; + (pCache[addressStr].Peripheral as WinBlePeripheralInfo).SetName(name); + } + if(sensor == SensorType.None) + { + return; + } + pCache[addressStr].SensorType = sensor; + //Debug.Log(sensor); + //pCache[address.ToString()].SensorType = sensor; + foreach (var item in services) { - pCache[address.ToString()].TryAddService(item); - } - pCache[address.ToString()].Index++; - if(pCache[address.ToString()].SensorType == SensorType.Power && pCache[address.ToString()].Services.Any(s=> s.Equals(ServiceUuids.Get(ServiceUuids.TacxBle).IdGuid))) - { - pCache[address.ToString()].SensorType = SensorType.Trainer; - //Debug.Log("纠正为trainer, "+ pCache[address.ToString()].Index); + pCache[addressStr].TryAddService(item); } + + pCache[addressStr].Index++; + if(pCache[addressStr].SensorType == SensorType.Power && pCache[addressStr].Services.Any(s=> s.Equals(ServiceUuids.Get(ServiceUuids.TacxBle).IdGuid))) + { + pCache[addressStr].SensorType = SensorType.Trainer; + //Debug.Log("纠正为trainer, "+ pCache[address.ToString()].Index); + } + - - if (pCache[address.ToString()].Index > 4 || pCache[address.ToString()].SensorType != SensorType.Power) + if (pCache[addressStr].SensorType == SensorType.Power) + { + if (pCache[addressStr].Index > 4) { - _discoveredCallback?.Invoke(pCache[address.ToString()]); + _discoveredCallback?.Invoke(pCache[addressStr]); } } + else if(pCache[addressStr].SensorType != SensorType.None) + { + _discoveredCallback?.Invoke(pCache[addressStr]); + } } private WclBleGattThread SetUpGattClient(BlePeripheralInfo peripheral) @@ -203,8 +203,10 @@ namespace Assets.Scripts.Ble { this.callbacks.Add(info, callback); WclBleGattThread wclBleGattThread = this.wclBleMainThread.GetGattThread(info); + if(wclBleGattThread == null) { + wclBleGattThread = this.SetUpGattClient(info); this.ConnectInternal(wclBleGattThread); return; @@ -259,7 +261,7 @@ namespace Assets.Scripts.Ble private void ManagerStatusChanged(WclBleMainThread sender, WclBleManagerStatus status) { this.BleState = BleWinHwInterface.StateFromNativeState(status); - Debug.Log("win hw:" + status); + //Debug.Log("win hw:" + status); } @@ -272,6 +274,7 @@ namespace Assets.Scripts.Ble return; } this.callbacks[gattClient.Peripheral].Invoke(this, gattClient.Peripheral, response); + this.callbacks.Remove(gattClient.Peripheral); } private void CleanUpPeripheral(BlePeripheralInfo peripheralInfo) @@ -285,13 +288,13 @@ namespace Assets.Scripts.Ble } private void GattServicesDiscovered(WclBleGattThread gattClient, BleResponse> response) { - Debug.Log("services discovered"); + //Debug.Log("services discovered"); //this.callbacks[gattClient.Peripheral].Invoke(this, gattClient.Peripheral, response); - foreach (var item in response.Data) - { - Debug.Log(item.ToString()); - } + //foreach (var item in response.Data) + //{ + // Debug.Log(item.ToString()); + //} if (this.servicesCallbacks.ContainsKey(gattClient.Peripheral)) { @@ -311,7 +314,7 @@ namespace Assets.Scripts.Ble private void GattCharacteristicSubscribed(WclBleGattThread gattClient, BleCharacteristicInfo characteristic, BleResponse response) { - Debug.Log("characteristics subscribed"); + //Debug.Log("characteristics subscribed"); if (this.characteristicNotificationCallbacks.ContainsKey(gattClient.Peripheral)) { this.characteristicNotificationCallbacks[gattClient.Peripheral].Invoke(this, characteristic, response); @@ -428,6 +431,8 @@ namespace Assets.Scripts.Ble public void Dispose() { + this.wclBleMainThread.ManagerStatusChanged -= ManagerStatusChanged; + this.wclBleMainThread.ScanInfoReceived -= WatcherScanInfoReceived; this.wclBleMainThread.Stop(); this.wclBleMainThread = null; hwInterface = null; diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs b/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs index 2e5fe915..0341f2ad 100644 --- a/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs +++ b/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs @@ -218,6 +218,7 @@ namespace Assets.Scripts.Ble.Win { try { + Debug.Log("onconnected"); WclBleGattClient.GattConnectionChanged connected = this.Connected; if (connected != null) { diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs b/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs index ffcb5561..43de822d 100644 --- a/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs +++ b/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs @@ -12,8 +12,8 @@ using UnityEngine; namespace Assets.Scripts.Devices.Ble.Win { - internal class WclBleGattThread - { + internal class WclBleGattThread: WclBleThread + { public delegate void GattCharacteristicChangedDelegate(WclBleGattThread gattClient, BleCharacteristicInfo characteristic, BleResponse response); public delegate void GattCharacteristicReadDelegate(WclBleGattThread gattClient, BleCharacteristicInfo characteristic, BleResponse response); public delegate void GattCharacteristicsDiscoveredDelegate(WclBleGattThread gattClient, BleServiceInfo service, BleResponse> response); @@ -175,57 +175,7 @@ namespace Assets.Scripts.Devices.Ble.Win this.Peripheral = bleDevice; this.rPtr = radio; _bleDevice = bleDevice; - //this.address = long.Parse(_bleDevice.Address, System.Globalization.NumberStyles.HexNumber); - this.address = long.Parse(_bleDevice.Address); - } - - public bool Start() - { - if (this.start) - { - return false; - } - this.start = true; - - this.sEvent = new ManualResetEvent(false); - this.tEvent = new ManualResetEvent(false); - this.aEvent = new AutoResetEvent(false); - - //thread = new Thread(new ThreadStart(ThreadProc)); - // this.sEvent.Set(); - - // IntPtr[] handle = new IntPtr[] - // { - // this.tEvent.SafeWaitHandle.DangerousGetHandle(), - // this.aEvent.SafeWaitHandle.DangerousGetHandle() - // }; - // while (WclAlertableWait.Wait(handle, 2U, WclAlertableWait.INFINITE) != WclAlertableWait.WAIT_OBJECT_0) - // { - // Action action; - // if (this.actions.TryDequeue(out action)) - // { - // if (action != null) - // { - // Debug.Log("连接设备"); - // action(); - // } - // } - // } - - // })); - //thread.Start(); - - //this.sEvent.WaitOne(); - ThreadProc(); - return true; - } - - public void Stop() - { - Debug.Log("停止"); - start = false; - thread?.Abort(); - + this.address = long.Parse(_bleDevice.Address, System.Globalization.NumberStyles.HexNumber); } private void ThreadProc() @@ -238,28 +188,15 @@ namespace Assets.Scripts.Devices.Ble.Win //this.InternalCleanUp(); } - private void CleanUpWorkerThread() + protected override void CleanUpWorkerThread() { this.gatt.Disconnect(); + base.ProcessPendingAPCMessages(); this.gatt.Dispose(); this.gatt = null; } - private void InternalCleanUp() - { - this.sEvent.Close(); - this.sEvent.Dispose(); - this.sEvent = null; - this.aEvent.Close(); - this.aEvent.Dispose(); - this.aEvent = null; - - this.tEvent.Close(); - this.tEvent.Dispose(); - this.tEvent = null; - } - - private void SetUpWorkerThread() + protected override void SetUpWorkerThread() { this.gatt = new WclBleGattClient(this.address, this.rPtr) { @@ -302,7 +239,13 @@ namespace Assets.Scripts.Devices.Ble.Win IsSuccess = true, Data = value }; - this.gattCharacteristicChanged?.Invoke(this, characteristic, response); + if (!base.IsTerminating) + { + //Loom.QueueOnMainThread(() => + //{ + this.gattCharacteristicChanged?.Invoke(this, characteristic, response); + //}); + } } private void OnCharacteristicRead(BleCharacteristicInfo characteristic, int result, byte[] data) @@ -319,7 +262,13 @@ namespace Assets.Scripts.Devices.Ble.Win { response.Error = new BleHwInterfaceError(new int?(result), "WclBleGattClientErrorDomain", "Error when reading value"); } - this.gattCharacteristicRead.Invoke(this, characteristic, response); + if (!base.IsTerminating) + { + //Loom.QueueOnMainThread(() => + //{ + this.gattCharacteristicRead.Invoke(this, characteristic, response); + //}); + } } private void OnCharacteristicsDiscovered(BleServiceInfo service, int result, GattCharacteristics characteristics) @@ -336,18 +285,33 @@ namespace Assets.Scripts.Devices.Ble.Win { // response.Error = new BleHwInterfaceError(new int?(result), "WclBleGattClientErrorDomain", "Error when reading BLE services"); } - this.gattCharacteristicsDiscovered(this, service, response); + + if (!base.IsTerminating) + { + + //Loom.QueueOnMainThread(() => + //{ + this.gattCharacteristicsDiscovered(this, service, response); + //}); + } } private void OnConnected(WclBleGattClient sender, int error) { - BleResponse response = new BleResponse - { - IsSuccess = WclBleErrors.IsSuccessCode(error) - }; - - this.gattConnected?.Invoke(this, response); - } + //Debug.Log("gatt thread onconnected"); + if (base.IsTerminating) + { + return; + } + BleResponse response = new BleResponse + { + IsSuccess = WclBleErrors.IsSuccessCode(error) + }; + //Loom.QueueOnMainThread(() => + //{ + this.gattConnected?.Invoke(this, response); + //}); + } private void OnDisconnected(WclBleGattClient sender, int reason) { @@ -356,16 +320,29 @@ namespace Assets.Scripts.Devices.Ble.Win IsSuccess = true, Error = new BleHwInterfaceError(new int?(reason), "WclBleGattClientErrorDomain", string.Format("GATT disconnect reason is - {0}", reason)) }; - this.gattDisconnected?.Invoke(this, response); + //Loom.QueueOnMainThread(() => + //{ + this.gattDisconnected?.Invoke(this, response); + //}); } public int Connect() { - this.gatt.Connect(); - //this.actions.Enqueue(() => - //{ - // this.gatt.Connect(); - //}); + if (!base.CanLoadWork) + { + return WclBleErrors.WCL_E_CONNECTION_NOT_ACTIVE; + + } + if(this.gatt.State != WclBleGattClientState.Disconnected) + { + return WclBleErrors.WCL_E_BLUETOOTH_CLIENT_CONNECTED; + } + base.ClearActionQueue(); + + base.EnqueueAction(() => + { + this.gatt.Connect(); + }); return WclBleErrors.WCL_E_SUCCESS; } @@ -378,9 +355,12 @@ namespace Assets.Scripts.Devices.Ble.Win public int DiscoverServices() { - GattServices services; - int result = this.gatt.DiscoverServices(out services); - this.OnServicesDiscovered(result, services); + base.EnqueueAction(() => + { + GattServices services; + int result = this.gatt.DiscoverServices(out services); + this.OnServicesDiscovered(result, services); + }); return WclBleErrors.WCL_E_SUCCESS; } @@ -398,8 +378,12 @@ namespace Assets.Scripts.Devices.Ble.Win { response.Error = new BleHwInterfaceError(new int?(result), "WclBleGattClientErrorDomain", "Error when reading BLE services"); } - - gattServicesDiscovered(this, response); + if (!base.IsTerminating) { + //Loom.QueueOnMainThread(() => + //{ + gattServicesDiscovered(this, response); + //}); + } } private List ProcessCharacteristics(BleServiceInfo service, GattCharacteristics characteristics) @@ -431,10 +415,12 @@ namespace Assets.Scripts.Devices.Ble.Win { GattService ns = this.servicesMapping[service]; - GattCharacteristics characteristics; - int result = this.gatt.DiscoverCharacteristics(ns, out characteristics); - this.OnCharacteristicsDiscovered(service, result, characteristics); - + base.EnqueueAction(() => + { + GattCharacteristics characteristics; + int result = this.gatt.DiscoverCharacteristics(ns, out characteristics); + this.OnCharacteristicsDiscovered(service, result, characteristics); + }); return WclBleErrors.WCL_E_SUCCESS; } @@ -447,10 +433,12 @@ namespace Assets.Scripts.Devices.Ble.Win } GattCharacteristic nCh = this.charMapping[characteristic]; - byte[] data; - int result = this.gatt.ReadCharacteristicValue(nCh, out data); - this.OnCharacteristicRead(characteristic, result, data); - + base.EnqueueAction(() => + { + byte[] data; + int result = this.gatt.ReadCharacteristicValue(nCh, out data); + this.OnCharacteristicRead(characteristic, result, data); + }); return WclBleErrors.WCL_E_SUCCESS; } @@ -462,16 +450,17 @@ namespace Assets.Scripts.Devices.Ble.Win } GattCharacteristic nCh = this.charMapping[characteristic]; - - int result = this.gatt.SubscribeCharacteristic(nCh); - this.OnCharacteristicsSubscribed(characteristic, nCh, result); - + base.EnqueueAction(() => + { + int result = this.gatt.SubscribeCharacteristic(nCh); + this.OnCharacteristicsSubscribed(characteristic, nCh, result); + }); return WclBleErrors.WCL_E_SUCCESS; } private void OnCharacteristicsSubscribed(BleCharacteristicInfo characteristic, GattCharacteristic nCharacteristic, int result) { - Debug.Log("char subscribed"); + //Debug.Log("char subscribed"); BleResponse response = new BleResponse { IsSuccess = WclBleErrors.IsSuccessCode(result) @@ -484,7 +473,12 @@ namespace Assets.Scripts.Devices.Ble.Win { response.Error = new BleHwInterfaceError(new int?(result), "WclBleGattClientErrorDomain", "Error when subscribing Characteristics"); } - this.gattCharacteristicsSubscribed(this, characteristic, response); + if (!base.IsTerminating) + { + //Loom.QueueOnMainThread(() => { + this.gattCharacteristicsSubscribed(this, characteristic, response); + //}); + } } public int WriteCharacteristic(BleCharacteristicInfo characteristicInfo, byte[] data) @@ -494,14 +488,27 @@ namespace Assets.Scripts.Devices.Ble.Win return WclBleErrors.WCL_E_CONNECTION_NOT_ACTIVE; } GattCharacteristic gCh = this.charMapping[characteristicInfo]; - - int result = this.gatt.WriteCharacteristic(gCh, data); - + base.EnqueueAction(() => + { + int result = this.gatt.WriteCharacteristic(gCh, data); + this.OnCharactersisticsWrote(characteristicInfo, result); + }); return WclBleErrors.WCL_E_SUCCESS; } + private void OnCharactersisticsWrote(BleCharacteristicInfo characteristic, int result) + { + var response = new BleResponse + { + IsSuccess = WclBleErrors.IsSuccessCode(result), + Data = BleCharacteristicWriteType.WriteWithResponse + }; + + this.gattCharacteristicWrote?.Invoke(this, characteristic, response); + } + private class WinBleCharacteristicInfo : BleCharacteristicInfo { // Token: 0x06003F85 RID: 16261 RVA: 0x000EA274 File Offset: 0x000E8474 diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs b/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs index e3ea3ab1..0ada684c 100644 --- a/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs +++ b/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs @@ -11,7 +11,7 @@ using UnityEngine; namespace Assets.Scripts.Devices.Ble.Win { - internal class WclBleMainThread + internal class WclBleMainThread: WclBleThread { internal delegate void ManagerStatusChangedCallback(WclBleMainThread thread, WclBleManagerStatus status); @@ -34,24 +34,11 @@ namespace Assets.Scripts.Devices.Ble.Win private readonly Dictionary gattClients = new Dictionary(); internal WclBleMainThread() { - - } - private Thread wThread; - - public bool Start() - { - //this.wThread = new Thread(new ThreadStart(this.SetUpWorkerThread)); - //this.wThread.Start(); - //Task.Run(() => - //{ - // this.SetUpWorkerThread(); - //}); - - SetUpWorkerThread(); - return true; + WclAlertableWait.SetApcSync(); } - private void SetUpWorkerThread() + + protected override void SetUpWorkerThread() { wclBleManager = new WclBleManager { @@ -72,6 +59,28 @@ namespace Assets.Scripts.Devices.Ble.Win //Debug.Log("bbb"); } + protected override void CleanUpWorkerThread() + { + this.wclWatcher.InfoPacketReceived = null; + this.wclWatcher.UuidPacketReceived = null; + if (this.wclWatcher.Active) + { + this.wclWatcher.StopScan(); + } + //this.StopGattThreads(); + if (this.wclBleManager.Active) + { + this.wclBleManager.ManagerStatusChanged = null; + this.wclBleManager.Close(); + } + + base.ProcessPendingAPCMessages(); + this.wclWatcher.Dispose(); + this.wclBleManager.Dispose(); + this.wclBleManager = null; + this.wclWatcher = null; + } + private void OnManagerStatusChanged(WclBleManager manager, WclBleManagerStatus status) { //Debug.Log(status); diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs b/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs index 8418b6f8..8c6178ee 100644 --- a/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs +++ b/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs @@ -62,11 +62,6 @@ namespace Assets.Scripts.Ble // Token: 0x06002178 RID: 8568 RVA: 0x0008B1CD File Offset: 0x000893CD private void OnStatusChanges(IntPtr sender, WclBleManagerStatus status) { - //if (WclBleManager.Info) - //{ - Debug.Log(string.Format("WCLBleManger state changed -> new state {0}", status)); - //} - //System.IO.File.WriteAllText("d:/demo.log", status.ToString()); this.BleStatus = status; } diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs b/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs index 8be3d505..7da35c89 100644 --- a/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs +++ b/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs @@ -103,7 +103,10 @@ namespace Assets.Scripts.Ble //{ // WclBleWatcher.SafeInvoke(this.InfoPacketReceived, this, address, timestamp, rssi, name, packetType, flags); //}.OnUIThreadAsync(); - this.InfoPacketReceived(this, address, timestamp, rssi, name, packetType, flags); + Loom.QueueOnMainThread(() => + { + this.InfoPacketReceived(this, address, timestamp, rssi, name, packetType, flags); + }); } // Token: 0x06002133 RID: 8499 RVA: 0x000895BC File Offset: 0x000877BC @@ -115,7 +118,10 @@ namespace Assets.Scripts.Ble // WclBleWatcher.SafeInvoke(this.UuidPacketReceived, this, address, timestamp, rssi, uuid); //}.OnUIThreadAsync(); - this.UuidPacketReceived(this, address, timestamp, rssi, uuid); + Loom.QueueOnMainThread(() => + { + this.UuidPacketReceived(this, address, timestamp, rssi, uuid); + }); } // Token: 0x06002134 RID: 8500 RVA: 0x000895F9 File Offset: 0x000877F9 diff --git a/Assets/Scripts/Scenes/MainController.cs b/Assets/Scripts/Scenes/MainController.cs index 9fa86c3b..18867add 100644 --- a/Assets/Scripts/Scenes/MainController.cs +++ b/Assets/Scripts/Scenes/MainController.cs @@ -17,7 +17,7 @@ public class MainController : MonoBehaviour Version = this.transform.Find("GameObject").Find("Version").GetComponent(); Version.text = "V"+App.AppVersion; DeviceCache.Init(PFConstants.DeviceCacheFolder); - + Loom.Initialize(); //AntConnector.Instance((device2) => { // if (device2.State == DeviceState.Disconnected) // { diff --git a/Assets/Scripts/UI/Prefab/Device/DeviceCache.cs b/Assets/Scripts/UI/Prefab/Device/DeviceCache.cs index ff934417..c5aa4b37 100644 --- a/Assets/Scripts/UI/Prefab/Device/DeviceCache.cs +++ b/Assets/Scripts/UI/Prefab/Device/DeviceCache.cs @@ -13,7 +13,7 @@ namespace Assets.Scripts.UI.Prefab.Device { public class DeviceCache { - private static Dictionary dict = null; + private static Dictionary dict = null; private static string _dataPath; public static void Init(string dataPath) { if(dict != null) @@ -24,23 +24,23 @@ namespace Assets.Scripts.UI.Prefab.Device if(!System.IO.File.Exists(_dataPath + "/Devices.txt")) { - dict = new Dictionary(); + dict = new Dictionary(); return; } //var str = PlayerPrefs.GetString("DeviceCache", ""); var str = System.IO.File.ReadAllText(_dataPath + "/Devices.txt", Encoding.UTF8); if (!string.IsNullOrWhiteSpace(str)) { - dict = Newtonsoft.Json.JsonConvert.DeserializeObject>(str); + dict = Newtonsoft.Json.JsonConvert.DeserializeObject>(str); } else { - dict = new Dictionary(); + dict = new Dictionary(); } } public static void Add(AbstractDevice antDevice) { - Debug.Log("添加设备" + antDevice.DeviceNumber); + //Debug.Log("添加设备" + antDevice.DeviceNumber); //new System.Collections.Concurrent.ConcurrentDictionary().AddOrUpdate //dict.AddOrUpdate(antDevice.Sensor.ToString(), antDevice.DeviceNumber, (key, oldValue)=> { @@ -49,16 +49,16 @@ namespace Assets.Scripts.UI.Prefab.Device // return antDevice.DeviceNumber; //}); - dict[antDevice.Sensor.ToString()] = antDevice.DeviceNumber; + dict[antDevice.Sensor.ToString()] = antDevice.Id; Write(); } public static bool Exist(AbstractDevice antDevice) { - ushort a; + string a; if(dict.TryGetValue(antDevice.Sensor.ToString(), out a)) { - return a == antDevice.DeviceNumber; + return a == antDevice.Id; } return false; @@ -72,7 +72,7 @@ namespace Assets.Scripts.UI.Prefab.Device } if (dict.ContainsKey(antDevice.Sensor.ToString())) { - if(dict[antDevice.Sensor.ToString()] == antDevice.DeviceNumber) + if(dict[antDevice.Sensor.ToString()] == antDevice.Id) { dict.Remove(antDevice.Sensor.ToString()); Write(); diff --git a/Assets/Scripts/UI/Prefab/Device/DeviceView.cs b/Assets/Scripts/UI/Prefab/Device/DeviceView.cs index 3f9e6d91..539e549b 100644 --- a/Assets/Scripts/UI/Prefab/Device/DeviceView.cs +++ b/Assets/Scripts/UI/Prefab/Device/DeviceView.cs @@ -199,9 +199,13 @@ public class DeviceView : MonoBehaviour // Update is called once per frame void Update() { + //if(SensorType != SensorType.Trainer) + //{ + // return; + //} timer -= Time.deltaTime; if (timer <= 0) - { + { Main(); timer = 1.0f; @@ -232,6 +236,8 @@ public class DeviceView : MonoBehaviour mSearchButton.SetActive(false); mPairButton.SetActive(true); logo.sprite = sprite1; + + //App.MainDeviceAdapter.GetDevices().First(d => d.Sensor == SensorType).Connect(); } else { @@ -280,7 +286,9 @@ public class DeviceView : MonoBehaviour { powerValue.text = GetValue(connectedDevice); } - } + } + + //Debug.Log(Newtonsoft.Json.JsonConvert.SerializeObject(App.MainDeviceAdapter.GetDevices().Where(d => d.Sensor == SensorType))); } string GetTitle() diff --git a/Assets/Scripts/Utils/Loom.cs b/Assets/Scripts/Utils/Loom.cs index 98db69f9..23b73591 100644 --- a/Assets/Scripts/Utils/Loom.cs +++ b/Assets/Scripts/Utils/Loom.cs @@ -10,145 +10,154 @@ using UnityEngine; /// public class Loom : MonoBehaviour { - public static int maxThreads = 8; - static int numThreads; + public static int maxThreads = 8; + static int numThreads; - private static Loom _current; - private int _count; - public static Loom Current - { - get - { - Initialize(); - return _current; - } - } + private static Loom _current; + public static Loom Current + { + get + { + Initialize(); + return _current; + } + } + //####去除Awake + // void Awake() + // { + // _current = this; + // initialized = true; + // } - void Awake() - { - _current = this; - initialized = true; - } + static bool initialized; - static bool initialized; + //####作为初始化方法自己调用,可在初始化场景调用一次即可 + public static void Initialize() + { + if (!initialized) + { - static void Initialize() - { - if (!initialized) - { + if (!Application.isPlaying) + return; + initialized = true; + GameObject g = new GameObject("Loom"); + //####永不销毁 + DontDestroyOnLoad(g); + _current = g.AddComponent(); + } - if (!Application.isPlaying) - return; - initialized = true; - var g = new GameObject("Loom"); - _current = g.AddComponent(); - } + } - } + private List _actions = new List(); + public struct DelayedQueueItem + { + public float time; + public Action action; + } + private List _delayed = new List(); - private List _actions = new List(); - public struct DelayedQueueItem - { - public float time; - public Action action; - } - private List _delayed = new List(); + List _currentDelayed = new List(); - List _currentDelayed = new List(); + public static void QueueOnMainThread(Action action) + { + QueueOnMainThread(action, 0f); + } + public static void QueueOnMainThread(Action action, float time) + { + if (time != 0) + { + if (Current != null) + { + lock (Current._delayed) + { + Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action }); + } + } + } + else + { + if (Current != null) + { + lock (Current._actions) + { + Current._actions.Add(action); + } + } + } + } - public static void QueueOnMainThread(Action action) - { - QueueOnMainThread(action, 0f); - } - public static void QueueOnMainThread(Action action, float time) - { - if (time != 0) - { - lock (Current._delayed) - { - Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action }); - } - } - else - { - lock (Current._actions) - { - Current._actions.Add(action); - } - } - } + public static Thread RunAsync(Action a) + { + Initialize(); + while (numThreads >= maxThreads) + { + Thread.Sleep(1); + } + Interlocked.Increment(ref numThreads); + ThreadPool.QueueUserWorkItem(RunAction, a); + return null; + } - public static Thread RunAsync(Action a) - { - Initialize(); - while (numThreads >= maxThreads) - { - Thread.Sleep(1); - } - Interlocked.Increment(ref numThreads); - ThreadPool.QueueUserWorkItem(RunAction, a); - return null; - } + private static void RunAction(object action) + { + try + { + ((Action)action)(); + } + catch + { + } + finally + { + Interlocked.Decrement(ref numThreads); + } - private static void RunAction(object action) - { - try - { - ((Action)action)(); - } - catch - { - } - finally - { - Interlocked.Decrement(ref numThreads); - } - - } + } - void OnDisable() - { - if (_current == this) - { + void OnDisable() + { + if (_current == this) + { - _current = null; - } - } + _current = null; + } + } - // Use this for initialization - void Start() - { + // Use this for initialization + void Start() + { - } + } - List _currentActions = new List(); + List _currentActions = new List(); - // Update is called once per frame - void Update() - { - lock (_actions) - { - _currentActions.Clear(); - _currentActions.AddRange(_actions); - _actions.Clear(); - } - foreach (var a in _currentActions) - { - a(); - } - lock (_delayed) - { - _currentDelayed.Clear(); - _currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time)); - foreach (var item in _currentDelayed) - _delayed.Remove(item); - } - foreach (var delayed in _currentDelayed) - { - delayed.action(); - } - } + // Update is called once per frame + void Update() + { + lock (_actions) + { + _currentActions.Clear(); + _currentActions.AddRange(_actions); + _actions.Clear(); + } + foreach (var a in _currentActions) + { + a(); + } + lock (_delayed) + { + _currentDelayed.Clear(); + _currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time)); + foreach (var item in _currentDelayed) + _delayed.Remove(item); + } + foreach (var delayed in _currentDelayed) + { + delayed.action(); + } + + } }