接入基本设备

This commit is contained in:
suntao committed 2021-06-04 13:22:59 +08:00
1 parent 2f84f70a5f
commit 7729332f41
62 files changed
+2880 -86

No files matched your search

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace Assets.Scripts.Ble
{
/// <summary>
/// rouvy里的 WinBlePeripheralInfo类
/// r里的 WinBlePeripheralInfo类
/// </summary>
public class BleDeviceProxy
{
@@ -2,6 +2,7 @@
using Assets.Scripts.Ble.Win;
using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Win;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -96,53 +97,90 @@ namespace Assets.Scripts.Ble
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(address != 224160707349234)
//{
//return;
//}
if (service.HasValue)
{
//Debug.Log($"address:{ address }, name:{ name }, service:{ (service == null ? "" : service.Value.ToString()) }");
}
if (!string.IsNullOrWhiteSpace(name))
{
if (pCache.ContainsKey(address.ToString()))
{
((pCache[address.ToString()].Peripheral) as WinBlePeripheralInfo).SetName(name);
(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)))
if (!service.HasValue || ServiceUuids.Services.Select(s => s.IdGuid).All(x => !x.Equals(service.Value)))
{
return;
}
SensorType sensor = SensorType.None;
List<Guid> services = null;
if (service != null)
{
SensorType sensor = SensorType.None;
List<Guid> services = null;
if (service != null)
{
services = new List<Guid> { service.Value };
foreach(var item in ServiceUuids.Services)
services = new List<Guid> { service.Value };
foreach(var item in ServiceUuids.Services)
{
if(item.IdGuid != service.Value)
{
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;
}
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;
//sensor = SensorType.Trainer;
}
else if(item.IdByteArray == ServiceUuids.CyclingSpeedCadence)
{
sensor = SensorType.SpeedCadence;
}
else if(item.IdByteArray == ServiceUuids.TacxBle)
{
sensor = SensorType.Trainer;
}
}
};
if (!pCache.ContainsKey(address.ToString())) {
var device = new BleAdvertisementInfo(new WinBlePeripheralInfo(address.ToString(), name), rssi, true, services, null, sensor);
pCache.Add(address.ToString(), device);
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);
WclBleGattThread gattClient = this.SetUpGattClient(device.Peripheral);
//this.ConnectInternal(gattClient);
}
else
{
//Debug.Log(sensor);
//pCache[address.ToString()].SensorType = sensor;
foreach (var item in services)
{
pCache[address.ToString()].TryAddService(item);
}
pCache[address.ToString()].Index++;
if(pCache[address.ToString()].SensorType == SensorType.Power && pCache[address.ToString()].Services.Any(s=> s.Equals(ServiceUuids.Get(ServiceUuids.TacxBle).IdGuid)))
{
pCache[address.ToString()].SensorType = SensorType.Trainer;
//Debug.Log("纠正为trainer, "+ pCache[address.ToString()].Index);
}
_discoveredCallback?.Invoke(pCache[address.ToString()]);
if (pCache[address.ToString()].Index > 4 || pCache[address.ToString()].SensorType != SensorType.Power)
{
_discoveredCallback?.Invoke(pCache[address.ToString()]);
}
}
}
@@ -179,8 +217,11 @@ namespace Assets.Scripts.Ble
private void ConnectInternal(WclBleGattThread gattClient)
{
int num = gattClient.Connect();
Debug.Log("连接设备返回" + num);
//Task.Run(() =>
//{
int num = gattClient.Connect();
Debug.Log("连接设备返回" + num);
//});
}
internal void DisconnectPeripheral(BlePeripheralInfo peripheral, Action callback)
@@ -323,7 +364,10 @@ namespace Assets.Scripts.Ble
{
return;
}
this.characteristicsDiscoveredCallbacks.Add(service, callback);
if (!this.characteristicsDiscoveredCallbacks.ContainsKey(service))
{
this.characteristicsDiscoveredCallbacks.Add(service, callback);
}
int num = gattThread.DiscoverCharacteristics(service);
if (WclBleErrors.IsSuccessCode(num))
{
@@ -355,11 +399,29 @@ namespace Assets.Scripts.Ble
this.GattCharacteristicSubscribed(gattThread, characteristic, response);
}
public void WriteCharacteristic(BleCharacteristicInfo characteristic, byte[] data)
{
var gattThread = this.wclBleMainThread.GetGattThread(characteristic.Peripheral);
if(gattThread == null)
{
return;
}
int num = gattThread.WriteCharacteristic(characteristic, data);
if (WclBleErrors.IsSuccessCode(num))
{
Debug.Log("设置命令成功");
return;
}
}
public void Dispose()
{
this.wclBleMainThread.Dispose();
this.wclBleMainThread = null;
hwInterface = null;
pCache.Clear();
}
public void ReadCharacteristic(BleCharacteristicInfo characteristic, CharacteristicReadCallback callback)
@@ -1,4 +1,5 @@
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Win;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -1,4 +1,5 @@
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Win;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scripts.Devices.Ble.Win
{
internal class WclAlertableWait
{
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "WCLWait")]
[return: MarshalAs(UnmanagedType.U4)]
public static extern uint Wait([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.SysInt, SizeParamIndex = 1)][In] IntPtr[] Handle, [MarshalAs(UnmanagedType.U4)][In] uint Cnt, [MarshalAs(UnmanagedType.U4)][In] uint Timeout);
// Token: 0x0600207E RID: 8318
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "WCLFlushApc")]
[return: MarshalAs(UnmanagedType.U4)]
public static extern uint FlushApc();
// Token: 0x0600207F RID: 8319
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "WCLSetApcSync")]
public static extern void SetApcSync();
// Token: 0x04001189 RID: 4489
public const uint WAIT_OBJECT_0 = 0U;
// Token: 0x0400118A RID: 4490
public const uint WAIT_IO_COMPLETION = 192U;
// Token: 0x0400118B RID: 4491
public const uint WAIT_TIMEOUT = 258U;
// Token: 0x0400118C RID: 4492
public const uint WAIT_FAILED = 4294967295U;
// Token: 0x0400118D RID: 4493
public const uint INFINITE = 4294967295U;
// Token: 0x0400118E RID: 4494
public const string GuidTemplate = "0000XXXX-0000-1000-8000-00805F9B34FB";
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4ec3942a1d98efc4eb36cd00001109b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,15 +1,16 @@
using Assets.Scripts.Ble.Win;
using Assets.Scripts.Ble;
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.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
namespace Assets.Scripts.Ble
namespace Assets.Scripts.Devices.Ble.Win
{
internal class WclBleGattThread
{
@@ -163,7 +164,12 @@ namespace Assets.Scripts.Ble
private readonly long address;
public BlePeripheralInfo Peripheral { get; }
private Thread thread;
private ConcurrentQueue<Action> actions = new ConcurrentQueue<Action>();
private bool start = false;
private ManualResetEvent sEvent;
private AutoResetEvent aEvent;
private ManualResetEvent tEvent;
internal WclBleGattThread(BlePeripheralInfo bleDevice, IntPtr radio)
{
this.Peripheral = bleDevice;
@@ -175,10 +181,84 @@ namespace Assets.Scripts.Ble
public bool Start()
{
this.SetUpWorkerThread();
if (this.start)
{
return false;
}
this.start = true;
this.sEvent = new ManualResetEvent(false);
this.tEvent = new ManualResetEvent(false);
this.aEvent = new AutoResetEvent(false);
//thread = new Thread(new ThreadStart(ThreadProc));
// this.sEvent.Set();
// IntPtr[] handle = new IntPtr[]
// {
// this.tEvent.SafeWaitHandle.DangerousGetHandle(),
// this.aEvent.SafeWaitHandle.DangerousGetHandle()
// };
// while (WclAlertableWait.Wait(handle, 2U, WclAlertableWait.INFINITE) != WclAlertableWait.WAIT_OBJECT_0)
// {
// Action action;
// if (this.actions.TryDequeue(out action))
// {
// if (action != null)
// {
// Debug.Log("连接设备");
// action();
// }
// }
// }
// }));
//thread.Start();
//this.sEvent.WaitOne();
ThreadProc();
return true;
}
public void Stop()
{
Debug.Log("停止");
start = false;
thread?.Abort();
}
private void ThreadProc()
{
this.SetUpWorkerThread();
//this.sEvent.Set();
//this.DoWorkerLoop();
//this.CleanUpWorkerThread();
//this.InternalCleanUp();
}
private void CleanUpWorkerThread()
{
this.gatt.Disconnect();
this.gatt.Dispose();
this.gatt = null;
}
private void InternalCleanUp()
{
this.sEvent.Close();
this.sEvent.Dispose();
this.sEvent = null;
this.aEvent.Close();
this.aEvent.Dispose();
this.aEvent = null;
this.tEvent.Close();
this.tEvent.Dispose();
this.tEvent = null;
}
private void SetUpWorkerThread()
{
this.gatt = new WclBleGattClient(this.address, this.rPtr)
@@ -189,6 +269,28 @@ namespace Assets.Scripts.Ble
};
}
private void DoWorkerLoop()
{
IntPtr[] handle = new IntPtr[]
{
this.tEvent.SafeWaitHandle.DangerousGetHandle(),
this.aEvent.SafeWaitHandle.DangerousGetHandle()
};
while (WclAlertableWait.Wait(handle, 2U, 4294967295U) != 0U)
{
//this.InvokeQueuedActions();
Action action;
if (this.actions.TryDequeue(out action))
{
if (action != null)
{
Debug.Log("连接设备");
action();
}
}
}
}
private void OnCharacteristicChanged(WclBleGattClient connection, ushort handle, byte[] value)
{
if (!this.subscribedCharHandles.ContainsKey(handle)) {
@@ -260,6 +362,10 @@ namespace Assets.Scripts.Ble
public int Connect()
{
this.gatt.Connect();
//this.actions.Enqueue(() =>
//{
// this.gatt.Connect();
//});
return WclBleErrors.WCL_E_SUCCESS;
}
@@ -381,6 +487,21 @@ namespace Assets.Scripts.Ble
this.gattCharacteristicsSubscribed(this, characteristic, response);
}
public int WriteCharacteristic(BleCharacteristicInfo characteristicInfo, byte[] data)
{
if (!this.charMapping.ContainsKey(characteristicInfo))
{
return WclBleErrors.WCL_E_CONNECTION_NOT_ACTIVE;
}
GattCharacteristic gCh = this.charMapping[characteristicInfo];
int result = this.gatt.WriteCharacteristic(gCh, data);
return WclBleErrors.WCL_E_SUCCESS;
}
private class WinBleCharacteristicInfo : BleCharacteristicInfo
{
// Token: 0x06003F85 RID: 16261 RVA: 0x000EA274 File Offset: 0x000E8474
@@ -1,4 +1,5 @@
using Assets.Scripts.Ble.CPPBridge;
using Assets.Scripts.Ble;
using Assets.Scripts.Ble.CPPBridge;
using Assets.Scripts.Devices.Ble;
using System;
using System.Collections.Generic;
@@ -8,7 +9,7 @@ using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
namespace Assets.Scripts.Ble
namespace Assets.Scripts.Devices.Ble.Win
{
internal class WclBleMainThread
{
@@ -99,6 +100,12 @@ namespace Assets.Scripts.Ble
public void Dispose()
{
Debug.Log("停止thread");
foreach (var item in this.gattClients.Values)
{
item.Stop();
}
wclBleManager.Dispose();
}
@@ -0,0 +1,215 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Threading;
namespace Assets.Scripts.Devices.Ble.Win
{
internal abstract class WclBleThread
{
// Token: 0x170005E2 RID: 1506
// (get) Token: 0x06002114 RID: 8468 RVA: 0x000890FE File Offset: 0x000872FE
public bool IsRunning
{
get
{
return this.started || this.IsTerminating;
}
}
// Token: 0x170005E3 RID: 1507
// (get) Token: 0x06002115 RID: 8469 RVA: 0x00089112 File Offset: 0x00087312
public bool IsTerminating
{
get
{
return this.terminating;
}
}
// Token: 0x170005E4 RID: 1508
// (get) Token: 0x06002116 RID: 8470 RVA: 0x0008911C File Offset: 0x0008731C
public bool CanLoadWork
{
get
{
return this.IsRunning && !this.IsTerminating;
}
}
// Token: 0x06002117 RID: 8471
protected abstract void SetUpWorkerThread();
// Token: 0x06002118 RID: 8472
protected abstract void CleanUpWorkerThread();
// Token: 0x06002119 RID: 8473 RVA: 0x00089131 File Offset: 0x00087331
protected void TreadProcInitialized()
{
this.sEvent.Set();
}
// Token: 0x0600211A RID: 8474 RVA: 0x0008913F File Offset: 0x0008733F
protected void ProcessPendingAPCMessages()
{
while (WclAlertableWait.FlushApc() != 0U)
{
}
}
// Token: 0x0600211B RID: 8475 RVA: 0x00089148 File Offset: 0x00087348
protected void InternalCleanUp()
{
this.sEvent.Close();
this.sEvent.Dispose();
this.sEvent = null;
this.aEvent.Close();
this.aEvent.Dispose();
this.aEvent = null;
this.tEvent.Close();
this.tEvent.Dispose();
this.tEvent = null;
this.terminating = false;
}
// Token: 0x0600211C RID: 8476 RVA: 0x000891B5 File Offset: 0x000873B5
private void ThreadProc()
{
this.SetUpWorkerThread();
this.sEvent.Set();
this.DoWorkerLoop();
this.CleanUpWorkerThread();
this.InternalCleanUp();
}
// Token: 0x0600211D RID: 8477 RVA: 0x000891DC File Offset: 0x000873DC
private void DoWorkerLoop()
{
IntPtr[] handle = new IntPtr[]
{
this.tEvent.SafeWaitHandle.DangerousGetHandle(),
this.aEvent.SafeWaitHandle.DangerousGetHandle()
};
while (WclAlertableWait.Wait(handle, 2U, 4294967295U) != 0U && !this.terminating)
{
this.InvokeQueuedActions();
if (this.terminating)
{
break;
}
}
}
// Token: 0x0600211E RID: 8478 RVA: 0x0008923C File Offset: 0x0008743C
public virtual bool Start()
{
if (this.IsRunning)
{
return false;
}
this.sEvent = new ManualResetEvent(false);
this.tEvent = new ManualResetEvent(false);
this.aEvent = new AutoResetEvent(false);
this.wThread = new Thread(new ThreadStart(this.ThreadProc));
this.wThread.Start();
this.sEvent.WaitOne();
this.started = true;
return true;
}
// Token: 0x0600211F RID: 8479 RVA: 0x000892B0 File Offset: 0x000874B0
public virtual bool Stop()
{
if (!this.started || this.IsTerminating)
{
return false;
}
this.terminating = true;
this.tEvent.Set();
this.wThread = null;
this.ClearActionQueue();
this.started = false;
return true;
}
// Token: 0x06002120 RID: 8480 RVA: 0x000892FD File Offset: 0x000874FD
protected bool EnqueueAction(Action action)
{
if (this.CanLoadWork)
{
this.aQueue.Enqueue(action);
this.aEvent.Set();
return true;
}
return false;
}
// Token: 0x06002121 RID: 8481 RVA: 0x00089324 File Offset: 0x00087524
protected void ClearActionQueue()
{
Action action;
while (this.aQueue.TryDequeue(out action))
{
}
}
// Token: 0x06002122 RID: 8482 RVA: 0x00089340 File Offset: 0x00087540
protected void InvokeQueuedActions()
{
while (this.DequeueAdnInvokeAction())
{
}
}
// Token: 0x06002123 RID: 8483 RVA: 0x0008934C File Offset: 0x0008754C
protected bool DequeueAdnInvokeAction()
{
Action action = this.TryDequActione();
if (action == null)
{
return false;
}
action();
return true;
}
// Token: 0x06002124 RID: 8484 RVA: 0x0008936C File Offset: 0x0008756C
private Action TryDequActione()
{
if (!this.CanLoadWork)
{
return null;
}
Action result;
if (!this.aQueue.TryDequeue(out result))
{
return null;
}
return result;
}
// Token: 0x04001341 RID: 4929
protected ManualResetEvent tEvent;
// Token: 0x04001342 RID: 4930
protected AutoResetEvent aEvent;
// Token: 0x04001343 RID: 4931
private readonly ConcurrentQueue<Action> aQueue = new ConcurrentQueue<Action>();
// Token: 0x04001344 RID: 4932
protected ManualResetEvent sEvent;
// Token: 0x04001345 RID: 4933
protected Thread wThread;
// Token: 0x04001346 RID: 4934
protected volatile bool terminating;
// Token: 0x04001347 RID: 4935
private volatile bool started;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 25f702c985f2a1b41990cc8fcdcb0450
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: