diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBMutableCharacteristic.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBMutableCharacteristic.cs index 5475bd9..47b318f 100644 --- a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBMutableCharacteristic.cs +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBMutableCharacteristic.cs @@ -1,7 +1,4 @@ using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; namespace CoreBluetooth { diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/Initializer.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/Initializer.cs new file mode 100644 index 0000000..5d0028f --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/Initializer.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +namespace CoreBluetooth +{ + internal class Initializer + { + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + static void Initialize() + { + ServiceLocator.Instance.Register(new NativeCentralManagerCallbacks()); + ServiceLocator.Instance.Register(new NativePeripheralManagerCallbacks()); + ServiceLocator.Instance.Register(new NativePeripheralCallbacks()); + } + } +} diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/Initializer.cs.meta b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/Initializer.cs.meta new file mode 100644 index 0000000..75ccae1 --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/Initializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac3bce9747e914f5980212a50bfb4e48 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks.meta b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks.meta new file mode 100644 index 0000000..b18db8f --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4a8784e988b834584b3d2e5e2e6b074e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativeCentralManagerCallbacks.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativeCentralManagerCallbacks.cs new file mode 100644 index 0000000..fa27f10 --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativeCentralManagerCallbacks.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace CoreBluetooth +{ + internal class NativeCentralManagerCallbacks : INativeCentralManagerCallbacks + { + readonly static Dictionary s_centralManagerDelegateMap = new Dictionary(); + + public void Register(SafeNativeCentralManagerHandle handle, INativeCentralManagerDelegate centralManagerDelegate) + { + s_centralManagerDelegateMap[handle.DangerousGetHandle()] = centralManagerDelegate; + NativeMethods.cb4u_central_manager_register_handlers( + handle, + DidConnect, + DidDisconnectPeripheral, + DidFailToConnect, + DidDiscoverPeripheral, + DidUpdateState + ); + } + + public void Unregister(SafeNativeCentralManagerHandle handle) + { + s_centralManagerDelegateMap.Remove(handle.DangerousGetHandle()); + } + + static INativeCentralManagerDelegate GetDelegate(IntPtr centralPtr) + { + return s_centralManagerDelegateMap.GetValueOrDefault(centralPtr); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidConnectHandler))] + static void DidConnect(IntPtr centralPtr, IntPtr peripheralIdPtr) + { + GetDelegate(centralPtr)?.DidConnect(Marshal.PtrToStringUTF8(peripheralIdPtr)); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidDisconnectPeripheralHandler))] + static void DidDisconnectPeripheral(IntPtr centralPtr, IntPtr peripheralIdPtr, int errorCode) + { + GetDelegate(centralPtr)?.DidDisconnectPeripheral( + Marshal.PtrToStringUTF8(peripheralIdPtr), + CBError.CreateOrNullFromCode(errorCode) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidFailToConnectHandler))] + static void DidFailToConnect(IntPtr centralPtr, IntPtr peripheralIdPtr, int errorCode) + { + GetDelegate(centralPtr)?.DidFailToConnect( + Marshal.PtrToStringUTF8(peripheralIdPtr), + CBError.CreateOrNullFromCode(errorCode) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidDiscoverPeripheralHandler))] + static void DidDiscoverPeripheral(IntPtr centralPtr, IntPtr peripheralPtr, int rssi) + { + GetDelegate(centralPtr)?.DidDiscoverPeripheral( + new SafeNativePeripheralHandle(peripheralPtr), + rssi + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidUpdateStateHandler))] + static void DidUpdateState(IntPtr centralPtr, CBManagerState state) + { + GetDelegate(centralPtr)?.DidUpdateState(state); + } + } +} diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativeCentralManagerCallbacks.cs.meta b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativeCentralManagerCallbacks.cs.meta new file mode 100644 index 0000000..3236299 --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativeCentralManagerCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cebdd2a683bf44a3d8287b2d184259bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralCallbacks.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralCallbacks.cs new file mode 100644 index 0000000..4b553f3 --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralCallbacks.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace CoreBluetooth +{ + internal class NativePeripheralCallbacks : INativePeripheralCallbacks + { + readonly static Dictionary s_nativePeripheralDelegateMap = new Dictionary(); + + public void Register(SafeNativePeripheralHandle handle, INativePeripheralDelegate peripheralDelegate) + { + s_nativePeripheralDelegateMap[handle.DangerousGetHandle()] = peripheralDelegate; + NativeMethods.cb4u_peripheral_register_handlers( + handle, + DidDiscoverServices, + DidDiscoverCharacteristics, + DidUpdateValueForCharacteristic, + DidWriteValueForCharacteristic, + IsReadyToSendWriteWithoutResponse, + DidUpdateNotificationStateForCharacteristic, + DidReadRSSI, + DidUpdateName, + DidModifyServices + ); + } + + public void Unregister(SafeNativePeripheralHandle handle) + { + s_nativePeripheralDelegateMap.Remove(handle.DangerousGetHandle()); + } + + static INativePeripheralDelegate GetDelegate(IntPtr peripheralPtr) + { + return s_nativePeripheralDelegateMap.GetValueOrDefault(peripheralPtr); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidDiscoverServicesHandler))] + public static void DidDiscoverServices(IntPtr peripheralPtr, IntPtr commaSeparatedServiceUUIDsPtr, int errorCode) + { + string commaSeparatedServiceUUIDs = Marshal.PtrToStringUTF8(commaSeparatedServiceUUIDsPtr); + GetDelegate(peripheralPtr)?.DidDiscoverServices( + commaSeparatedServiceUUIDs.Split(','), + CBError.CreateOrNullFromCode(errorCode) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidDiscoverCharacteristicsHandler))] + public static void DidDiscoverCharacteristics(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr commaSeparatedCharacteristicUUIDsPtr, int errorCode) + { + string commaSeparatedCharacteristicUUIDs = Marshal.PtrToStringUTF8(commaSeparatedCharacteristicUUIDsPtr); + GetDelegate(peripheralPtr)?.DidDiscoverCharacteristics( + Marshal.PtrToStringUTF8(serviceUUIDPtr), + commaSeparatedCharacteristicUUIDs.Split(','), + CBError.CreateOrNullFromCode(errorCode) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidUpdateValueForCharacteristicHandler))] + public static void DidUpdateValueForCharacteristic(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, IntPtr dataPtr, int dataLength, int errorCode) + { + var dataBytes = new byte[dataLength]; + Marshal.Copy(dataPtr, dataBytes, 0, dataLength); + + GetDelegate(peripheralPtr)?.DidUpdateValueForCharacteristic( + Marshal.PtrToStringUTF8(serviceUUIDPtr), + Marshal.PtrToStringUTF8(characteristicUUIDPtr), + dataBytes, + CBError.CreateOrNullFromCode(errorCode) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidWriteValueForCharacteristicHandler))] + public static void DidWriteValueForCharacteristic(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, int errorCode) + { + GetDelegate(peripheralPtr)?.DidWriteValueForCharacteristic( + Marshal.PtrToStringUTF8(serviceUUIDPtr), + Marshal.PtrToStringUTF8(characteristicUUIDPtr), + CBError.CreateOrNullFromCode(errorCode) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralIsReadyToSendWriteWithoutResponseHandler))] + public static void IsReadyToSendWriteWithoutResponse(IntPtr peripheralPtr) + { + GetDelegate(peripheralPtr)?.IsReadyToSendWriteWithoutResponse(); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidUpdateNotificationStateForCharacteristicHandler))] + public static void DidUpdateNotificationStateForCharacteristic(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, int notificationState, int errorCode) + { + GetDelegate(peripheralPtr)?.DidUpdateNotificationStateForCharacteristic( + Marshal.PtrToStringUTF8(serviceUUIDPtr), + Marshal.PtrToStringUTF8(characteristicUUIDPtr), + notificationState == 1, + CBError.CreateOrNullFromCode(errorCode) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidReadRSSIHandler))] + public static void DidReadRSSI(IntPtr peripheralPtr, int rssi, int errorCode) + { + GetDelegate(peripheralPtr)?.DidReadRSSI( + rssi, + CBError.CreateOrNullFromCode(errorCode) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidUpdateNameHandler))] + public static void DidUpdateName(IntPtr peripheralPtr) + { + GetDelegate(peripheralPtr)?.DidUpdateName(); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidModifyServicesHandler))] + public static void DidModifyServices(IntPtr peripheralPtr, IntPtr commaSeparatedServiceUUIDsPtr) + { + string commaSeparatedServiceUUIDs = Marshal.PtrToStringUTF8(commaSeparatedServiceUUIDsPtr); + GetDelegate(peripheralPtr)?.DidModifyServices( + commaSeparatedServiceUUIDs.Split(',') + ); + } + } +} diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralCallbacks.cs.meta b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralCallbacks.cs.meta new file mode 100644 index 0000000..f05dcb9 --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20fa0ebfac1694eb187459a3fd262839 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralManagerCallbacks.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralManagerCallbacks.cs new file mode 100644 index 0000000..cd7daa4 --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralManagerCallbacks.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace CoreBluetooth +{ + internal class NativePeripheralManagerCallbacks : INativePeripheralManagerCallbacks + { + readonly static Dictionary s_peripheralManagerDelegateMap = new Dictionary(); + + public void Register(SafeNativePeripheralManagerHandle handle, INativePeripheralManagerDelegate peripheralManagerDelegate) + { + s_peripheralManagerDelegateMap[handle.DangerousGetHandle()] = peripheralManagerDelegate; + NativeMethods.cb4u_peripheral_manager_register_handlers( + handle, + DidUpdateState, + DidAddService, + DidStartAdvertising, + DidSubscribeToCharacteristic, + DidUnsubscribeFromCharacteristic, + IsReadyToUpdateSubscribers, + DidReceiveReadRequest, + DidReceiveWriteRequests + ); + } + + public void Unregister(SafeNativePeripheralManagerHandle handle) + { + s_peripheralManagerDelegateMap.Remove(handle.DangerousGetHandle()); + } + + static INativePeripheralManagerDelegate GetDelegate(IntPtr peripheralPtr) + { + return s_peripheralManagerDelegateMap.GetValueOrDefault(peripheralPtr); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidUpdateStateHandler))] + static void DidUpdateState(IntPtr peripheralPtr, CBManagerState state) + { + GetDelegate(peripheralPtr)?.DidUpdateState(state); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidAddServiceHandler))] + static void DidAddService(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, int errorCode) + { + GetDelegate(peripheralPtr)?.DidAddService( + Marshal.PtrToStringUTF8(serviceUUIDPtr), + CBError.CreateOrNullFromCode(errorCode) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidStartAdvertisingHandler))] + static void DidStartAdvertising(IntPtr peripheralPtr, int errorCode) + { + GetDelegate(peripheralPtr)?.DidStartAdvertising(CBError.CreateOrNullFromCode(errorCode)); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidSubscribeToCharacteristicHandler))] + static void DidSubscribeToCharacteristic(IntPtr peripheralPtr, IntPtr centralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr) + { + GetDelegate(peripheralPtr)?.DidSubscribeToCharacteristic( + new SafeNativeCentralHandle(centralPtr), + Marshal.PtrToStringUTF8(serviceUUIDPtr), + Marshal.PtrToStringUTF8(characteristicUUIDPtr) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidUnsubscribeFromCharacteristicHandler))] + static void DidUnsubscribeFromCharacteristic(IntPtr peripheralPtr, IntPtr centralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr) + { + GetDelegate(peripheralPtr)?.DidUnsubscribeFromCharacteristic( + new SafeNativeCentralHandle(centralPtr), + Marshal.PtrToStringUTF8(serviceUUIDPtr), + Marshal.PtrToStringUTF8(characteristicUUIDPtr) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerIsReadyToUpdateSubscribersHandler))] + static void IsReadyToUpdateSubscribers(IntPtr peripheralPtr) + { + GetDelegate(peripheralPtr)?.IsReadyToUpdateSubscribers(); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidReceiveReadRequestHandler))] + static void DidReceiveReadRequest(IntPtr peripheralPtr, IntPtr requestPtr) + { + GetDelegate(peripheralPtr)?.DidReceiveReadRequest( + new SafeNativeATTRequestHandle(requestPtr) + ); + } + + [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidReceiveWriteRequestsHandler))] + static void DidReceiveWriteRequests(IntPtr peripheralPtr, IntPtr requestsPtr) + { + GetDelegate(peripheralPtr)?.DidReceiveWriteRequests( + new SafeNativeATTRequestsHandle(requestsPtr) + ); + } + } +} diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralManagerCallbacks.cs.meta b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralManagerCallbacks.cs.meta new file mode 100644 index 0000000..8930f1e --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativePeripheralManagerCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e86702b2f853478cb8ab72e3e55c33a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCentralManagerProxy.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCentralManagerProxy.cs index c190c52..8fa03b7 100644 --- a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCentralManagerProxy.cs +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCentralManagerProxy.cs @@ -1,24 +1,27 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; namespace CoreBluetooth { - internal class NativeCentralManagerProxy : IDisposable + internal interface INativeCentralManagerCallbacks { - readonly static Dictionary s_centralManagerDelegateMap = new Dictionary(); + void Register(SafeNativeCentralManagerHandle centralPtr, INativeCentralManagerDelegate centralManagerDelegate); + void Unregister(SafeNativeCentralManagerHandle centralPtr); + } + internal class NativeCentralManagerProxy : IDisposable + { readonly SafeNativeCentralManagerHandle _handle; + readonly INativeCentralManagerCallbacks _callbacks; public NativeCentralManagerProxy(SafeNativeCentralManagerHandle handle, INativeCentralManagerDelegate centralManagerDelegate) { _handle = handle; + _callbacks = ServiceLocator.Instance.Resolve(); if (centralManagerDelegate != null) { - s_centralManagerDelegateMap[handle.DangerousGetHandle()] = centralManagerDelegate; + _callbacks.Register(handle, centralManagerDelegate); } - RegisterHandlers(); } public void Connect(CBPeripheral peripheral) @@ -62,65 +65,9 @@ public bool IsScanning() return NativeMethods.cb4u_central_manager_is_scanning(_handle); } - void RegisterHandlers() - { - NativeMethods.cb4u_central_manager_register_handlers( - _handle, - DidConnect, - DidDisconnectPeripheral, - DidFailToConnect, - DidDiscoverPeripheral, - DidUpdateState - ); - } - public void Dispose() { - s_centralManagerDelegateMap.Remove(_handle.DangerousGetHandle()); - } - - static INativeCentralManagerDelegate GetDelegate(IntPtr centralPtr) - { - return s_centralManagerDelegateMap.GetValueOrDefault(centralPtr); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidConnectHandler))] - internal static void DidConnect(IntPtr centralPtr, IntPtr peripheralIdPtr) - { - GetDelegate(centralPtr)?.DidConnect(Marshal.PtrToStringUTF8(peripheralIdPtr)); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidDisconnectPeripheralHandler))] - public static void DidDisconnectPeripheral(IntPtr centralPtr, IntPtr peripheralIdPtr, int errorCode) - { - GetDelegate(centralPtr)?.DidDisconnectPeripheral( - Marshal.PtrToStringUTF8(peripheralIdPtr), - CBError.CreateOrNullFromCode(errorCode) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidFailToConnectHandler))] - public static void DidFailToConnect(IntPtr centralPtr, IntPtr peripheralIdPtr, int errorCode) - { - GetDelegate(centralPtr)?.DidFailToConnect( - Marshal.PtrToStringUTF8(peripheralIdPtr), - CBError.CreateOrNullFromCode(errorCode) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidDiscoverPeripheralHandler))] - public static void DidDiscoverPeripheral(IntPtr centralPtr, IntPtr peripheralPtr, int rssi) - { - GetDelegate(centralPtr)?.DidDiscoverPeripheral( - new SafeNativePeripheralHandle(peripheralPtr), - rssi - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidUpdateStateHandler))] - public static void DidUpdateState(IntPtr centralPtr, CBManagerState state) - { - GetDelegate(centralPtr)?.DidUpdateState(state); + _callbacks.Unregister(_handle); } } } diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativePeripheralManagerProxy.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativePeripheralManagerProxy.cs index 0e5028b..90ef27e 100644 --- a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativePeripheralManagerProxy.cs +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativePeripheralManagerProxy.cs @@ -5,21 +5,25 @@ namespace CoreBluetooth { - internal class NativePeripheralManagerProxy : IDisposable + internal interface INativePeripheralManagerCallbacks { - static Dictionary s_peripheralManagerDelegateMap = new Dictionary(); + void Register(SafeNativePeripheralManagerHandle handle, INativePeripheralManagerDelegate peripheralManagerDelegate); + void Unregister(SafeNativePeripheralManagerHandle handle); + } + internal class NativePeripheralManagerProxy : IDisposable + { readonly SafeNativePeripheralManagerHandle _handle; + readonly INativePeripheralManagerCallbacks _callbacks; internal NativePeripheralManagerProxy(SafeNativePeripheralManagerHandle handle, INativePeripheralManagerDelegate peripheralManagerDelegate) { _handle = handle; - if (peripheralManagerDelegate != null) + _callbacks = ServiceLocator.Instance.Resolve(); + if (_callbacks != null) { - s_peripheralManagerDelegateMap[handle.DangerousGetHandle()] = peripheralManagerDelegate; + _callbacks.Register(handle, peripheralManagerDelegate); } - - RegisterHandlers(); } internal void AddService(SafeNativeMutableServiceHandle service) @@ -100,92 +104,9 @@ internal void RespondToRequest(CBATTRequest request, CBATTError result) NativeMethods.cb4u_peripheral_manager_respond_to_request(_handle, request.Handle, (int)result); } - void RegisterHandlers() - { - NativeMethods.cb4u_peripheral_manager_register_handlers( - _handle, - DidUpdateState, - DidAddService, - DidStartAdvertising, - DidSubscribeToCharacteristic, - DidUnsubscribeFromCharacteristic, - IsReadyToUpdateSubscribers, - DidReceiveReadRequest, - DidReceiveWriteRequests - ); - } - public void Dispose() { - s_peripheralManagerDelegateMap.Remove(_handle.DangerousGetHandle()); - } - - static INativePeripheralManagerDelegate GetDelegate(IntPtr peripheralPtr) - { - return s_peripheralManagerDelegateMap.GetValueOrDefault(peripheralPtr); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidUpdateStateHandler))] - public static void DidUpdateState(IntPtr peripheralPtr, CBManagerState state) - { - GetDelegate(peripheralPtr)?.DidUpdateState(state); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidAddServiceHandler))] - public static void DidAddService(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, int errorCode) - { - GetDelegate(peripheralPtr)?.DidAddService( - Marshal.PtrToStringUTF8(serviceUUIDPtr), - CBError.CreateOrNullFromCode(errorCode) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidStartAdvertisingHandler))] - public static void DidStartAdvertising(IntPtr peripheralPtr, int errorCode) - { - GetDelegate(peripheralPtr)?.DidStartAdvertising(CBError.CreateOrNullFromCode(errorCode)); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidSubscribeToCharacteristicHandler))] - public static void DidSubscribeToCharacteristic(IntPtr peripheralPtr, IntPtr centralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr) - { - GetDelegate(peripheralPtr)?.DidSubscribeToCharacteristic( - new SafeNativeCentralHandle(centralPtr), - Marshal.PtrToStringUTF8(serviceUUIDPtr), - Marshal.PtrToStringUTF8(characteristicUUIDPtr) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidUnsubscribeFromCharacteristicHandler))] - public static void DidUnsubscribeFromCharacteristic(IntPtr peripheralPtr, IntPtr centralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr) - { - GetDelegate(peripheralPtr)?.DidUnsubscribeFromCharacteristic( - new SafeNativeCentralHandle(centralPtr), - Marshal.PtrToStringUTF8(serviceUUIDPtr), - Marshal.PtrToStringUTF8(characteristicUUIDPtr) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerIsReadyToUpdateSubscribersHandler))] - public static void IsReadyToUpdateSubscribers(IntPtr peripheralPtr) - { - GetDelegate(peripheralPtr)?.IsReadyToUpdateSubscribers(); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidReceiveReadRequestHandler))] - public static void DidReceiveReadRequest(IntPtr peripheralPtr, IntPtr requestPtr) - { - GetDelegate(peripheralPtr)?.DidReceiveReadRequest( - new SafeNativeATTRequestHandle(requestPtr) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralManagerDidReceiveWriteRequestsHandler))] - public static void DidReceiveWriteRequests(IntPtr peripheralPtr, IntPtr requestsPtr) - { - GetDelegate(peripheralPtr)?.DidReceiveWriteRequests( - new SafeNativeATTRequestsHandle(requestsPtr) - ); + _callbacks?.Unregister(_handle); } } } diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativePeripheralProxy.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativePeripheralProxy.cs index 5dfabad..bb9a980 100644 --- a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativePeripheralProxy.cs +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativePeripheralProxy.cs @@ -5,20 +5,25 @@ namespace CoreBluetooth { - internal class NativePeripheralProxy : IDisposable + internal interface INativePeripheralCallbacks { - readonly static Dictionary s_nativePeripheralDelegateMap = new Dictionary(); + void Register(SafeNativePeripheralHandle handle, INativePeripheralDelegate peripheralDelegate); + void Unregister(SafeNativePeripheralHandle handle); + } + internal class NativePeripheralProxy : IDisposable + { readonly SafeNativePeripheralHandle _handle; + readonly INativePeripheralCallbacks _callbacks; public NativePeripheralProxy(SafeNativePeripheralHandle handle, INativePeripheralDelegate peripheralDelegate) { _handle = handle; + _callbacks = ServiceLocator.Instance.Resolve(); if (peripheralDelegate != null) { - s_nativePeripheralDelegateMap[handle.DangerousGetHandle()] = peripheralDelegate; + _callbacks.Register(handle, peripheralDelegate); } - RegisterHandlers(); } public string Identifier @@ -154,116 +159,9 @@ public void ReadRSSI() NativeMethods.cb4u_peripheral_read_rssi(_handle); } - void RegisterHandlers() - { - NativeMethods.cb4u_peripheral_register_handlers( - _handle, - DidDiscoverServices, - DidDiscoverCharacteristics, - DidUpdateValueForCharacteristic, - DidWriteValueForCharacteristic, - IsReadyToSendWriteWithoutResponse, - DidUpdateNotificationStateForCharacteristic, - DidReadRSSI, - DidUpdateName, - DidModifyServices - ); - } - public void Dispose() { - s_nativePeripheralDelegateMap.Remove(_handle.DangerousGetHandle()); - } - - static INativePeripheralDelegate GetDelegate(IntPtr peripheralPtr) - { - return s_nativePeripheralDelegateMap.GetValueOrDefault(peripheralPtr); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidDiscoverServicesHandler))] - public static void DidDiscoverServices(IntPtr peripheralPtr, IntPtr commaSeparatedServiceUUIDsPtr, int errorCode) - { - string commaSeparatedServiceUUIDs = Marshal.PtrToStringUTF8(commaSeparatedServiceUUIDsPtr); - GetDelegate(peripheralPtr)?.DidDiscoverServices( - commaSeparatedServiceUUIDs.Split(','), - CBError.CreateOrNullFromCode(errorCode) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidDiscoverCharacteristicsHandler))] - public static void DidDiscoverCharacteristics(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr commaSeparatedCharacteristicUUIDsPtr, int errorCode) - { - string commaSeparatedCharacteristicUUIDs = Marshal.PtrToStringUTF8(commaSeparatedCharacteristicUUIDsPtr); - GetDelegate(peripheralPtr)?.DidDiscoverCharacteristics( - Marshal.PtrToStringUTF8(serviceUUIDPtr), - commaSeparatedCharacteristicUUIDs.Split(','), - CBError.CreateOrNullFromCode(errorCode) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidUpdateValueForCharacteristicHandler))] - public static void DidUpdateValueForCharacteristic(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, IntPtr dataPtr, int dataLength, int errorCode) - { - var dataBytes = new byte[dataLength]; - Marshal.Copy(dataPtr, dataBytes, 0, dataLength); - - GetDelegate(peripheralPtr)?.DidUpdateValueForCharacteristic( - Marshal.PtrToStringUTF8(serviceUUIDPtr), - Marshal.PtrToStringUTF8(characteristicUUIDPtr), - dataBytes, - CBError.CreateOrNullFromCode(errorCode) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidWriteValueForCharacteristicHandler))] - public static void DidWriteValueForCharacteristic(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, int errorCode) - { - GetDelegate(peripheralPtr)?.DidWriteValueForCharacteristic( - Marshal.PtrToStringUTF8(serviceUUIDPtr), - Marshal.PtrToStringUTF8(characteristicUUIDPtr), - CBError.CreateOrNullFromCode(errorCode) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralIsReadyToSendWriteWithoutResponseHandler))] - public static void IsReadyToSendWriteWithoutResponse(IntPtr peripheralPtr) - { - GetDelegate(peripheralPtr)?.IsReadyToSendWriteWithoutResponse(); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidUpdateNotificationStateForCharacteristicHandler))] - public static void DidUpdateNotificationStateForCharacteristic(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, int notificationState, int errorCode) - { - GetDelegate(peripheralPtr)?.DidUpdateNotificationStateForCharacteristic( - Marshal.PtrToStringUTF8(serviceUUIDPtr), - Marshal.PtrToStringUTF8(characteristicUUIDPtr), - notificationState == 1, - CBError.CreateOrNullFromCode(errorCode) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidReadRSSIHandler))] - public static void DidReadRSSI(IntPtr peripheralPtr, int rssi, int errorCode) - { - GetDelegate(peripheralPtr)?.DidReadRSSI( - rssi, - CBError.CreateOrNullFromCode(errorCode) - ); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidUpdateNameHandler))] - public static void DidUpdateName(IntPtr peripheralPtr) - { - GetDelegate(peripheralPtr)?.DidUpdateName(); - } - - [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidModifyServicesHandler))] - public static void DidModifyServices(IntPtr peripheralPtr, IntPtr commaSeparatedServiceUUIDsPtr) - { - string commaSeparatedServiceUUIDs = Marshal.PtrToStringUTF8(commaSeparatedServiceUUIDsPtr); - GetDelegate(peripheralPtr)?.DidModifyServices( - commaSeparatedServiceUUIDs.Split(',') - ); + _callbacks.Unregister(_handle); } } } diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/ServiceLocator.cs b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/ServiceLocator.cs new file mode 100644 index 0000000..c4d1fcb --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/ServiceLocator.cs @@ -0,0 +1,33 @@ + +using System; +using System.Collections.Generic; + +namespace CoreBluetooth +{ + internal class ServiceLocator + { + public static ServiceLocator Instance { get; private set; } = new ServiceLocator(); + readonly Dictionary container = new Dictionary(); + + public void Register(T obj) where T : class + { + container[typeof(T)] = obj; + } + + public bool Unregister() where T : class + { + return container.Remove(typeof(T)); + } + + public T Resolve() where T : class + { + Type targetType = typeof(T); + if (container.TryGetValue(targetType, out object obj)) + { + return obj as T; + } + + return null; + } + } +} diff --git a/Packages/com.teach310.core-bluetooth-for-unity/Runtime/ServiceLocator.cs.meta b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/ServiceLocator.cs.meta new file mode 100644 index 0000000..9dfc90e --- /dev/null +++ b/Packages/com.teach310.core-bluetooth-for-unity/Runtime/ServiceLocator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0bf5f61d29ee5492b88ed01b09a105b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: