diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBCentralManager.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBCentralManager.cs
index 4a5b430..5b3d34c 100644
--- a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBCentralManager.cs
+++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBCentralManager.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
namespace CoreBluetooth
{
@@ -40,6 +41,11 @@ public ICBCentralManagerDelegate Delegate
}
}
+ ///
+ /// ICBCentralManagerDelegate callbacks will be called in this context.
+ ///
+ public SynchronizationContext CallbackContext { get; set; }
+
NativeCentralManagerProxy _nativeCentralManagerProxy;
public CBCentralManager(ICBCentralManagerDelegate centralDelegate = null, CBCentralInitOptions options = null)
@@ -55,6 +61,7 @@ public CBCentralManager(ICBCentralManagerDelegate centralDelegate = null, CBCent
}
Delegate = centralDelegate;
_nativeCentralManagerProxy = new NativeCentralManagerProxy(_handle, this);
+ CallbackContext = SynchronizationContext.Current;
}
public void Connect(CBPeripheral peripheral)
@@ -76,7 +83,7 @@ public CBPeripheral[] RetrievePeripherals(params string[] peripheralIds)
var result = new CBPeripheral[peripheralHandles.Length];
for (var i = 0; i < peripheralHandles.Length; i++)
{
- var peripheral = new CBPeripheral(peripheralHandles[i]);
+ var peripheral = new CBPeripheral(peripheralHandles[i], CallbackContext);
SetPeripheral(peripheral);
result[i] = peripheral;
}
@@ -126,42 +133,56 @@ void SetPeripheral(CBPeripheral peripheral)
void INativeCentralManagerDelegate.DidConnect(string peripheralId)
{
- if (_disposed) return;
- var peripheral = GetPeripheral(peripheralId);
- if (peripheral == null) return;
- Delegate?.DidConnectPeripheral(this, peripheral);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var peripheral = GetPeripheral(peripheralId);
+ if (peripheral == null) return;
+ Delegate?.DidConnectPeripheral(this, peripheral);
+ }, null);
}
void INativeCentralManagerDelegate.DidDisconnectPeripheral(string peripheralId, CBError error)
{
- if (_disposed) return;
- var peripheral = GetPeripheral(peripheralId);
- if (peripheral == null) return;
- Delegate?.DidDisconnectPeripheral(this, peripheral, error);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var peripheral = GetPeripheral(peripheralId);
+ if (peripheral == null) return;
+ Delegate?.DidDisconnectPeripheral(this, peripheral, error);
+ }, null);
}
void INativeCentralManagerDelegate.DidFailToConnect(string peripheralId, CBError error)
{
- if (_disposed) return;
- var peripheral = GetPeripheral(peripheralId);
- if (peripheral == null) return;
- Delegate?.DidFailToConnectPeripheral(this, peripheral, error);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var peripheral = GetPeripheral(peripheralId);
+ if (peripheral == null) return;
+ Delegate?.DidFailToConnectPeripheral(this, peripheral, error);
+ }, null);
}
void INativeCentralManagerDelegate.DidDiscoverPeripheral(SafeNativePeripheralHandle peripheralHandle, int rssi)
{
- if (_disposed) return;
-
- var peripheral = new CBPeripheral(peripheralHandle);
- SetPeripheral(peripheral);
- Delegate?.DidDiscoverPeripheral(this, peripheral, rssi);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var peripheral = new CBPeripheral(peripheralHandle, CallbackContext);
+ SetPeripheral(peripheral);
+ Delegate?.DidDiscoverPeripheral(this, peripheral, rssi);
+ }, null);
}
void INativeCentralManagerDelegate.DidUpdateState(CBManagerState state)
{
- if (_disposed) return;
- this.State = state;
- Delegate?.DidUpdateState(this);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ this.State = state;
+ Delegate?.DidUpdateState(this);
+ }, null);
}
public void Dispose()
diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBPeripheral.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBPeripheral.cs
index ba68581..ac85a78 100644
--- a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBPeripheral.cs
+++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBPeripheral.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
+using System.Threading;
namespace CoreBluetooth
{
@@ -61,14 +62,21 @@ public string Name
}
public ICBPeripheralDelegate Delegate { get; set; }
+
+ ///
+ /// ICBPeripheralDelegate callbacks will be called in this context.
+ ///
+ public SynchronizationContext CallbackContext { get; set; }
+
List _services = new List();
public ReadOnlyCollection Services { get; }
- internal CBPeripheral(SafeNativePeripheralHandle nativePeripheral)
+ internal CBPeripheral(SafeNativePeripheralHandle nativePeripheral, SynchronizationContext callbackContext)
{
Handle = nativePeripheral;
_nativePeripheral = new NativePeripheralProxy(Handle, this);
- this.Services = _services.AsReadOnly();
+ Services = _services.AsReadOnly();
+ CallbackContext = callbackContext;
}
///
@@ -189,87 +197,113 @@ CBCharacteristic FindOrInitializeCharacteristic(CBService service, string charac
void INativePeripheralDelegate.DidDiscoverServices(string[] serviceUUIDs, CBError error)
{
- if (_disposed) return;
- var services = serviceUUIDs.Select(uuid =>
+ CallbackContext.Post(_ =>
{
- return _services.FirstOrDefault(s => s.UUID == uuid) ?? new CBService(uuid, this);
- }).ToArray();
- _services.Clear();
- _services.AddRange(services);
+ if (_disposed) return;
+ var services = serviceUUIDs.Select(uuid =>
+ {
+ return _services.FirstOrDefault(s => s.UUID == uuid) ?? new CBService(uuid, this);
+ }).ToArray();
+ _services.Clear();
+ _services.AddRange(services);
- Delegate?.DidDiscoverServices(this, error);
+ Delegate?.DidDiscoverServices(this, error);
+ }, null);
}
void INativePeripheralDelegate.DidDiscoverCharacteristics(string serviceUUID, string[] characteristicUUIDs, CBError error)
{
- if (_disposed) return;
- var service = _services.FirstOrDefault(s => s.UUID == serviceUUID);
- if (service == null) return;
- var characteristics = characteristicUUIDs.Select(uuid => FindOrInitializeCharacteristic(service, uuid)).ToArray();
- service.UpdateCharacteristics(characteristics);
- Delegate?.DidDiscoverCharacteristics(this, service, error);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var service = _services.FirstOrDefault(s => s.UUID == serviceUUID);
+ if (service == null) return;
+ var characteristics = characteristicUUIDs.Select(uuid => FindOrInitializeCharacteristic(service, uuid)).ToArray();
+ service.UpdateCharacteristics(characteristics);
+ Delegate?.DidDiscoverCharacteristics(this, service, error);
+ }, null);
}
void INativePeripheralDelegate.DidUpdateValueForCharacteristic(string serviceUUID, string characteristicUUID, byte[] data, CBError error)
{
- if (_disposed) return;
- var characteristic = FindCharacteristic(serviceUUID, characteristicUUID);
- if (characteristic == null) return;
- characteristic.UpdateValue(data);
- Delegate?.DidUpdateValueForCharacteristic(this, characteristic, error);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var characteristic = FindCharacteristic(serviceUUID, characteristicUUID);
+ if (characteristic == null) return;
+ characteristic.UpdateValue(data);
+ Delegate?.DidUpdateValueForCharacteristic(this, characteristic, error);
+ }, null);
}
void INativePeripheralDelegate.DidWriteValueForCharacteristic(string serviceUUID, string characteristicUUID, CBError error)
{
- if (_disposed) return;
- var characteristic = FindCharacteristic(serviceUUID, characteristicUUID);
- if (characteristic == null) return;
-
- Delegate?.DidWriteValueForCharacteristic(this, characteristic, error);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var characteristic = FindCharacteristic(serviceUUID, characteristicUUID);
+ if (characteristic == null) return;
+ Delegate?.DidWriteValueForCharacteristic(this, characteristic, error);
+ }, null);
}
void INativePeripheralDelegate.IsReadyToSendWriteWithoutResponse()
{
- if (_disposed) return;
- Delegate?.IsReadyToSendWriteWithoutResponse(this);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ Delegate?.IsReadyToSendWriteWithoutResponse(this);
+ }, null);
}
void INativePeripheralDelegate.DidUpdateNotificationStateForCharacteristic(string serviceUUID, string characteristicUUID, bool isNotifying, CBError error)
{
- if (_disposed) return;
- var characteristic = FindCharacteristic(serviceUUID, characteristicUUID);
- if (characteristic == null) return;
- characteristic.UpdateIsNotifying(isNotifying);
- Delegate?.DidUpdateNotificationStateForCharacteristic(this, characteristic, error);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var characteristic = FindCharacteristic(serviceUUID, characteristicUUID);
+ if (characteristic == null) return;
+ characteristic.UpdateIsNotifying(isNotifying);
+ Delegate?.DidUpdateNotificationStateForCharacteristic(this, characteristic, error);
+ }, null);
}
void INativePeripheralDelegate.DidReadRSSI(int rssi, CBError error)
{
- if (_disposed) return;
- Delegate?.DidReadRSSI(this, rssi, error);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ Delegate?.DidReadRSSI(this, rssi, error);
+ }, null);
}
void INativePeripheralDelegate.DidUpdateName()
{
- if (_disposed) return;
- Delegate?.DidUpdateName(this);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ Delegate?.DidUpdateName(this);
+ }, null);
}
void INativePeripheralDelegate.DidModifyServices(string[] invalidatedServiceUUIDs)
{
- if (_disposed) return;
- List invalidatedServices = new List();
- foreach (var uuid in invalidatedServiceUUIDs)
+ CallbackContext.Post(_ =>
{
- var service = _services.FirstOrDefault(s => s.UUID == uuid);
- if (service != null)
+ if (_disposed) return;
+ List invalidatedServices = new List();
+ foreach (var uuid in invalidatedServiceUUIDs)
{
- invalidatedServices.Add(service);
- _services.Remove(service);
+ var service = _services.FirstOrDefault(s => s.UUID == uuid);
+ if (service != null)
+ {
+ invalidatedServices.Add(service);
+ _services.Remove(service);
+ }
}
- }
- Delegate?.DidModifyServices(this, invalidatedServices.ToArray());
+ Delegate?.DidModifyServices(this, invalidatedServices.ToArray());
+ }, null);
}
public override string ToString()
diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBPeripheralManager.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBPeripheralManager.cs
index be6c805..cfe7269 100644
--- a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBPeripheralManager.cs
+++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBPeripheralManager.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading;
namespace CoreBluetooth
{
@@ -39,6 +40,11 @@ public ICBPeripheralManagerDelegate Delegate
}
}
+ ///
+ /// ICBPeripheralManagerDelegate callbacks will be called in this context.
+ ///
+ public SynchronizationContext CallbackContext { get; set; }
+
// key: centralId
Dictionary _centrals = new Dictionary();
@@ -53,6 +59,7 @@ public CBPeripheralManager(ICBPeripheralManagerDelegate peripheralDelegate = nul
_handle = SafeNativePeripheralManagerHandle.Create();
Delegate = peripheralDelegate;
_nativePeripheralManagerProxy = new NativePeripheralManagerProxy(_handle, this);
+ CallbackContext = SynchronizationContext.Current;
}
void AddATTRequestDisposable(IDisposable disposable)
@@ -176,68 +183,92 @@ CBCharacteristic IPeripheralManagerData.FindCharacteristic(string serviceUUID, s
void INativePeripheralManagerDelegate.DidUpdateState(CBManagerState state)
{
- if (_disposed) return;
- State = state;
- _delegate?.DidUpdateState(this);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ State = state;
+ _delegate?.DidUpdateState(this);
+ }, null);
}
void INativePeripheralManagerDelegate.DidAddService(string serviceUUID, CBError error)
{
- if (_disposed) return;
- if (!_addingServiceUUIDs.Remove(serviceUUID))
+ CallbackContext.Post(_ =>
{
- return;
- }
+ if (_disposed) return;
+ if (!_addingServiceUUIDs.Remove(serviceUUID))
+ {
+ return;
+ }
- _delegate?.DidAddService(this, _services[serviceUUID], error);
+ _delegate?.DidAddService(this, _services[serviceUUID], error);
+ }, null);
}
void INativePeripheralManagerDelegate.DidStartAdvertising(CBError error)
{
- if (_disposed) return;
- _delegate?.DidStartAdvertising(this, error);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ _delegate?.DidStartAdvertising(this, error);
+ }, null);
}
void INativePeripheralManagerDelegate.DidSubscribeToCharacteristic(SafeNativeCentralHandle centralHandle, string serviceUUID, string characteristicUUID)
{
- if (_disposed) return;
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
- var central = FindOrCreateCentral(centralHandle);
+ var central = FindOrCreateCentral(centralHandle);
- var characteristic = ((IPeripheralManagerData)this).FindCharacteristic(serviceUUID, characteristicUUID);
- _delegate?.DidSubscribeToCharacteristic(this, central, characteristic);
+ var characteristic = ((IPeripheralManagerData)this).FindCharacteristic(serviceUUID, characteristicUUID);
+ _delegate?.DidSubscribeToCharacteristic(this, central, characteristic);
+ }, null);
}
void INativePeripheralManagerDelegate.DidUnsubscribeFromCharacteristic(SafeNativeCentralHandle centralHandle, string serviceUUID, string characteristicUUID)
{
- if (_disposed) return;
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
- var central = FindOrCreateCentral(centralHandle);
+ var central = FindOrCreateCentral(centralHandle);
- var characteristic = ((IPeripheralManagerData)this).FindCharacteristic(serviceUUID, characteristicUUID);
- _delegate?.DidUnsubscribeFromCharacteristic(this, central, characteristic);
+ var characteristic = ((IPeripheralManagerData)this).FindCharacteristic(serviceUUID, characteristicUUID);
+ _delegate?.DidUnsubscribeFromCharacteristic(this, central, characteristic);
+ }, null);
}
void INativePeripheralManagerDelegate.IsReadyToUpdateSubscribers()
{
- if (_disposed) return;
- _delegate?.IsReadyToUpdateSubscribers(this);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ _delegate?.IsReadyToUpdateSubscribers(this);
+ }, null);
}
void INativePeripheralManagerDelegate.DidReceiveReadRequest(SafeNativeATTRequestHandle requestHandle)
{
- if (_disposed) return;
- var request = new CBATTRequest(requestHandle, new NativeATTRequestProxy(requestHandle, this));
- _delegate?.DidReceiveReadRequest(this, request);
- AddATTRequestDisposable(request);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var request = new CBATTRequest(requestHandle, new NativeATTRequestProxy(requestHandle, this));
+ _delegate?.DidReceiveReadRequest(this, request);
+ AddATTRequestDisposable(request);
+ }, null);
}
void INativePeripheralManagerDelegate.DidReceiveWriteRequests(SafeNativeATTRequestsHandle requestsHandle)
{
- if (_disposed) return;
- var requests = new CBATTRequests(requestsHandle, new NativeATTRequestsProxy(requestsHandle, this));
- _delegate?.DidReceiveWriteRequests(this, requests.Requests);
- AddATTRequestDisposable(requests);
+ CallbackContext.Post(_ =>
+ {
+ if (_disposed) return;
+ var requests = new CBATTRequests(requestsHandle, new NativeATTRequestsProxy(requestsHandle, this));
+ _delegate?.DidReceiveWriteRequests(this, requests.Requests);
+ AddATTRequestDisposable(requests);
+ }, null);
}
public void Dispose()