支持蓝牙可用状态变更。搜索不到设备自动停止当前线程。

This commit is contained in:
suntao 2021-06-10 17:46:43 +08:00
parent dd474f1f61
commit 734893ff83
27 changed files with 290 additions and 143 deletions

View File

@ -308,7 +308,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 30, y: -169} m_AnchoredPosition: {x: 30, y: -169}
m_SizeDelta: {x: 85, y: 20} m_SizeDelta: {x: 205.19348, y: 20}
m_Pivot: {x: 0, y: 1} m_Pivot: {x: 0, y: 1}
--- !u!222 &615180660641507081 --- !u!222 &615180660641507081
CanvasRenderer: CanvasRenderer:

View File

@ -939,7 +939,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 136, y: -72} m_AnchoredPosition: {x: 136, y: -72}
m_SizeDelta: {x: 85, y: 20} m_SizeDelta: {x: 251.36475, y: 20}
m_Pivot: {x: 0, y: 1} m_Pivot: {x: 0, y: 1}
--- !u!222 &6939795344602196707 --- !u!222 &6939795344602196707
CanvasRenderer: CanvasRenderer:

View File

@ -435,7 +435,7 @@ MonoBehaviour:
m_ChildForceExpandWidth: 1 m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1 m_ChildForceExpandHeight: 1
m_ChildControlWidth: 0 m_ChildControlWidth: 0
m_ChildControlHeight: 0 m_ChildControlHeight: 1
m_ChildScaleWidth: 0 m_ChildScaleWidth: 0
m_ChildScaleHeight: 0 m_ChildScaleHeight: 0
--- !u!114 &2674253312174825381 --- !u!114 &2674253312174825381
@ -1275,12 +1275,12 @@ PrefabInstance:
- target: {fileID: 5329299856310536127, guid: 6b94e789d6585a04dbdc04c8a7cf97b2, - target: {fileID: 5329299856310536127, guid: 6b94e789d6585a04dbdc04c8a7cf97b2,
type: 3} type: 3}
propertyPath: m_AnchorMax.y propertyPath: m_AnchorMax.y
value: 1 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 5329299856310536127, guid: 6b94e789d6585a04dbdc04c8a7cf97b2, - target: {fileID: 5329299856310536127, guid: 6b94e789d6585a04dbdc04c8a7cf97b2,
type: 3} type: 3}
propertyPath: m_AnchorMin.y propertyPath: m_AnchorMin.y
value: 1 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 5329299856310536127, guid: 6b94e789d6585a04dbdc04c8a7cf97b2, - target: {fileID: 5329299856310536127, guid: 6b94e789d6585a04dbdc04c8a7cf97b2,
type: 3} type: 3}
@ -1290,7 +1290,7 @@ PrefabInstance:
- target: {fileID: 5329299856310536127, guid: 6b94e789d6585a04dbdc04c8a7cf97b2, - target: {fileID: 5329299856310536127, guid: 6b94e789d6585a04dbdc04c8a7cf97b2,
type: 3} type: 3}
propertyPath: m_AnchoredPosition.y propertyPath: m_AnchoredPosition.y
value: -9 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8688565590564084001, guid: 6b94e789d6585a04dbdc04c8a7cf97b2, - target: {fileID: 8688565590564084001, guid: 6b94e789d6585a04dbdc04c8a7cf97b2,
type: 3} type: 3}

View File

@ -21,7 +21,7 @@ namespace Assets.Scripts.Devices.Ant
//自动连接 //自动连接
if (DeviceCache.Exist(device2)) if (DeviceCache.Exist(device2))
{ {
Debug.Log("自动连接" + device2.DeviceNumber); //Debug.Log("自动连接" + device2.DeviceNumber);
device2.Connect(); device2.Connect();
} }
} }

View File

@ -1,6 +1,7 @@
using Assets.Scripts.Ble; using Assets.Scripts.Ble;
using Assets.Scripts.Ble.HeartRate; using Assets.Scripts.Ble.HeartRate;
using Assets.Scripts.Ble.Service; using Assets.Scripts.Ble.Service;
using Assets.Scripts.Ble.Win;
using Assets.Scripts.Devices.Ant; using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Devices.Ble.Characteristic; using Assets.Scripts.Devices.Ble.Characteristic;
using Assets.Scripts.Devices.Ble.Interfaces; using Assets.Scripts.Devices.Ble.Interfaces;
@ -51,9 +52,13 @@ namespace Assets.Scripts.Devices.Ble
private void HwInterface_PeripheralDisconnectedEvent(BleWinHwInterface hwInterface, BlePeripheralInfo peripheral, BleResponse response, bool manualDisconnect) private void HwInterface_PeripheralDisconnectedEvent(BleWinHwInterface hwInterface, BlePeripheralInfo peripheral, BleResponse response, bool manualDisconnect)
{ {
if (!peripheral.MatchAddress(this.peripheralInfo.Address))
{
return;
}
Debug.Log("disconnected event");
if (this.State != DeviceState.Disconnected) if (this.State != DeviceState.Disconnected)
{ {
//Debug.Log("111111111111111111111111111111111111111111111111111111111111");
this.State = DeviceState.Disconnected; this.State = DeviceState.Disconnected;
if (!manualDisconnect) if (!manualDisconnect)
@ -98,8 +103,17 @@ namespace Assets.Scripts.Devices.Ble
hwInterface.DiscoverServices(this.peripheralInfo, ServicesDiscoveredAction);//, this.ServicesDiscoveredAction); hwInterface.DiscoverServices(this.peripheralInfo, ServicesDiscoveredAction);//, this.ServicesDiscoveredAction);
return; return;
} }
this.State = DeviceState.Disconnected; this.State = DeviceState.Disconnected;
if (response.Error != null)
{
if (response.Error.Code == WclBleErrors.WCL_E_BLUETOOTH_LE_DEVICE_NOT_FOUND)
{
Debug.Log("未找到设备");
App.MainDeviceAdapter.ClearDevice(this.peripheralInfo.Address);
}
}
} }
private void Disconnect() private void Disconnect()
@ -107,12 +121,21 @@ namespace Assets.Scripts.Devices.Ble
if (this.State != DeviceState.Disconnected) if (this.State != DeviceState.Disconnected)
{ {
Debug.Log("断开设备" + this.Name); Debug.Log("断开设备" + this.Name);
//App.MainDeviceAdapter.PrintStatus();
this.hwInterface.DisconnectPeripheral(this.peripheralInfo, () => { this.hwInterface.DisconnectPeripheral(this.peripheralInfo, () => {
//App.MainDeviceAdapter.PrintStatus();
this.State = DeviceState.Disconnected; this.State = DeviceState.Disconnected;
}); });
} }
} }
private void ServicesDiscoveredAction(BleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse<List<BleServiceInfo>> response) private void ServicesDiscoveredAction(BleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse<List<BleServiceInfo>> response)
{ {
//Debug.Log("搜索service"); //Debug.Log("搜索service");
@ -166,83 +189,15 @@ namespace Assets.Scripts.Devices.Ble
//} //}
//this.AddService(service, null); //this.AddService(service, null);
// } // }
//} //}
private void CreateFtmsService(BleServiceInfo serviceInfo) protected bool CheckPendingServiceCharacteristicsResponse(BleServiceInfo serviceInfo, BleResponse bleResponse)
{
this.hwInterface.DiscoverCharacteristic(serviceInfo, (hwInterface, bleServiceInfo, response) =>
{
if (this.CheckPendingServiceCharacteristicsResponse(serviceInfo, response))
{
this.CreateFtmsService(serviceInfo, response);
}
});
}
private void CreateFtmsService(BleServiceInfo serviceInfo, BleResponse<List<BleCharacteristicInfo>> 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<List<BleCharacteristicInfo>> 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<List<BleCharacteristicInfo>> scanCharacteristicsResponse = null)
{
if (service == null)
{
return;
}
this.services.Add(service);
service.DiscoverCharacteristics(scanCharacteristicsResponse);
}
private bool CheckPendingServiceCharacteristicsResponse(BleServiceInfo serviceInfo, BleResponse bleResponse)
{ {
if (bleResponse.IsSuccess) if (bleResponse.IsSuccess)
{ {
return true; return true;
} }
this.pendingServices.Remove(serviceInfo); //this.pendingServices.Remove(serviceInfo);
this.CheckAndSetConnectionStatus(); this.CheckAndSetConnectionStatus();
return false; return false;
} }

View File

@ -21,6 +21,21 @@ namespace Assets.Scripts.Devices.Ble
public BleDeviceAdapter() public BleDeviceAdapter()
{ {
hwInterface = BleWinHwInterface.GetInterface(); hwInterface = BleWinHwInterface.GetInterface();
hwInterface.BluetoothStateChangedEvent += HwInterface_BluetoothStateChangedEvent;
}
private void HwInterface_BluetoothStateChangedEvent(BleWinHwInterface hwInterface, BleState bleState)
{
//Debug.Log("22222222222222" + bleState);
if(bleState == BleState.Off)
{
discoveredDevices.Clear();
}
else
{
this.StartScan();
}
} }
public override IEnumerable<AbstractDevice> GetDevices() public override IEnumerable<AbstractDevice> GetDevices()
@ -39,7 +54,7 @@ namespace Assets.Scripts.Devices.Ble
} }
public override void StartScan() public override void StartScan()
{ {
hwInterface.StartScan((device) => hwInterface.StartScan((device) =>
{ {
if (!discoveredDevices.ContainsKey(device.Peripheral.Address)) if (!discoveredDevices.ContainsKey(device.Peripheral.Address))
@ -123,14 +138,19 @@ namespace Assets.Scripts.Devices.Ble
/// <summary> /// <summary>
/// 清除未连接的设备 /// 清除未连接的设备
/// </summary> /// </summary>
public void ClearDevice() public void ClearDevice(string address)
{ {
var list = discoveredDevices.ToList(); var list = discoveredDevices.ToList();
foreach (var item in list) foreach (var item in list)
{ {
if(item.Value.State == Ant.DeviceState.Disconnected) if(item.Value.State == Ant.DeviceState.Disconnected)
{ {
if (!string.IsNullOrWhiteSpace(address) && item.Key != address)
{
continue;
}
hwInterface.pCache.Remove(item.Key); hwInterface.pCache.Remove(item.Key);
item.Value.Dispose();
discoveredDevices.Remove(item.Key); discoveredDevices.Remove(item.Key);
} }
} }

View File

@ -36,9 +36,13 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
public void HandleAttributeReceived(byte[] data) public void HandleAttributeReceived(byte[] data)
{ {
if(data.Length < 1)
{
return;
}
BatteryLevelValue = (int)data[0]; BatteryLevelValue = (int)data[0];
Debug.Log($"电量:{ BatteryLevelValue }"); //Debug.Log($"电量:{ BatteryLevelValue }");
} }
public void SetUnavailable() public void SetUnavailable()

View File

@ -20,7 +20,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
public void HandleAttributeReceived(byte[] data) public void HandleAttributeReceived(byte[] data)
{ {
//throw new NotImplementedException(); //throw new NotImplementedException();
Debug.Log(Encoding.UTF8.GetString(data)); //Debug.Log(Encoding.UTF8.GetString(data));
} }
public void SetUnavailable() public void SetUnavailable()

View File

@ -20,7 +20,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
public void HandleAttributeReceived(byte[] data) public void HandleAttributeReceived(byte[] data)
{ {
//throw new NotImplementedException(); //throw new NotImplementedException();
Debug.Log($"model number:\t{ Encoding.UTF8.GetString(data) }"); //Debug.Log($"model number:\t{ Encoding.UTF8.GetString(data) }");
} }
public void SetUnavailable() public void SetUnavailable()

View File

@ -56,7 +56,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
} }
else else
{ {
Debug.Log(item.GetType() + "服务可用"); //Debug.Log(item.GetType() + "服务可用");
GetBatteryLevel(ccc); GetBatteryLevel(ccc);
} }

View File

@ -51,6 +51,10 @@ namespace Assets.Scripts.Devices.Ble.Devices
{ {
hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) => hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) =>
{ {
if(!base.CheckPendingServiceCharacteristicsResponse(service1, response))
{
return;
}
foreach (var character in response.Data) foreach (var character in response.Data)
{ {
if (character.MatchGuid(ServiceUuids.Characteristics.TacxFecRead)) if (character.MatchGuid(ServiceUuids.Characteristics.TacxFecRead))

View File

@ -225,20 +225,22 @@ namespace Assets.Scripts.Ble
//{ //{
int num = gattClient.Connect(); int num = gattClient.Connect();
Debug.Log("连接设备返回" + num); Debug.Log("连接设备返回" + num);
//}); //});
} }
internal void DisconnectPeripheral(BlePeripheralInfo peripheral, Action callback) internal void DisconnectPeripheral(BlePeripheralInfo peripheral, Action callback)
{ {
var gattThread = this.wclBleMainThread.GetGattThread(peripheral); var gattThread = this.wclBleMainThread.GetGattThread(peripheral);
if(gattThread != null) if(gattThread != null && gattThread.CanLoadWork)
{ {
this.callbacks.Remove(peripheral); this.callbacks.Remove(peripheral);
this.servicesCallbacks.Remove(peripheral); this.servicesCallbacks.Remove(peripheral);
this.characteristicNotificationCallbacks.Remove(peripheral); this.characteristicNotificationCallbacks.Remove(peripheral);
this.disconnectedCallback.Add(peripheral, callback); this.disconnectedCallback.Add(peripheral, callback);
gattThread.Discounect(); gattThread.Discounect();
} }
} }
@ -255,6 +257,7 @@ namespace Assets.Scripts.Ble
public void StartScan(Action<BleAdvertisementInfo> discoveredCallBack) public void StartScan(Action<BleAdvertisementInfo> discoveredCallBack)
{ {
pCache.Clear();
_discoveredCallback = discoveredCallBack; _discoveredCallback = discoveredCallBack;
this.wclBleMainThread.StartWatcher(); this.wclBleMainThread.StartWatcher();
} }
@ -288,15 +291,17 @@ namespace Assets.Scripts.Ble
private void GattDisconnected(WclBleGattThread gattClient, BleResponse response) private void GattDisconnected(WclBleGattThread gattClient, BleResponse response)
{ {
Debug.Log("gatt disconnected"); Debug.Log($"gatt disconnected { gattClient.Peripheral.Name }");
this.callbacks.Remove(gattClient.Peripheral); this.callbacks.Remove(gattClient.Peripheral);
this.servicesCallbacks.Remove(gattClient.Peripheral); this.servicesCallbacks.Remove(gattClient.Peripheral);
this.characteristicNotificationCallbacks.Remove(gattClient.Peripheral); this.characteristicNotificationCallbacks.Remove(gattClient.Peripheral);
//App.MainDeviceAdapter.PrintStatus();
var manualDisconnect = disconnectedCallback.ContainsKey(gattClient.Peripheral); var manualDisconnect = disconnectedCallback.ContainsKey(gattClient.Peripheral);
this.peripheralDisconnectedEvent(this, gattClient.Peripheral, response, manualDisconnect); this.peripheralDisconnectedEvent(this, gattClient.Peripheral, response, manualDisconnect);
//App.MainDeviceAdapter.PrintStatus();
if (disconnectedCallback.ContainsKey(gattClient.Peripheral)) if (disconnectedCallback.ContainsKey(gattClient.Peripheral))
{ {
disconnectedCallback[gattClient.Peripheral].Invoke(); disconnectedCallback[gattClient.Peripheral].Invoke();
@ -304,7 +309,8 @@ namespace Assets.Scripts.Ble
} }
//this.pCache.Remove(gattClient.Peripheral.Address); //this.pCache.Remove(gattClient.Peripheral.Address);
} }
private void GattServicesDiscovered(WclBleGattThread gattClient, BleResponse<List<BleServiceInfo>> response) private void GattServicesDiscovered(WclBleGattThread gattClient, BleResponse<List<BleServiceInfo>> response)
{ {
@ -324,7 +330,7 @@ namespace Assets.Scripts.Ble
private void GattCharacteristicsDiscovered(WclBleGattThread gattClient, BleServiceInfo service, BleResponse<List<BleCharacteristicInfo>> response) private void GattCharacteristicsDiscovered(WclBleGattThread gattClient, BleServiceInfo service, BleResponse<List<BleCharacteristicInfo>> response)
{ {
Debug.Log("characteristics discovered"); //Debug.Log("characteristics discovered");
if (this.characteristicsDiscoveredCallbacks.ContainsKey(service)) if (this.characteristicsDiscoveredCallbacks.ContainsKey(service))
{ {

View File

@ -0,0 +1,10 @@
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 GattThreadStopped(WclBleMainThread thread, WclBleGattThread gatt);
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9ea66f9d6ac61144a97caaaa882a2cb9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -194,7 +194,7 @@ namespace Assets.Scripts.Ble.Win
{ {
try try
{ {
Debug.Log("onconnected"); Debug.Log($"wclbleGattClient onconnected { error }");
WclBleGattClient.GattConnectionChanged connected = this.Connected; WclBleGattClient.GattConnectionChanged connected = this.Connected;
if (connected != null) if (connected != null)
{ {

View File

@ -170,23 +170,24 @@ namespace Assets.Scripts.Devices.Ble.Win
private ManualResetEvent sEvent; private ManualResetEvent sEvent;
private AutoResetEvent aEvent; private AutoResetEvent aEvent;
private ManualResetEvent tEvent; private ManualResetEvent tEvent;
internal WclBleGattThread(BlePeripheralInfo bleDevice, IntPtr radio) internal WclBleGattThread(BlePeripheralInfo bleDevice, IntPtr radio, WclBleGattThread.WclBleGattThreadStoppedCallback stopCallback)
{ {
this.Peripheral = bleDevice; this.Peripheral = bleDevice;
this.rPtr = radio; this.rPtr = radio;
_bleDevice = bleDevice; _bleDevice = bleDevice;
this.address = long.Parse(_bleDevice.Address, System.Globalization.NumberStyles.HexNumber); this.address = long.Parse(_bleDevice.Address, System.Globalization.NumberStyles.HexNumber);
this.threadStoppedCallback = stopCallback;
} }
private void ThreadProc() //private void ThreadProc()
{ // {
this.SetUpWorkerThread(); // this.SetUpWorkerThread();
//this.sEvent.Set(); // //this.sEvent.Set();
//this.DoWorkerLoop(); // //this.DoWorkerLoop();
//this.CleanUpWorkerThread(); // //this.CleanUpWorkerThread();
//this.InternalCleanUp(); // //this.InternalCleanUp();
} //}
protected override void CleanUpWorkerThread() protected override void CleanUpWorkerThread()
{ {
@ -194,7 +195,10 @@ namespace Assets.Scripts.Devices.Ble.Win
base.ProcessPendingAPCMessages(); base.ProcessPendingAPCMessages();
this.gatt.Dispose(); this.gatt.Dispose();
this.gatt = null; this.gatt = null;
}
this.threadStoppedCallback?.Invoke(this);
}
protected override void SetUpWorkerThread() protected override void SetUpWorkerThread()
{ {
@ -305,8 +309,13 @@ namespace Assets.Scripts.Devices.Ble.Win
} }
BleResponse response = new BleResponse BleResponse response = new BleResponse
{ {
IsSuccess = WclBleErrors.IsSuccessCode(error) IsSuccess = WclBleErrors.IsSuccessCode(error),
};
};
if (!response.IsSuccess)
{
response.Error = new BleHwInterfaceError(error, "", "");
}
//Loom.QueueOnMainThread(() => //Loom.QueueOnMainThread(() =>
//{ //{
this.gattConnected?.Invoke(this, response); this.gattConnected?.Invoke(this, response);
@ -508,6 +517,8 @@ namespace Assets.Scripts.Devices.Ble.Win
this.gattCharacteristicWrote?.Invoke(this, characteristic, response); this.gattCharacteristicWrote?.Invoke(this, characteristic, response);
} }
private WclBleGattThread.WclBleGattThreadStoppedCallback threadStoppedCallback;
public delegate void WclBleGattThreadStoppedCallback(WclBleGattThread clientThread);
private class WinBleCharacteristicInfo : BleCharacteristicInfo private class WinBleCharacteristicInfo : BleCharacteristicInfo
{ {

View File

@ -28,6 +28,19 @@ namespace Assets.Scripts.Devices.Ble.Win
} }
} }
private GattThreadStopped gattThreadStopped;
public event GattThreadStopped GattThreadStopped
{
add
{
this.gattThreadStopped += value;
}
remove
{
this.gattThreadStopped -= value;
}
}
private WclBleManager wclBleManager; private WclBleManager wclBleManager;
private WclBleWatcher wclWatcher; private WclBleWatcher wclWatcher;
private readonly object locker = new object(); private readonly object locker = new object();
@ -107,7 +120,7 @@ namespace Assets.Scripts.Devices.Ble.Win
}); });
} }
public void Stop() public override bool Stop()
{ {
Debug.Log("停止thread"); Debug.Log("停止thread");
foreach (var item in this.gattClients.Values) foreach (var item in this.gattClients.Values)
@ -116,6 +129,8 @@ namespace Assets.Scripts.Devices.Ble.Win
} }
wclBleManager.Dispose(); wclBleManager.Dispose();
return true;
} }
public string Test() public string Test()
@ -153,13 +168,33 @@ namespace Assets.Scripts.Devices.Ble.Win
throw new ArgumentException("gatt thread 已经创建"); throw new ArgumentException("gatt thread 已经创建");
} }
WclBleGattThread wclBleGattThread = new WclBleGattThread(info, this.wclBleManager.Radio); WclBleGattThread wclBleGattThread = new WclBleGattThread(info, this.wclBleManager.Radio, this.GattThreadStoppedCallback);
this.gattClients[info] = wclBleGattThread; this.gattClients[info] = wclBleGattThread;
return wclBleGattThread; return wclBleGattThread;
} }
} }
private void GattThreadStoppedCallback(WclBleGattThread gattThread)
{
Debug.Log("stop callback");
bool flag = false;
object obj = this.locker;
lock (obj)
{
if (this.gattClients.ContainsKey(gattThread.Peripheral))
{
this.gattClients.Remove(gattThread.Peripheral);
flag = true;
}
}
if (flag)
{
this.gattThreadStopped?.Invoke(this, gattThread);
}
}
public event WclBleMainThread.WclAdvertisementPacketDelegate ScanInfoReceived public event WclBleMainThread.WclAdvertisementPacketDelegate ScanInfoReceived
{ {
add add

View File

@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading; using System.Threading;
using UnityEngine;
namespace Assets.Scripts.Devices.Ble.Win namespace Assets.Scripts.Devices.Ble.Win
{ {
@ -16,6 +17,7 @@ namespace Assets.Scripts.Devices.Ble.Win
{ {
get get
{ {
//Debug.Log($"{ this.started }, { this.IsTerminating }");
return this.started || this.IsTerminating; return this.started || this.IsTerminating;
} }
} }
@ -36,6 +38,7 @@ namespace Assets.Scripts.Devices.Ble.Win
{ {
get get
{ {
//Debug.Log($"{ this.IsRunning }, { this.IsTerminating }");
return this.IsRunning && !this.IsTerminating; return this.IsRunning && !this.IsTerminating;
} }
} }

View File

@ -76,15 +76,36 @@ namespace Assets.Scripts.Devices
/// <summary> /// <summary>
/// 清除未连接的设备 /// 清除未连接的设备
/// </summary> /// </summary>
public void ClearDevice() public void ClearDevice(string address="")
{ {
Debug.Log($"clear device {address}");
foreach (var item in adapters) foreach (var item in adapters)
{ {
if(item is BleDeviceAdapter) if(item is BleDeviceAdapter)
{ {
(item as BleDeviceAdapter).ClearDevice(); (item as BleDeviceAdapter).ClearDevice(address);
} }
} }
} }
public void PrintStatus()
{
var str = "----------------------------\r\n";
var devices = App.MainDeviceAdapter.GetDevices().ToList();
foreach (var item in devices)
{
if (item.Sensor != SensorType.Trainer)
{
continue;
}
if (item.Network != NetworkType.BLE)
{
continue;
}
str += item.Name + $"{ item.State }\r\n";
}
str += "---------------------------\r\n";
Debug.Log(str);
}
} }
} }

View File

@ -32,4 +32,17 @@ public static class PFConstants
return Application.persistentDataPath; return Application.persistentDataPath;
} }
} }
public static string LogFolder
{
get
{
if (!Directory.Exists(Application.persistentDataPath + "/Logs/"))
{
Directory.CreateDirectory(Application.persistentDataPath + "/Logs/");
}
return Application.persistentDataPath + "/Logs/";
}
}
} }

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace Assets.Scripts.Scenes
{
public abstract class BaseScene: MonoBehaviour
{
protected virtual void Awake()
{
Debug.Log("base scene awake");
Application.logMessageReceived += Application_logMessageReceived;
}
private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
{
//Debug.Log("application log");
if (type == LogType.Error || type == LogType.Exception)
{
string log = $"time:{ System.DateTime.Now.ToString() }\r\n";
log += $"type:{ type }\r\n";
log += $"msg:{ condition }\r\n";
log += $"stack trace:{ stackTrace }\r\n";
System.IO.File.AppendAllText($"{PFConstants.LogFolder}\\{ System.DateTime.Now.ToString("yyyy-MM-dd") }.txt", log);
//Debug.Log(PFConstants.LogFolder);
}
}
private void OnApplicationQuit()
{
App.MainDeviceAdapter.Dispose();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e959496c1867434a9491c1416cb1c68
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,6 @@
using Assets.Scripts; using Assets.Scripts;
using Assets.Scripts.Devices.Ant; using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Scenes;
using Assets.Scripts.UI.Prefab.Device; using Assets.Scripts.UI.Prefab.Device;
using Mapbox.Examples; using Mapbox.Examples;
using System.Collections; using System.Collections;
@ -8,32 +9,20 @@ using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
public class MainController : MonoBehaviour public class MainController : BaseScene
{ {
[SerializeField]GameObject root; [SerializeField]GameObject root;
private Text Version; private Text Version;
private void Awake() protected override void Awake()
{ {
base.Awake();
Version = this.transform.Find("GameObject").Find("Version").GetComponent<Text>(); Version = this.transform.Find("GameObject").Find("Version").GetComponent<Text>();
Version.text = "V"+App.AppVersion; Version.text = "V"+App.AppVersion;
DeviceCache.Init(PFConstants.DeviceCacheFolder); DeviceCache.Init(PFConstants.DeviceCacheFolder);
Loom.Initialize(); Loom.Initialize();
//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); App.MainDeviceAdapter.StartScan();
} }
// Start is called before the first frame update // Start is called before the first frame update
@ -76,6 +65,8 @@ public class MainController : MonoBehaviour
} }
} }
// Update is called once per frame // Update is called once per frame
void Update() void Update()
{ {
@ -87,9 +78,4 @@ public class MainController : MonoBehaviour
var result = await ConfigHelper.userApi.Login("13115011550", "laozhong", ""); var result = await ConfigHelper.userApi.Login("13115011550", "laozhong", "");
App.CurrentUser = result.data; App.CurrentUser = result.data;
} }
private void OnApplicationQuit()
{
App.MainDeviceAdapter.Dispose();
}
} }

View File

@ -48,7 +48,7 @@ public class DeviceItem : Selectable, IEventSystemHandler, IPointerClickHandler
{ {
signal.enabled = false; signal.enabled = false;
} }
SetSignal(); SetSignal();
} }

View File

@ -251,15 +251,16 @@ public class DeviceView : MonoBehaviour
connectionPanel.SetActive(false); connectionPanel.SetActive(false);
logo.sprite = sprite1; logo.sprite = sprite1;
title.text = connectedDevice.Name; //title.text = connectedDevice.Name;
if (connectedDevice.Network == NetworkType.BLE) if (connectedDevice.Network == NetworkType.BLE)
{ {
noDevice.enabled = false; //noDevice.enabled = false;
noDevice.text = connectedDevice.Name;
} }
else else
{ {
noDevice.enabled = true; //noDevice.enabled = true;
noDevice.text = connectedDevice.DeviceNumber.ToString(); noDevice.text = connectedDevice.Name +" "+ connectedDevice.DeviceNumber.ToString();
} }
searchState.text = "Connecting..."; searchState.text = "Connecting...";
@ -287,15 +288,16 @@ public class DeviceView : MonoBehaviour
logo.sprite = sprite3; logo.sprite = sprite3;
title.text = connectedDevice.Name; //title.text = connectedDevice.Name;
if (connectedDevice.Network == NetworkType.BLE) if (connectedDevice.Network == NetworkType.BLE)
{ {
noDevice.enabled = false; //noDevice.enabled = false;
noDevice.text = connectedDevice.Name;
} }
else else
{ {
noDevice.enabled = true; //noDevice.enabled = true;
noDevice.text = connectedDevice.DeviceNumber.ToString(); noDevice.text = connectedDevice.Name +" "+ connectedDevice.DeviceNumber.ToString();
} }
noDevice.color = Color.white; noDevice.color = Color.white;

View File

@ -264,7 +264,7 @@ public class EditUserController : PFUIPanel
void SetDayDropdown() void SetDayDropdown()
{ {
Debug.Log(mDayDropdown.SelectedItem); //Debug.Log(mDayDropdown.SelectedItem);
mDayDropdown.ClearOptions(); mDayDropdown.ClearOptions();

View File

@ -18,7 +18,7 @@ PlayerSettings:
cursorHotspot: {x: 0, y: 0} cursorHotspot: {x: 0, y: 0}
m_SplashScreenBackgroundColor: {r: 0.20784314, g: 0.20784314, b: 0.2627451, a: 1} m_SplashScreenBackgroundColor: {r: 0.20784314, g: 0.20784314, b: 0.2627451, a: 1}
m_ShowUnitySplashScreen: 1 m_ShowUnitySplashScreen: 1
m_ShowUnitySplashLogo: 0 m_ShowUnitySplashLogo: 1
m_SplashScreenOverlayOpacity: 1 m_SplashScreenOverlayOpacity: 1
m_SplashScreenAnimation: 1 m_SplashScreenAnimation: 1
m_SplashScreenLogoStyle: 1 m_SplashScreenLogoStyle: 1
@ -43,6 +43,12 @@ PlayerSettings:
- logo: {fileID: 21300000, guid: e5cb6c21d2f3d0746ad3437ddd022558, type: 3} - logo: {fileID: 21300000, guid: e5cb6c21d2f3d0746ad3437ddd022558, type: 3}
duration: 2 duration: 2
m_VirtualRealitySplashScreen: {fileID: 0} m_VirtualRealitySplashScreen: {fileID: 0}
m_ShowUnitySplashAds: 0
m_AdsAndroidGameId:
m_AdsIosGameId:
m_ShowSplashAdsSlogan: 0
m_SloganImage: {fileID: 0}
m_SloganHeight: 150
m_HolographicTrackingLossScreen: {fileID: 0} m_HolographicTrackingLossScreen: {fileID: 0}
defaultScreenWidth: 1024 defaultScreenWidth: 1024
defaultScreenHeight: 768 defaultScreenHeight: 768
@ -113,17 +119,21 @@ PlayerSettings:
switchNVNShaderPoolsGranularity: 33554432 switchNVNShaderPoolsGranularity: 33554432
switchNVNDefaultPoolsGranularity: 16777216 switchNVNDefaultPoolsGranularity: 16777216
switchNVNOtherPoolsGranularity: 16777216 switchNVNOtherPoolsGranularity: 16777216
switchNVNMaxPublicTextureIDCount: 0
switchNVNMaxPublicSamplerIDCount: 0
stadiaPresentMode: 0 stadiaPresentMode: 0
stadiaTargetFramerate: 0 stadiaTargetFramerate: 0
vulkanNumSwapchainBuffers: 3 vulkanNumSwapchainBuffers: 3
vulkanEnableSetSRGBWrite: 0 vulkanEnableSetSRGBWrite: 0
vulkanEnableLateAcquireNextImage: 0
useSecurityBuild: 0
m_SupportedAspectRatios: m_SupportedAspectRatios:
4:3: 1 4:3: 1
5:4: 1 5:4: 1
16:10: 1 16:10: 1
16:9: 1 16:9: 1
Others: 1 Others: 1
bundleVersion: 1.0.0 bundleVersion: 1.1.0
preloadedAssets: [] preloadedAssets: []
metroInputSource: 0 metroInputSource: 0
wsaTransparentSwapchain: 0 wsaTransparentSwapchain: 0
@ -230,6 +240,7 @@ PlayerSettings:
metalEditorSupport: 1 metalEditorSupport: 1
metalAPIValidation: 1 metalAPIValidation: 1
iOSRenderExtraFrameOnPause: 0 iOSRenderExtraFrameOnPause: 0
iosCopyPluginsCodeInsteadOfSymlink: 0
appleDeveloperTeamID: appleDeveloperTeamID:
iOSManualSigningProvisioningProfileID: iOSManualSigningProvisioningProfileID:
tvOSManualSigningProvisioningProfileID: tvOSManualSigningProvisioningProfileID:
@ -328,6 +339,7 @@ PlayerSettings:
- m_BuildTarget: WebGL - m_BuildTarget: WebGL
m_StaticBatching: 0 m_StaticBatching: 0
m_DynamicBatching: 0 m_DynamicBatching: 0
m_BuildTargetEncrypting: []
m_BuildTargetGraphicsJobs: m_BuildTargetGraphicsJobs:
- m_BuildTarget: MacStandaloneSupport - m_BuildTarget: MacStandaloneSupport
m_GraphicsJobs: 0 m_GraphicsJobs: 0
@ -556,6 +568,7 @@ PlayerSettings:
ps4ShareFilePath: ps4ShareFilePath:
ps4ShareOverlayImagePath: ps4ShareOverlayImagePath:
ps4PrivacyGuardImagePath: ps4PrivacyGuardImagePath:
ps4ExtraSceSysFile:
ps4NPtitleDatPath: ps4NPtitleDatPath:
ps4RemotePlayKeyAssignment: -1 ps4RemotePlayKeyAssignment: -1
ps4RemotePlayKeyMappingDir: ps4RemotePlayKeyMappingDir:
@ -598,6 +611,8 @@ PlayerSettings:
ps4disableAutoHideSplash: 0 ps4disableAutoHideSplash: 0
ps4videoRecordingFeaturesUsed: 0 ps4videoRecordingFeaturesUsed: 0
ps4contentSearchFeaturesUsed: 0 ps4contentSearchFeaturesUsed: 0
ps4CompatibilityPS5: 0
ps4GPU800MHz: 1
ps4attribEyeToEyeDistanceSettingVR: 0 ps4attribEyeToEyeDistanceSettingVR: 0
ps4IncludedModules: [] ps4IncludedModules: []
ps4attribVROutputEnabled: 0 ps4attribVROutputEnabled: 0
@ -633,6 +648,7 @@ PlayerSettings:
additionalIl2CppArgs: additionalIl2CppArgs:
scriptingRuntimeVersion: 1 scriptingRuntimeVersion: 1
gcIncremental: 0 gcIncremental: 0
assemblyVersionValidation: 1
gcWBarrierValidation: 0 gcWBarrierValidation: 0
apiCompatibilityLevelPerPlatform: apiCompatibilityLevelPerPlatform:
Standalone: 3 Standalone: 3
@ -683,6 +699,7 @@ PlayerSettings:
XboxOneCapability: [] XboxOneCapability: []
XboxOneGameRating: {} XboxOneGameRating: {}
XboxOneIsContentPackage: 0 XboxOneIsContentPackage: 0
XboxOneEnhancedXboxCompatibilityMode: 0
XboxOneEnableGPUVariability: 1 XboxOneEnableGPUVariability: 1
XboxOneSockets: {} XboxOneSockets: {}
XboxOneSplashScreen: {fileID: 0} XboxOneSplashScreen: {fileID: 0}