diff --git a/Assets/Plugins/WclBlePluginCPP.dll b/Assets/Plugins/WclBlePluginCPP.dll new file mode 100644 index 00000000..dc28c791 Binary files /dev/null and b/Assets/Plugins/WclBlePluginCPP.dll differ diff --git a/Assets/Plugins/WclBlePluginCPP.dll.meta b/Assets/Plugins/WclBlePluginCPP.dll.meta new file mode 100644 index 00000000..2aefccfb --- /dev/null +++ b/Assets/Plugins/WclBlePluginCPP.dll.meta @@ -0,0 +1,27 @@ +fileFormatVersion: 2 +guid: cfc0710c09383b54f8aa661624975c47 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/App.cs b/Assets/Scripts/App.cs index cb6dfbe8..b22a285c 100644 --- a/Assets/Scripts/App.cs +++ b/Assets/Scripts/App.cs @@ -7,6 +7,7 @@ using UnityEngine; using System.Net; using System.Globalization; using System.Threading; +using Assets.Scripts.Devices; public static class App { @@ -50,6 +51,19 @@ public static class App //public static string AppDownloadUrl { get; internal set; } //public static string AppVersionCode { get; internal set; } + private static MainDeviceAdapter mainDeviceAdapter; + public static MainDeviceAdapter MainDeviceAdapter + { + get + { + if(mainDeviceAdapter == null) + { + mainDeviceAdapter = new MainDeviceAdapter(); + } + return mainDeviceAdapter; + } + } + static App() { CultureInfo currentCulture = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone(); diff --git a/Assets/Scripts/Devices/AbstractDevice.cs b/Assets/Scripts/Devices/AbstractDevice.cs new file mode 100644 index 00000000..0ecc01ea --- /dev/null +++ b/Assets/Scripts/Devices/AbstractDevice.cs @@ -0,0 +1,33 @@ +using Assets.Scripts.Devices.Ant; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices +{ + public abstract class AbstractDevice + { + public virtual DeviceState State { get; set; } = DeviceState.Disconnected; + + public SensorType Sensor { get; protected set; } + + public virtual string Name + { + get; + protected set; + } + + public virtual ushort DeviceNumber { get; set; } + + public virtual int Priority + { + get; protected set; + } + + public abstract void Connect(); + + public abstract void Disconnect(bool save = true); + } +} diff --git a/Assets/Scripts/Devices/AbstractDevice.cs.meta b/Assets/Scripts/Devices/AbstractDevice.cs.meta new file mode 100644 index 00000000..f7dd1d69 --- /dev/null +++ b/Assets/Scripts/Devices/AbstractDevice.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c92a5d01ab0176b46bb79faf3ffa2fc0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ant/AbstractAntDevice.cs b/Assets/Scripts/Devices/Ant/AbstractAntDevice.cs index 1eff0d37..22a60158 100644 --- a/Assets/Scripts/Devices/Ant/AbstractAntDevice.cs +++ b/Assets/Scripts/Devices/Ant/AbstractAntDevice.cs @@ -12,16 +12,12 @@ namespace Assets.Scripts.Devices.Ant { public abstract class AbstractAntDevice : DataSourceBase { - public string Name - { - get; - protected set; - } + public AntChannelProfile searchProfile; public bool isInitialized = false; private DeviceState state; - public DeviceState State + public override DeviceState State { get { @@ -37,7 +33,7 @@ namespace Assets.Scripts.Devices.Ant StateChange?.Invoke(state); } } - public SensorType Sensor { get; private set; } + private int _ManufacturerId; /// @@ -56,7 +52,7 @@ namespace Assets.Scripts.Devices.Ant } private ushort _DeviceNumber; - public ushort DeviceNumber + public override ushort DeviceNumber { get { @@ -92,10 +88,6 @@ namespace Assets.Scripts.Devices.Ant public bool pairingEnabled; } - public virtual int Priority - { - get; protected set; - } //private readonly Rhino.PowerFun.Services.DeviceService deviceService; //private readonly DeviceDetailService _deviceDetailService; @@ -174,7 +166,7 @@ namespace Assets.Scripts.Devices.Ant // base.reset(); //} - public void Connect() + public override void Connect() { if (State == DeviceState.Connected || State == DeviceState.Connecting) return; @@ -182,7 +174,7 @@ namespace Assets.Scripts.Devices.Ant AntConnector.Instance().ConnectDevice(this); } - public void Disconnect(bool save = true) + public override void Disconnect(bool save = true) { if (State == DeviceState.Disconnected || State == DeviceState.Disconnecting) return; diff --git a/Assets/Scripts/Devices/Ant/AntDeviceAdapter.cs b/Assets/Scripts/Devices/Ant/AntDeviceAdapter.cs new file mode 100644 index 00000000..bea79f1f --- /dev/null +++ b/Assets/Scripts/Devices/Ant/AntDeviceAdapter.cs @@ -0,0 +1,61 @@ +using Assets.Scripts.UI.Prefab.Device; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Devices.Ant +{ + public class AntDeviceAdapter : DeviceAdapter + { + public override ConnectionInterface Interface => ConnectionInterface.ANT; + + public AntDeviceAdapter() + { + AntConnector.Instance((device2) => { + if (device2.State == DeviceState.Disconnected) + { + //Debug.Log($"探索到新的设备{ device2.DeviceNumber }"); + //自动连接 + if (DeviceCache.Exist(device2)) + { + Debug.Log("自动连接" + device2.DeviceNumber); + device2.Connect(); + } + } + }, Debug.Log); + } + + public override DeviceAdapterState GetState() + { + if (AntConnector.Instance().IsAvailable) + { + return DeviceAdapterState.On; + } + return DeviceAdapterState.Unavailable; + } + + public override IEnumerable GetDevices() + { + return AntConnector.Instance().discoveredDevices; + } + + public override void StartScan() + { + //throw new NotImplementedException(); + } + + public override void StopScan() + { + //throw new NotImplementedException(); + } + + public override void Dispose() + { + AntConnector.Instance().Dispose(); + base.Dispose(); + } + } +} diff --git a/Assets/Scripts/Devices/Ant/AntDeviceAdapter.cs.meta b/Assets/Scripts/Devices/Ant/AntDeviceAdapter.cs.meta new file mode 100644 index 00000000..7062acc4 --- /dev/null +++ b/Assets/Scripts/Devices/Ant/AntDeviceAdapter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa2b23675a0486a40881d44a57de8d73 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ant/DataSourceBase.cs b/Assets/Scripts/Devices/Ant/DataSourceBase.cs index d496c7dc..54098f96 100644 --- a/Assets/Scripts/Devices/Ant/DataSourceBase.cs +++ b/Assets/Scripts/Devices/Ant/DataSourceBase.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Assets.Scripts.Devices.Ant { - public abstract class DataSourceBase + public abstract class DataSourceBase : AbstractDevice { //double distanceTravelled = 0; //DataSourcePacket lastPacketRcvd = null; diff --git a/Assets/Scripts/Devices/Ble.meta b/Assets/Scripts/Devices/Ble.meta new file mode 100644 index 00000000..c3abd978 --- /dev/null +++ b/Assets/Scripts/Devices/Ble.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 157803f0c8b4ed542a209a947896097b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BitConvertHelper.cs b/Assets/Scripts/Devices/Ble/BitConvertHelper.cs new file mode 100644 index 00000000..242e8f3a --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BitConvertHelper.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts +{ + public static class BitConvertHelper + { + public static byte Lsn(byte b) + { + return (byte)(b & 15); + } + + // Token: 0x060032F7 RID: 13047 RVA: 0x000C22C3 File Offset: 0x000C04C3 + public static byte Lsn(byte[] bytes, int index) + { + return BitConvertHelper.Lsn(bytes[index]); + } + + public static byte ToUInt8(byte[] bytes, int index) + { + return bytes[index]; + } + + // Token: 0x060032FB RID: 13051 RVA: 0x000C22E8 File Offset: 0x000C04E8 + public static ushort ToUInt12(byte[] bytes, int index) + { + return (ushort)((int)bytes[index] + ((int)BitConvertHelper.Lsn(bytes[index + 1]) << 8)); + } + + public static ushort ToUInt16(byte[] bytes, int startIndex) + { + return BitConverter.ToUInt16(bytes, startIndex); + } + + public static short ToInt16(byte[] bytes, int startIndex) + { + return BitConverter.ToInt16(bytes, startIndex); + } + + public static uint ToUInt32(byte[] bytes, int startIndex) + { + return BitConverter.ToUInt32(bytes, startIndex); + } + } +} diff --git a/Assets/Scripts/Devices/Ble/BitConvertHelper.cs.meta b/Assets/Scripts/Devices/Ble/BitConvertHelper.cs.meta new file mode 100644 index 00000000..9956fb13 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BitConvertHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26dac648c68553d4bb2bccf4e54c4dfc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BleCharacteristicInfo.cs b/Assets/Scripts/Devices/Ble/BleCharacteristicInfo.cs new file mode 100644 index 00000000..addcc5e5 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleCharacteristicInfo.cs @@ -0,0 +1,77 @@ +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + public abstract class BleCharacteristicInfo + { + // Token: 0x170005BF RID: 1471 + // (get) Token: 0x06001FE3 RID: 8163 RVA: 0x00085CF7 File Offset: 0x00083EF7 + public BlePeripheralInfo Peripheral + { + get + { + return this.Service.Peripheral; + } + } + + // Token: 0x170005C0 RID: 1472 + // (get) Token: 0x06001FE4 RID: 8164 RVA: 0x00085D04 File Offset: 0x00083F04 + public BleServiceInfo Service { get; } + + // Token: 0x170005C1 RID: 1473 + // (get) Token: 0x06001FE5 RID: 8165 RVA: 0x00085D0C File Offset: 0x00083F0C + public Guid Id { get; } + + // Token: 0x170005C2 RID: 1474 + // (get) Token: 0x06001FE6 RID: 8166 RVA: 0x00085D14 File Offset: 0x00083F14 + public BleCharacteristicProperties Properties { get; } + + // Token: 0x06001FE7 RID: 8167 RVA: 0x00085D1C File Offset: 0x00083F1C + protected BleCharacteristicInfo(Guid id, BleServiceInfo service, BleCharacteristicProperties properties) + { + this.Id = id; + this.Service = service; + this.Properties = properties; + } + + // Token: 0x06001FE8 RID: 8168 RVA: 0x00085D3C File Offset: 0x00083F3C + public bool MatchGuid(Guid guid) + { + return this.Id.Equals(guid); + } + + // Token: 0x06001FE9 RID: 8169 RVA: 0x00085D58 File Offset: 0x00083F58 + public bool MatchAddress(string address) + { + return this.Peripheral.MatchAddress(address); + } + + // Token: 0x06001FEA RID: 8170 RVA: 0x00085D68 File Offset: 0x00083F68 + public override bool Equals(object obj) + { + if (obj == null || !(base.GetType() == obj.GetType())) + { + return false; + } + BleCharacteristicInfo bleCharacteristicInfo = (BleCharacteristicInfo)obj; + return this.Id.Equals(bleCharacteristicInfo.Id) && this.Service.Equals(bleCharacteristicInfo.Service); + } + + // Token: 0x06001FEB RID: 8171 RVA: 0x00085DC0 File Offset: 0x00083FC0 + public override int GetHashCode() + { + return (17 * 23 + this.Id.GetHashCode()) * 23 + this.Peripheral.GetHashCode(); + } + + // Token: 0x06001FEC RID: 8172 RVA: 0x00085DF6 File Offset: 0x00083FF6 + public override string ToString() + { + return this.Id.ToString(); + } + } +} diff --git a/Assets/Scripts/Devices/Ble/BleCharacteristicInfo.cs.meta b/Assets/Scripts/Devices/Ble/BleCharacteristicInfo.cs.meta new file mode 100644 index 00000000..567ac8d2 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleCharacteristicInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f417f704e04e35e4aaef2dcd366551ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BleCharacteristicProperties.cs b/Assets/Scripts/Devices/Ble/BleCharacteristicProperties.cs new file mode 100644 index 00000000..331d99a5 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleCharacteristicProperties.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + [Flags] + public enum BleCharacteristicProperties + { + // Token: 0x0400115A RID: 4442 + Broadcast = 1, + // Token: 0x0400115B RID: 4443 + Read = 2, + // Token: 0x0400115C RID: 4444 + WriteWithoutResponse = 4, + // Token: 0x0400115D RID: 4445 + Write = 8, + // Token: 0x0400115E RID: 4446 + Notify = 16, + // Token: 0x0400115F RID: 4447 + Indicate = 32, + // Token: 0x04001160 RID: 4448 + SignedWrites = 64, + // Token: 0x04001161 RID: 4449 + ExtendedProperties = 128 + } +} diff --git a/Assets/Scripts/Devices/Ble/BleCharacteristicProperties.cs.meta b/Assets/Scripts/Devices/Ble/BleCharacteristicProperties.cs.meta new file mode 100644 index 00000000..2908cb19 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleCharacteristicProperties.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44ea993e814c6f8408d93324b7cf4232 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BleCharacteristicWriteType.cs b/Assets/Scripts/Devices/Ble/BleCharacteristicWriteType.cs new file mode 100644 index 00000000..947c3e68 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleCharacteristicWriteType.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + public enum BleCharacteristicWriteType + { + // Token: 0x04001163 RID: 4451 + WriteWithResponse, + // Token: 0x04001164 RID: 4452 + WriteWithoutResponse + } +} diff --git a/Assets/Scripts/Devices/Ble/BleCharacteristicWriteType.cs.meta b/Assets/Scripts/Devices/Ble/BleCharacteristicWriteType.cs.meta new file mode 100644 index 00000000..4908201b --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleCharacteristicWriteType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 849439c6d534a5f4c9fd3ae52018478f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BleDevice.cs b/Assets/Scripts/Devices/Ble/BleDevice.cs new file mode 100644 index 00000000..6041daef --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleDevice.cs @@ -0,0 +1,236 @@ +using Assets.Scripts.Ble; +using Assets.Scripts.Ble.HeartRate; +using Assets.Scripts.Ble.Service; +using Assets.Scripts.Devices.Ant; +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 BleDevice(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface, SensorType sensor) //: base(peripheralInfo) + { + this.hwInterface = bleWinHwInterface; + this.hwInterface.BluetoothStateChangedEvent += BluetoothStateChangedEvent; + this.peripheralInfo = peripheralInfo; + + base.Sensor = sensor; + + //base.Name = this.peripheralInfo.Name; + + //Debug.Log(base.Name + "," + sensor.ToString()); + } + + public void ConnectToPeripheralIfPossible() + { + this.hwInterface.ConnectPeripheral(this.peripheralInfo, PeripheralConnectedAction); + } + + private void PeripheralConnectedAction(BleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse response) + { + if (response.IsSuccess) + { + State = DeviceState.Connected; + Debug.Log("连接成功"); + hwInterface.DiscoverServices(this.peripheralInfo, ServicesDiscoveredAction);//, this.ServicesDiscoveredAction); + } + } + + private void ServicesDiscoveredAction(BleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse> response) + { + //Debug.Log("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); + + 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) + { + 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(); + + } + } +} diff --git a/Assets/Scripts/Devices/Ble/BleDevice.cs.meta b/Assets/Scripts/Devices/Ble/BleDevice.cs.meta new file mode 100644 index 00000000..fb0b2e1c --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleDevice.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b14e74cc46a1e184ea96a01f17bb4e3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs b/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs new file mode 100644 index 00000000..d4be45c5 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs @@ -0,0 +1,78 @@ +using Assets.Scripts.Ble; +using Assets.Scripts.Ble.Service; +using Assets.Scripts.Devices.Ble.Devices; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Devices.Ble +{ + public class BleDeviceAdapter : DeviceAdapter + { + public override ConnectionInterface Interface => ConnectionInterface.BLE; + + private IDictionary discoveredDevices = new Dictionary(); + + private BleWinHwInterface hwInterface; + public BleDeviceAdapter() + { + hwInterface = BleWinHwInterface.GetInterface(); + } + + public override IEnumerable GetDevices() + { + //throw new NotImplementedException(); + return discoveredDevices.Select(d => d.Value); + } + + public override DeviceAdapterState GetState() + { + if(hwInterface.BleState == BleState.On) + { + return DeviceAdapterState.On; + } + return DeviceAdapterState.Unavailable; + } + + public override void StartScan() + { + hwInterface.StartScan((device) => + { + if (!discoveredDevices.ContainsKey(device.Peripheral.Address)) + { + Debug.Log("发现设备" + device.Peripheral.Address + device.Peripheral.Name + ", type:" + device.SensorType); + if(device.SensorType == Ant.SensorType.Trainer) + { + //var device1 = new Ftms(device.Peripheral, hwInterface); + //discoveredDevices.Add(device.Peripheral.Address, device1); + } + else if(device.SensorType == Ant.SensorType.HeartRate) + { + var device1 = new HeartRate(device.Peripheral, hwInterface); + discoveredDevices.Add(device.Peripheral.Address, device1); + } + else if(device.SensorType == Ant.SensorType.Power) + { + var device1 = new CyclingPower(device.Peripheral, hwInterface); + discoveredDevices.Add(device.Peripheral.Address, device1); + } + //discoveredDevices.Add(device.Peripheral.Address, new BleDevice(device.Peripheral, hwInterface, device.SensorType)); + } + }); + } + + public override void StopScan() + { + + } + + public override void Dispose() + { + hwInterface.Dispose(); + base.Dispose(); + } + } +} diff --git a/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs.meta b/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs.meta new file mode 100644 index 00000000..fdb7d4bc --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleDeviceAdapter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21c2c84c243633f4ba4403b51c0272c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BleHwInterfaceError.cs b/Assets/Scripts/Devices/Ble/BleHwInterfaceError.cs new file mode 100644 index 00000000..41af1800 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleHwInterfaceError.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices.Ble +{ + public class BleHwInterfaceError + { + public int? Code { get; } + + // Token: 0x170005C4 RID: 1476 + // (get) Token: 0x06001FEE RID: 8174 RVA: 0x00085E0B File Offset: 0x0008400B + public string Domain { get; } + + // Token: 0x170005C5 RID: 1477 + // (get) Token: 0x06001FEF RID: 8175 RVA: 0x00085E13 File Offset: 0x00084013 + public string Description { get; } + + // Token: 0x06001FF0 RID: 8176 RVA: 0x00085E1B File Offset: 0x0008401B + public BleHwInterfaceError(int? code, string domain, string description) + { + this.Code = code; + this.Domain = domain; + this.Description = description; + } + + // Token: 0x06001FF1 RID: 8177 RVA: 0x00085E38 File Offset: 0x00084038 + public BleHwInterfaceError(string description) : this(null, null, description) + { + } + + // Token: 0x06001FF2 RID: 8178 RVA: 0x00085E58 File Offset: 0x00084058 + public override string ToString() + { + int? code = this.Code; + if (code != null && this.Domain == "WclBleGattClientErrorDomain") + { + string str = "BleHWPluginError:\n"; + code = this.Code; + return str + ((code != null) ? code.GetValueOrDefault().ToString() : null) + "\n-Description: " + this.Description; + } + code = this.Code; + if (code != null && this.Domain != null) + { + return string.Format("BleHWPluginError:\n-Domain: {0}\n-Code: {1}\n-Description: {2}", this.Domain, this.Code, this.Description); + } + return "BleHWPluginError:-Description: " + this.Description; + } + + // Token: 0x06001FF3 RID: 8179 RVA: 0x00085F08 File Offset: 0x00084108 + public static BleHwInterfaceError ParseFromString(string message) + { + string[] array = (message != null) ? message.Split(new char[] + { + '|' + }, 3, StringSplitOptions.RemoveEmptyEntries) : null; + if (array == null || array.Length == 0) + { + return null; + } + int value; + if (array.Length == 3 && int.TryParse(array[1], out value)) + { + return new BleHwInterfaceError(new int?(value), array[0], array[2]); + } + return new BleHwInterfaceError(message); + } + + // Token: 0x06001FF4 RID: 8180 RVA: 0x00085F64 File Offset: 0x00084164 + public override int GetHashCode() + { + return (this.Code.GetHashCode() * 397 ^ ((this.Domain != null) ? this.Domain.GetHashCode() : 0)) * 397 ^ ((this.Description != null) ? this.Description.GetHashCode() : 0); + } + } +} diff --git a/Assets/Scripts/Devices/Ble/BleHwInterfaceError.cs.meta b/Assets/Scripts/Devices/Ble/BleHwInterfaceError.cs.meta new file mode 100644 index 00000000..c74e6e24 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleHwInterfaceError.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58ab8c2cfa7e96e43b69bb7e0e7e10c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BlePeripheralInfo.cs b/Assets/Scripts/Devices/Ble/BlePeripheralInfo.cs new file mode 100644 index 00000000..2b12c5ce --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BlePeripheralInfo.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices.Ble +{ + public abstract class BlePeripheralInfo + { + // Token: 0x170005C6 RID: 1478 + // (get) Token: 0x06001FF5 RID: 8181 RVA: 0x00085FBF File Offset: 0x000841BF + // (set) Token: 0x06001FF6 RID: 8182 RVA: 0x00085FC7 File Offset: 0x000841C7 + public string Name { get; protected set; } + + // Token: 0x170005C7 RID: 1479 + // (get) Token: 0x06001FF7 RID: 8183 RVA: 0x00085FD0 File Offset: 0x000841D0 + public string Address { get; } + + // Token: 0x06001FF8 RID: 8184 RVA: 0x00085FD8 File Offset: 0x000841D8 + protected BlePeripheralInfo(string address, string name) + { + this.Address = address; + this.Name = name; + } + + // Token: 0x06001FF9 RID: 8185 RVA: 0x00085FEE File Offset: 0x000841EE + public bool MatchAddress(string address) + { + return address != null && address.Equals(this.Address); + } + + // Token: 0x06001FFA RID: 8186 RVA: 0x00086001 File Offset: 0x00084201 + public override bool Equals(object other) + { + return other != null && base.GetType() == other.GetType() && this.Address.Equals(((BlePeripheralInfo)other).Address); + } + + // Token: 0x06001FFB RID: 8187 RVA: 0x00086031 File Offset: 0x00084231 + public override int GetHashCode() + { + return this.Address.GetHashCode(); + } + + // Token: 0x06001FFC RID: 8188 RVA: 0x00086040 File Offset: 0x00084240 + public override string ToString() + { + return string.Concat(new string[] + { + base.GetType().Name, + ": ", + string.IsNullOrEmpty(this.Name) ? "" : (this.Name + " "), + "[", + this.Address, + "]" + }); + } + } +} diff --git a/Assets/Scripts/Devices/Ble/BlePeripheralInfo.cs.meta b/Assets/Scripts/Devices/Ble/BlePeripheralInfo.cs.meta new file mode 100644 index 00000000..3d425929 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BlePeripheralInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 006773ea103cc3042a0b5e2f815a24eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BleResponse.cs b/Assets/Scripts/Devices/Ble/BleResponse.cs new file mode 100644 index 00000000..0c15559d --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleResponse.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices.Ble +{ + public class BleResponse + { + // Token: 0x170005C8 RID: 1480 + // (get) Token: 0x06001FFD RID: 8189 RVA: 0x000860AE File Offset: 0x000842AE + // (set) Token: 0x06001FFE RID: 8190 RVA: 0x000860B6 File Offset: 0x000842B6 + public bool IsSuccess { get; set; } + + // Token: 0x170005C9 RID: 1481 + // (get) Token: 0x06001FFF RID: 8191 RVA: 0x000860BF File Offset: 0x000842BF + // (set) Token: 0x06002000 RID: 8192 RVA: 0x000860C7 File Offset: 0x000842C7 + public BleHwInterfaceError Error { get; set; } + + // Token: 0x06002001 RID: 8193 RVA: 0x000860D0 File Offset: 0x000842D0 + public override string ToString() + { + return (this.IsSuccess ? "Success" : "Fail") + "\n" + ((this.Error == null) ? "" : this.Error.ToString()); + } + } + + public class BleResponse : BleResponse + { + // Token: 0x170005CA RID: 1482 + // (get) Token: 0x06002003 RID: 8195 RVA: 0x00086112 File Offset: 0x00084312 + // (set) Token: 0x06002004 RID: 8196 RVA: 0x0008611A File Offset: 0x0008431A + public T Data { get; set; } + + // Token: 0x06002005 RID: 8197 RVA: 0x00086123 File Offset: 0x00084323 + public override string ToString() + { + return base.ToString() + "\n" + this.Data; + } + } +} diff --git a/Assets/Scripts/Devices/Ble/BleResponse.cs.meta b/Assets/Scripts/Devices/Ble/BleResponse.cs.meta new file mode 100644 index 00000000..ce84e17f --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d19e34c55f7b3347ac0cbc36b231d9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BleServiceInfo.cs b/Assets/Scripts/Devices/Ble/BleServiceInfo.cs new file mode 100644 index 00000000..2934d274 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleServiceInfo.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices.Ble +{ + public abstract class BleServiceInfo + { + // Token: 0x170005CB RID: 1483 + // (get) Token: 0x06002007 RID: 8199 RVA: 0x00086148 File Offset: 0x00084348 + public BlePeripheralInfo Peripheral { get; } + + // Token: 0x170005CC RID: 1484 + // (get) Token: 0x06002008 RID: 8200 RVA: 0x00086150 File Offset: 0x00084350 + public Guid Id { get; } + + // Token: 0x06002009 RID: 8201 RVA: 0x00086158 File Offset: 0x00084358 + protected BleServiceInfo(Guid id, BlePeripheralInfo peripheral) + { + this.Id = id; + this.Peripheral = peripheral; + } + + // Token: 0x0600200A RID: 8202 RVA: 0x00086170 File Offset: 0x00084370 + public bool MatchGuid(Guid serviceId) + { + return this.Id.Equals(serviceId); + } + + // Token: 0x0600200B RID: 8203 RVA: 0x0008618C File Offset: 0x0008438C + public bool MatchAddress(string address) + { + return this.Peripheral.MatchAddress(address); + } + + // Token: 0x0600200C RID: 8204 RVA: 0x0008619C File Offset: 0x0008439C + public override bool Equals(object obj) + { + if (obj == null || !(base.GetType() == obj.GetType())) + { + return false; + } + BleServiceInfo bleServiceInfo = (BleServiceInfo)obj; + return this.Id.Equals(bleServiceInfo.Id) && this.Peripheral.Equals(bleServiceInfo.Peripheral); + } + + // Token: 0x0600200D RID: 8205 RVA: 0x000861F4 File Offset: 0x000843F4 + public override int GetHashCode() + { + return (17 * 23 + this.Id.GetHashCode()) * 23 + this.Peripheral.GetHashCode(); + } + + // Token: 0x0600200E RID: 8206 RVA: 0x0008622A File Offset: 0x0008442A + public override string ToString() + { + return this.Id.ToString(); + } + } +} diff --git a/Assets/Scripts/Devices/Ble/BleServiceInfo.cs.meta b/Assets/Scripts/Devices/Ble/BleServiceInfo.cs.meta new file mode 100644 index 00000000..ab1da8e5 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleServiceInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06cb344f28950ca4496070fab301ae52 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BleState.cs b/Assets/Scripts/Devices/Ble/BleState.cs new file mode 100644 index 00000000..97919388 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleState.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + public enum BleState + { + // Token: 0x04001072 RID: 4210 + Unknown, + // Token: 0x04001073 RID: 4211 + Unavailable, + // Token: 0x04001074 RID: 4212 + Unauthorize, + // Token: 0x04001075 RID: 4213 + Reseting, + // Token: 0x04001076 RID: 4214 + Off, + // Token: 0x04001077 RID: 4215 + On + } +} diff --git a/Assets/Scripts/Devices/Ble/BleState.cs.meta b/Assets/Scripts/Devices/Ble/BleState.cs.meta new file mode 100644 index 00000000..4101ee6b --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BleState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3ac691d8c317dd743bf581fce607c5a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/BluetoothStateChangedCallback.cs b/Assets/Scripts/Devices/Ble/BluetoothStateChangedCallback.cs new file mode 100644 index 00000000..c8fd1484 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BluetoothStateChangedCallback.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + public delegate void BluetoothStateChangedCallback(BleWinHwInterface hwInterface, BleState bleState); + +} diff --git a/Assets/Scripts/Devices/Ble/BluetoothStateChangedCallback.cs.meta b/Assets/Scripts/Devices/Ble/BluetoothStateChangedCallback.cs.meta new file mode 100644 index 00000000..b94dc648 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/BluetoothStateChangedCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 663a2ebaee4b5a6428d06a6d0a113f9a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Characteristic.meta b/Assets/Scripts/Devices/Ble/Characteristic.meta new file mode 100644 index 00000000..89fdd514 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fb86ae4477864e74bb38dbdbf83bd787 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Characteristic/BaseCharacteristicValue.cs b/Assets/Scripts/Devices/Ble/Characteristic/BaseCharacteristicValue.cs new file mode 100644 index 00000000..991eb00e --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/BaseCharacteristicValue.cs @@ -0,0 +1,29 @@ +using Assets.Scripts.Ble.Commands; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Characteristic +{ + public abstract class BaseCharacteristicValue + { + protected BaseCharacteristicValue(Guid id, byte[] data) + { + this.RawData = data; + this.Id = id; + } + + // Token: 0x17000665 RID: 1637 + // (get) Token: 0x060022A2 RID: 8866 RVA: 0x0008F366 File Offset: 0x0008D566 + public Guid Id { get; } + + // Token: 0x17000666 RID: 1638 + // (get) Token: 0x060022A3 RID: 8867 RVA: 0x0008F36E File Offset: 0x0008D56E + public byte[] RawData { get; } + + // Token: 0x060022A4 RID: 8868 + public abstract CommandResponseCode ToDeviceCommandResponseCode(); + } +} diff --git a/Assets/Scripts/Devices/Ble/Characteristic/BaseCharacteristicValue.cs.meta b/Assets/Scripts/Devices/Ble/Characteristic/BaseCharacteristicValue.cs.meta new file mode 100644 index 00000000..cf8805ec --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/BaseCharacteristicValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2b671ee375ec854c8074b434d7ef555 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Characteristic/BleMathHelper.cs b/Assets/Scripts/Devices/Ble/Characteristic/BleMathHelper.cs new file mode 100644 index 00000000..2d8f176e --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/BleMathHelper.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Characteristic +{ + public static class BleMathHelper + { + // Token: 0x06000028 RID: 40 RVA: 0x00002740 File Offset: 0x00000940 + public static double WheelFrequency(WheelRevolution? lastWheelRevolution, WheelRevolution? newWheelRevolution, uint timeResolution) + { + return WheelRevolution.ComputeValue(lastWheelRevolution, newWheelRevolution, delegate (WheelRevolution lastValue, WheelRevolution newValue) + { + WheelRevolution wheelRevolution = newValue - lastValue; + return wheelRevolution.Count / ((double)wheelRevolution.Time / timeResolution); + }); + } + + // Token: 0x06000029 RID: 41 RVA: 0x0000276D File Offset: 0x0000096D + public static double CrankFrequency(CrankRevolution? lastCrankRevolutions, CrankRevolution? newCrankRevolutions) + { + return CrankRevolution.ComputeValue(lastCrankRevolutions, newCrankRevolutions, delegate (CrankRevolution lastValue, CrankRevolution newValue) + { + CrankRevolution crankRevolution = newValue - lastValue; + return (double)crankRevolution.Count / ((double)crankRevolution.Time / 1024.0); + }); + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Characteristic/BleMathHelper.cs.meta b/Assets/Scripts/Devices/Ble/Characteristic/BleMathHelper.cs.meta new file mode 100644 index 00000000..8a094579 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/BleMathHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 94d000bcb9e71fe4cbc87260ce666252 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Characteristic/CrankRevolution.cs b/Assets/Scripts/Devices/Ble/Characteristic/CrankRevolution.cs new file mode 100644 index 00000000..e2e68ccb --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/CrankRevolution.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Characteristic +{ + public struct CrankRevolution + { + // Token: 0x060022A5 RID: 8869 RVA: 0x0008F378 File Offset: 0x0008D578 + public static CrankRevolution operator -(CrankRevolution obj1, CrankRevolution obj2) + { + return new CrankRevolution + { + Count = (ushort)(obj1.Count - obj2.Count), + Time = (ushort)(obj1.Time - obj2.Time) + }; + } + + // Token: 0x060022A6 RID: 8870 RVA: 0x0008F3B8 File Offset: 0x0008D5B8 + public static double ComputeValue(CrankRevolution? lastValue, CrankRevolution? newValue, Func validValueComputation) + { + if (newValue == null || lastValue == null || validValueComputation == null) + { + return double.NaN; + } + if (newValue.Value.Time != lastValue.Value.Time) + { + return validValueComputation(lastValue.Value, newValue.Value); + } + if (newValue.Value.Count == lastValue.Value.Count) + { + return double.NaN; + } + throw new ArgumentException("CrankRevolution Count changed but Time remain same -> strange behaviour"); + } + + // Token: 0x060022A7 RID: 8871 RVA: 0x0008F441 File Offset: 0x0008D641 + public override string ToString() + { + return string.Format("Time: {0}, Count: {1}", this.Time, this.Count); + } + + // Token: 0x04001543 RID: 5443 + public const ushort MaxCount = 65535; + + // Token: 0x04001544 RID: 5444 + public const ushort MaxTime = 65535; + + // Token: 0x04001545 RID: 5445 + public ushort Count; + + // Token: 0x04001546 RID: 5446 + public ushort Time; + } +} diff --git a/Assets/Scripts/Devices/Ble/Characteristic/CrankRevolution.cs.meta b/Assets/Scripts/Devices/Ble/Characteristic/CrankRevolution.cs.meta new file mode 100644 index 00000000..49f3ed9c --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/CrankRevolution.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1dea0a9f55f16ac45bfd5aa6a6eda4f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Characteristic/HeartRateMeasurement.cs b/Assets/Scripts/Devices/Ble/Characteristic/HeartRateMeasurement.cs new file mode 100644 index 00000000..00985c01 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/HeartRateMeasurement.cs @@ -0,0 +1,76 @@ +using Assets.Scripts.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Devices.Ble.Characteristic +{ + public class HeartRateMeasurement + { + public Guid Uuid + { + get + { + return ServiceUuids.Characteristics.HrMeasurement; + } + } + + public Guid ServiceUuid + { + get + { + return ServiceUuids.Get(ServiceUuids.HeartRate).IdGuid; + } + } + + private HrmFormat Format { get; set; } + + // Token: 0x170005EB RID: 1515 + // (get) Token: 0x0600214D RID: 8525 RVA: 0x0008999B File Offset: 0x00087B9B + public int BeatsPerMinute { get; private set; } + + public void HandleAttributeReceived(byte[] data) + { + HrmFlags hrmFlags = (HrmFlags)BitConvertHelper.ToUInt8(data, 0); + this.Format = (HrmFormat)(hrmFlags.HasFlag(HrmFlags.Format) ? 1 : 0); + if (this.Format == HrmFormat.Short) + { + this.BeatsPerMinute = BitConvertHelper.ToUInt8(data, 1); + Debug.Log("心率:" + this.BeatsPerMinute); + return; + } + if (data.Length < 3) + { + throw new ArgumentException("数据出错"); + } + this.BeatsPerMinute = BitConvertHelper.ToUInt16(data, 1); + } + + [Flags] + private enum HrmFlags + { + // Token: 0x040029D0 RID: 10704 + Format = 1, + // Token: 0x040029D1 RID: 10705 + SensorContactStatus1 = 2, + // Token: 0x040029D2 RID: 10706 + SensorContactStatus2 = 4, + // Token: 0x040029D3 RID: 10707 + Energy = 8, + // Token: 0x040029D4 RID: 10708 + RR = 16 + } + + // Token: 0x02000921 RID: 2337 + private enum HrmFormat + { + // Token: 0x040029D6 RID: 10710 + Short, + // Token: 0x040029D7 RID: 10711 + Long + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Characteristic/HeartRateMeasurement.cs.meta b/Assets/Scripts/Devices/Ble/Characteristic/HeartRateMeasurement.cs.meta new file mode 100644 index 00000000..26291525 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/HeartRateMeasurement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3d7a13de9df31a478b0a0c9dbcb1ac4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Characteristic/SuccessOnlyCharacteristicValue.cs b/Assets/Scripts/Devices/Ble/Characteristic/SuccessOnlyCharacteristicValue.cs new file mode 100644 index 00000000..f2e158a8 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/SuccessOnlyCharacteristicValue.cs @@ -0,0 +1,22 @@ +using Assets.Scripts.Ble.Commands; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Characteristic +{ + public abstract class SuccessOnlyCharacteristicValue : BaseCharacteristicValue + { + protected SuccessOnlyCharacteristicValue(Guid id, byte[] data) : base(id, data) + { + } + + // Token: 0x060022AB RID: 8875 RVA: 0x0008F4F0 File Offset: 0x0008D6F0 + public override CommandResponseCode ToDeviceCommandResponseCode() + { + return CommandResponseCode.Success; + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Characteristic/SuccessOnlyCharacteristicValue.cs.meta b/Assets/Scripts/Devices/Ble/Characteristic/SuccessOnlyCharacteristicValue.cs.meta new file mode 100644 index 00000000..067f0acb --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/SuccessOnlyCharacteristicValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: afeabe604a3dc29409ecbf61f6939275 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Characteristic/WheelRevolution.cs b/Assets/Scripts/Devices/Ble/Characteristic/WheelRevolution.cs new file mode 100644 index 00000000..0317806a --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/WheelRevolution.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Characteristic +{ + public struct WheelRevolution + { + // Token: 0x060022AE RID: 8878 RVA: 0x0008F510 File Offset: 0x0008D710 + public static WheelRevolution operator -(WheelRevolution obj1, WheelRevolution obj2) + { + return new WheelRevolution + { + Count = obj1.Count - obj2.Count, + Time = (ushort)(obj1.Time - obj2.Time) + }; + } + + // Token: 0x060022AF RID: 8879 RVA: 0x0008F550 File Offset: 0x0008D750 + public static double ComputeValue(WheelRevolution? lastValue, WheelRevolution? newValue, Func validValueComputation) + { + if (newValue == null || lastValue == null) + { + return double.NaN; + } + if (newValue.Value.Time != lastValue.Value.Time) + { + return validValueComputation(lastValue.Value, newValue.Value); + } + if (newValue.Value.Count == lastValue.Value.Count) + { + return double.NaN; + } + throw new ArgumentException("WheelRevolution Count changed but Time remain same -> strange behaviour"); + } + + // Token: 0x060022B0 RID: 8880 RVA: 0x0008F5D6 File Offset: 0x0008D7D6 + public override string ToString() + { + return string.Format("Time: {0}, Count: {1}", this.Time, this.Count); + } + + // Token: 0x04001548 RID: 5448 + public const uint MaxCount = 4294967295U; + + // Token: 0x04001549 RID: 5449 + public const ushort MaxTime = 65535; + + // Token: 0x0400154A RID: 5450 + public uint Count; + + // Token: 0x0400154B RID: 5451 + public ushort Time; + } +} diff --git a/Assets/Scripts/Devices/Ble/Characteristic/WheelRevolution.cs.meta b/Assets/Scripts/Devices/Ble/Characteristic/WheelRevolution.cs.meta new file mode 100644 index 00000000..a09df0b5 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Characteristic/WheelRevolution.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee3e38fcbff71ea4f90a92eb251bcad4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/CharacteristicReadCallback.cs b/Assets/Scripts/Devices/Ble/CharacteristicReadCallback.cs new file mode 100644 index 00000000..9328c12a --- /dev/null +++ b/Assets/Scripts/Devices/Ble/CharacteristicReadCallback.cs @@ -0,0 +1,11 @@ +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + public delegate void CharacteristicReadCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse response); +} diff --git a/Assets/Scripts/Devices/Ble/CharacteristicReadCallback.cs.meta b/Assets/Scripts/Devices/Ble/CharacteristicReadCallback.cs.meta new file mode 100644 index 00000000..10ff1995 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/CharacteristicReadCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c69fa47ce56b72942920665130ab2bde +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/CharacteristicsDiscoveredCallback.cs b/Assets/Scripts/Devices/Ble/CharacteristicsDiscoveredCallback.cs new file mode 100644 index 00000000..d3fab0e7 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/CharacteristicsDiscoveredCallback.cs @@ -0,0 +1,11 @@ +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + public delegate void CharacteristicsDiscoveredCallback(BleWinHwInterface hwInterface, BleServiceInfo service, BleResponse> response); +} diff --git a/Assets/Scripts/Devices/Ble/CharacteristicsDiscoveredCallback.cs.meta b/Assets/Scripts/Devices/Ble/CharacteristicsDiscoveredCallback.cs.meta new file mode 100644 index 00000000..9ca5c131 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/CharacteristicsDiscoveredCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 18b405762349d704d807b732d2ddb8b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Commands.meta b/Assets/Scripts/Devices/Ble/Commands.meta new file mode 100644 index 00000000..6da855f4 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Commands.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b91b6f3c17790a0429113c8b8cba4da1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Commands/CommandResponseCode.cs b/Assets/Scripts/Devices/Ble/Commands/CommandResponseCode.cs new file mode 100644 index 00000000..338b40fd --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Commands/CommandResponseCode.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Commands +{ + public enum CommandResponseCode + { + // Token: 0x04000FEB RID: 4075 + Success = 1, + // Token: 0x04000FEC RID: 4076 + NotSupported, + // Token: 0x04000FED RID: 4077 + InvalidParameter, + // Token: 0x04000FEE RID: 4078 + OperationFailed, + // Token: 0x04000FEF RID: 4079 + UnexpectedResult, + // Token: 0x04000FF0 RID: 4080 + TypeMismatch, + // Token: 0x04000FF1 RID: 4081 + Expired + } +} diff --git a/Assets/Scripts/Devices/Ble/Commands/CommandResponseCode.cs.meta b/Assets/Scripts/Devices/Ble/Commands/CommandResponseCode.cs.meta new file mode 100644 index 00000000..670df178 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Commands/CommandResponseCode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49da5bf4f261fb04b927a90f0e1dd85b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Devices.meta b/Assets/Scripts/Devices/Ble/Devices.meta new file mode 100644 index 00000000..a565efe4 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Devices.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 925f23e73bb082b4f8420a22aa1a96e6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Devices/CyclingPower.cs b/Assets/Scripts/Devices/Ble/Devices/CyclingPower.cs new file mode 100644 index 00000000..bbfafbd1 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Devices/CyclingPower.cs @@ -0,0 +1,52 @@ +using Assets.Scripts.Ble; +using Assets.Scripts.Devices.Ant.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Devices.Ble.Devices +{ + public class CyclingPower : BleDevice, IPowerDevice + { + private List Services; + public CyclingPower(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Power) + { + bleWinHwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback; + } + + public int Power { get => 999; set => throw new NotImplementedException(); } + + protected override void CreateServices(List discoveredServices) + { + this.Services = discoveredServices; + + foreach (var service in this.Services) + { + hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) => + { + foreach (var character in response.Data) + { + if (character.MatchGuid(ServiceUuids.Characteristics.CyclingPowerMeasurement)) + { + Debug.Log("功率功能"); + + this.hwInterface.SubscribeCharacteristic(character, (hw, cha, res) => + { + Debug.Log("1111111111111111111111"); + }); + } + } + }); + } + } + + + private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse response) + { + Debug.Log("main call" + string.Join(",", response.Data)); + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Devices/CyclingPower.cs.meta b/Assets/Scripts/Devices/Ble/Devices/CyclingPower.cs.meta new file mode 100644 index 00000000..28fd3a11 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Devices/CyclingPower.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1bfee528ff9d5854a87190f63ce65ee6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Devices/Ftms.cs b/Assets/Scripts/Devices/Ble/Devices/Ftms.cs new file mode 100644 index 00000000..141fbcfc --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Devices/Ftms.cs @@ -0,0 +1,26 @@ +using Assets.Scripts.Ble; +using Assets.Scripts.Devices.Ant.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices.Ble.Devices +{ + public class Ftms : BleDevice, IPowerDevice + { + + public Ftms(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) :base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Trainer) + { + + } + + public int Power { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + protected override void CreateServices(List discoveredServices) + { + throw new NotImplementedException(); + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Devices/Ftms.cs.meta b/Assets/Scripts/Devices/Ble/Devices/Ftms.cs.meta new file mode 100644 index 00000000..943c760b --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Devices/Ftms.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c3826d0749b3b743876392548083207 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs b/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs new file mode 100644 index 00000000..437e3798 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs @@ -0,0 +1,62 @@ +using Assets.Scripts.Ble; +using Assets.Scripts.Devices.Ant.Interfaces; +using Assets.Scripts.Devices.Ble.Characteristic; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Devices.Ble.Devices +{ + public class HeartRate : BleDevice, IHeartRateDevice + { + int IHeartRateDevice.HeartRate { get => heartRateMeasurement.BeatsPerMinute; set => throw new NotImplementedException(); } + + private List Services; + private HeartRateMeasurement heartRateMeasurement; + public HeartRate(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.HeartRate) + { + Debug.Log("创建心率设备"); + heartRateMeasurement = new HeartRateMeasurement(); + + bleWinHwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback; + } + + + + protected override void CreateServices(List discoveredServices) + { + //throw new NotImplementedException(); + this.Services = discoveredServices; + + foreach (var service in this.Services) + { + hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) => + { + foreach (var character in response.Data) + { + if (character.MatchGuid(heartRateMeasurement.Uuid)) + { + Debug.Log("心率功能"); + + this.hwInterface.SubscribeCharacteristic(character, (hw, cha, res) => + { + Debug.Log("1111111111111111111111"); + }); + } + } + }); + } + + } + + private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse response) + { + Debug.Log("main call" + string.Join(",", response.Data)); + heartRateMeasurement.HandleAttributeReceived(response.Data); + } + } + +} diff --git a/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs.meta b/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs.meta new file mode 100644 index 00000000..1291f208 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Devices/HeartRate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b880a0d1b518452488d5e1a69d0cc1ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Extension.meta b/Assets/Scripts/Devices/Ble/Extension.meta new file mode 100644 index 00000000..ab4d04f5 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Extension.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f4e5e995271d2b04ea04a51eb6c999c5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Extension/EnumExtensions.cs b/Assets/Scripts/Devices/Ble/Extension/EnumExtensions.cs new file mode 100644 index 00000000..3d887c8a --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Extension/EnumExtensions.cs @@ -0,0 +1,17 @@ +using Assets.Scripts.Ble.Commands; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices.Ble.Extension +{ + public static class EnumExtensions + { + public static CommandResponseCode ToDeviceCommandResponseType(this BleHwInterfaceError error) + { + return CommandResponseCode.OperationFailed; + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Extension/EnumExtensions.cs.meta b/Assets/Scripts/Devices/Ble/Extension/EnumExtensions.cs.meta new file mode 100644 index 00000000..fab97449 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Extension/EnumExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e363293eef5f264c9de132f6c24b01e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/HeartRate.meta b/Assets/Scripts/Devices/Ble/HeartRate.meta new file mode 100644 index 00000000..b17abb5e --- /dev/null +++ b/Assets/Scripts/Devices/Ble/HeartRate.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d9ddacaed9a7562489aa2476a0f74aca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/HeartRate/HeartRateMeasurementValue.cs b/Assets/Scripts/Devices/Ble/HeartRate/HeartRateMeasurementValue.cs new file mode 100644 index 00000000..8dd7457b --- /dev/null +++ b/Assets/Scripts/Devices/Ble/HeartRate/HeartRateMeasurementValue.cs @@ -0,0 +1,70 @@ +using Assets.Scripts.Ble.Characteristic; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.HeartRate +{ + public class HeartRateMeasurementValue : SuccessOnlyCharacteristicValue + { + private HeartRateMeasurementValue.HrmFormat Format { get; } + + // Token: 0x170005EB RID: 1515 + // (get) Token: 0x0600214D RID: 8525 RVA: 0x0008999B File Offset: 0x00087B9B + public int BeatsPerMinute { get; } + + public HeartRateMeasurementValue(byte[] data): base(ServiceUuids.Characteristics.HrMeasurement, data) + { + if(data == null || data.Length < 2) + { + throw new ArgumentException(string.Concat(new string[] + { + "Invalid data for ", + base.Id.ToString(), + " ", + (data != null) ? string.Join(",", data) : null, + "." + }), "data"); + } + HeartRateMeasurementValue.HrmFlags hrmFlags = (HeartRateMeasurementValue.HrmFlags)BitConvertHelper.ToUInt8(data, 0); + this.Format = (HrmFormat)(hrmFlags.HasFlag(HeartRateMeasurementValue.HrmFlags.Format) ? 1 : 0); + if (this.Format == HeartRateMeasurementValue.HrmFormat.Short) + { + this.BeatsPerMinute = BitConvertHelper.ToUInt8(data, 1); + return; + } + if(data.Length < 3) + { + throw new ArgumentException("数据出错"); + } + this.BeatsPerMinute = BitConvertHelper.ToUInt16(data, 1); + } + + + [Flags] + private enum HrmFlags + { + // Token: 0x040029D0 RID: 10704 + Format = 1, + // Token: 0x040029D1 RID: 10705 + SensorContactStatus1 = 2, + // Token: 0x040029D2 RID: 10706 + SensorContactStatus2 = 4, + // Token: 0x040029D3 RID: 10707 + Energy = 8, + // Token: 0x040029D4 RID: 10708 + RR = 16 + } + + // Token: 0x02000921 RID: 2337 + private enum HrmFormat + { + // Token: 0x040029D6 RID: 10710 + Short, + // Token: 0x040029D7 RID: 10711 + Long + } + } +} diff --git a/Assets/Scripts/Devices/Ble/HeartRate/HeartRateMeasurementValue.cs.meta b/Assets/Scripts/Devices/Ble/HeartRate/HeartRateMeasurementValue.cs.meta new file mode 100644 index 00000000..e4b82809 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/HeartRate/HeartRateMeasurementValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3668128267e8c52448ad703e31f8bd88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/HeartRate/HeartRateService.cs b/Assets/Scripts/Devices/Ble/HeartRate/HeartRateService.cs new file mode 100644 index 00000000..dc9f5fef --- /dev/null +++ b/Assets/Scripts/Devices/Ble/HeartRate/HeartRateService.cs @@ -0,0 +1,60 @@ +using Assets.Scripts.Ble.Commands; +using Assets.Scripts.Ble.Service; +using Assets.Scripts.Commands; +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Ble.HeartRate +{ + public class HeartRateService : BleService + { + private BleCharacteristicInfo heartRateCharacteristic; + + public HeartRateService(BleServiceInfo serviceInfo, BleWinHwInterface bleWinHwInterface) :base(serviceInfo, bleWinHwInterface) + { + + } + + protected override void CharacteristicsDiscovered(BleResponse> response) + { + foreach (var item in response.Data) + { + if (item.MatchGuid(ServiceUuids.Characteristics.HrMeasurement)) + { + this.heartRateCharacteristic = item; + base.SubscribeCharacteristic(item, HrmCharacteristicSubscribed, HrmCharacteristicRead); + } + if (item.MatchGuid(ServiceUuids.Characteristics.BodySensorLocation)) + { + + } + } + } + + private void HrmCharacteristicSubscribed(BleWinHwInterface winHwInterface, BleCharacteristicInfo characteristic, BleResponse response) + { + + } + + private void HrmCharacteristicRead(BleWinHwInterface winHwInterface, BleCharacteristicInfo characteristic, BleResponse response) + { + HeartRateMeasurementValue heartRateMeasurementValue; + if(base.CheckCharacteristicResponse(characteristic, response, (BleCharacteristicInfo info, BleResponse bleResponse) => new HeartRateMeasurementValue(bleResponse.Data), out heartRateMeasurementValue) != CommandResponseCode.Success) + { + return; + } + + //Debug.Log("心率:"+heartRateMeasurementValue.BeatsPerMinute); + } + + protected override BleCharacteristicInfo GetCharacteristicForCommandType(CommandType type) + { + return null; + } + } +} diff --git a/Assets/Scripts/Devices/Ble/HeartRate/HeartRateService.cs.meta b/Assets/Scripts/Devices/Ble/HeartRate/HeartRateService.cs.meta new file mode 100644 index 00000000..fea5edb0 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/HeartRate/HeartRateService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d36bb0439a6a6c142af91aa05a67a7e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/PeripheralDisconnectedCallback.cs b/Assets/Scripts/Devices/Ble/PeripheralDisconnectedCallback.cs new file mode 100644 index 00000000..aefb5811 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/PeripheralDisconnectedCallback.cs @@ -0,0 +1,11 @@ +using Assets.Scripts.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices.Ble +{ + public delegate void PeripheralDisconnectedCallback(BleWinHwInterface hwInterface, BlePeripheralInfo peripheral, BleResponse response); +} diff --git a/Assets/Scripts/Devices/Ble/PeripheralDisconnectedCallback.cs.meta b/Assets/Scripts/Devices/Ble/PeripheralDisconnectedCallback.cs.meta new file mode 100644 index 00000000..7b270e3c --- /dev/null +++ b/Assets/Scripts/Devices/Ble/PeripheralDisconnectedCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 267fe052d333eec4db01b694b8d68180 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Scan.meta b/Assets/Scripts/Devices/Ble/Scan.meta new file mode 100644 index 00000000..2c283a69 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Scan.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 42dcd8e06e630564bb971b809b953305 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs b/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs new file mode 100644 index 00000000..b66dcdf9 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs @@ -0,0 +1,40 @@ +using Assets.Scripts.Devices.Ant; +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Scan +{ + /// + /// 广播数据 + /// + public class BleAdvertisementInfo + { + public BlePeripheralInfo Peripheral { get; } + public int Rssi { get; } + + public SensorType SensorType { get; } + public BleAdvertisementInfo(BlePeripheralInfo peripheral, int rssi, bool connectible, List services, byte[] manufactureData, SensorType sensor) + { + this.Peripheral = peripheral; + this.Rssi = rssi; + //this.Connectible = connectible; + this.services = services; + //this.ManufactureData = manufactureData; + + this.SensorType = sensor; + } + + private readonly List services; + public IReadOnlyList Services + { + get + { + return this.services; + } + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs.meta b/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs.meta new file mode 100644 index 00000000..acc74136 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Scan/BleAdvertisementInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4809c38d934e9a247a4e70bbcf6fd67b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Service.meta b/Assets/Scripts/Devices/Ble/Service.meta new file mode 100644 index 00000000..06b84002 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Service.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ffc07810002114f4e845efdbc1f8f47e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Service/BleService.cs b/Assets/Scripts/Devices/Ble/Service/BleService.cs new file mode 100644 index 00000000..40a0f123 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Service/BleService.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Assets.Scripts.Ble.Characteristic; +using Assets.Scripts.Ble.Commands; +using Assets.Scripts.Commands; +using Assets.Scripts.Devices.Ble; +using Assets.Scripts.Devices.Ble.Extension; +using UnityEngine; + +namespace Assets.Scripts.Ble.Service +{ + public abstract class BleService + { + private BleWinHwInterface hwInterface; + private BleServiceInfo serviceInfo; + + private List characteristics; + private readonly Dictionary>> registeredCharacteristicReadEvents = new Dictionary>>(); + + public IReadOnlyList Characteristics + { + get + { + return this.characteristics; + } + } + + private CommandType supportedCommands; + + // Token: 0x0400110D RID: 4365 + private CommandType tempCommands; + + public CommandType SupportedCommands + { + get + { + return this.supportedCommands; + } + private set + { + if (this.supportedCommands.HasFlag(value)) + { + return; + } + this.supportedCommands |= value; + } + } + + + public BleService(BleServiceInfo serviceInfo, BleWinHwInterface bleHwInterface) + { + this.hwInterface = bleHwInterface; + this.serviceInfo = serviceInfo; + + this.hwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback; + } + + private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse response) + { + //Debug.Log("read main callback"); + if (this.registeredCharacteristicReadEvents.ContainsKey(characteristic.Id) && characteristic.Service.Equals(this.serviceInfo)) + { + //Debug.Log("read main callback 1111111111111"); + this.registeredCharacteristicReadEvents[characteristic.Id](hwInterface, characteristic, response); + } + } + + public void DiscoverCharacteristics(BleResponse> scanCharacteristicsResponse = null) + { + if (scanCharacteristicsResponse == null) + { + Debug.Log("ccc ======================================== "+this.serviceInfo.Peripheral.Name); + this.hwInterface.DiscoverCharacteristic(this.serviceInfo, this.CheckCharacteristicDiscoveredResponse); + return; + } + this.CheckCharacteristicDiscoveredResponse(this.hwInterface, this.serviceInfo, scanCharacteristicsResponse); + } + + private void CheckCharacteristicDiscoveredResponse(BleWinHwInterface hwInterface, BleServiceInfo service, BleResponse> response) + { + if (!service.Equals(this.serviceInfo)) + { + return; + } + if (!response.IsSuccess) + { + return; + } + //if(response.Data) + + this.characteristics = response.Data; + + this.CharacteristicsDiscovered(response); + } + + protected abstract void CharacteristicsDiscovered(BleResponse> response); + + protected void SubscribeCharacteristic(BleCharacteristicInfo characteristic, Action notificationCallback, + Action> readCallback) + { + this.hwInterface.SubscribeCharacteristic(characteristic, (hw, info, response) => + { + if (readCallback != null) + { + this.registeredCharacteristicReadEvents[characteristic.Id] = readCallback; + Debug.Log("添加callback"); + } + + if (notificationCallback == null) + { + return; + } + notificationCallback.Invoke(hw, info, response); + }); + } + + protected Commands.CommandResponseCode CheckCharacteristicResponse(BleCharacteristicInfo characteristic, BleResponse response, + Func, TResponseValue> valueCreator, out TResponseValue value) where TResponseValue : BaseCharacteristicValue + { + value = default(TResponseValue); + + if (!response.IsSuccess) + { + return response.Error.ToDeviceCommandResponseType(); + } + + try + { + value = valueCreator(characteristic, response); + } + catch (Exception ex) + { + + throw; + } + + CommandResponseCode commandResponseCode = value.ToDeviceCommandResponseCode(); + + return commandResponseCode; + } + + protected void AddSupportedCommand(CommandType newCommands) + { + this.SupportedCommands |= newCommands; + + if (newCommands.HasFlag(CommandType.SetSimParameters)) + { + + + } + + } + + + + protected void ReadCharacteristic(BleCharacteristicInfo characteristic, CharacteristicReadCallback callback) + { + this.hwInterface.ReadCharacteristic(characteristic, callback); + } + + protected BleCharacteristicInfo CheckServiceCanSendCommand(Command command) + { + CommandType type = command.Type; + //if (!this.SupportedCommands(type)) + //{ + + //} + + BleCharacteristicInfo characteristicForCommandType = this.GetCharacteristicForCommandType(type); + + return characteristicForCommandType; + } + + + protected abstract BleCharacteristicInfo GetCharacteristicForCommandType(CommandType type); + + public bool SupportsCommands(CommandType flags) + { + return this.SupportedCommands.HasFlag(flags); + } + + public virtual bool SendCommand(Command command) + { + return false; + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Service/BleService.cs.meta b/Assets/Scripts/Devices/Ble/Service/BleService.cs.meta new file mode 100644 index 00000000..df8b2a9b --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Service/BleService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 927b28f8d3c950b4793567e37f28d27c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win.meta b/Assets/Scripts/Devices/Ble/Win.meta new file mode 100644 index 00000000..1b572306 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bee6ebee782762641bf45036d063e6d5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/BleDeviceProxy.cs b/Assets/Scripts/Devices/Ble/Win/BleDeviceProxy.cs new file mode 100644 index 00000000..498a4540 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/BleDeviceProxy.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + /// + /// rouvy里的 WinBlePeripheralInfo类 + /// + public class BleDeviceProxy + { + public string Address { get; set; } + + public string Name { get; set; } + + public int Rssi { get; set; } + + public List Services { get; set; } + + public BleDeviceProxy() + { + + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/BleDeviceProxy.cs.meta b/Assets/Scripts/Devices/Ble/Win/BleDeviceProxy.cs.meta new file mode 100644 index 00000000..b247debe --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/BleDeviceProxy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33bb64404b5022f4d888be258a6b970a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs b/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs new file mode 100644 index 00000000..e9a623e5 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs @@ -0,0 +1,409 @@ +using Assets.Scripts.Ble.Scan; +using Assets.Scripts.Ble.Win; +using Assets.Scripts.Devices.Ant; +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Ble +{ + public sealed class BleWinHwInterface + { + private static BleWinHwInterface hwInterface; + private WclBleMainThread wclBleMainThread; + + private readonly Dictionary pCache = new Dictionary(); + + private Action _discoveredCallback; + + private Dictionary> callbacks = new Dictionary>(); + private Dictionary>>> servicesCallbacks = new Dictionary>>>(); + //private Dictionary>>> characteristicsCallbacks = new Dictionary>>>(); + private Dictionary> characteristicNotificationCallbacks = new Dictionary>(); + private Dictionary characteristicReadCallbacks = new Dictionary(); + private Dictionary characteristicsDiscoveredCallbacks = new Dictionary(); + + + private CharacteristicReadCallback characteristicReadEvent; + public event CharacteristicReadCallback CharacteristicReadEvent + { + add + { + this.characteristicReadEvent += value; + } + remove + { + this.characteristicReadEvent -= value; + } + } + + private BluetoothStateChangedCallback bluetoothStateChanged; + public event BluetoothStateChangedCallback BluetoothStateChangedEvent + { + add + { + this.bluetoothStateChanged += value; + } + remove + { + this.bluetoothStateChanged -= value; + } + } + + private BleState nativeState; + public BleState BleState + { + get + { + return this.nativeState; + } + private set + { + if(this.nativeState != value) + { + this.nativeState = value; + this.bluetoothStateChanged?.Invoke(this, this.nativeState); + } + } + } + + private PeripheralDisconnectedCallback peripheralDisconnectedEvent; + public event PeripheralDisconnectedCallback PeripheralDisconnectedEvent + { + add + { + this.peripheralDisconnectedEvent += value; + } + remove + { + this.peripheralDisconnectedEvent -= value; + } + } + + private BleWinHwInterface() + { + wclBleMainThread = new WclBleMainThread(); + wclBleMainThread.ManagerStatusChanged += ManagerStatusChanged; + wclBleMainThread.ScanInfoReceived += WatcherScanInfoReceived; + //wclBleMainThread.gatt + wclBleMainThread.Start(); + + } + + private void WatcherScanInfoReceived(WclBleMainThread sender, long address, string name, int rssi, CPPBridge.WclBleAdvertisementType packetType, Guid? service) + { + //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).Any(x => x.Equals(service.Value))) + { + SensorType sensor = SensorType.None; + List services = null; + if (service != null) + { + + services = new List { service.Value }; + foreach(var item in ServiceUuids.Services) + { + if(item.IdGuid != service.Value) + { + continue; + } + if(item.IdByteArray == ServiceUuids.Ftms) + { + sensor = SensorType.Trainer; + } + else if(item.IdByteArray == ServiceUuids.HeartRate) + { + sensor = SensorType.HeartRate; + } + else if(item.IdByteArray == ServiceUuids.CyclingPower) + { + sensor = SensorType.Power; + } + } + }; + + if (!pCache.ContainsKey(address.ToString())) { + var device = new BleAdvertisementInfo(new WinBlePeripheralInfo(address.ToString(), name), rssi, true, services, null, sensor); + pCache.Add(address.ToString(), device); + + WclBleGattThread gattClient = this.SetUpGattClient(device.Peripheral); + //this.ConnectInternal(gattClient); + } + + _discoveredCallback?.Invoke(pCache[address.ToString()]); + } + } + + private WclBleGattThread SetUpGattClient(BlePeripheralInfo peripheral) + { + WclBleGattThread wclBleGattThread = this.wclBleMainThread.CreateGattThread(peripheral); + wclBleGattThread.GattConnected += this.GattConnected; + wclBleGattThread.GattDisconnected += this.GattDisconnected; + wclBleGattThread.GattServicesDiscovered += this.GattServicesDiscovered; + wclBleGattThread.GattCharacteristicsDiscovered += this.GattCharacteristicsDiscovered; + wclBleGattThread.GattCharacteristicSubscribed += this.GattCharacteristicSubscribed; + wclBleGattThread.GattCharacteristicRead += this.GattCharacteristicRead; + wclBleGattThread.GattCharacteristicWrote += this.GattCharacteristicWrote; + wclBleGattThread.GattCharacteristicChanged += this.GattCharacteristicChanged; + wclBleGattThread.Start(); + return wclBleGattThread; + } + + internal void ConnectPeripheral(BlePeripheralInfo info, Action callback) + { + this.callbacks.Add(info, callback); + WclBleGattThread wclBleGattThread = this.wclBleMainThread.GetGattThread(info); + if(wclBleGattThread == null) + { + wclBleGattThread = this.SetUpGattClient(info); + this.ConnectInternal(wclBleGattThread); + return; + } + else + { + this.ConnectInternal(wclBleGattThread); + } + } + + private void ConnectInternal(WclBleGattThread gattClient) + { + int num = gattClient.Connect(); + Debug.Log("连接设备返回" + num); + } + + internal void DisconnectPeripheral(BlePeripheralInfo peripheral, Action callback) + { + var gattThread = this.wclBleMainThread.GetGattThread(peripheral); + if(gattThread != null) + { + this.callbacks.Remove(peripheral); + this.servicesCallbacks.Remove(peripheral); + this.characteristicNotificationCallbacks.Remove(peripheral); + + gattThread.Discounect(); + + callback?.Invoke(); + } + } + + + public static BleWinHwInterface GetInterface() + { + if(hwInterface == null) + { + hwInterface = new BleWinHwInterface(); + } + + return hwInterface; + } + + public void StartScan(Action discoveredCallBack) + { + _discoveredCallback = discoveredCallBack; + this.wclBleMainThread.StartWatcher(); + } + + private void ManagerStatusChanged(WclBleMainThread sender, WclBleManagerStatus status) + { + this.BleState = BleWinHwInterface.StateFromNativeState(status); + Debug.Log("win hw:" + status); + + } + + private void GattConnected(WclBleGattThread gattClient, BleResponse response) + { + Debug.Log($"gatt connected { response.ToString() }"); + this.callbacks[gattClient.Peripheral].Invoke(this, gattClient.Peripheral, response); + } + + private void GattDisconnected(WclBleGattThread gattClient, BleResponse response) + { + Debug.Log("gatt disconnected"); + } + private void GattServicesDiscovered(WclBleGattThread gattClient, BleResponse> response) + { + Debug.Log("services discovered"); + //this.callbacks[gattClient.Peripheral].Invoke(this, gattClient.Peripheral, response); + + foreach (var item in response.Data) + { + Debug.Log(item.ToString()); + } + + if (this.servicesCallbacks.ContainsKey(gattClient.Peripheral)) + { + this.servicesCallbacks[gattClient.Peripheral].Invoke(this, gattClient.Peripheral, response); + } + } + + private void GattCharacteristicsDiscovered(WclBleGattThread gattClient, BleServiceInfo service, BleResponse> response) + { + Debug.Log("characteristics discovered"); + + if (this.characteristicsDiscoveredCallbacks.ContainsKey(service)) + { + this.characteristicsDiscoveredCallbacks[service].Invoke(this, service, response); + } + } + + private void GattCharacteristicSubscribed(WclBleGattThread gattClient, BleCharacteristicInfo characteristic, BleResponse response) + { + Debug.Log("characteristics subscribed"); + if (this.characteristicNotificationCallbacks.ContainsKey(gattClient.Peripheral)) + { + this.characteristicNotificationCallbacks[gattClient.Peripheral].Invoke(this, characteristic, response); + } + } + private void GattCharacteristicRead(WclBleGattThread gattClient, BleCharacteristicInfo characteristic, BleResponse response) + { + Debug.Log("characteristic read"); + + if (this.characteristicReadCallbacks.ContainsKey(characteristic)) + { + this.characteristicReadCallbacks[characteristic].Invoke(this, characteristic, response); + this.characteristicReadCallbacks.Remove(characteristic); + } + + this.characteristicReadEvent.Invoke(this, characteristic, response); + } + + private void GattCharacteristicWrote(WclBleGattThread gattClient, BleCharacteristicInfo characteristic, BleResponse response) + { + Debug.Log("characteristic wrote"); + } + private void GattCharacteristicChanged(WclBleGattThread gattClient, BleCharacteristicInfo characteristic, BleResponse response) + { + Debug.Log("characteristic changed"); + if(this.wclBleMainThread.GetGattThread(characteristic.Peripheral) != null) + { + this.characteristicReadEvent.Invoke(this, characteristic, response); + } + } + + public void DiscoverServices(BlePeripheralInfo peripheral, Action>> callback) + { + WclBleGattThread gattThread = this.wclBleMainThread.GetGattThread(peripheral); + if(gattThread == null) + { + return; + } + + this.servicesCallbacks.Add(peripheral, callback); + int num = gattThread.DiscoverServices(); + if (WclBleErrors.IsSuccessCode(num)) + { + return; + } + + + BleResponse> response = new BleResponse> + { + IsSuccess = false, + Error = new BleHwInterfaceError(new int?(num), "WclBleGattClientErrorDomain", string.Format("Error discovering services - {0}", num)) + }; + this.GattServicesDiscovered(gattThread, response); + } + + public void DiscoverCharacteristic(BleServiceInfo service, CharacteristicsDiscoveredCallback callback) + { + WclBleGattThread gattThread = this.wclBleMainThread.GetGattThread(service.Peripheral); + if(gattThread == null) + { + return; + } + this.characteristicsDiscoveredCallbacks.Add(service, callback); + int num = gattThread.DiscoverCharacteristics(service); + if (WclBleErrors.IsSuccessCode(num)) + { + return; + } + BleResponse> response = new BleResponse> + { + IsSuccess = false, + Error = new BleHwInterfaceError(new int?(num), "WclBleGattClientErrorDomain", string.Format("Error discovering characteristics - {0}", num)) + }; + this.GattCharacteristicsDiscovered(gattThread, service, response); + } + + public void SubscribeCharacteristic(BleCharacteristicInfo characteristic, Action callback) + { + WclBleGattThread gattThread = this.wclBleMainThread.GetGattThread(characteristic.Peripheral); + + this.characteristicNotificationCallbacks.Add(gattThread.Peripheral, callback); + int num = gattThread.SubscribeCharacteristic(characteristic); + if (WclBleErrors.IsSuccessCode(num)) + { + return; + } + BleResponse> response = new BleResponse> + { + IsSuccess = false, + Error = new BleHwInterfaceError(new int?(num), "WclBleGattClientErrorDomain", string.Format("Error subscribing characteristic - {0}", num)) + }; + this.GattCharacteristicSubscribed(gattThread, characteristic, response); + } + + public void Dispose() + { + this.wclBleMainThread.Dispose(); + this.wclBleMainThread = null; + hwInterface = null; + } + + public void ReadCharacteristic(BleCharacteristicInfo characteristic, CharacteristicReadCallback callback) + { + WclBleGattThread gattThread = this.wclBleMainThread.GetGattThread(characteristic.Peripheral); + if(gattThread == null) + { + return; + } + this.characteristicReadCallbacks.Add(characteristic, callback); + int num = gattThread.ReadCharacteristicValue(characteristic); + if (WclBleErrors.IsSuccessCode(num)) + { + return; + } + } + + private static BleState StateFromNativeState(WclBleManagerStatus status) + { + switch (status) + { + case WclBleManagerStatus.RadioOff: + return BleState.Off; + case WclBleManagerStatus.RadioOn: + return BleState.On; + case WclBleManagerStatus.Unknown: + return BleState.Unknown; + default: + return BleState.Unavailable; + } + } + + private class WinBlePeripheralInfo : BlePeripheralInfo + { + // Token: 0x06003F35 RID: 16181 RVA: 0x000E9FBF File Offset: 0x000E81BF + public WinBlePeripheralInfo(string address, string name) : base(address, name) + { + } + + // Token: 0x06003F36 RID: 16182 RVA: 0x000E9FC9 File Offset: 0x000E81C9 + public void SetName(string name) + { + base.Name = name; + } + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs.meta b/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs.meta new file mode 100644 index 00000000..3fdd7831 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/BleWinHwInterface.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8749d096f14d0ea44ad8ab90a45d70f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge.meta new file mode 100644 index 00000000..577cbda2 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a5379f968d8a33a4fa0f222d169164d4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristic.cs b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristic.cs new file mode 100644 index 00000000..0178f415 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristic.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win.CPPBridge +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct GattCharacteristic + { + // Token: 0x04001350 RID: 4944 + [MarshalAs(UnmanagedType.U2)] + public ushort ServiceHandle; + + // Token: 0x04001351 RID: 4945 + public GattUuid Uuid; + + // Token: 0x04001352 RID: 4946 + [MarshalAs(UnmanagedType.U2)] + public ushort Handle; + + // Token: 0x04001353 RID: 4947 + [MarshalAs(UnmanagedType.U2)] + public ushort ValueHandle; + + // Token: 0x04001354 RID: 4948 + [MarshalAs(UnmanagedType.Bool)] + public bool IsBroadcastable; + + // Token: 0x04001355 RID: 4949 + [MarshalAs(UnmanagedType.Bool)] + public bool IsReadable; + + // Token: 0x04001356 RID: 4950 + [MarshalAs(UnmanagedType.Bool)] + public bool IsWritable; + + // Token: 0x04001357 RID: 4951 + [MarshalAs(UnmanagedType.Bool)] + public bool IsWritableWithoutResponse; + + // Token: 0x04001358 RID: 4952 + [MarshalAs(UnmanagedType.Bool)] + public bool IsSignedWritable; + + // Token: 0x04001359 RID: 4953 + [MarshalAs(UnmanagedType.Bool)] + public bool IsNotifiable; + + // Token: 0x0400135A RID: 4954 + [MarshalAs(UnmanagedType.Bool)] + public bool IsIndicatable; + + // Token: 0x0400135B RID: 4955 + [MarshalAs(UnmanagedType.Bool)] + public bool HasExtendedProperties; + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristic.cs.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristic.cs.meta new file mode 100644 index 00000000..39e293f7 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristic.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e3cd838ef790974db97b48787131436 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristics.cs b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristics.cs new file mode 100644 index 00000000..c0887ecd --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristics.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win.CPPBridge +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct GattCharacteristics + { + // Token: 0x0400135C RID: 4956 + [MarshalAs(UnmanagedType.U1)] + public byte Count; + + // Token: 0x0400135D RID: 4957 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)] + public GattCharacteristic[] Chars; + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristics.cs.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristics.cs.meta new file mode 100644 index 00000000..9234834f --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattCharacteristics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34261dc02869ee243a7168adabe60fc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattService.cs b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattService.cs new file mode 100644 index 00000000..671acdb7 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattService.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win.CPPBridge +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct GattService + { + // Token: 0x0400135E RID: 4958 + public GattUuid Uuid; + + // Token: 0x0400135F RID: 4959 + [MarshalAs(UnmanagedType.U2)] + public ushort Handle; + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattService.cs.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattService.cs.meta new file mode 100644 index 00000000..8ffc3239 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2daabe73d2950c243a1a6a872bd74445 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattServices.cs b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattServices.cs new file mode 100644 index 00000000..dc545bd2 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattServices.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win.CPPBridge +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct GattServices + { + // Token: 0x04001360 RID: 4960 + [MarshalAs(UnmanagedType.U1)] + public byte Count; + + // Token: 0x04001361 RID: 4961 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)] + public GattService[] Services; + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattServices.cs.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattServices.cs.meta new file mode 100644 index 00000000..7c3ded3f --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattServices.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb895de0d5e252c4e9cf793690ddf39c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuid.cs b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuid.cs new file mode 100644 index 00000000..63fb41d7 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuid.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win.CPPBridge +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct GattUuid + { + // Token: 0x06002139 RID: 8505 RVA: 0x000896C8 File Offset: 0x000878C8 + public override string ToString() + { + if (!this.IsShortUuid) + { + return string.Format("{0:D}", this.LongUuid); + } + return string.Format("0x{0:X}", this.ShortUuid); + } + + // Token: 0x04001362 RID: 4962 + [MarshalAs(UnmanagedType.Bool)] + public bool IsShortUuid; + + // Token: 0x04001363 RID: 4963 + [MarshalAs(UnmanagedType.U2)] + public ushort ShortUuid; + + // Token: 0x04001364 RID: 4964 + public Guid LongUuid; + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuid.cs.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuid.cs.meta new file mode 100644 index 00000000..3de27e38 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 980c29814813f4c419759b2b0f6158eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuidExtension.cs b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuidExtension.cs new file mode 100644 index 00000000..dd8965f8 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuidExtension.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win.CPPBridge +{ + internal static class GattUuidExtension + { + // Token: 0x0600213A RID: 8506 RVA: 0x000896FD File Offset: 0x000878FD + public static Guid WclShortGuidToGuid(this ushort shortUuid) + { + return new Guid("0000XXXX-0000-1000-8000-00805F9B34FB".Replace("XXXX", shortUuid.ToString("X4"))); + } + + // Token: 0x0600213B RID: 8507 RVA: 0x0008971F File Offset: 0x0008791F + public static Guid WclGuidToNormalizedGuid(this GattUuid uuid) + { + if (uuid.IsShortUuid) + { + return new Guid("0000XXXX-0000-1000-8000-00805F9B34FB".Replace("XXXX", uuid.ShortUuid.ToString("X4"))); + } + return uuid.LongUuid; + } + + // Token: 0x04001365 RID: 4965 + public const string GuidTemplate = "0000XXXX-0000-1000-8000-00805F9B34FB"; + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuidExtension.cs.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuidExtension.cs.meta new file mode 100644 index 00000000..d4fc0e46 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/GattUuidExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a96dd52c07e9f749806d13f85953f1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/WCL_NOTIFY_EVENT.cs b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WCL_NOTIFY_EVENT.cs new file mode 100644 index 00000000..2279053c --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WCL_NOTIFY_EVENT.cs @@ -0,0 +1,8 @@ +using System; +using System.Runtime.InteropServices; + +namespace Assets.Scripts.Ble.CPPBridge +{ + [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)] + internal delegate void WCL_NOTIFY_EVENT([MarshalAs(UnmanagedType.SysInt)][In] IntPtr sender); +} diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/WCL_NOTIFY_EVENT.cs.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WCL_NOTIFY_EVENT.cs.meta new file mode 100644 index 00000000..dbf2d834 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WCL_NOTIFY_EVENT.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 857859a8d81c3474d98b6f9a08158d1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleAdvertisementType.cs b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleAdvertisementType.cs new file mode 100644 index 00000000..4e6a5bac --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleAdvertisementType.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.CPPBridge +{ + internal enum WclBleAdvertisementType + { + // Token: 0x0400136D RID: 4973 + ConnectableUndirected, + // Token: 0x0400136E RID: 4974 + ConnectableDirected, + // Token: 0x0400136F RID: 4975 + ScannableUndirected, + // Token: 0x04001370 RID: 4976 + NonConnectableUndirected, + // Token: 0x04001371 RID: 4977 + ScanResponse, + // Token: 0x04001372 RID: 4978 + Unknown + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleAdvertisementType.cs.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleAdvertisementType.cs.meta new file mode 100644 index 00000000..6813d51d --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleAdvertisementType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da17e15eaae28fb4aaa037e484e6563b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleGattClientState.cs b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleGattClientState.cs new file mode 100644 index 00000000..c371ed1b --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleGattClientState.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win.CPPBridge +{ + internal enum WclBleGattClientState + { + // Token: 0x04001374 RID: 4980 + Disconnected, + // Token: 0x04001375 RID: 4981 + Preparing, + // Token: 0x04001376 RID: 4982 + Connecting, + // Token: 0x04001377 RID: 4983 + Connected, + // Token: 0x04001378 RID: 4984 + Disconnecting + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleGattClientState.cs.meta b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleGattClientState.cs.meta new file mode 100644 index 00000000..b2b92363 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/CPPBridge/WclBleGattClientState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ba37be1c32d2744fb72633ab646ca6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/GattConnected.cs b/Assets/Scripts/Devices/Ble/Win/GattConnected.cs new file mode 100644 index 00000000..c7d4da72 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/GattConnected.cs @@ -0,0 +1,11 @@ +using Assets.Scripts.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices.Ble.Win +{ + internal delegate void GattConnected(WclBleGattThread gatt, BleResponse response); +} diff --git a/Assets/Scripts/Devices/Ble/Win/GattConnected.cs.meta b/Assets/Scripts/Devices/Ble/Win/GattConnected.cs.meta new file mode 100644 index 00000000..b1cf5251 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/GattConnected.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4daa321f84b44e14a8784f7470afefe2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/GattDisconnected.cs b/Assets/Scripts/Devices/Ble/Win/GattDisconnected.cs new file mode 100644 index 00000000..1d54c17a --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/GattDisconnected.cs @@ -0,0 +1,11 @@ +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win +{ + internal delegate void GattDisconnected(WclBleGattThread gatt, BleResponse response); +} diff --git a/Assets/Scripts/Devices/Ble/Win/GattDisconnected.cs.meta b/Assets/Scripts/Devices/Ble/Win/GattDisconnected.cs.meta new file mode 100644 index 00000000..a3b6e54c --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/GattDisconnected.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d6d9e75965935a47a46eb30e0faf550 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/GattServicesDiscovered.cs b/Assets/Scripts/Devices/Ble/Win/GattServicesDiscovered.cs new file mode 100644 index 00000000..c39ed4dd --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/GattServicesDiscovered.cs @@ -0,0 +1,11 @@ +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win +{ + internal delegate void GattServicesDiscovered(WclBleGattThread gatt, BleResponse> response); +} diff --git a/Assets/Scripts/Devices/Ble/Win/GattServicesDiscovered.cs.meta b/Assets/Scripts/Devices/Ble/Win/GattServicesDiscovered.cs.meta new file mode 100644 index 00000000..3aab0a45 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/GattServicesDiscovered.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d817b05c3d2f464b97cefe9f618803a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/ServiceUuid.cs b/Assets/Scripts/Devices/Ble/Win/ServiceUuid.cs new file mode 100644 index 00000000..9d29cbf4 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/ServiceUuid.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + public class ServiceUuid + { + public Guid IdGuid { get; } + + public byte[] IdByteArray { get; } + + public bool IsCycling { get; } + + public ServiceUuid(Guid idGuid, byte[] idByteArray, bool isCycling) + { + // ISSUE: reference to a compiler-generated field + this.IdByteArray = idByteArray; + // ISSUE: reference to a compiler-generated field + this.IdGuid = idGuid; + // ISSUE: reference to a compiler-generated field + this.IsCycling = isCycling; + } + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/ServiceUuid.cs.meta b/Assets/Scripts/Devices/Ble/Win/ServiceUuid.cs.meta new file mode 100644 index 00000000..2a835ce7 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/ServiceUuid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 219f9436857f49e40a86f16c35aafca5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/ServiceUuids.cs b/Assets/Scripts/Devices/Ble/Win/ServiceUuids.cs new file mode 100644 index 00000000..ac77290a --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/ServiceUuids.cs @@ -0,0 +1,343 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + public static class ServiceUuids + { + public static readonly byte[] GenericAccessService = new byte[2] + { + (byte) 24, + (byte) 0 + }; + public static readonly byte[] DeviceInformation = new byte[2] + { + (byte) 24, + (byte) 10 + }; + public static readonly byte[] Battery = new byte[2] + { + (byte) 24, + (byte) 15 + }; + public static readonly byte[] CyclingPower = new byte[2] + { + (byte) 24, + (byte) 24 + }; + public static readonly byte[] CyclingSpeedCadence = new byte[2] + { + (byte) 24, + (byte) 22 + }; + public static readonly byte[] HeartRate = new byte[2] + { + (byte) 24, + (byte) 13 + }; + public static readonly byte[] Ftms = new byte[2] + { + (byte) 24, + (byte) 38 + }; + public static readonly byte[] KineticInRide = new byte[16] + { + (byte) 233, + (byte) 65, + (byte) 1, + (byte) 0, + (byte) 180, + (byte) 52, + (byte) 68, + (byte) 107, + (byte) 181, + (byte) 204, + (byte) 54, + (byte) 89, + (byte) 47, + (byte) 196, + (byte) 199, + (byte) 36 + }; + public static readonly byte[] KineticSmartControl = new byte[16] + { + (byte) 233, + (byte) 65, + (byte) 2, + (byte) 0, + (byte) 180, + (byte) 52, + (byte) 68, + (byte) 107, + (byte) 181, + (byte) 204, + (byte) 54, + (byte) 89, + (byte) 47, + (byte) 196, + (byte) 199, + (byte) 36 + }; + public static readonly byte[] TacxBle = new byte[16] + { + (byte) 110, + (byte) 64, + (byte) 254, + (byte) 193, + (byte) 181, + (byte) 163, + (byte) 243, + (byte) 147, + (byte) 224, + (byte) 169, + (byte) 229, + (byte) 14, + (byte) 36, + (byte) 220, + (byte) 202, + (byte) 158 + }; + public static readonly byte[] Elite = new byte[16] + { + (byte) 52, + (byte) 123, + (byte) 0, + (byte) 1, + (byte) 118, + (byte) 53, + (byte) 64, + (byte) 139, + (byte) 137, + (byte) 24, + (byte) 143, + (byte) 243, + (byte) 148, + (byte) 156, + (byte) 229, + (byte) 146 + }; + public static readonly byte[] PowerBeam = new byte[16] + { + (byte) 192, + (byte) 244, + (byte) 1, + (byte) 58, + (byte) 168, + (byte) 55, + (byte) 65, + (byte) 101, + (byte) 186, + (byte) 185, + (byte) 101, + (byte) 78, + (byte) 247, + (byte) 7, + (byte) 71, + (byte) 198 + }; + public static readonly byte[][] CyclingRelatedServices = new byte[9][] + { + ServiceUuids.CyclingPower, + ServiceUuids.CyclingSpeedCadence, + ServiceUuids.HeartRate, + ServiceUuids.KineticInRide, + ServiceUuids.KineticSmartControl, + ServiceUuids.TacxBle, + ServiceUuids.Elite, + ServiceUuids.PowerBeam, + ServiceUuids.Ftms, + }; + public static readonly IReadOnlyList Services = (IReadOnlyList)new List() + { + new ServiceUuid(new Guid("0000180A-0000-1000-8000-00805F9B34FB"), ServiceUuids.DeviceInformation, false), + new ServiceUuid(new Guid("0000180F-0000-1000-8000-00805F9B34FB"), ServiceUuids.Battery, false), + new ServiceUuid(new Guid("00001818-0000-1000-8000-00805F9B34FB"), ServiceUuids.CyclingPower, true), + new ServiceUuid(new Guid("00001816-0000-1000-8000-00805F9B34FB"), ServiceUuids.CyclingSpeedCadence, true), + new ServiceUuid(new Guid("0000180D-0000-1000-8000-00805F9B34FB"), ServiceUuids.HeartRate, true), + new ServiceUuid(new Guid("00001826-0000-1000-8000-00805F9B34FB"), ServiceUuids.Ftms, true), + new ServiceUuid(new Guid("000141e9-34b4-6b44-b5cc-36592fc4c724"), ServiceUuids.KineticInRide, true), + new ServiceUuid(new Guid("000241e9-34b4-6b44-b5cc-36592fc4c724"), ServiceUuids.KineticSmartControl, true), + new ServiceUuid(new Guid("6e40fec1-b5a3-f393-e0a9-e50e24dcca9e"), ServiceUuids.TacxBle, true), + new ServiceUuid(new Guid("01007b34-3576-8b40-8918-8ff3949ce592"), ServiceUuids.Elite, true), + new ServiceUuid(new Guid("3a01f4c0-37a8-6541-bab9-654ef70747c6"), ServiceUuids.PowerBeam, true), + }; + public static readonly IReadOnlyList CyclingServices = ServiceUuids.Services.Where(s => s.IsCycling).ToList(); + + public static ServiceUuid Get(byte[] type) + { + return ServiceUuids.Services.Single(s => s.IdByteArray == type); + } + + + public static class Characteristics + { + /// + /// Heart Rate Measurement + /// + public static Guid HrMeasurement = new Guid("00002A37-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028D4 RID: 10452 + public static Guid BodySensorLocation = new Guid("00002A38-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028D5 RID: 10453 + public static Guid CscMeasurement = new Guid("00002A5B-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028D6 RID: 10454 + public static Guid CscFeature = new Guid("00002A5C-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028D7 RID: 10455 + public static Guid SensorLocation = new Guid("00002A5D-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028D8 RID: 10456 + public static Guid ScControlPoint = new Guid("00002A55-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028D9 RID: 10457 + public static Guid CyclingPowerMeasurement = new Guid("00002A63-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028DA RID: 10458 + public static Guid CyclingPowerVector = new Guid("00002A64-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028DB RID: 10459 + public static Guid CyclingPowerFeature = new Guid("00002A65-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028DC RID: 10460 + public static Guid CyclingPowerControlPoint = new Guid("00002A66-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028DD RID: 10461 + public static Guid FitnessMachineFeature = new Guid("00002ACC-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028DE RID: 10462 + public static Guid FitnessMachineControlPoint = new Guid("00002AD9-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028DF RID: 10463 + public static Guid IndoorBikeData = new Guid("00002AD2-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E0 RID: 10464 + public static Guid FitnessMachineStatus = new Guid("00002ADA-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E1 RID: 10465 + public static Guid FirmwareRevision = new Guid("00002A26-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E2 RID: 10466 + public static Guid HardwareRevision = new Guid("00002A27-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E3 RID: 10467 + public static Guid SoftwareRevision = new Guid("00002A28-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E4 RID: 10468 + public static Guid ManufactureNameString = new Guid("00002A29-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E5 RID: 10469 + public static Guid ModelNumber = new Guid("00002A24-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E6 RID: 10470 + public static Guid SerialNumber = new Guid("00002A25-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E7 RID: 10471 + public static Guid PnPId = new Guid("00002A50-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E8 RID: 10472 + public static Guid BatteryLevel = new Guid("00002A19-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028E9 RID: 10473 + public static Guid RscMeasurement = new Guid("00002A53-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028EA RID: 10474 + public static Guid RscFeature = new Guid("00002A54-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028EB RID: 10475 + public static Guid CycleOpsControlPoint = new Guid("CA31A533-A858-4DC7-A650-FDEB6DAD4C14"); + + // Token: 0x040028EC RID: 10476 + public static Guid CycleOpsFtmsSystemWeight = new Guid("0D18A170-5498-11E9-8647-D663BD873D93"); + + // Token: 0x040028ED RID: 10477 + public static Guid EliteBreak = new Guid("347B0010-7635-408B-8918-8FF3949CE592"); + + // Token: 0x040028EE RID: 10478 + public static Guid EliteOutOfRange = new Guid("347B0011-7635-408B-8918-8FF3949CE592"); + + // Token: 0x040028EF RID: 10479 + public static Guid EliteSystemWeight = new Guid("347B0018-7635-408B-8918-8FF3949CE592"); + + // Token: 0x040028F0 RID: 10480 + public static Guid EliteTrainerCapabilities = new Guid("347B0019-7635-408B-8918-8FF3949CE592"); + + // Token: 0x040028F1 RID: 10481 + public static Guid StagesRead = new Guid("0C46BEB0-9C22-48FF-AE0E-C6EAE1A2F4E5"); + + // Token: 0x040028F2 RID: 10482 + public static Guid StagesWrite = new Guid("0C46BEB1-9C22-48FF-AE0E-C6EAE1A2F4E5"); + + // Token: 0x040028F3 RID: 10483 + public static Guid TacxFecRead = new Guid("6E40FEC2-B5A3-F393-E0A9-E50E24DCCA9E"); + + // Token: 0x040028F4 RID: 10484 + public static Guid TacxFecWrite = new Guid("6E40FEC3-B5A3-F393-E0A9-E50E24DCCA9E"); + + // Token: 0x040028F5 RID: 10485 + public static Guid TechnoGymStSimulation = new Guid("58094966-498C-470D-8051-37E617A13895"); + + // Token: 0x040028F6 RID: 10486 + public static Guid WahooControlPoint = new Guid("A026E005-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x040028F7 RID: 10487 + public static Guid WattbikeAtomRead = new Guid("B4CC1224-BC02-4CAE-ADB9-1217AD2860D1"); + + // Token: 0x040028F8 RID: 10488 + public static Guid WattbikeAtomWrite = new Guid("B4CC1225-BC02-4CAE-ADB9-1217AD2860D1"); + + // Token: 0x040028F9 RID: 10489 + public static Guid WattbikeAtomXRead = new Guid("BABF1724-CEDB-444C-88C3-C672C7A59806"); + + // Token: 0x040028FA RID: 10490 + public static Guid WattbikeAtomXWrite = new Guid("BABF1725-CEDB-444C-88C3-C672C7A59806"); + + // Token: 0x040028FB RID: 10491 + public static Guid FitnessMachineTrainingStatus = new Guid("00002AD3-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028FC RID: 10492 + public static Guid FitnessMachineSupportedResistanceLevelRange = new Guid("00002AD6-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028FD RID: 10493 + public static Guid FitnessMachineSupportedPowerRange = new Guid("00002AD8-0000-1000-8000-00805F9B34FB"); + + // Token: 0x040028FE RID: 10494 + public static Guid GemFwUpdate = new Guid("A026E002-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x040028FF RID: 10495 + public static Guid GemFwUpdate4 = new Guid("A026E004-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x04002900 RID: 10496 + public static Guid WahooA = new Guid("A026E00A-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x04002901 RID: 10497 + public static Guid Wahoo23 = new Guid("A026E023-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x04002902 RID: 10498 + public static Guid Wahoo37 = new Guid("A026E037-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x04002903 RID: 10499 + public static Guid WahooFitnessType = new Guid("A026E01F-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x04002904 RID: 10500 + public static Guid WahooFitnessState = new Guid("A026E01E-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x04002905 RID: 10501 + public static Guid WahooFitnessStateName = new Guid("A026E020-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x04002906 RID: 10502 + public static Guid WahooFitnessMeasurement = new Guid("A026E01D-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x04002907 RID: 10503 + public static Guid WahooFitnessWorkoutProgramName = new Guid("A026E01B-0A7D-4AB3-97FA-F1500F9FEB8B"); + + // Token: 0x04002908 RID: 10504 + public static Guid WahooFitnessSensorMeasurementInput = new Guid("A026E016-0A7D-4AB3-97FA-F1500F9FEB8B"); + } + + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/ServiceUuids.cs.meta b/Assets/Scripts/Devices/Ble/Win/ServiceUuids.cs.meta new file mode 100644 index 00000000..f3ac9e89 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/ServiceUuids.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c595e469b7e8ef744bf1d32496bbb15d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleErrors.cs b/Assets/Scripts/Devices/Ble/Win/WclBleErrors.cs new file mode 100644 index 00000000..922e91fb --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleErrors.cs @@ -0,0 +1,1151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble.Win +{ + public static class WclBleErrors + { + // Token: 0x06002081 RID: 8321 RVA: 0x00087496 File Offset: 0x00085696 + public static bool IsSuccessCode(int code) + { + return code == 0; + } + + // Token: 0x0400118F RID: 4495 + public const int WCL_E_SUCCESS = 0; + + // Token: 0x04001190 RID: 4496 + public const int WCL_E_BASE = 65536; + + // Token: 0x04001191 RID: 4497 + public const int WCL_E_INVALID_ARGUMENT = 65536; + + // Token: 0x04001192 RID: 4498 + public const int WCL_E_OUT_OF_MEMORY = 65537; + + // Token: 0x04001193 RID: 4499 + public const int WCL_E_THREAD_RUNNING = 65538; + + // Token: 0x04001194 RID: 4500 + public const int WCL_E_UNABLE_CREATE_THREAD_INIT_EVENT = 65539; + + // Token: 0x04001195 RID: 4501 + public const int WCL_E_UNABLE_CREATE_THREAD = 65540; + + // Token: 0x04001196 RID: 4502 + public const int WCL_E_THREAD_NOT_RUNNING = 65541; + + // Token: 0x04001197 RID: 4503 + public const int WCL_E_THREAD_SIGNAL_FAILED = 65542; + + // Token: 0x04001198 RID: 4504 + public const int WCL_E_THREAD_MESSAGE_REGISTRATION_FAILED = 65543; + + // Token: 0x04001199 RID: 4505 + public const int WCL_E_THREAD_WINDOW_CREATION_FAILED = 65544; + + // Token: 0x0400119A RID: 4506 + public const int WCL_E_THREAD_INITIALIZATION_FAILED = 65545; + + // Token: 0x0400119B RID: 4507 + public const int WCL_E_MR_BASE = 69632; + + // Token: 0x0400119C RID: 4508 + public const int WCL_E_MR_CLOSED = 69632; + + // Token: 0x0400119D RID: 4509 + public const int WCL_E_MR_OPENED = 69633; + + // Token: 0x0400119E RID: 4510 + public const int WCL_E_MR_NOT_OPENED = 69634; + + // Token: 0x0400119F RID: 4511 + public const int WCL_E_MR_UNABLE_SYNCHRONIZE = 69635; + + // Token: 0x040011A0 RID: 4512 + public const int WCL_E_MR_UNABLE_REGISTER_SYNC_OBJ = 69636; + + // Token: 0x040011A1 RID: 4513 + public const int WCL_E_MR_UNABLE_CREATE_SYNC_OBJ = 69637; + + // Token: 0x040011A2 RID: 4514 + public const int WCL_E_MR_SYNC_OBJ_NOT_CREATED = 69638; + + // Token: 0x040011A3 RID: 4515 + public const int WCL_E_MB_BASE = 73728; + + // Token: 0x040011A4 RID: 4516 + public const int WCL_E_MB_RECEIVER_ALREADY_SUBSCRIBED = 73728; + + // Token: 0x040011A5 RID: 4517 + public const int WCL_E_MB_RECEIVER_NOT_SUBSCRIBED = 73729; + + // Token: 0x040011A6 RID: 4518 + public const int WCL_E_MB_CAN_NOT_INIT_HW_THREAD = 73730; + + // Token: 0x040011A7 RID: 4519 + public const int WCL_E_MB_CAN_NOT_START_HW_THREAD = 73731; + + // Token: 0x040011A8 RID: 4520 + public const int WCL_E_MB_UNABLE_CREATE_HW_OBJ = 73732; + + // Token: 0x040011A9 RID: 4521 + public const int WCL_E_MB_UNABLE_REGISTER_HW_NOTIFY = 73733; + + // Token: 0x040011AA RID: 4522 + public const int WCL_E_MB_UNABLE_CREATE_MUTEX = 73734; + + // Token: 0x040011AB RID: 4523 + public const int WCL_E_MB_NOT_CREATED = 73735; + + // Token: 0x040011AC RID: 4524 + public const int WCL_E_MB_REF_COUNT_ERROR = 73736; + + // Token: 0x040011AD RID: 4525 + public const int WCL_E_MB_RUNNING = 73737; + + // Token: 0x040011AE RID: 4526 + public const int WCL_E_WINRT_BASE = 77824; + + // Token: 0x040011AF RID: 4527 + public const int WCL_E_WINRT_UNABLE_CREATE_MUTEX = 77824; + + // Token: 0x040011B0 RID: 4528 + public const int WCL_E_WINRT_UNABLE_LOAD_CORE_DLL = 77825; + + // Token: 0x040011B1 RID: 4529 + public const int WCL_E_WINRT_UNABLE_LOAD_STRING_DLL = 77826; + + // Token: 0x040011B2 RID: 4530 + public const int WCL_E_WINRT_INIT_FAILED = 77827; + + // Token: 0x040011B3 RID: 4531 + public const int WCL_E_WINRT_UNABLE_CREATE_STRING = 77828; + + // Token: 0x040011B4 RID: 4532 + public const int WCL_E_WINRT_UNABLE_ACTIVATE_INSTANCE = 77829; + + // Token: 0x040011B5 RID: 4533 + public const int WCL_E_WINRT_UNABLE_CREATE_INTERFACE = 77830; + + // Token: 0x040011B6 RID: 4534 + public const int WCL_E_WINRT_ASYNC_OPERATION_FAILED = 77831; + + // Token: 0x040011B7 RID: 4535 + public const int WCL_E_WINRT_ASYNC_OPERATION_CANCELLED = 77832; + + // Token: 0x040011B8 RID: 4536 + public const int WCL_E_WINRT_ASYNC_OPERATION_ERROR = 77833; + + // Token: 0x040011B9 RID: 4537 + public const int WCL_E_WINRT_DETACH_BUFFER_FAILED = 77834; + + // Token: 0x040011BA RID: 4538 + public const int WCL_E_CONNECTION_BASE = 196608; + + // Token: 0x040011BB RID: 4539 + public const int WCL_E_CONNECTION_ACTIVE = 196608; + + // Token: 0x040011BC RID: 4540 + public const int WCL_E_CONNECTION_NOT_ACTIVE = 196609; + + // Token: 0x040011BD RID: 4541 + public const int WCL_E_CONNECTION_UNABLE_CREATE_TERMINATE_EVENT = 196610; + + // Token: 0x040011BE RID: 4542 + public const int WCL_E_CONNECTION_UNABLE_CREATE_CONNECTION_COMPLETE_EVENT = 196611; + + // Token: 0x040011BF RID: 4543 + public const int WCL_E_CONNECTION_UNABLE_START_COMMUNICATION = 196612; + + // Token: 0x040011C0 RID: 4544 + public const int WCL_E_CONNECTION_TERMINATED = 196613; + + // Token: 0x040011C1 RID: 4545 + public const int WCL_E_CONNECTION_TERMINATED_BY_USER = 196614; + + // Token: 0x040011C2 RID: 4546 + public const int WCL_E_CONNECTION_UNABLE_CREATE_INIT_EVENT = 196615; + + // Token: 0x040011C3 RID: 4547 + public const int WCL_E_CONNECTION_CLOSED = 196616; + + // Token: 0x040011C4 RID: 4548 + public const int WCL_E_CONNECTION_UNEXPECTED = 196617; + + // Token: 0x040011C5 RID: 4549 + public const int WCL_E_CONNECTION_UNABLE_CREATE_OR_INIT_CLIENT = 196618; + + // Token: 0x040011C6 RID: 4550 + public const int WCL_E_CONNECTION_UNABLE_FIND_CLIENT_CLASS = 196619; + + // Token: 0x040011C7 RID: 4551 + public const int WCL_E_OBEX_BASE = 200704; + + // Token: 0x040011C8 RID: 4552 + public const int WCL_E_OBEX_NOT_CONNECTED = 200704; + + // Token: 0x040011C9 RID: 4553 + public const int WCL_E_OBEX_CONNECTED = 200705; + + // Token: 0x040011CA RID: 4554 + public const int WCL_E_OBEX_OPERATION_IN_PROGRESS = 200706; + + // Token: 0x040011CB RID: 4555 + public const int WCL_E_OBEX_CONTINUE = 200707; + + // Token: 0x040011CC RID: 4556 + public const int WCL_E_OBEX_CREATED = 200708; + + // Token: 0x040011CD RID: 4557 + public const int WCL_E_OBEX_ACCEPTED = 200709; + + // Token: 0x040011CE RID: 4558 + public const int WCL_E_OBEX_NON_AUTHORITATIVE = 200710; + + // Token: 0x040011CF RID: 4559 + public const int WCL_E_OBEX_NO_CONTENT = 200711; + + // Token: 0x040011D0 RID: 4560 + public const int WCL_E_OBEX_RESET_CONTENT = 200712; + + // Token: 0x040011D1 RID: 4561 + public const int WCL_E_OBEX_PARTIAL_CONTENT = 200713; + + // Token: 0x040011D2 RID: 4562 + public const int WCL_E_OBEX_MULTIPLE_CHOICES = 200714; + + // Token: 0x040011D3 RID: 4563 + public const int WCL_E_OBEX_MOVED_PERMANENTLY = 200715; + + // Token: 0x040011D4 RID: 4564 + public const int WCL_E_OBEX_MOVED_TEMPORARY = 200716; + + // Token: 0x040011D5 RID: 4565 + public const int WCL_E_OBEX_SEE_OTHER = 200717; + + // Token: 0x040011D6 RID: 4566 + public const int WCL_E_OBEX_NOT_MODIFIED = 200718; + + // Token: 0x040011D7 RID: 4567 + public const int WCL_E_OBEX_USE_PROXY = 200719; + + // Token: 0x040011D8 RID: 4568 + public const int WCL_E_OBEX_BAD_REQUEST = 200720; + + // Token: 0x040011D9 RID: 4569 + public const int WCL_E_OBEX_UNAUTHORIZED = 200721; + + // Token: 0x040011DA RID: 4570 + public const int WCL_E_OBEX_PAYMENT_REQUIRED = 200722; + + // Token: 0x040011DB RID: 4571 + public const int WCL_E_OBEX_FORBIDDEN = 200723; + + // Token: 0x040011DC RID: 4572 + public const int WCL_E_OBEX_NOT_FOUND = 200724; + + // Token: 0x040011DD RID: 4573 + public const int WCL_E_OBEX_METHOD_NOT_ALLOWED = 200725; + + // Token: 0x040011DE RID: 4574 + public const int WCL_E_OBEX_NOT_ACCEPTABLE = 200726; + + // Token: 0x040011DF RID: 4575 + public const int WCL_E_OBEX_PROXY_AUTH_REQUIRED = 200727; + + // Token: 0x040011E0 RID: 4576 + public const int WCL_E_OBEX_REQUEST_TIMEOUT = 200728; + + // Token: 0x040011E1 RID: 4577 + public const int WCL_E_OBEX_CONFLICT = 200729; + + // Token: 0x040011E2 RID: 4578 + public const int WCL_E_OBEX_GONE = 200730; + + // Token: 0x040011E3 RID: 4579 + public const int WCL_E_OBEX_LENGTH_REQUIRED = 200731; + + // Token: 0x040011E4 RID: 4580 + public const int WCL_E_OBEX_PRECONDITION_FAILED = 200732; + + // Token: 0x040011E5 RID: 4581 + public const int WCL_E_OBEX_REQUEST_TOO_LARGE = 200733; + + // Token: 0x040011E6 RID: 4582 + public const int WCL_E_OBEX_URL_TOO_LARGE = 200734; + + // Token: 0x040011E7 RID: 4583 + public const int WCL_E_OBEX_UNSUPPORTED_MEDIA_TYPE = 200735; + + // Token: 0x040011E8 RID: 4584 + public const int WCL_E_OBEX_INTERNAL = 200736; + + // Token: 0x040011E9 RID: 4585 + public const int WCL_E_OBEX_NOT_IMPLEMENTED = 200737; + + // Token: 0x040011EA RID: 4586 + public const int WCL_E_OBEX_BAD_GATEWAY = 200738; + + // Token: 0x040011EB RID: 4587 + public const int WCL_E_OBEX_SERVICE_UNAVAILABLE = 200739; + + // Token: 0x040011EC RID: 4588 + public const int WCL_E_OBEX_GATEWAY_TIMEOUT = 200740; + + // Token: 0x040011ED RID: 4589 + public const int WCL_E_OBEX_HTTP_VERSION_NOT_SUPPORTED = 200741; + + // Token: 0x040011EE RID: 4590 + public const int WCL_E_OBEX_DATABASE_FULL = 200742; + + // Token: 0x040011EF RID: 4591 + public const int WCL_E_OBEX_DATABASE_LOCKED = 200743; + + // Token: 0x040011F0 RID: 4592 + public const int WCL_E_OBEX_OPERATION_TERMINATED_BY_DISCONNECT = 200744; + + // Token: 0x040011F1 RID: 4593 + public const int WCL_E_OBEX_OPERATION_TERMINATED_BY_USER = 200745; + + // Token: 0x040011F2 RID: 4594 + public const int WCL_E_OBEX_INVALID_OPERATION_SEQUENCE = 200746; + + // Token: 0x040011F3 RID: 4595 + public const int WCL_E_OBEX_DISCONNECTED = 200747; + + // Token: 0x040011F4 RID: 4596 + public const int WCL_E_OBEX_UNEXPECTED = 200748; + + // Token: 0x040011F5 RID: 4597 + public const int WCL_E_OBEX_CREATE_CONNECTION_ID_MUTEX_FAILED = 200749; + + // Token: 0x040011F6 RID: 4598 + public const int WCL_E_OBEX_MAX_CONNECTION_ID = 200750; + + // Token: 0x040011F7 RID: 4599 + public const int WCL_E_OBEX_INVALID_STATE = 200751; + + // Token: 0x040011F8 RID: 4600 + public const int WCL_E_BLUETOOTH_BASE = 327680; + + // Token: 0x040011F9 RID: 4601 + public const int WCL_E_BLUETOOTH_MANAGER_CLOSED = 327680; + + // Token: 0x040011FA RID: 4602 + public const int WCL_E_BLUETOOTH_MANAGER_OPENED = 327681; + + // Token: 0x040011FB RID: 4603 + public const int WCL_E_BLUETOOTH_MANAGER_OPEN_FAILED = 327682; + + // Token: 0x040011FC RID: 4604 + public const int WCL_E_BLUETOOTH_MANAGER_EXISTS = 327683; + + // Token: 0x040011FD RID: 4605 + public const int WCL_E_BLUETOOTH_DRIVER_NOT_AVAILABLE = 327684; + + // Token: 0x040011FE RID: 4606 + public const int WCL_E_BLUETOOTH_HARDWARE_NOT_AVAILABLE = 327685; + + // Token: 0x040011FF RID: 4607 + public const int WCL_E_BLUETOOTH_API_NOT_LOADED = 327686; + + // Token: 0x04001200 RID: 4608 + public const int WCL_E_BLUETOOTH_API_INITIALIZATION_FAILED = 327687; + + // Token: 0x04001201 RID: 4609 + public const int WCL_E_BLUETOOTH_API_NOT_FOUND = 327688; + + // Token: 0x04001202 RID: 4610 + public const int WCL_E_BLUETOOTH_API_NOT_INITIALIZED = 327689; + + // Token: 0x04001203 RID: 4611 + public const int WCL_E_BLUETOOTH_WRONG_DRIVER_VERSION = 327690; + + // Token: 0x04001204 RID: 4612 + public const int WCL_E_BLUETOOTH_RADIO_OPENED = 327691; + + // Token: 0x04001205 RID: 4613 + public const int WCL_E_BLUETOOTH_RADIO_CLOSED = 327692; + + // Token: 0x04001206 RID: 4614 + public const int WCL_E_BLUETOOTH_RADIO_REMOVED = 327693; + + // Token: 0x04001207 RID: 4615 + public const int WCL_E_BLUETOOTH_RADIO_INSTANCE_INIT_FAILED = 327694; + + // Token: 0x04001208 RID: 4616 + public const int WCL_E_BLUETOOTH_RADIO_INSTANCE_EXISTS = 327695; + + // Token: 0x04001209 RID: 4617 + public const int WCL_E_BLUETOOTH_RADIO_UNAVAILABLE = 327696; + + // Token: 0x0400120A RID: 4618 + public const int WCL_E_BLUETOOTH_UNABLE_CHANGE_CONNECTABLE_STATE = 327697; + + // Token: 0x0400120B RID: 4619 + public const int WCL_E_BLUETOOTH_UNABLE_CHANGE_DISCOVERABLE_STATE = 327698; + + // Token: 0x0400120C RID: 4620 + public const int WCL_E_BLUETOOTH_UNABLE_CHANGE_NAME = 327699; + + // Token: 0x0400120D RID: 4621 + public const int WCL_E_BLUETOOTH_FEATURE_NOT_SUPPORTED = 327700; + + // Token: 0x0400120E RID: 4622 + public const int WCL_E_BLUETOOTH_UNEXPECTED = 327701; + + // Token: 0x0400120F RID: 4623 + public const int WCL_E_BLUETOOTH_LINK_UNEXPECTED = 327702; + + // Token: 0x04001210 RID: 4624 + public const int WCL_E_BLUETOOTH_OPERATION_FAILED = 327703; + + // Token: 0x04001211 RID: 4625 + public const int WCL_E_BLUETOOTH_OPERATION_CONFLICT = 327704; + + // Token: 0x04001212 RID: 4626 + public const int WCL_E_BLUETOOTH_NO_MORE_CONNECTION_ALLOWED = 327705; + + // Token: 0x04001213 RID: 4627 + public const int WCL_E_BLUETOOTH_OBJECT_EXISTS = 327706; + + // Token: 0x04001214 RID: 4628 + public const int WCL_E_BLUETOOTH_OBJECT_IN_USE = 327707; + + // Token: 0x04001215 RID: 4629 + public const int WCL_E_BLUETOOTH_DISCOVERING_RUNNING = 327708; + + // Token: 0x04001216 RID: 4630 + public const int WCL_E_BLUETOOTH_DISCOVERING_NOT_RUNNING = 327709; + + // Token: 0x04001217 RID: 4631 + public const int WCL_E_BLUETOOTH_DISCOVERING_TERMINATED = 327710; + + // Token: 0x04001218 RID: 4632 + public const int WCL_E_BLUETOOTH_CANCELLED_BY_USER = 327711; + + // Token: 0x04001219 RID: 4633 + public const int WCL_E_BLUETOOTH_TIMEOUT = 327712; + + // Token: 0x0400121A RID: 4634 + public const int WCL_E_BLUETOOTH_CONNECTION_TERMINATED_BY_USER = 327713; + + // Token: 0x0400121B RID: 4635 + public const int WCL_E_BLUETOOTH_PENDING = 327714; + + // Token: 0x0400121C RID: 4636 + public const int WCL_E_BLUETOOTH_CONNECTION_FAILED = 327715; + + // Token: 0x0400121D RID: 4637 + public const int WCL_E_BLUETOOTH_DEVICE_NOT_FOUND = 327716; + + // Token: 0x0400121E RID: 4638 + public const int WCL_E_BLUETOOTH_PAIRING = 327717; + + // Token: 0x0400121F RID: 4639 + public const int WCL_E_BLUETOOTH_UNABLE_START_PAIRING = 327718; + + // Token: 0x04001220 RID: 4640 + public const int WCL_E_BLUETOOTH_ALREADY_PAIRED = 327719; + + // Token: 0x04001221 RID: 4641 + public const int WCL_E_BLUETOOTH_DEVICE_NOT_PAIRED = 327720; + + // Token: 0x04001222 RID: 4642 + public const int WCL_E_BLUETOOTH_ACCESS_DENIED = 327721; + + // Token: 0x04001223 RID: 4643 + public const int WCL_E_BLUETOOTH_AUTHENTICATION_FAILED = 327722; + + // Token: 0x04001224 RID: 4644 + public const int WCL_E_BLUETOOTH_REJECTED = 327723; + + // Token: 0x04001225 RID: 4645 + public const int WCL_E_BLUETOOTH_UNABLE_GET_READ_BUFFER = 327724; + + // Token: 0x04001226 RID: 4646 + public const int WCL_E_BLUETOOTH_UNABLE_GET_WRITE_BUFFER = 327725; + + // Token: 0x04001227 RID: 4647 + public const int WCL_E_BLUETOOTH_UNABLE_SET_READ_BUFFER = 327726; + + // Token: 0x04001228 RID: 4648 + public const int WCL_E_BLUETOOTH_UNABLE_SET_WRITE_BUFFER = 327727; + + // Token: 0x04001229 RID: 4649 + public const int WCL_E_BLUETOOTH_CLIENT_CONNECTED = 327728; + + // Token: 0x0400122A RID: 4650 + public const int WCL_E_BLUETOOTH_CLIENT_NOT_CONNECTED = 327729; + + // Token: 0x0400122B RID: 4651 + public const int WCL_E_BLUETOOTH_L2CAP_DISCONNECTED = 327730; + + // Token: 0x0400122C RID: 4652 + public const int WCL_E_BLUETOOTH_INVALID_DEVICE_TYPE = 327731; + + // Token: 0x0400122D RID: 4653 + public const int WCL_E_BLUETOOTH_CHANNEL_IN_USE = 327732; + + // Token: 0x0400122E RID: 4654 + public const int WCL_E_BLUETOOTH_SERVICE_NOT_VALID = 327733; + + // Token: 0x0400122F RID: 4655 + public const int WCL_E_BLUETOOTH_SERVICE_NOT_FOUND = 327734; + + // Token: 0x04001230 RID: 4656 + public const int WCL_E_BLUETOOTH_UNABLE_CREATE_SOCKET = 327735; + + // Token: 0x04001231 RID: 4657 + public const int WCL_E_BLUETOOTH_UNABLE_SET_CLIENT_SECURITY = 327736; + + // Token: 0x04001232 RID: 4658 + public const int WCL_E_BLUETOOTH_UNABLE_CREATE_EVENT = 327737; + + // Token: 0x04001233 RID: 4659 + public const int WCL_E_BLUETOOTH_UNABLE_SET_EVENT = 327738; + + // Token: 0x04001234 RID: 4660 + public const int WCL_E_BLUETOOTH_UNABLE_LOCK_CONNECT_MUTEX = 327739; + + // Token: 0x04001235 RID: 4661 + public const int WCL_E_BLUETOOTH_UNABLE_INIT_OVERLAPPED_OPERATION = 327740; + + // Token: 0x04001236 RID: 4662 + public const int WCL_E_BLUETOOTH_UNABLE_CREATE_DISCONNECT_EVENT = 327741; + + // Token: 0x04001237 RID: 4663 + public const int WCL_E_BLUETOOTH_UNABLE_CREATE_CONNECT_EVENT = 327742; + + // Token: 0x04001238 RID: 4664 + public const int WCL_E_BLUETOOTH_UNABLE_LOCK_SDP_MUTEX = 327743; + + // Token: 0x04001239 RID: 4665 + public const int WCL_E_BLUETOOTH_RFCOMM_SESSION_DISCONNECTED = 327744; + + // Token: 0x0400123A RID: 4666 + public const int WCL_E_BLUETOOTH_RFCOMM_DOWN = 327745; + + // Token: 0x0400123B RID: 4667 + public const int WCL_E_BLUETOOTH_RFCOMM_DISCONNECTED = 327746; + + // Token: 0x0400123C RID: 4668 + public const int WCL_E_BLUETOOTH_UNABLE_TO_RESOLVE_ADDRESS = 327747; + + // Token: 0x0400123D RID: 4669 + public const int WCL_E_BLUETOOTH_UNABLE_ADD_ADP_RECORD = 327748; + + // Token: 0x0400123E RID: 4670 + public const int WCL_E_BLUETOOTH_UNABLE_SET_SERVER_SECURITY = 327749; + + // Token: 0x0400123F RID: 4671 + public const int WCL_E_BLUETOOTH_LOCAL_SERVICE_ACTIVE = 327750; + + // Token: 0x04001240 RID: 4672 + public const int WCL_E_BLUETOOTH_UNABLE_CREATE_SERVER = 327751; + + // Token: 0x04001241 RID: 4673 + public const int WCL_E_BLUETOOTH_UNABLE_ENUMERATE_LOCAL_SERVICES = 327752; + + // Token: 0x04001242 RID: 4674 + public const int WCL_E_BLUETOOTH_UNABLE_STOP_LOCAL_SERVER = 327753; + + // Token: 0x04001243 RID: 4675 + public const int WCL_E_BLUETOOTH_UNABLE_TO_UPDATE_LOCAL_SERVER = 327754; + + // Token: 0x04001244 RID: 4676 + public const int WCL_E_BLUETOOTH_SETUP_COM_FAILED = 327755; + + // Token: 0x04001245 RID: 4677 + public const int WCL_E_BLUETOOTH_UNABLE_OPEN_CLIENT_COM = 327756; + + // Token: 0x04001246 RID: 4678 + public const int WCL_E_BLUETOOTH_UNABLE_OPEN_SERVER_COM = 327757; + + // Token: 0x04001247 RID: 4679 + public const int WCL_E_BLUETOOTH_WRITE_FAILED = 327758; + + // Token: 0x04001248 RID: 4680 + public const int WCL_E_BLUETOOTH_READ_FAILED = 327759; + + // Token: 0x04001249 RID: 4681 + public const int WCL_E_BLUETOOTH_UNABLE_CREATE_WND = 327760; + + // Token: 0x0400124A RID: 4682 + public const int WCL_E_BLUETOOTH_UNABLE_REGISTER_MESSAGE = 327761; + + // Token: 0x0400124B RID: 4683 + public const int WCL_E_BLUETOOTH_UNABLE_CREATE_SYNC_EVENT = 327762; + + // Token: 0x0400124C RID: 4684 + public const int WCL_E_BLUETOOTH_SDP_TRANSACTION = 327763; + + // Token: 0x0400124D RID: 4685 + public const int WCL_E_BLUETOOTH_UNABLE_START_SDP_THREAD = 327764; + + // Token: 0x0400124E RID: 4686 + public const int WCL_E_BLUETOOTH_UNABLE_START_CONNECT_THREAD = 327765; + + // Token: 0x0400124F RID: 4687 + public const int WCL_E_BLUETOOTH_UNABLE_START_LISTEN_THREAD = 327766; + + // Token: 0x04001250 RID: 4688 + public const int WCL_E_BLUETOOTH_DISCOVERING_FAILED = 327767; + + // Token: 0x04001251 RID: 4689 + public const int WCL_E_BLUETOOTH_READ_REMOTE_NAME_FAILED = 327768; + + // Token: 0x04001252 RID: 4690 + public const int WCL_E_BLUETOOTH_DESTROY_COM_FAILED = 327769; + + // Token: 0x04001253 RID: 4691 + public const int WCL_E_BLUETOOTH_CONNECT_COM_FAILED = 327770; + + // Token: 0x04001254 RID: 4692 + public const int WCL_E_BLUETOOTH_DISCONNECT_COM_FAILED = 327771; + + // Token: 0x04001255 RID: 4693 + public const int WCL_E_BLUETOOTH_UNABLE_TO_SWITCH_ON_OR_OFF = 327772; + + // Token: 0x04001256 RID: 4694 + public const int WCL_E_BLUETOOTH_CANNOT_ASSIGN_PSM = 327773; + + // Token: 0x04001257 RID: 4695 + public const int WCL_E_BLUETOOTH_GETLOCALINFO_FAILED = 327774; + + // Token: 0x04001258 RID: 4696 + public const int WCL_E_BLUETOOTH_DISCONNECT_SDP_FAILED = 327775; + + // Token: 0x04001259 RID: 4697 + public const int WCL_E_BLUETOOTH_UNABLE_REGISTER_COM_NOTIFICATION = 327776; + + // Token: 0x0400125A RID: 4698 + public const int WCL_E_BLUETOOTH_SETLOCALINFO_FAILED = 327777; + + // Token: 0x0400125B RID: 4699 + public const int WCL_E_BLUETOOTH_UNABLE_TO_GET_CONNECTED_DEVICES = 327778; + + // Token: 0x0400125C RID: 4700 + public const int WCL_E_BLUETOOTH_UNABLE_CONNECT = 327779; + + // Token: 0x0400125D RID: 4701 + public const int WCL_E_BLUETOOTH_CONNECT_PSM = 327780; + + // Token: 0x0400125E RID: 4702 + public const int WCL_E_BLUETOOTH_SDP_PARSE_ERROR = 327781; + + // Token: 0x0400125F RID: 4703 + public const int WCL_E_BLUETOOTH_UNABLE_READ_RSSI = 327782; + + // Token: 0x04001260 RID: 4704 + public const int WCL_E_BLUETOOTH_UNABLE_CHANGE_PAIRING_MODE = 327783; + + // Token: 0x04001261 RID: 4705 + public const int WCL_E_BLUETOOTH_SDP_ERROR = 327784; + + // Token: 0x04001262 RID: 4706 + public const int WCL_E_BLUETOOTH_UNABLE_START_THREAD = 327785; + + // Token: 0x04001263 RID: 4707 + public const int WCL_E_BLUETOOTH_UNABLE_CREATE_INIT_EVENT = 327786; + + // Token: 0x04001264 RID: 4708 + public const int WCL_E_BLUETOOTH_UNABLE_START_INIT_THREAD = 327787; + + // Token: 0x04001265 RID: 4709 + public const int WCL_E_BLUETOOTH_VCOM_NOT_FOUND = 327788; + + // Token: 0x04001266 RID: 4710 + public const int WCL_E_BLUETOOTH_VCOM_EXISTS = 327789; + + // Token: 0x04001267 RID: 4711 + public const int WCL_E_BLUETOOTH_CREATE_DEVICE_STATICS_FAILED = 327790; + + // Token: 0x04001268 RID: 4712 + public const int WCL_E_BLUETOOTH_START_ASYNC_OPERATION_FAILED = 327791; + + // Token: 0x04001269 RID: 4713 + public const int WCL_E_BLUETOOTH_SET_ASYNC_OPERATION_EVENT_HANDLER_FAILED = 327792; + + // Token: 0x0400126A RID: 4714 + public const int WCL_E_BLUETOOTH_CREATE_DEVICE_FAILED = 327793; + + // Token: 0x0400126B RID: 4715 + public const int WCL_E_BLUETOOTH_GET_ASYNC_OPERATION_RESULT_FAILED = 327794; + + // Token: 0x0400126C RID: 4716 + public const int WCL_E_BLUETOOTH_GET_DEVICE_ID_FAILED = 327795; + + // Token: 0x0400126D RID: 4717 + public const int WCL_E_BLUETOOTH_GET_DEVICE_PROPERTIES_FAILED = 327796; + + // Token: 0x0400126E RID: 4718 + public const int WCL_E_BLUETOOTH_START_RSSI_THREAD_FAILED = 327797; + + // Token: 0x0400126F RID: 4719 + public const int WCL_E_BLUETOOTH_GET_RSSI_READING_RESULT_FAILED = 327798; + + // Token: 0x04001270 RID: 4720 + public const int WCL_E_BLUETOOTH_INCOMPATIBLE_OS_BITS = 327799; + + // Token: 0x04001271 RID: 4721 + public const int WCL_E_BLUETOOTH_GET_RADIOS_LIST_FAILED = 327800; + + // Token: 0x04001272 RID: 4722 + public const int WCL_E_BLUETOOTH_GET_RADIOS_COUNT_FAILED = 327801; + + // Token: 0x04001273 RID: 4723 + public const int WCL_E_BLUETOOTH_GET_BLUETOOTH_RADIO_FAILED = 327802; + + // Token: 0x04001274 RID: 4724 + public const int WCL_E_BLUETOOTH_UNABLE_CHANGE_RADIO_STATE = 327803; + + // Token: 0x04001275 RID: 4725 + public const int WCL_E_BLUETOOTH_START_GET_DEV_TYPE_THREAD_FAILED = 327804; + + // Token: 0x04001276 RID: 4726 + public const int WCL_E_BLUETOOTH_GET_DEV_TYPE_THREAD_GET_RESULT_FAILED = 327805; + + // Token: 0x04001277 RID: 4727 + public const int WCL_E_BLUETOOTH_START_GET_DEV_NAME_THREAD_FAILED = 327806; + + // Token: 0x04001278 RID: 4728 + public const int WCL_E_BLUETOOTH_GET_DEV_NAME_THREAD_GET_RESULT_FAILED = 327807; + + // Token: 0x04001279 RID: 4729 + public const int WCL_E_BLUETOOTH_NO_SYSTEM_RESOURCES = 327808; + + // Token: 0x0400127A RID: 4730 + public const int WCL_E_BLUETOOTH_CREATE_REG_CHANGE_TERMINATION_EVENT_FAILED = 327809; + + // Token: 0x0400127B RID: 4731 + public const int WCL_E_BLUETOOTH_CREATE_REG_CHANGE_RESULT_EVENT_FAILED = 327810; + + // Token: 0x0400127C RID: 4732 + public const int WCL_E_BLUETOOTH_START_REG_CHANGE_THREAD_FAILED = 327811; + + // Token: 0x0400127D RID: 4733 + public const int WCL_E_BLUETOOTH_REGISTER_AUTHENTICATION_CALLBACK_FAILED = 327812; + + // Token: 0x0400127E RID: 4734 + public const int WCL_E_BLUETOOTH_FAILED_TO_OPEN_AUTH_AGENT_REG_KEY = 327813; + + // Token: 0x0400127F RID: 4735 + public const int WCL_E_BLUETOOTH_CREATE_REG_CHANGES_NOTIFICATION_EVENT_FAILED = 327814; + + // Token: 0x04001280 RID: 4736 + public const int WCL_E_BLUETOOTH_UNABLE_SET_REGISTRY_CHANGES_NOTIFICATIONS = 327815; + + // Token: 0x04001281 RID: 4737 + public const int WCL_E_BLUETOOTH_UNABLE_TO_DISABLE_AUTHENTICATION_AGENT = 327816; + + // Token: 0x04001282 RID: 4738 + public const int WCL_E_BLUETOOTH_PAIRED_BY_OTHER = 327817; + + // Token: 0x04001283 RID: 4739 + public const int WCL_E_BLUETOOTH_DEVICE_ALREADY_INSTALLED = 327818; + + // Token: 0x04001284 RID: 4740 + public const int WCL_E_BLUETOOTH_DEVICE_NOT_INSTALLED = 327819; + + // Token: 0x04001285 RID: 4741 + public const int WCL_E_BLUETOOTH_DEVICE_NOT_CONNECTED = 327820; + + // Token: 0x04001286 RID: 4742 + public const int WCL_E_BLUETOOTH_ENUM_CONNECTION_FAILED = 327821; + + // Token: 0x04001287 RID: 4743 + public const int WCL_E_BLUETOOTH_WAIT_FAILED = 327822; + + // Token: 0x04001288 RID: 4744 + public const int WCL_E_BLUETOOTH_LE_BASE = 331776; + + // Token: 0x04001289 RID: 4745 + public const int WCL_E_BLUETOOTH_LE_INVALID_HANDLE = 331776; + + // Token: 0x0400128A RID: 4746 + public const int WCL_E_BLUETOOTH_LE_READ_NOT_PERMITTED = 331777; + + // Token: 0x0400128B RID: 4747 + public const int WCL_E_BLUETOOTH_LE_WRITE_NOT_PERMITTED = 331778; + + // Token: 0x0400128C RID: 4748 + public const int WCL_E_BLUETOOTH_LE_INVALID_PDU = 331779; + + // Token: 0x0400128D RID: 4749 + public const int WCL_E_BLUETOOTH_LE_INSUFFICIENT_AUTHENTICATION = 331780; + + // Token: 0x0400128E RID: 4750 + public const int WCL_E_BLUETOOTH_LE_REQUEST_NOT_SUPPORTED = 331781; + + // Token: 0x0400128F RID: 4751 + public const int WCL_E_BLUETOOTH_LE_INVALID_OFFSET = 331782; + + // Token: 0x04001290 RID: 4752 + public const int WCL_E_BLUETOOTH_LE_INSUFFICIENT_AUTHORIZATION = 331783; + + // Token: 0x04001291 RID: 4753 + public const int WCL_E_BLUETOOTH_LE_PREPARE_QUEUE_FULL = 331784; + + // Token: 0x04001292 RID: 4754 + public const int WCL_E_BLUETOOTH_LE_ATTRIBUTE_NOT_FOUND = 331785; + + // Token: 0x04001293 RID: 4755 + public const int WCL_E_BLUETOOTH_LE_ATTRIBUTE_NOT_LONG = 331786; + + // Token: 0x04001294 RID: 4756 + public const int WCL_E_BLUETOOTH_LE_INSUFFICIENT_ENCRYPTION_KEYSIZE = 331787; + + // Token: 0x04001295 RID: 4757 + public const int WCL_E_BLUETOOTH_LE_INVALID_ATTRIBUTE_VALUE_LENGTH = 331788; + + // Token: 0x04001296 RID: 4758 + public const int WCL_E_BLUETOOTH_LE_INSUFFICIENT_ENCRYPTION = 331789; + + // Token: 0x04001297 RID: 4759 + public const int WCL_E_BLUETOOTH_LE_UNSUPPORTED_GROUP_TYPE = 331790; + + // Token: 0x04001298 RID: 4760 + public const int WCL_E_BLUETOOTH_LE_INSUFFICIENT_RESOURCES = 331791; + + // Token: 0x04001299 RID: 4761 + public const int WCL_E_BLUETOOTH_LE_SMP_FAILED = 331792; + + // Token: 0x0400129A RID: 4762 + public const int WCL_E_BLUETOOTH_LE_TASK_CANCEL = 331793; + + // Token: 0x0400129B RID: 4763 + public const int WCL_E_BLUETOOTH_LE_CONNECT_FAILED = 331794; + + // Token: 0x0400129C RID: 4764 + public const int WCL_E_BLUETOOTH_LE_TIMEOUT = 331795; + + // Token: 0x0400129D RID: 4765 + public const int WCL_E_BLUETOOTH_LE_WRONG_CONFIGURATION = 331796; + + // Token: 0x0400129E RID: 4766 + public const int WCL_E_BLUETOOTH_LE_PROCEDURE_IN_PROGRESS = 331797; + + // Token: 0x0400129F RID: 4767 + public const int WCL_E_BLUETOOTH_LE_OUT_OF_RANGE = 331798; + + // Token: 0x040012A0 RID: 4768 + public const int WCL_E_BLUETOOTH_LE_RELIABLE_WRITE_ACTIVE = 331799; + + // Token: 0x040012A1 RID: 4769 + public const int WCL_E_BLUETOOTH_LE_RELIABLE_WRITE_NOT_ACTIVE = 331800; + + // Token: 0x040012A2 RID: 4770 + public const int WCL_E_BLUETOOTH_LE_ALREADY_SUBSCRIBED = 331801; + + // Token: 0x040012A3 RID: 4771 + public const int WCL_E_BLUETOOTH_LE_NOT_SUBSCRIBED = 331802; + + // Token: 0x040012A4 RID: 4772 + public const int WCL_E_BLUETOOTH_LE_DEVICES_SCANNING_ENABLED = 331803; + + // Token: 0x040012A5 RID: 4773 + public const int WCL_E_BLUETOOTH_LE_DEVICES_SCANNING_DISABLED = 331804; + + // Token: 0x040012A6 RID: 4774 + public const int WCL_E_BLUETOOTH_LE_INAVLID_USER_BUFFER = 331805; + + // Token: 0x040012A7 RID: 4775 + public const int WCL_E_BLUETOOTH_LE_INCONSISTENT_DATA = 331806; + + // Token: 0x040012A8 RID: 4776 + public const int WCL_E_BLUETOOTH_LE_COMMUNICATION_FAILED = 331807; + + // Token: 0x040012A9 RID: 4777 + public const int WCL_E_BLUETOOTH_LE_CHARACTERISTIC_NOT_READABLE = 331808; + + // Token: 0x040012AA RID: 4778 + public const int WCL_E_BLUETOOTH_LE_CREATE_WATCHER_FAILED = 331809; + + // Token: 0x040012AB RID: 4779 + public const int WCL_E_BLUETOOTH_LE_SET_SCANNING_MODE_FAILED = 331810; + + // Token: 0x040012AC RID: 4780 + public const int WCL_E_BLUETOOTH_LE_START_WATCHER_FAILED = 331811; + + // Token: 0x040012AD RID: 4781 + public const int WCL_E_BLUETOOTH_LE_START_WINRT_THREAD_FAILED = 331812; + + // Token: 0x040012AE RID: 4782 + public const int WCL_E_BLUETOOTH_LE_SET_EVENT_HANDLER_FAILED = 331813; + + // Token: 0x040012AF RID: 4783 + public const int WCL_E_BLUETOOTH_LE_CREATE_DEVICE_STATICS_FAILED = 331814; + + // Token: 0x040012B0 RID: 4784 + public const int WCL_E_BLUETOOTH_LE_CREATE_DEVICE_FAILED = 331815; + + // Token: 0x040012B1 RID: 4785 + public const int WCL_E_BLUETOOTH_LE_START_ASYNC_OPERATION_FAILED = 331816; + + // Token: 0x040012B2 RID: 4786 + public const int WCL_E_BLUETOOTH_LE_SET_ASYNC_OPERATION_EVENT_HANDLER_FAILED = 331817; + + // Token: 0x040012B3 RID: 4787 + public const int WCL_E_BLUETOOTH_LE_GET_ASYNC_OPERATION_RESULT_FAILED = 331818; + + // Token: 0x040012B4 RID: 4788 + public const int WCL_E_BLUETOOTH_LE_CREATE_DEVICE2_FAILED = 331819; + + // Token: 0x040012B5 RID: 4789 + public const int WCL_E_BLUETOOTH_LE_GET_DEVICE_INFORMATION_FAILED = 331820; + + // Token: 0x040012B6 RID: 4790 + public const int WCL_E_BLUETOOTH_LE_GET_DEVICE_INFORMATION2_FAILED = 331821; + + // Token: 0x040012B7 RID: 4791 + public const int WCL_E_BLUETOOTH_LE_GET_DEVICE_INFORMATION_PAIRING_FAILED = 331822; + + // Token: 0x040012B8 RID: 4792 + public const int WCL_E_BLUETOOTH_LE_GET_DEVICE_INFORMATION_PAIRING2_FAILED = 331823; + + // Token: 0x040012B9 RID: 4793 + public const int WCL_E_BLUETOOTH_LE_GET_DEVICE_INFORMATION_CUSTOM_PAIRING_FAILED = 331824; + + // Token: 0x040012BA RID: 4794 + public const int WCL_E_BLUETOOTH_LE_BEACON_MONITORING_RUNNING = 331825; + + // Token: 0x040012BB RID: 4795 + public const int WCL_E_BLUETOOTH_LE_BEACON_MONITORING_NOT_RUNNING = 331826; + + // Token: 0x040012BC RID: 4796 + public const int WCL_E_BLUETOOTH_LE_ADVERTISING_RUNNING = 331827; + + // Token: 0x040012BD RID: 4797 + public const int WCL_E_BLUETOOTH_LE_ADVERTISING_NOT_RUNNING = 331828; + + // Token: 0x040012BE RID: 4798 + public const int WCL_E_BLUETOOTH_LE_ADVERTISING_UNBALE_CREATE_INIT_EVENT = 331829; + + // Token: 0x040012BF RID: 4799 + public const int WCL_E_BLUETOOTH_LE_ADVERTISING_UNBALE_CREATE_TERMINATE_EVENT = 331830; + + // Token: 0x040012C0 RID: 4800 + public const int WCL_E_BLUETOOTH_LE_ADVERTISING_UNBALE_START_THREAD = 331831; + + // Token: 0x040012C1 RID: 4801 + public const int WCL_E_BLUETOOTH_LE_ADVERTISING_START_FAILED = 331832; + + // Token: 0x040012C2 RID: 4802 + public const int WCL_E_BLUETOOTH_LE_UNABLE_GET_ADVERTISER = 331833; + + // Token: 0x040012C3 RID: 4803 + public const int WCL_E_BLUETOOTH_LE_UNABLE_GET_ADVERTISER_MANUFACTURER_DATA = 331834; + + // Token: 0x040012C4 RID: 4804 + public const int WCL_E_BLUETOOTH_LE_UNABLE_SET_ADVERTISING_DATA = 331835; + + // Token: 0x040012C5 RID: 4805 + public const int WCL_E_BLUETOOTH_LE_UNABLE_ADD_ADVERTISING_DATA = 331836; + + // Token: 0x040012C6 RID: 4806 + public const int WCL_E_BLUETOOTH_LE_UNABLE_GET_ADVERTISER_DATA = 331837; + + // Token: 0x040012C7 RID: 4807 + public const int WCL_E_BLUETOOTH_LE_EDDYSTONE_URL_TOO_SHORT = 331838; + + // Token: 0x040012C8 RID: 4808 + public const int WCL_E_BLUETOOTH_LE_EDDYSTONE_URL_SCHEME_INVALID = 331839; + + // Token: 0x040012C9 RID: 4809 + public const int WCL_E_BLUETOOTH_LE_EDDYSTONE_URL_TOO_LONG = 331840; + + // Token: 0x040012CA RID: 4810 + public const int WCL_E_BLUETOOTH_LE_ASYNC_PAIR_FAILED = 331841; + + // Token: 0x040012CB RID: 4811 + public const int WCL_E_BLUETOOTH_LE_ASYNC_PAIR_ERROR = 331842; + + // Token: 0x040012CC RID: 4812 + public const int WCL_E_BLUETOOTH_LE_MANUAL_PAIRING_REQUIRED = 331843; + + // Token: 0x040012CD RID: 4813 + public const int WCL_E_BLUETOOTH_LE_AUTH_NOT_READY_TO_PAIR = 331844; + + // Token: 0x040012CE RID: 4814 + public const int WCL_E_BLUETOOTH_LE_AUTH_NOT_PAIRED = 331845; + + // Token: 0x040012CF RID: 4815 + public const int WCL_E_BLUETOOTH_LE_AUTH_CONNECTION_REJECTED = 331846; + + // Token: 0x040012D0 RID: 4816 + public const int WCL_E_BLUETOOTH_LE_AUTH_TOO_MANY_CONNECTIONS = 331847; + + // Token: 0x040012D1 RID: 4817 + public const int WCL_E_BLUETOOTH_LE_AUTH_HARDWARE_FAILURE = 331848; + + // Token: 0x040012D2 RID: 4818 + public const int WCL_E_BLUETOOTH_LE_AUTH_TIMEOUT = 331849; + + // Token: 0x040012D3 RID: 4819 + public const int WCL_E_BLUETOOTH_LE_AUTH_NOT_ALLOWED = 331850; + + // Token: 0x040012D4 RID: 4820 + public const int WCL_E_BLUETOOTH_LE_AUTH_FAILURE = 331851; + + // Token: 0x040012D5 RID: 4821 + public const int WCL_E_BLUETOOTH_LE_AUTH_NO_SUPPORTED_PROFILE = 331852; + + // Token: 0x040012D6 RID: 4822 + public const int WCL_E_BLUETOOTH_LE_AUTH_PROTECTION_LEVEL_COULD_NOT_BE_MET = 331853; + + // Token: 0x040012D7 RID: 4823 + public const int WCL_E_BLUETOOTH_LE_AUTH_ACCESS_DENIED = 331854; + + // Token: 0x040012D8 RID: 4824 + public const int WCL_E_BLUETOOTH_LE_AUTH_INVALID_CEREMONY_DATA = 331855; + + // Token: 0x040012D9 RID: 4825 + public const int WCL_E_BLUETOOTH_LE_AUTH_PAIRING_CANCELED = 331856; + + // Token: 0x040012DA RID: 4826 + public const int WCL_E_BLUETOOTH_LE_AUTH_OPERATION_ALREADY_IN_POROGRESS = 331857; + + // Token: 0x040012DB RID: 4827 + public const int WCL_E_BLUETOOTH_LE_AUTH_REQUIRED_HANDLER_NOT_REGISTERED = 331858; + + // Token: 0x040012DC RID: 4828 + public const int WCL_E_BLUETOOTH_LE_AUTH_REJECTED_BY_HANDLER = 331859; + + // Token: 0x040012DD RID: 4829 + public const int WCL_E_BLUETOOTH_LE_AUTH_REMOTE_DEVICE_HAS_ASSOCIATION = 331860; + + // Token: 0x040012DE RID: 4830 + public const int WCL_E_BLUETOOTH_LE_AUTH_FAILED = 331861; + + // Token: 0x040012DF RID: 4831 + public const int WCL_E_BLUETOOTH_LE_SET_PROTECTION_LEVEL_FAILED = 331862; + + // Token: 0x040012E0 RID: 4832 + public const int WCL_E_BLUETOOTH_LE_CHARACTERISTIC_NOT_WRITABLE = 331863; + + // Token: 0x040012E1 RID: 4833 + public const int WCL_E_BLUETOOTH_LE_DEVICE_NOT_DISCOVERED = 331864; + + // Token: 0x040012E2 RID: 4834 + public const int WCL_E_BLUETOOTH_LE_ALREADY_PAIRED = 331865; + + // Token: 0x040012E3 RID: 4835 + public const int WCL_E_BLUETOOTH_LE_UNSUPPORTED_BY_HARDWARE = 331866; + + // Token: 0x040012E4 RID: 4836 + public const int WCL_E_BLUETOOTH_LE_UNABLE_START_UNPAIRING = 331867; + + // Token: 0x040012E5 RID: 4837 + public const int WCL_E_BLUETOOTH_LE_DEVICE_NOT_FOUND = 331868; + + // Token: 0x040012E6 RID: 4838 + public const int WCL_E_BLUETOOTH_LE_GET_DEVICE_ID_FAILED = 331869; + + // Token: 0x040012E7 RID: 4839 + public const int WCL_E_BLUETOOTH_LE_GET_DEVICE_PROPERTIES_FAILED = 331870; + + // Token: 0x040012E8 RID: 4840 + public const int WCL_E_BLUETOOTH_LE_FEATURE_NOT_SUPPORTED = 331871; + + // Token: 0x040012E9 RID: 4841 + public const int WCL_E_BLUETOOTH_LE_UNABLE_READ_RSSI = 331872; + + // Token: 0x040012EA RID: 4842 + public const int WCL_E_BLUETOOTH_LE_START_RSSI_THREAD_FAILED = 331873; + + // Token: 0x040012EB RID: 4843 + public const int WCL_E_BLUETOOTH_LE_GET_RSSI_READING_RESULT_FAILED = 331874; + + // Token: 0x040012EC RID: 4844 + public const int WCL_E_BLUETOOTH_LE_ADVERTISING_SET_NAME_FAILED = 331875; + + // Token: 0x040012ED RID: 4845 + public const int WCL_E_BLUETOOTH_LE_GET_OPERATION_RESULT_FAULED = 331876; + + // Token: 0x040012EE RID: 4846 + public const int WCL_E_BLUETOOTH_LE_GET_ROOT_SERVICE_FAILED = 331877; + + // Token: 0x040012EF RID: 4847 + public const int WCL_E_BLUETOOTH_LE_GET_SERVICE_HANDLE_FAILED = 331878; + + // Token: 0x040012F0 RID: 4848 + public const int WCL_E_BLUETOOTH_LE_GET_CHARACTERISTIC_HANDLE_FAILED = 331879; + + // Token: 0x040012F1 RID: 4849 + public const int WCL_E_BLUETOOTH_LE_GET_DESCRIPTOR_HANDLE_FAILED = 331880; + + // Token: 0x040012F2 RID: 4850 + public const int WCL_E_BLUETOOTH_LE_GET_DESCRIPTOR_UUID_FAILED = 331881; + + // Token: 0x040012F3 RID: 4851 + public const int WCL_E_BLUETOOTH_LE_GET_PRESENTATION_FORMATS_FAILED = 331882; + + // Token: 0x040012F4 RID: 4852 + public const int WCL_E_BLUETOOTH_LE_GET_PRESENTATION_FORMATS_LIST_SIZE_FAILED = 331883; + + // Token: 0x040012F5 RID: 4853 + public const int WCL_E_BLUETOOTH_LE_GET_PRESENTATION_FORMAT_FAILED = 331884; + + // Token: 0x040012F6 RID: 4854 + public const int WCL_E_BLUETOOTH_LE_GET_PRESENTATION_FORMAT_TYPE_FAILED = 331885; + + // Token: 0x040012F7 RID: 4855 + public const int WCL_E_BLUETOOTH_LE_GET_PRESENTATION_FORMAT_EXPONENT_FAILED = 331886; + + // Token: 0x040012F8 RID: 4856 + public const int WCL_E_BLUETOOTH_LE_GET_PRESENTATION_FORMAT_UNIT_FAILED = 331887; + + // Token: 0x040012F9 RID: 4857 + public const int WCL_E_BLUETOOTH_LE_GET_PRESENTATION_FORMAT_NAMESPACE_FAILED = 331888; + + // Token: 0x040012FA RID: 4858 + public const int WCL_E_BLUETOOTH_LE_GET_PRESENTATION_FORMAT_DESCRIPTION_FAILED = 331889; + + // Token: 0x040012FB RID: 4859 + public const int WCL_E_BLUETOOTH_LE_GET_DESCRIPTOR_VALUE_SIZE_FAILED = 331890; + + // Token: 0x040012FC RID: 4860 + public const int WCL_E_BLUETOOTH_LE_GET_DESCRIPTOR_VALUE_RAW_DATA_FAILED = 331891; + + // Token: 0x040012FD RID: 4861 + public const int WCL_E_BLUETOOTH_LE_GET_DESCRIPTOR_VALUE_DATA_FAILED = 331892; + + // Token: 0x040012FE RID: 4862 + public const int WCL_E_BLUETOOTH_LE_GET_CHARACTERISTIC_UUID_FAILED = 331893; + + // Token: 0x040012FF RID: 4863 + public const int WCL_E_BLUETOOTH_LE_GET_CHARACTERISTIC_PROPETIES_FAILED = 331894; + + // Token: 0x04001300 RID: 4864 + public const int WCL_E_BLUETOOTH_LE_GET_DESCRIPTOR_VALUE_DATA_BUFFER_FAILED = 331895; + + // Token: 0x04001301 RID: 4865 + public const int WCL_E_BLUETOOTH_LE_GET_CHARACTERISTIC_VALUE_DATA_BUFFER_FAILED = 331896; + + // Token: 0x04001302 RID: 4866 + public const int WCL_E_BLUETOOTH_LE_GET_CHARACTERISTIC_VALUE_SIZE_FAILED = 331897; + + // Token: 0x04001303 RID: 4867 + public const int WCL_E_BLUETOOTH_LE_GET_CHARACTERISITC_VALUE_RAW_DATA_FAILED = 331898; + + // Token: 0x04001304 RID: 4868 + public const int WCL_E_BLUETOOTH_LE_GET_CHARACTERISITC_VALUE_DATA_FAILED = 331899; + + // Token: 0x04001305 RID: 4869 + public const int WCL_E_BLUETOOTH_LE_GET_DESCRIPTORS_LIST_SIZE_FAILED = 331900; + + // Token: 0x04001306 RID: 4870 + public const int WCL_E_BLUETOOTH_LE_GET_SERVICE_UUID_FAILED = 331901; + + // Token: 0x04001307 RID: 4871 + public const int WCL_E_BLUETOOTH_LE_GET_CHARACTERISITCS_LIST_SIZE_FAILED = 331902; + + // Token: 0x04001308 RID: 4872 + public const int WCL_E_BLUETOOTH_LE_GET_SERVICES_LIST_SIZE_FAILED = 331903; + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleErrors.cs.meta b/Assets/Scripts/Devices/Ble/Win/WclBleErrors.cs.meta new file mode 100644 index 00000000..5197840c --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleErrors.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 037f3eff461a68d40bdf5880692fc0cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs b/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs new file mode 100644 index 00000000..2e5fe915 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs @@ -0,0 +1,302 @@ +using Assets.Scripts.Ble.Win.CPPBridge; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Ble.Win +{ + internal class WclBleGattClient + { + public WclBleGattClient(long address, IntPtr radio) + { + this.gattAddress = address; + this.rPtr = radio; + this.CConnectEvent = new WclBleGattClient.GATTCLIENT_CONNECT(this.OnConnected); + this.CDisconnectEvent = new WclBleGattClient.GATTCLIENT_DISCONNECT(this.OnDisconnected); + this.FCharacteristicChangedEvent = new WclBleGattClient.GATTCLIENT_ONCHANGED(this.OnCharacteristicChanged); + this.mPtr = WclBleGattClient.WCLGattClientCreate(this.CConnectEvent, this.CDisconnectEvent, this.FCharacteristicChangedEvent); + } + + // Token: 0x06002086 RID: 8326 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLGattClientConnect([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [MarshalAs(UnmanagedType.SysInt)][In] IntPtr Radio, [MarshalAs(UnmanagedType.I8)][In] long Address); + + // Token: 0x06002087 RID: 8327 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.SysInt)] + private static extern IntPtr WCLGattClientCreate([MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleGattClient.GATTCLIENT_CONNECT OnConnect, [MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleGattClient.GATTCLIENT_DISCONNECT OnDisconnect, [MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleGattClient.GATTCLIENT_ONCHANGED OnChanged); + + // Token: 0x06002088 RID: 8328 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + private static extern void WCLGattClientDestroy([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client); + + // Token: 0x06002089 RID: 8329 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLGattClientDisconnect([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client); + + // Token: 0x0600208A RID: 8330 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + private static extern void WCLGattClientFreeMem([MarshalAs(UnmanagedType.SysInt)][In] IntPtr pMem); + + // Token: 0x0600208B RID: 8331 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLGattClientGetCharacteristics([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattService Service, [In][Out] ref GattCharacteristics Chars); + + // Token: 0x0600208C RID: 8332 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLGattClientGetServices([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In][Out] ref GattServices Services); + + // Token: 0x0600208D RID: 8333 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.U4)] + private static extern WclBleGattClientState WCLGattClientGetState([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client); + + // Token: 0x0600208E RID: 8334 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLGattClientReadCharacteristicValue([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattCharacteristic Char, [MarshalAs(UnmanagedType.SysInt)][In][Out] ref IntPtr ppValue, [MarshalAs(UnmanagedType.U4)][In][Out] ref uint pSize); + + // Token: 0x0600208F RID: 8335 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLGattClientSubscribeCharacteristic([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattCharacteristic Char); + + // Token: 0x06002090 RID: 8336 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLGattClientUnsubscribeCharacteristic([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattCharacteristic Char); + + // Token: 0x06002091 RID: 8337 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLGattClientWriteCharacteristicValue([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattCharacteristic Char, [MarshalAs(UnmanagedType.SysInt)][In] IntPtr pValue, [MarshalAs(UnmanagedType.U4)][In] uint Size); + + // Token: 0x170005D4 RID: 1492 + // (get) Token: 0x06002092 RID: 8338 RVA: 0x00087790 File Offset: 0x00085990 + public WclBleGattClientState State + { + get + { + return WclBleGattClient.WCLGattClientGetState(this.mPtr); + } + } + + // Token: 0x06002093 RID: 8339 RVA: 0x000877A4 File Offset: 0x000859A4 + public void Connect() + { + if (this.mPtr != IntPtr.Zero) + { + int num = WclBleGattClient.WCLGattClientConnect(this.mPtr, this.rPtr, this.gattAddress); + if (num != 0) + { + this.OnConnected(this.mPtr, num); + } + } + } + + // Token: 0x06002094 RID: 8340 RVA: 0x000877F4 File Offset: 0x000859F4 + public void Disconnect() + { + if (this.mPtr != IntPtr.Zero) + { + //WclBleGattClient.log.Info("Disconnect called", Array.Empty()); + int num = WclBleGattClient.WCLGattClientDisconnect(this.mPtr); + //WclBleGattClient.log.Info(string.Format("Disconnect {0:X} response {1}", this.gattAddress, num), Array.Empty()); + } + } + + // Token: 0x06002095 RID: 8341 RVA: 0x00087864 File Offset: 0x00085A64 + public int DiscoverCharacteristics(GattService service, out GattCharacteristics characteristics) + { + characteristics = new GattCharacteristics + { + Count = 0, + Chars = new GattCharacteristic[255] + }; + return WclBleGattClient.WCLGattClientGetCharacteristics(this.mPtr, ref service, ref characteristics); + } + + // Token: 0x06002096 RID: 8342 RVA: 0x000878B0 File Offset: 0x00085AB0 + public int DiscoverServices(out GattServices services) + { + services = new GattServices + { + Count = 0, + Services = new GattService[255] + }; + return WclBleGattClient.WCLGattClientGetServices(this.mPtr, ref services); + } + + // Token: 0x06002097 RID: 8343 RVA: 0x000878F8 File Offset: 0x00085AF8 + public int ReadCharacteristicValue(GattCharacteristic characteristic, out byte[] value) + { + value = null; + IntPtr zero = IntPtr.Zero; + uint num = 0U; + int num2 = WclBleGattClient.WCLGattClientReadCharacteristicValue(this.mPtr, ref characteristic, ref zero, ref num); + if (num2 == 0 && zero != IntPtr.Zero && num > 0U) + { + value = new byte[num]; + Marshal.Copy(zero, value, 0, (int)num); + WclBleGattClient.WCLGattClientFreeMem(zero); + } + return num2; + } + + // Token: 0x06002098 RID: 8344 RVA: 0x00087953 File Offset: 0x00085B53 + public int SubscribeCharacteristic(GattCharacteristic characteristic) + { + return WclBleGattClient.WCLGattClientSubscribeCharacteristic(this.mPtr, ref characteristic); + } + + // Token: 0x06002099 RID: 8345 RVA: 0x00087968 File Offset: 0x00085B68 + public int WriteCharacteristic(GattCharacteristic characteristic, byte[] value) + { + IntPtr intPtr; + try + { + intPtr = Marshal.AllocHGlobal(value.Length); + } + catch + { + intPtr = IntPtr.Zero; + } + if (intPtr == IntPtr.Zero) + { + return 65537; + } + Marshal.Copy(value, 0, intPtr, value.Length); + int result = WclBleGattClient.WCLGattClientWriteCharacteristicValue(this.mPtr, ref characteristic, intPtr, (uint)value.Length); + Marshal.FreeHGlobal(intPtr); + return result; + } + + // Token: 0x0600209A RID: 8346 RVA: 0x000879D4 File Offset: 0x00085BD4 + public void Dispose() + { + WclBleGattClient.WCLGattClientDestroy(this.mPtr); + this.mPtr = IntPtr.Zero; + this.rPtr = IntPtr.Zero; + this.CConnectEvent = null; + this.CDisconnectEvent = null; + this.FCharacteristicChangedEvent = null; + } + + // Token: 0x0600209B RID: 8347 RVA: 0x00087A0C File Offset: 0x00085C0C + private void OnCharacteristicChanged(IntPtr sender, ushort handle, IntPtr pValue, uint valueLen) + { + //Debug.Log("char changed"); + if (pValue != IntPtr.Zero && valueLen > 0U) + { + byte[] array = new byte[valueLen]; + Marshal.Copy(pValue, array, 0, (int)valueLen); + try + { + WclBleGattClient.GattCharacteristicChanged characteristicChanged = this.CharacteristicChanged; + if (characteristicChanged != null) + { + characteristicChanged(this, handle, array); + } + } + catch (Exception arg) + { + //WclBleGattClient.log.Error(string.Format("GattConnection characteristic changed callback processing error - {0}", arg), Array.Empty()); + } + } + } + + // Token: 0x0600209C RID: 8348 RVA: 0x00087A80 File Offset: 0x00085C80 + private void OnConnected(IntPtr client, int error) + { + try + { + WclBleGattClient.GattConnectionChanged connected = this.Connected; + if (connected != null) + { + connected(this, error); + } + } + catch (Exception arg) + { + //WclBleGattClient.log.Error(string.Format("GattConnection connect callback processing error - {0}", arg), Array.Empty()); + Debug.LogError(arg); + } + } + + // Token: 0x0600209D RID: 8349 RVA: 0x00087AD0 File Offset: 0x00085CD0 + private void OnDisconnected(IntPtr client, int reason) + { + try + { + WclBleGattClient.GattConnectionChanged disconnected = this.Disconnected; + if (disconnected != null) + { + disconnected(this, reason); + } + } + catch (Exception arg) + { + //WclBleGattClient.log.Error(string.Format("GattConnection disconnect callback processing error - {0}", arg), Array.Empty()); + } + } + + // Token: 0x0400130B RID: 4875 + public WclBleGattClient.GattCharacteristicChanged CharacteristicChanged; + + // Token: 0x0400130C RID: 4876 + public WclBleGattClient.GattConnectionChanged Connected; + + // Token: 0x0400130D RID: 4877 + public WclBleGattClient.GattConnectionChanged Disconnected; + + // Token: 0x0400130F RID: 4879 + private WclBleGattClient.GATTCLIENT_CONNECT CConnectEvent; + + // Token: 0x04001310 RID: 4880 + private WclBleGattClient.GATTCLIENT_DISCONNECT CDisconnectEvent; + + // Token: 0x04001311 RID: 4881 + private WclBleGattClient.GATTCLIENT_ONCHANGED FCharacteristicChangedEvent; + + // Token: 0x04001312 RID: 4882 + private readonly long gattAddress; + + // Token: 0x04001313 RID: 4883 + private IntPtr mPtr; + + // Token: 0x04001314 RID: 4884 + private IntPtr rPtr; + + // Token: 0x020008FB RID: 2299 + // (Invoke) Token: 0x06003F5A RID: 16218 + public delegate void GattCharacteristicChanged(WclBleGattClient connection, ushort handle, byte[] value); + + // Token: 0x020008FC RID: 2300 + // (Invoke) Token: 0x06003F5E RID: 16222 + public delegate void GattConnectionChanged(WclBleGattClient connection, int error); + + // Token: 0x020008FD RID: 2301 + // (Invoke) Token: 0x06003F62 RID: 16226 + [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)] + private delegate void GATTCLIENT_CONNECT([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Sender, [MarshalAs(UnmanagedType.I4)][In] int Error); + + // Token: 0x020008FE RID: 2302 + // (Invoke) Token: 0x06003F66 RID: 16230 + [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)] + private delegate void GATTCLIENT_DISCONNECT([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Sender, [MarshalAs(UnmanagedType.I4)][In] int Reason); + + // Token: 0x020008FF RID: 2303 + // (Invoke) Token: 0x06003F6A RID: 16234 + [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)] + private delegate void GATTCLIENT_ONCHANGED([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Sender, [MarshalAs(UnmanagedType.U2)][In] ushort Handle, [MarshalAs(UnmanagedType.SysInt)][In] IntPtr Value, [MarshalAs(UnmanagedType.U4)][In] uint ValueLen); + + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs.meta b/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs.meta new file mode 100644 index 00000000..1442e67b --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c6d5039e76dd26d40a81e37ae83d2587 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs b/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs new file mode 100644 index 00000000..869a7cb1 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs @@ -0,0 +1,403 @@ +using Assets.Scripts.Ble.Win; +using Assets.Scripts.Ble.Win.CPPBridge; +using Assets.Scripts.Devices.Ble; +using Assets.Scripts.Devices.Ble.Win; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Ble +{ + internal class WclBleGattThread + { + 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); + public delegate void GattCharacteristicSubscribedDelegate(WclBleGattThread gattClient, BleCharacteristicInfo characteristic, BleResponse response); + public delegate void GattCharacteristicWroteDelegate(WclBleGattThread gattClient, BleCharacteristicInfo characteristic, BleResponse response); + + + private WclBleGattThread.GattCharacteristicChangedDelegate gattCharacteristicChanged; + private WclBleGattThread.GattCharacteristicReadDelegate gattCharacteristicRead; + + // Token: 0x0400131E RID: 4894 + private WclBleGattThread.GattCharacteristicsDiscoveredDelegate gattCharacteristicsDiscovered; + + // Token: 0x0400131F RID: 4895 + private WclBleGattThread.GattCharacteristicSubscribedDelegate gattCharacteristicsSubscribed; + + + private GattConnected gattConnected; + + // Token: 0x04001322 RID: 4898 + private GattDisconnected gattDisconnected; + + private GattServicesDiscovered gattServicesDiscovered; + + public event WclBleGattThread.GattCharacteristicChangedDelegate GattCharacteristicChanged + { + add + { + this.gattCharacteristicChanged += value; + } + remove + { + this.gattCharacteristicChanged -= value; + } + } + + // Token: 0x14000039 RID: 57 + // (add) Token: 0x060020AE RID: 8366 RVA: 0x00087BB3 File Offset: 0x00085DB3 + // (remove) Token: 0x060020AF RID: 8367 RVA: 0x00087BC7 File Offset: 0x00085DC7 + public event WclBleGattThread.GattCharacteristicReadDelegate GattCharacteristicRead + { + add + { + this.gattCharacteristicRead += value; + } + remove + { + this.gattCharacteristicRead -= value; + } + } + + // Token: 0x1400003A RID: 58 + // (add) Token: 0x060020B0 RID: 8368 RVA: 0x00087BDB File Offset: 0x00085DDB + // (remove) Token: 0x060020B1 RID: 8369 RVA: 0x00087BEF File Offset: 0x00085DEF + public event WclBleGattThread.GattCharacteristicsDiscoveredDelegate GattCharacteristicsDiscovered + { + add + { + this.gattCharacteristicsDiscovered += value; + } + remove + { + this.gattCharacteristicsDiscovered -= value; + } + } + + // Token: 0x1400003B RID: 59 + // (add) Token: 0x060020B2 RID: 8370 RVA: 0x00087C03 File Offset: 0x00085E03 + // (remove) Token: 0x060020B3 RID: 8371 RVA: 0x00087C17 File Offset: 0x00085E17 + public event WclBleGattThread.GattCharacteristicSubscribedDelegate GattCharacteristicSubscribed + { + add + { + this.gattCharacteristicsSubscribed += value; + } + remove + { + this.gattCharacteristicsSubscribed -= value; + } + } + + private WclBleGattThread.GattCharacteristicWroteDelegate gattCharacteristicWrote; + public event WclBleGattThread.GattCharacteristicWroteDelegate GattCharacteristicWrote + { + add + { + this.gattCharacteristicWrote += value; + } + remove + { + this.gattCharacteristicWrote -= value; + } + } + + // Token: 0x1400003D RID: 61 + // (add) Token: 0x060020B6 RID: 8374 RVA: 0x00087C53 File Offset: 0x00085E53 + // (remove) Token: 0x060020B7 RID: 8375 RVA: 0x00087C67 File Offset: 0x00085E67 + public event GattConnected GattConnected + { + add + { + this.gattConnected += value; + } + remove + { + this.gattConnected -= value; + } + } + + // Token: 0x1400003E RID: 62 + // (add) Token: 0x060020B8 RID: 8376 RVA: 0x00087C7B File Offset: 0x00085E7B + // (remove) Token: 0x060020B9 RID: 8377 RVA: 0x00087C8F File Offset: 0x00085E8F + public event GattDisconnected GattDisconnected + { + add + { + this.gattDisconnected += value; + } + remove + { + this.gattDisconnected -= value; + } + } + + // Token: 0x1400003F RID: 63 + // (add) Token: 0x060020BA RID: 8378 RVA: 0x00087CA3 File Offset: 0x00085EA3 + // (remove) Token: 0x060020BB RID: 8379 RVA: 0x00087CB7 File Offset: 0x00085EB7 + public event GattServicesDiscovered GattServicesDiscovered + { + add + { + this.gattServicesDiscovered += value; + } + remove + { + this.gattServicesDiscovered -= value; + } + } + private readonly Dictionary charMapping = new Dictionary(); + + private readonly Dictionary servicesMapping = new Dictionary(); + + private readonly Dictionary subscribedCharHandles = new Dictionary(); + + private WclBleGattClient gatt; + private IntPtr rPtr; + private BlePeripheralInfo _bleDevice; + private readonly long address; + + public BlePeripheralInfo Peripheral { get; } + + internal WclBleGattThread(BlePeripheralInfo bleDevice, IntPtr radio) + { + 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() + { + this.SetUpWorkerThread(); + return true; + } + + private void SetUpWorkerThread() + { + this.gatt = new WclBleGattClient(this.address, this.rPtr) + { + Connected = new WclBleGattClient.GattConnectionChanged(this.OnConnected), + Disconnected = new WclBleGattClient.GattConnectionChanged(this.OnDisconnected), + CharacteristicChanged = new WclBleGattClient.GattCharacteristicChanged(this.OnCharacteristicChanged) + }; + } + + private void OnCharacteristicChanged(WclBleGattClient connection, ushort handle, byte[] value) + { + if (!this.subscribedCharHandles.ContainsKey(handle)) { + return; + } + BleCharacteristicInfo characteristic = this.subscribedCharHandles[handle]; + BleResponse response = new BleResponse + { + IsSuccess = true, + Data = value + }; + this.gattCharacteristicChanged?.Invoke(this, characteristic, response); + } + + private void OnCharacteristicRead(BleCharacteristicInfo characteristic, int result, byte[] data) + { + BleResponse response = new BleResponse + { + IsSuccess = WclBleErrors.IsSuccessCode(result) + }; + if (response.IsSuccess) + { + response.Data = data; + } + else + { + response.Error = new BleHwInterfaceError(new int?(result), "WclBleGattClientErrorDomain", "Error when reading value"); + } + this.gattCharacteristicRead.Invoke(this, characteristic, response); + } + + private void OnCharacteristicsDiscovered(BleServiceInfo service, int result, GattCharacteristics characteristics) + { + BleResponse> response = new BleResponse> + { + IsSuccess = WclBleErrors.IsSuccessCode(result) + }; + if (response.IsSuccess) + { + response.Data = this.ProcessCharacteristics(service, characteristics); + } + else + { + // response.Error = new BleHwInterfaceError(new int?(result), "WclBleGattClientErrorDomain", "Error when reading BLE services"); + } + 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); + } + + private void OnDisconnected(WclBleGattClient sender, int reason) + { + BleResponse response = new BleResponse + { + IsSuccess = true, + Error = new BleHwInterfaceError(new int?(reason), "WclBleGattClientErrorDomain", string.Format("GATT disconnect reason is - {0}", reason)) + }; + this.gattDisconnected?.Invoke(this, response); + } + + public int Connect() + { + this.gatt.Connect(); + return WclBleErrors.WCL_E_SUCCESS; + } + + public int Discounect() + { + this.gatt.Disconnect(); + return WclBleErrors.WCL_E_SUCCESS; + } + + + public int DiscoverServices() + { + GattServices services; + int result = this.gatt.DiscoverServices(out services); + this.OnServicesDiscovered(result, services); + return WclBleErrors.WCL_E_SUCCESS; + } + + private void OnServicesDiscovered(int result, GattServices services) + { + BleResponse> response = new BleResponse> + { + IsSuccess = WclBleErrors.IsSuccessCode(result) + }; + if (response.IsSuccess) + { + response.Data = this.ProcessServices(services); + } + else + { + response.Error = new BleHwInterfaceError(new int?(result), "WclBleGattClientErrorDomain", "Error when reading BLE services"); + } + + gattServicesDiscovered(this, response); + } + + private List ProcessCharacteristics(BleServiceInfo service, GattCharacteristics characteristics) + { + List list = new List((int)characteristics.Count); + for (int i = 0; i < (int)characteristics.Count; i++) + { + GattCharacteristic gattCharacteristic = characteristics.Chars[i]; + WclBleGattThread.WinBleCharacteristicInfo winBleCharacteristicInfo = new WclBleGattThread.WinBleCharacteristicInfo(service, gattCharacteristic.Uuid.WclGuidToNormalizedGuid()); + this.charMapping[winBleCharacteristicInfo] = gattCharacteristic; + list.Add(winBleCharacteristicInfo); + } + return list; + } + private List ProcessServices(GattServices services) + { + List list = new List((int)services.Count); + for (int i = 0; i < (int)services.Count; i++) + { + GattService gattService = services.Services[i]; + WclBleGattThread.WinBleServiceInfo winBleServiceInfo = new WclBleGattThread.WinBleServiceInfo(this._bleDevice, gattService.Uuid.WclGuidToNormalizedGuid()); + this.servicesMapping[winBleServiceInfo] = gattService; + list.Add(winBleServiceInfo); + } + return list; + } + + public int DiscoverCharacteristics(BleServiceInfo service) + { + GattService ns = this.servicesMapping[service]; + + GattCharacteristics characteristics; + int result = this.gatt.DiscoverCharacteristics(ns, out characteristics); + this.OnCharacteristicsDiscovered(service, result, characteristics); + + return WclBleErrors.WCL_E_SUCCESS; + } + + + public int ReadCharacteristicValue(BleCharacteristicInfo characteristic) + { + if (!charMapping.ContainsKey(characteristic)) + { + return WclBleErrors.WCL_E_CONNECTION_NOT_ACTIVE; + } + GattCharacteristic nCh = this.charMapping[characteristic]; + + byte[] data; + int result = this.gatt.ReadCharacteristicValue(nCh, out data); + this.OnCharacteristicRead(characteristic, result, data); + + return WclBleErrors.WCL_E_SUCCESS; + } + + public int SubscribeCharacteristic(BleCharacteristicInfo characteristic) + { + if (!this.charMapping.ContainsKey(characteristic)) + { + return WclBleErrors.WCL_E_CONNECTION_NOT_ACTIVE; + } + + GattCharacteristic nCh = this.charMapping[characteristic]; + + 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"); + BleResponse response = new BleResponse + { + IsSuccess = WclBleErrors.IsSuccessCode(result) + }; + if (response.IsSuccess) + { + this.subscribedCharHandles[nCharacteristic.Handle] = characteristic; + } + else + { + response.Error = new BleHwInterfaceError(new int?(result), "WclBleGattClientErrorDomain", "Error when subscribing Characteristics"); + } + this.gattCharacteristicsSubscribed(this, characteristic, response); + } + + private class WinBleCharacteristicInfo : BleCharacteristicInfo + { + // Token: 0x06003F85 RID: 16261 RVA: 0x000EA274 File Offset: 0x000E8474 + public WinBleCharacteristicInfo(BleServiceInfo service, Guid id) : base(id, service, (BleCharacteristicProperties)0) + { + } + } + + private class WinBleServiceInfo : BleServiceInfo + { + // Token: 0x06003F86 RID: 16262 RVA: 0x000EA27F File Offset: 0x000E847F + public WinBleServiceInfo(BlePeripheralInfo peripheral, Guid id) : base(id, peripheral) + { + } + } + + + + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs.meta b/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs.meta new file mode 100644 index 00000000..f0de77fb --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleGattThread.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39de45743ce824f4ea156708d5ce5e66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs b/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs new file mode 100644 index 00000000..11f9535e --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs @@ -0,0 +1,163 @@ +using Assets.Scripts.Ble.CPPBridge; +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Ble +{ + internal class WclBleMainThread + { + internal delegate void ManagerStatusChangedCallback(WclBleMainThread thread, WclBleManagerStatus status); + + private WclBleMainThread.ManagerStatusChangedCallback managerStatusChanged; + public event WclBleMainThread.ManagerStatusChangedCallback ManagerStatusChanged + { + add + { + this.managerStatusChanged += value; + } + remove + { + this.managerStatusChanged -= value; + } + } + + private WclBleManager wclBleManager; + private WclBleWatcher wclWatcher; + private readonly object locker = new object(); + 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; + } + + private void SetUpWorkerThread() + { + wclBleManager = new WclBleManager + { + ManagerStatusChanged = new WclBleManager.ManagerStatusChangedCallback(this.OnManagerStatusChanged) + + }; + var num = wclBleManager.Open(); + if (num != 0) + { + Debug.LogWarning(string.Format("WCL BLE open failed: 0x{0:X8}", num)); + } + + wclWatcher = new WclBleWatcher + { + InfoPacketReceived = new WclBleWatcher.InfoPacketReceivedEvent(OnInfoPacketReceived), + UuidPacketReceived = new WclBleWatcher.UuidPacketReceivedEvent(OnUuidPacketReceived) + }; + //Debug.Log("bbb"); + } + + private void OnManagerStatusChanged(WclBleManager manager, WclBleManagerStatus status) + { + //Debug.Log(status); + //WclBleMainThread.SafeInvoke(this.managerStatusChanged, this, status); + this.managerStatusChanged(this, status); + } + + private void OnInfoPacketReceived(object sender, long address, long timestamp, sbyte rssi, string name, WclBleAdvertisementType packetType, byte flags) + { + this.scanInfoReceived(this, address, name, rssi, packetType, null); + } + + // Token: 0x060020E7 RID: 8423 RVA: 0x000889ED File Offset: 0x00086BED + private void OnUuidPacketReceived(object sender, long address, long timestamp, sbyte rssi, Guid uuid) + { + this.scanInfoReceived(this, address, null, rssi, WclBleAdvertisementType.Unknown, new Guid?(uuid)); + } + + private static void SafeInvoke(WclBleMainThread.ManagerStatusChangedCallback callback, WclBleMainThread thread, WclBleManagerStatus status) + { + callback.Method.Invoke(callback.Target, new object[] { + thread, + status, + }); + } + + public void Dispose() + { + wclBleManager.Dispose(); + } + + public string Test() + { + return wclBleManager.Test(); + } + + public WclBleGattThread GetGattThread(BlePeripheralInfo info) + { + lock (locker) + { + if (this.gattClients.ContainsKey(info)) + { + return this.gattClients[info]; + } + + return null; + } + } + + public bool StartWatcher() + { + this.wclWatcher.StartScan(this.wclBleManager.Radio); + return true; + } + + + public WclBleGattThread CreateGattThread(BlePeripheralInfo info) + { + lock (locker) + { + if (gattClients.ContainsKey(info)) + { + throw new ArgumentException("gatt thread 已经创建"); + } + + WclBleGattThread wclBleGattThread = new WclBleGattThread(info, this.wclBleManager.Radio); + this.gattClients[info] = wclBleGattThread; + + return wclBleGattThread; + } + } + + public event WclBleMainThread.WclAdvertisementPacketDelegate ScanInfoReceived + { + add + { + this.scanInfoReceived += value; + } + remove + { + this.scanInfoReceived -= value; + } + } + + private WclBleMainThread.WclAdvertisementPacketDelegate scanInfoReceived; + + public delegate void WclAdvertisementPacketDelegate(WclBleMainThread sender, long address, string name, int rssi, WclBleAdvertisementType packetType, Guid? service); + + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs.meta b/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs.meta new file mode 100644 index 00000000..b5f9bc4d --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleMainThread.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1a6d20f12634ae6478884e4f302c6622 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs b/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs new file mode 100644 index 00000000..8418b6f8 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs @@ -0,0 +1,195 @@ +using Assets.Scripts.Ble.CPPBridge; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Assets.Scripts.Ble +{ + internal class WclBleManager + { + // Token: 0x06002170 RID: 8560 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.SysInt)] + private static extern IntPtr WCLManagerCreate([MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleManager.WCL_MANAGER_STATUS_CHANGED Initialize, [MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleManager.WCL_MANAGER_STATUS_CHANGED StatusCHanges, [MarshalAs(UnmanagedType.FunctionPtr)][In] WCL_NOTIFY_EVENT beforeClose); + + // Token: 0x06002171 RID: 8561 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + private static extern void WCLManagerDestroy([MarshalAs(UnmanagedType.SysInt)][In] IntPtr manager); + + // Token: 0x06002172 RID: 8562 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLManagerOpen([MarshalAs(UnmanagedType.SysInt)][In] IntPtr manager); + + // Token: 0x06002173 RID: 8563 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLManagerClose([MarshalAs(UnmanagedType.SysInt)][In] IntPtr manager); + + // Token: 0x06002174 RID: 8564 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool WCLManagerGetActive([MarshalAs(UnmanagedType.SysInt)][In] IntPtr manager); + + // Token: 0x06002175 RID: 8565 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.SysInt)] + private static extern IntPtr WCLManagerGetRadio([MarshalAs(UnmanagedType.SysInt)][In] IntPtr manager); + + // Token: 0x06002176 RID: 8566 RVA: 0x0008B181 File Offset: 0x00089381 + private void OnInitialized(IntPtr sender, WclBleManagerStatus status) + { + //if (WclBleManager.Info) + //{ + // WclBleManager.log.Info(string.Format("WCLBleManger initialized with state {0}", status), Array.Empty()); + //} + this.BleStatus = status; + } + + // Token: 0x06002177 RID: 8567 RVA: 0x0008B1B0 File Offset: 0x000893B0 + private void OnBeforeClose(IntPtr sender) + { + //if (WclBleManager.Info) + //{ + // WclBleManager.log.Info("Closing WCLBleManager -> BeforeClose called", Array.Empty()); + //} + } + + // 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; + } + + // Token: 0x170005F4 RID: 1524 + // (get) Token: 0x06002179 RID: 8569 RVA: 0x0008B1FC File Offset: 0x000893FC + public bool Active + { + get + { + return WclBleManager.WCLManagerGetActive(this.mPtr); + } + } + + // Token: 0x170005F5 RID: 1525 + // (get) Token: 0x0600217A RID: 8570 RVA: 0x0008B20F File Offset: 0x0008940F + public IntPtr Radio + { + get + { + return WclBleManager.WCLManagerGetRadio(this.mPtr); + } + } + + // Token: 0x170005F6 RID: 1526 + // (get) Token: 0x0600217B RID: 8571 RVA: 0x0008B222 File Offset: 0x00089422 + // (set) Token: 0x0600217C RID: 8572 RVA: 0x0008B22A File Offset: 0x0008942A + public WclBleManagerStatus BleStatus + { + get + { + return this.nativeStatus; + } + private set + { + if (this.nativeStatus != value) + { + this.nativeStatus = value; + WclBleManager.SafeInvoke(this.ManagerStatusChanged, this, this.nativeStatus); + } + } + } + + // Token: 0x170005F7 RID: 1527 + // (get) Token: 0x0600217D RID: 8573 RVA: 0x0008B24E File Offset: 0x0008944E + //public WclBleWatcher BleWatcher { get; } + + // Token: 0x0600217E RID: 8574 RVA: 0x0008B258 File Offset: 0x00089458 + public WclBleManager() + { + this.CInitialized = new WclBleManager.WCL_MANAGER_STATUS_CHANGED(this.OnInitialized); + this.CStatusChanged = new WclBleManager.WCL_MANAGER_STATUS_CHANGED(this.OnStatusChanges); + this.CBeforeClose = new WCL_NOTIFY_EVENT(this.OnBeforeClose); + this.mPtr = WclBleManager.WCLManagerCreate(this.CInitialized, this.CStatusChanged, this.CBeforeClose); + } + + // Token: 0x0600217F RID: 8575 RVA: 0x0008B2BE File Offset: 0x000894BE + public int Open() + { + return WclBleManager.WCLManagerOpen(this.mPtr); + } + + // Token: 0x06002180 RID: 8576 RVA: 0x0008B2D1 File Offset: 0x000894D1 + public int Close() + { + return WclBleManager.WCLManagerClose(this.mPtr); + } + + // Token: 0x06002181 RID: 8577 RVA: 0x0008B2E4 File Offset: 0x000894E4 + public void Dispose() + { + //if (WclBleManager.Debug) + //{ + // WclBleManager.log.Debug("WclBleManger disposed", Array.Empty()); + //} + WclBleManager.WCLManagerDestroy(this.mPtr); + this.mPtr = IntPtr.Zero; + this.CInitialized = null; + this.CBeforeClose = null; + this.CStatusChanged = null; + } + + public string Test() + { + return ""; + } + + // Token: 0x06002182 RID: 8578 RVA: 0x0008B337 File Offset: 0x00089537 + private static void SafeInvoke(WclBleManager.ManagerStatusChangedCallback callback, WclBleManager manager, WclBleManagerStatus status) + { + //ExceptionUtils.SafeInvoke(callback, new object[] + //{ + // manager, + // status + //}, WclBleManager.log); + callback(manager, status); + } + + // Token: 0x04001390 RID: 5008 + public WclBleManager.ManagerStatusChangedCallback ManagerStatusChanged; + + // Token: 0x04001391 RID: 5009 + private IntPtr mPtr; + + // Token: 0x04001392 RID: 5010 + private WclBleManager.WCL_MANAGER_STATUS_CHANGED CInitialized; + + // Token: 0x04001393 RID: 5011 + private WclBleManager.WCL_MANAGER_STATUS_CHANGED CStatusChanged; + + // Token: 0x04001394 RID: 5012 + private WCL_NOTIFY_EVENT CBeforeClose; + + // Token: 0x04001395 RID: 5013 + private WclBleManagerStatus nativeStatus; + + // Token: 0x0200093C RID: 2364 + // (Invoke) Token: 0x06004079 RID: 16505 + internal delegate void ManagerStatusChangedCallback(WclBleManager manager, WclBleManagerStatus status); + + // Token: 0x0200093D RID: 2365 + // (Invoke) Token: 0x0600407D RID: 16509 + [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)] + internal delegate void WCL_MANAGER_STATUS_CHANGED([MarshalAs(UnmanagedType.SysInt)][In] IntPtr sender, WclBleManagerStatus status); + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs.meta b/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs.meta new file mode 100644 index 00000000..1598f7f9 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c4b3ea90154c9e4b9cc0446bc75717b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleManagerStatus.cs b/Assets/Scripts/Devices/Ble/Win/WclBleManagerStatus.cs new file mode 100644 index 00000000..bf30522c --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleManagerStatus.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Ble +{ + internal enum WclBleManagerStatus + { + // Token: 0x04001339 RID: 4921 + HardwareNotFound, + // Token: 0x0400133A RID: 4922 + UnsupportedRadio, + // Token: 0x0400133B RID: 4923 + RadioOff, + // Token: 0x0400133C RID: 4924 + RadioOn, + // Token: 0x0400133D RID: 4925 + Unknown + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleManagerStatus.cs.meta b/Assets/Scripts/Devices/Ble/Win/WclBleManagerStatus.cs.meta new file mode 100644 index 00000000..4ce7b8e3 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleManagerStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9eb1abc2338676b4b8a7588b06c9f6cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs b/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs new file mode 100644 index 00000000..8be3d505 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs @@ -0,0 +1,201 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Runtime.InteropServices; +using Assets.Scripts.Ble.CPPBridge; +using UnityEngine; + +namespace Assets.Scripts.Ble +{ + internal class WclBleWatcher + { + internal WclBleWatcher() + { + this.CStarted = new WCL_NOTIFY_EVENT(this.OnStart); + this.CStopped = new WCL_NOTIFY_EVENT(this.OnStop); + this.CUuidPacketReceived = new WclBleWatcher.WCL_ADV_UUID_PKT_EVENT(this.OnUuidPacketReceived); + this.CInfoPackageReceived = new WclBleWatcher.WCL_ADV_INFO_PKT_EVENT(this.OnInfoPacketReceived); + this.mPtr = WclBleWatcher.WCLWatcherCreate(this.CInfoPackageReceived, this.CStarted, this.CStopped, this.CUuidPacketReceived); + } + + // Token: 0x170005E5 RID: 1509 + // (get) Token: 0x06002127 RID: 8487 RVA: 0x00089426 File Offset: 0x00087626 + public bool Active + { + get + { + //base.CheckDisposed(); + return WclBleWatcher.WCLWatcherGetActive(this.mPtr); + } + } + + // Token: 0x0600212A RID: 8490 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.SysInt)] + private static extern IntPtr WCLWatcherCreate([MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleWatcher.WCL_ADV_INFO_PKT_EVENT InfoPacketReceived, [MarshalAs(UnmanagedType.FunctionPtr)][In] WCL_NOTIFY_EVENT Started, [MarshalAs(UnmanagedType.FunctionPtr)][In] WCL_NOTIFY_EVENT Stopped, [MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleWatcher.WCL_ADV_UUID_PKT_EVENT UidPacketReceived); + + // Token: 0x0600212B RID: 8491 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + private static extern void WCLWatcherDestroy([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Watcher); + + // Token: 0x0600212C RID: 8492 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool WCLWatcherGetActive([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Watcher); + + // Token: 0x0600212D RID: 8493 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLWatcherStart([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Watcher, [MarshalAs(UnmanagedType.SysInt)][In] IntPtr Radio); + + // Token: 0x0600212E RID: 8494 + [DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)] + [return: MarshalAs(UnmanagedType.I4)] + private static extern int WCLWatcherStop([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Watcher); + + // Token: 0x0600212F RID: 8495 RVA: 0x00089464 File Offset: 0x00087664 + public void StartScan(IntPtr radio) + { + if (!this.Active) + { + int num = WclBleWatcher.WCLWatcherStart(this.mPtr, radio); + //if (WclBleWatcher.Info) + { + Debug.Log(string.Format("BLE watcher started with result {0}", num)); + } + } + } + + // Token: 0x06002130 RID: 8496 RVA: 0x000894B4 File Offset: 0x000876B4 + public bool StopScan() + { + if (this.Active) + { + int num = WclBleWatcher.WCLWatcherStop(this.mPtr); + + Debug.Log(string.Format("BLE watcher stopped with result {0}", num)); + + return num == 0; + } + return false; + } + + // Token: 0x06002131 RID: 8497 RVA: 0x00089508 File Offset: 0x00087708 + public void Dispose() + { + WclBleWatcher.WCLWatcherDestroy(this.mPtr); + this.mPtr = IntPtr.Zero; + this.CInfoPackageReceived = null; + this.CUuidPacketReceived = null; + this.CStarted = null; + this.CStopped = null; + + Debug.Log("BLE watcher disposed"); + } + + // Token: 0x06002132 RID: 8498 RVA: 0x00089564 File Offset: 0x00087764 + private void OnInfoPacketReceived(IntPtr sender, long address, long timestamp, sbyte rssi, string name, WclBleAdvertisementType packetType, byte flags) + { + //Debug.Log($"address:{ address }, name:{ name }, rssi:{ rssi }, type:{ packetType }"); + //delegate + //{ + // WclBleWatcher.SafeInvoke(this.InfoPacketReceived, this, address, timestamp, rssi, name, packetType, flags); + //}.OnUIThreadAsync(); + this.InfoPacketReceived(this, address, timestamp, rssi, name, packetType, flags); + } + + // Token: 0x06002133 RID: 8499 RVA: 0x000895BC File Offset: 0x000877BC + private void OnUuidPacketReceived(IntPtr sender, long address, long timestamp, sbyte rssi, Guid uuid) + { + //Debug.Log($"uuid:{ uuid.ToString() }, address:{ address }, rssi:{ rssi }"); + //delegate + //{ + // WclBleWatcher.SafeInvoke(this.UuidPacketReceived, this, address, timestamp, rssi, uuid); + //}.OnUIThreadAsync(); + + this.UuidPacketReceived(this, address, timestamp, rssi, uuid); + } + + // Token: 0x06002134 RID: 8500 RVA: 0x000895F9 File Offset: 0x000877F9 + private void OnStart(IntPtr Sender) + { + Debug.Log("watcher started"); + } + + // Token: 0x06002135 RID: 8501 RVA: 0x0008960F File Offset: 0x0008780F + private void OnStop(IntPtr Sender) + { + Debug.Log("Watcher closed"); + } + + // Token: 0x06002136 RID: 8502 RVA: 0x00089628 File Offset: 0x00087828 + private static void SafeInvoke(WclBleWatcher.InfoPacketReceivedEvent callback, object sender, long address, long timestamp, sbyte rssi, string name, WclBleAdvertisementType packetType, byte flags) + { + //ExceptionUtils.SafeInvoke(callback, new object[] + //{ + // sender, + // address, + // timestamp, + // rssi, + // name, + // packetType, + // flags + //}, WclBleWatcher.log); + } + + // Token: 0x06002137 RID: 8503 RVA: 0x0008967F File Offset: 0x0008787F + private static void SafeInvoke(WclBleWatcher.UuidPacketReceivedEvent callback, object sender, long address, long timestamp, sbyte rssi, Guid uuid) + { + //ExceptionUtils.SafeInvoke(callback, new object[] + //{ + // sender, + // address, + // timestamp, + // rssi, + // uuid + //}, WclBleWatcher.log); + } + + // Token: 0x04001348 RID: 4936 + public WclBleWatcher.InfoPacketReceivedEvent InfoPacketReceived; + + // Token: 0x04001349 RID: 4937 + public WclBleWatcher.UuidPacketReceivedEvent UuidPacketReceived; + + // Token: 0x0400134B RID: 4939 + private WclBleWatcher.WCL_ADV_INFO_PKT_EVENT CInfoPackageReceived; + + // Token: 0x0400134C RID: 4940 + private WCL_NOTIFY_EVENT CStarted; + + // Token: 0x0400134D RID: 4941 + private WCL_NOTIFY_EVENT CStopped; + + // Token: 0x0400134E RID: 4942 + private WclBleWatcher.WCL_ADV_UUID_PKT_EVENT CUuidPacketReceived; + + // Token: 0x0400134F RID: 4943 + private IntPtr mPtr; + + // Token: 0x02000919 RID: 2329 + // (Invoke) Token: 0x06003FB3 RID: 16307 + public delegate void InfoPacketReceivedEvent(object Sender, long Address, long Timestamp, sbyte Rssi, string Name, WclBleAdvertisementType PacketType, byte Flags); + + // Token: 0x0200091A RID: 2330 + // (Invoke) Token: 0x06003FB7 RID: 16311 + public delegate void UuidPacketReceivedEvent(object Sender, long Address, long Timestamp, sbyte Rssi, Guid Uuid); + + // Token: 0x0200091B RID: 2331 + // (Invoke) Token: 0x06003FBB RID: 16315 + [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)] + private delegate void WCL_ADV_INFO_PKT_EVENT([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Sender, [MarshalAs(UnmanagedType.I8)][In] long Address, [MarshalAs(UnmanagedType.I8)][In] long Timestamp, [MarshalAs(UnmanagedType.I1)][In] sbyte Rssi, [MarshalAs(UnmanagedType.LPWStr)][In] string Name, [MarshalAs(UnmanagedType.U4)][In] WclBleAdvertisementType PacketType, [MarshalAs(UnmanagedType.U1)][In] byte Flags); + + // Token: 0x0200091C RID: 2332 + // (Invoke) Token: 0x06003FBF RID: 16319 + [UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)] + private delegate void WCL_ADV_UUID_PKT_EVENT([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Sender, [MarshalAs(UnmanagedType.I8)][In] long Address, [MarshalAs(UnmanagedType.I8)][In] long Timestamp, [MarshalAs(UnmanagedType.I1)][In] sbyte Rssi, [In] Guid Uuid); + + } +} diff --git a/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs.meta b/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs.meta new file mode 100644 index 00000000..c62dbfa2 --- /dev/null +++ b/Assets/Scripts/Devices/Ble/Win/WclBleWatcher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4edd43fac4981e04b833e77483087f81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Commands.meta b/Assets/Scripts/Devices/Commands.meta new file mode 100644 index 00000000..91f9658f --- /dev/null +++ b/Assets/Scripts/Devices/Commands.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a2364164ca52b2d448ea4ae2a32e4fc5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Commands/Command.cs b/Assets/Scripts/Devices/Commands/Command.cs new file mode 100644 index 00000000..12c63aeb --- /dev/null +++ b/Assets/Scripts/Devices/Commands/Command.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Commands +{ + public sealed class Command + { + public CommandType Type { get; } + + // Token: 0x17000562 RID: 1378 + // (get) Token: 0x06001DF3 RID: 7667 RVA: 0x0007E52C File Offset: 0x0007C72C + public CommandAction Action { get; } + + // Token: 0x17000563 RID: 1379 + // (get) Token: 0x06001DF4 RID: 7668 RVA: 0x0007E534 File Offset: 0x0007C734 + public object Parameters { get; } + + public Command(CommandType type, CommandAction action) : this(type, null, action) + { + } + + public Command(CommandType type, object parameters, CommandAction action) + { + this.Type = type; + this.Action = action; + this.Parameters = parameters; + } + } +} diff --git a/Assets/Scripts/Devices/Commands/Command.cs.meta b/Assets/Scripts/Devices/Commands/Command.cs.meta new file mode 100644 index 00000000..348d604f --- /dev/null +++ b/Assets/Scripts/Devices/Commands/Command.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf2dd0151702c7b44bd89069c600abdf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Commands/CommandAction.cs b/Assets/Scripts/Devices/Commands/CommandAction.cs new file mode 100644 index 00000000..940bf9c8 --- /dev/null +++ b/Assets/Scripts/Devices/Commands/CommandAction.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Commands +{ + public delegate void CommandAction(CommandResponseStatus responseStatus, object responseData); +} diff --git a/Assets/Scripts/Devices/Commands/CommandAction.cs.meta b/Assets/Scripts/Devices/Commands/CommandAction.cs.meta new file mode 100644 index 00000000..d8b8d8a3 --- /dev/null +++ b/Assets/Scripts/Devices/Commands/CommandAction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d7be1a82849ca5489cbe39940c1e9ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Commands/CommandFactory.cs b/Assets/Scripts/Devices/Commands/CommandFactory.cs new file mode 100644 index 00000000..890aa8e0 --- /dev/null +++ b/Assets/Scripts/Devices/Commands/CommandFactory.cs @@ -0,0 +1,35 @@ +using Assets.Scripts.Ble.Commands; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Commands +{ + public static class CommandFactory + { + public static Command GetBatteryLevel(Action action = null) + { + return new Command(CommandType.GetBatteryLevel, CommandFactory.InjectCommandAction(action)); + } + + private static CommandAction InjectCommandAction(Action action) where T : struct + { + if (action == null) + { + return null; + } + return delegate (CommandResponseStatus status, object data) + { + T? arg = data as T?; + if (data != null && arg == null) + { + action(new CommandResponseStatus(status.Type, CommandResponseCode.TypeMismatch), null); + return; + } + action(status, arg); + }; + } + } +} diff --git a/Assets/Scripts/Devices/Commands/CommandFactory.cs.meta b/Assets/Scripts/Devices/Commands/CommandFactory.cs.meta new file mode 100644 index 00000000..01af21a9 --- /dev/null +++ b/Assets/Scripts/Devices/Commands/CommandFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3273ce1de02c2c49adbdce0197d700e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Commands/CommandResponseStatus.cs b/Assets/Scripts/Devices/Commands/CommandResponseStatus.cs new file mode 100644 index 00000000..766aa66d --- /dev/null +++ b/Assets/Scripts/Devices/Commands/CommandResponseStatus.cs @@ -0,0 +1,35 @@ +using Assets.Scripts.Ble.Commands; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Commands +{ + public sealed class CommandResponseStatus + { + public CommandResponseCode ResponseCode { get; } + + // Token: 0x17000565 RID: 1381 + // (get) Token: 0x06001E0C RID: 7692 RVA: 0x0007E7DC File Offset: 0x0007C9DC + public CommandType Type { get; } + + // Token: 0x17000566 RID: 1382 + // (get) Token: 0x06001E0D RID: 7693 RVA: 0x0007E7E4 File Offset: 0x0007C9E4 + public bool IsSuccess + { + get + { + return this.ResponseCode == CommandResponseCode.Success; + } + } + + // Token: 0x06001E0E RID: 7694 RVA: 0x0007E7EF File Offset: 0x0007C9EF + public CommandResponseStatus(CommandType type, CommandResponseCode responseCode) + { + this.ResponseCode = responseCode; + this.Type = type; + } + } +} diff --git a/Assets/Scripts/Devices/Commands/CommandResponseStatus.cs.meta b/Assets/Scripts/Devices/Commands/CommandResponseStatus.cs.meta new file mode 100644 index 00000000..6e1406e8 --- /dev/null +++ b/Assets/Scripts/Devices/Commands/CommandResponseStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e4aa7fe902c40744b67a6cc6dfc5f6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Commands/CommandType.cs b/Assets/Scripts/Devices/Commands/CommandType.cs new file mode 100644 index 00000000..3ee9cef8 --- /dev/null +++ b/Assets/Scripts/Devices/Commands/CommandType.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Commands +{ + [Flags] + public enum CommandType : long + { + // Token: 0x04000FF5 RID: 4085 + None = 0L, + // Token: 0x04000FF6 RID: 4086 + SetTargetPower = 1L, + // Token: 0x04000FF7 RID: 4087 + SetSimParameters = 2L, + // Token: 0x04000FF8 RID: 4088 + SetTargetGear = 4L, + // Token: 0x04000FF9 RID: 4089 + GetCurrentGear = 8L, + // Token: 0x04000FFA RID: 4090 + GetResistanceControlType = 16L, + // Token: 0x04000FFB RID: 4091 + SetResistanceControlType = 32L, + // Token: 0x04000FFC RID: 4092 + SupportGearing = 64L, + // Token: 0x04000FFD RID: 4093 + SetCircumference = 128L, + // Token: 0x04000FFE RID: 4094 + SetSystemWeight = 256L, + // Token: 0x04000FFF RID: 4095 + SetTargetInclination = 512L, + // Token: 0x04001000 RID: 4096 + GetAutoZeroSupport = 1024L, + // Token: 0x04001001 RID: 4097 + GetAutoZero = 2048L, + // Token: 0x04001002 RID: 4098 + SetAutoZero = 4096L, + // Token: 0x04001003 RID: 4099 + SetManualZeroSupport = 8192L, + // Token: 0x04001004 RID: 4100 + SetManualZero = 16384L, + // Token: 0x04001005 RID: 4101 + RequestCrankLength = 32768L, + // Token: 0x04001006 RID: 4102 + SetCrankLength = 65536L, + // Token: 0x04001007 RID: 4103 + WarmupRollDownCalibration = 131072L, + // Token: 0x04001008 RID: 4104 + StartRollDownCalibration = 262144L, + // Token: 0x04001009 RID: 4105 + StopRollDownCalibration = 524288L, + // Token: 0x0400100A RID: 4106 + GetRollDownCalibrationStatus = 1048576L, + // Token: 0x0400100B RID: 4107 + GetRollDownCalibrationParameters = 2097152L, + // Token: 0x0400100C RID: 4108 + GetRollDownCalibrationType = 4194304L, + // Token: 0x0400100D RID: 4109 + GetBatteryLevel = 1073741824L, + // Token: 0x0400100E RID: 4110 + GetPnPId = 2147483648L, + // Token: 0x0400100F RID: 4111 + GetSensorLocation = 549755813888L, + // Token: 0x04001010 RID: 4112 + GetSupportedSensorLocations = 1099511627776L, + // Token: 0x04001011 RID: 4113 + RequestFtmsControl = 1125899906842624L, + // Token: 0x04001012 RID: 4114 + StartTraining = 2251799813685248L, + // Token: 0x04001013 RID: 4115 + PauseTraining = 4503599627370496L, + // Token: 0x04001014 RID: 4116 + ResumeTraining = 9007199254740992L, + // Token: 0x04001015 RID: 4117 + StopTraining = 18014398509481984L, + // Token: 0x04001016 RID: 4118 + RequestAntPage = 1152921504606846976L, + // Token: 0x04001017 RID: 4119 + CyclingDevice = 1073741839L, + // Token: 0x04001018 RID: 4120 + RunningDevice = 1073741826L, + // Token: 0x04001019 RID: 4121 + TrainingController = 33776997205278720L + } +} diff --git a/Assets/Scripts/Devices/Commands/CommandType.cs.meta b/Assets/Scripts/Devices/Commands/CommandType.cs.meta new file mode 100644 index 00000000..3202420a --- /dev/null +++ b/Assets/Scripts/Devices/Commands/CommandType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a68646ff4441e2f4f8ea96a3056525d4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/ConnectionInterface.cs b/Assets/Scripts/Devices/ConnectionInterface.cs new file mode 100644 index 00000000..b5f6b4b0 --- /dev/null +++ b/Assets/Scripts/Devices/ConnectionInterface.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices +{ + public enum ConnectionInterface + { + BLE, + // Token: 0x04000F34 RID: 3892 + ANT, + } +} diff --git a/Assets/Scripts/Devices/ConnectionInterface.cs.meta b/Assets/Scripts/Devices/ConnectionInterface.cs.meta new file mode 100644 index 00000000..8e4c79af --- /dev/null +++ b/Assets/Scripts/Devices/ConnectionInterface.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f6046f9ad97fcc40852598494f5038a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/DeviceAdapter.cs b/Assets/Scripts/Devices/DeviceAdapter.cs new file mode 100644 index 00000000..d38547e3 --- /dev/null +++ b/Assets/Scripts/Devices/DeviceAdapter.cs @@ -0,0 +1,30 @@ +using Assets.Scripts.Devices.Ant; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices +{ + public abstract class DeviceAdapter : IDisposable + { + public abstract ConnectionInterface Interface { get; } + + + public abstract DeviceAdapterState GetState(); + + public abstract IEnumerable GetDevices(); + + public abstract void StartScan(); + + public abstract void StopScan(); + + public virtual void Dispose() + { + + } + + + } +} diff --git a/Assets/Scripts/Devices/DeviceAdapter.cs.meta b/Assets/Scripts/Devices/DeviceAdapter.cs.meta new file mode 100644 index 00000000..5342b235 --- /dev/null +++ b/Assets/Scripts/Devices/DeviceAdapter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 939bd48cf939e254f9ac83fce8a21377 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/DeviceAdapterState.cs b/Assets/Scripts/Devices/DeviceAdapterState.cs new file mode 100644 index 00000000..5e54dc5d --- /dev/null +++ b/Assets/Scripts/Devices/DeviceAdapterState.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices +{ + public enum DeviceAdapterState + { + Unavailable, + On + } +} diff --git a/Assets/Scripts/Devices/DeviceAdapterState.cs.meta b/Assets/Scripts/Devices/DeviceAdapterState.cs.meta new file mode 100644 index 00000000..40cffe3a --- /dev/null +++ b/Assets/Scripts/Devices/DeviceAdapterState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 31b98212ebf6189499c66311681482ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Devices/Ant/DeviceState.cs b/Assets/Scripts/Devices/DeviceState.cs similarity index 100% rename from Assets/Scripts/Devices/Ant/DeviceState.cs rename to Assets/Scripts/Devices/DeviceState.cs diff --git a/Assets/Scripts/Devices/Ant/DeviceState.cs.meta b/Assets/Scripts/Devices/DeviceState.cs.meta similarity index 100% rename from Assets/Scripts/Devices/Ant/DeviceState.cs.meta rename to Assets/Scripts/Devices/DeviceState.cs.meta diff --git a/Assets/Scripts/Devices/MainDeviceAdapter.cs b/Assets/Scripts/Devices/MainDeviceAdapter.cs new file mode 100644 index 00000000..c1e93101 --- /dev/null +++ b/Assets/Scripts/Devices/MainDeviceAdapter.cs @@ -0,0 +1,73 @@ +using Assets.Scripts.Devices.Ant; +using Assets.Scripts.Devices.Ble; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Devices +{ + public sealed class MainDeviceAdapter : IDisposable + { + private List adapters = new List(); + public MainDeviceAdapter() + { + this.CreateAntAdapter(); + this.CreateBleAdapter(); + } + + private void CreateAntAdapter() + { + adapters.Add(new AntDeviceAdapter()); + } + + private void CreateBleAdapter() + { + adapters.Add(new BleDeviceAdapter()); + } + + public void StartScan() + { + adapters.ForEach(item => + { + item.StartScan(); + }); + } + + public void StopScan() + { + + } + + public DeviceAdapterState GetState(ConnectionInterface connectionInterface) + { + var adapter = adapters.FirstOrDefault(a => a.Interface == connectionInterface); + if(adapter != null) + { + return adapter.GetState(); + } + return DeviceAdapterState.Unavailable; + } + + public IEnumerable GetDevices() + { + var result = new List(); + foreach (var item in adapters) + { + result.AddRange(item.GetDevices()); + } + + return result; + } + + public void Dispose() + { + //throw new NotImplementedException(); + foreach (var item in adapters) + { + item.Dispose(); + } + } + } +} diff --git a/Assets/Scripts/Devices/MainDeviceAdapter.cs.meta b/Assets/Scripts/Devices/MainDeviceAdapter.cs.meta new file mode 100644 index 00000000..ba6aa1cc --- /dev/null +++ b/Assets/Scripts/Devices/MainDeviceAdapter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2239cfdb557e6714f85ce68cf6a2ce0a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Scenes/MainController.cs b/Assets/Scripts/Scenes/MainController.cs index 4bf4fa70..9fa86c3b 100644 --- a/Assets/Scripts/Scenes/MainController.cs +++ b/Assets/Scripts/Scenes/MainController.cs @@ -18,18 +18,19 @@ public class MainController : MonoBehaviour Version.text = "V"+App.AppVersion; DeviceCache.Init(PFConstants.DeviceCacheFolder); - AntConnector.Instance((device2) => { - if (device2.State == DeviceState.Disconnected) - { - //Debug.Log($"探索到新的设备{ device2.DeviceNumber }"); - //自动连接 - if (DeviceCache.Exist(device2)) - { - Debug.Log("自动连接" + device2.DeviceNumber); - device2.Connect(); - } - } - }, Debug.Log); + //AntConnector.Instance((device2) => { + // if (device2.State == DeviceState.Disconnected) + // { + // //Debug.Log($"探索到新的设备{ device2.DeviceNumber }"); + // //自动连接 + // if (DeviceCache.Exist(device2)) + // { + // Debug.Log("自动连接" + device2.DeviceNumber); + // device2.Connect(); + // } + // } + //}, Debug.Log); + App.MainDeviceAdapter.StartScan(); //Debug.Log(Application.dataPath); @@ -89,6 +90,6 @@ public class MainController : MonoBehaviour private void OnApplicationQuit() { - AntConnector.Instance().Dispose(); + App.MainDeviceAdapter.Dispose(); } } diff --git a/Assets/Scripts/UI/Prefab/Device/ConnectDeviceModal.cs b/Assets/Scripts/UI/Prefab/Device/ConnectDeviceModal.cs index 446931be..1175eb8d 100644 --- a/Assets/Scripts/UI/Prefab/Device/ConnectDeviceModal.cs +++ b/Assets/Scripts/UI/Prefab/Device/ConnectDeviceModal.cs @@ -10,6 +10,7 @@ using Assets.Scripts.Devices.Ant.Interfaces; using Assets.Scripts.UI.Control; using Assets.Scripts; using Assets.Scripts.UI.Prefab.Device; +using Assets.Scripts.Devices; public class ConnectDeviceModal : PFUIPanel { @@ -126,26 +127,26 @@ public class ConnectDeviceModal : PFUIPanel { //Debug.Log(AntConnector.Instance().discoveredDevices.Count(d => d.Sensor == SensorType)); - var devices = new List(); - var a = AntConnector.Instance().discoveredDevices; + var devices = new List(); + //var a = AntConnector.Instance().discoveredDevices; switch (SensorType) { case SensorType.Cadence: - devices = AntConnector.Instance().discoveredDevices.Where(d => d.Sensor == SensorType || (d is ICadenceDevice && d.State == DeviceState.Connected)).OrderBy(d=>d.Priority).ToList(); + devices = App.MainDeviceAdapter.GetDevices().Where(d => d.Sensor == SensorType || (d is ICadenceDevice && d.State == DeviceState.Connected)).OrderBy(d=>d.Priority).ToList(); break; case SensorType.HeartRate: - devices = AntConnector.Instance().discoveredDevices.Where(d => d.Sensor == SensorType || (d is IHeartRateDevice && d.State == DeviceState.Connected)).OrderBy(d => d.Priority).ToList(); + devices = App.MainDeviceAdapter.GetDevices().Where(d => d.Sensor == SensorType || (d is IHeartRateDevice && d.State == DeviceState.Connected)).OrderBy(d => d.Priority).ToList(); break; case SensorType.Power: - devices = AntConnector.Instance().discoveredDevices.Where(d => d.Sensor == SensorType || (d is IPowerDevice && d.State == DeviceState.Connected)).OrderBy(d=>d.Priority).ToList(); + devices = App.MainDeviceAdapter.GetDevices().Where(d => d.Sensor == SensorType || (d is IPowerDevice && d.State == DeviceState.Connected)).OrderBy(d=>d.Priority).ToList(); break; case SensorType.Speed: break; case SensorType.SpeedCadence: - devices = AntConnector.Instance().discoveredDevices.Where(d => d.Sensor == SensorType || (d is ISpeedDevice && d.State == DeviceState.Connected)).OrderBy(d => d.Priority).ToList(); + devices = App.MainDeviceAdapter.GetDevices().Where(d => d.Sensor == SensorType || (d is ISpeedDevice && d.State == DeviceState.Connected)).OrderBy(d => d.Priority).ToList(); break; case SensorType.Trainer: - devices = AntConnector.Instance().discoveredDevices.Where(d => d.Sensor == SensorType).ToList(); + devices = App.MainDeviceAdapter.GetDevices().Where(d => d.Sensor == SensorType).ToList(); break; case SensorType.VirtualPower: break; diff --git a/Assets/Scripts/UI/Prefab/Device/DeviceCache.cs b/Assets/Scripts/UI/Prefab/Device/DeviceCache.cs index ebaaf8e6..ff934417 100644 --- a/Assets/Scripts/UI/Prefab/Device/DeviceCache.cs +++ b/Assets/Scripts/UI/Prefab/Device/DeviceCache.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using System.Collections.Concurrent; using UnityEngine; using Newtonsoft.Json; +using Assets.Scripts.Devices; namespace Assets.Scripts.UI.Prefab.Device { @@ -36,7 +37,7 @@ namespace Assets.Scripts.UI.Prefab.Device } } - public static void Add(AbstractAntDevice antDevice) + public static void Add(AbstractDevice antDevice) { Debug.Log("添加设备" + antDevice.DeviceNumber); @@ -52,7 +53,7 @@ namespace Assets.Scripts.UI.Prefab.Device Write(); } - public static bool Exist(AbstractAntDevice antDevice) + public static bool Exist(AbstractDevice antDevice) { ushort a; if(dict.TryGetValue(antDevice.Sensor.ToString(), out a)) @@ -63,7 +64,7 @@ namespace Assets.Scripts.UI.Prefab.Device return false; } - public static void Remove(AbstractAntDevice antDevice) + public static void Remove(AbstractDevice antDevice) { if(dict == null) { diff --git a/Assets/Scripts/UI/Prefab/Device/DeviceItem.cs b/Assets/Scripts/UI/Prefab/Device/DeviceItem.cs index 996023c0..ccee8601 100644 --- a/Assets/Scripts/UI/Prefab/Device/DeviceItem.cs +++ b/Assets/Scripts/UI/Prefab/Device/DeviceItem.cs @@ -1,4 +1,5 @@ -using Assets.Scripts.Devices.Ant; +using Assets.Scripts.Devices; +using Assets.Scripts.Devices.Ant; using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -9,7 +10,7 @@ public class DeviceItem : Selectable, IEventSystemHandler, IPointerClickHandler { private bool isOn; private Text mText; - public AbstractAntDevice DeviceInfo + public AbstractDevice DeviceInfo { get;set; } diff --git a/Assets/Scripts/UI/Prefab/Device/DeviceView.cs b/Assets/Scripts/UI/Prefab/Device/DeviceView.cs index 05eb71df..8af5e55f 100644 --- a/Assets/Scripts/UI/Prefab/Device/DeviceView.cs +++ b/Assets/Scripts/UI/Prefab/Device/DeviceView.cs @@ -12,6 +12,7 @@ using Assets.Scripts.UI.UIEffect; using Assets.Scripts; using DG.Tweening; using Assets.Scripts.UI.Prefab.Device; +using Assets.Scripts.Devices; public class DeviceView : MonoBehaviour { @@ -225,7 +226,7 @@ public class DeviceView : MonoBehaviour title.text = GetTitle(); - var hasDevice = AntConnector.Instance().discoveredDevices.Any(d => d.Sensor == SensorType); + var hasDevice = App.MainDeviceAdapter.GetDevices().Any(d => d.Sensor == SensorType); if (hasDevice) { mSearchButton.SetActive(false); @@ -309,7 +310,7 @@ public class DeviceView : MonoBehaviour } - string GetValue(AbstractAntDevice connectedDevice) + string GetValue(AbstractDevice connectedDevice) { switch (SensorType) { @@ -338,19 +339,20 @@ public class DeviceView : MonoBehaviour } return ""; } - AbstractAntDevice GetCurrentDevice() + AbstractDevice GetCurrentDevice() { - return AntConnector.Instance().discoveredDevices.FirstOrDefault(d => (d.State == DeviceState.Connected || d.State == DeviceState.Connecting) && d.Sensor == SensorType); + //return AntConnector.Instance().discoveredDevices.FirstOrDefault(d => (d.State == DeviceState.Connected || d.State == DeviceState.Connecting) && d.Sensor == SensorType); + return App.MainDeviceAdapter.GetDevices().FirstOrDefault(d => (d.State == DeviceState.Connected || d.State == DeviceState.Connecting) && d.Sensor == SensorType); } /// /// 获取已经连接的设备 /// /// - AbstractAntDevice GetDevice() + AbstractDevice GetDevice() { //return AntConnector.Instance().discoveredDevices.FirstOrDefault(d => (d.State == DeviceState.Connected || d.State == DeviceState.Connecting) && d.Sensor == SensorType); - var devices = AntConnector.Instance().discoveredDevices.Where(d => (d.State == DeviceState.Connected)); + var devices = App.MainDeviceAdapter.GetDevices().Where(d => (d.State == DeviceState.Connected)); switch (SensorType) { case SensorType.None: diff --git a/Assets/Scripts/UI/Prefab/Panel/DeviceController.cs b/Assets/Scripts/UI/Prefab/Panel/DeviceController.cs index 0cd3e1c4..6ff744fc 100644 --- a/Assets/Scripts/UI/Prefab/Panel/DeviceController.cs +++ b/Assets/Scripts/UI/Prefab/Panel/DeviceController.cs @@ -109,16 +109,9 @@ public class DeviceController : PFUIPanel timer -= Time.deltaTime; if (timer <= 0) { - Available = AntConnector.Instance().IsAvailable; - //if (AntConnector.Instance().IsAvailable) - //{ - // antStatus.sprite = ant1; - //} - //else - //{ - // antStatus.sprite = ant0; - //} - + //Available = AntConnector.Instance().IsAvailable; + Available = App.MainDeviceAdapter.GetState(Assets.Scripts.Devices.ConnectionInterface.ANT) == Assets.Scripts.Devices.DeviceAdapterState.On; + timer = 1.0f; } }