Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Assets/CoreBluetooth/Samples/12_Debug/SampleDebug_Central.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ public void DidWriteValueForCharacteristic(CBPeripheral peripheral, CBCharacteri
}
}

public void IsReadyToSendWriteWithoutResponse(CBPeripheral peripheral)
{
Debug.Log($"[IsReadyToSendWriteWithoutResponse] {peripheral}");
}

public void DidUpdateNotificationStateForCharacteristic(CBPeripheral peripheral, CBCharacteristic characteristic, CBError error)
{
Debug.Log($"[DidUpdateNotificationStateForCharacteristic] characteristic: {characteristic}");
Expand All @@ -149,9 +154,14 @@ public void OnClickWrite()
return;
}

if (!_peripheral.CanSendWriteWithoutResponse)
{
Debug.Log("CanSendWriteWithoutResponse is false.");
return;
}
var value = UnityEngine.Random.Range(100, 1000).ToString();
var data = Encoding.UTF8.GetBytes(value);
_peripheral.WriteValue(data, _remoteCharacteristic, CBCharacteristicWriteType.WithResponse);
_peripheral.WriteValue(data, _remoteCharacteristic, CBCharacteristicWriteType.WithoutResponse);
}

public void OnClickRead()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void DidUpdateState(CBPeripheralManager peripheral)
var service = new CBMutableService(_serviceUUID, true);
_characteristic = new CBMutableCharacteristic(
_characteristicUUID,
CBCharacteristicProperties.Read | CBCharacteristicProperties.Write | CBCharacteristicProperties.Notify,
CBCharacteristicProperties.Read | CBCharacteristicProperties.WriteWithoutResponse | CBCharacteristicProperties.Notify,
null,
CBAttributePermissions.Readable | CBAttributePermissions.Writeable
);
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ void DidDiscoverServices(CBPeripheral peripheral, CBError error) { }
void DidDiscoverCharacteristics(CBPeripheral peripheral, CBService service, CBError error) { }
void DidUpdateValueForCharacteristic(CBPeripheral peripheral, CBCharacteristic characteristic, CBError error) { }
void DidWriteValueForCharacteristic(CBPeripheral peripheral, CBCharacteristic characteristic, CBError error) { }
void IsReadyToSendWriteWithoutResponse(CBPeripheral peripheral) { }
void DidUpdateNotificationStateForCharacteristic(CBPeripheral peripheral, CBCharacteristic characteristic, CBError error) { }
}

Expand Down Expand Up @@ -71,27 +72,44 @@ internal CBPeripheral(SafeNativePeripheralHandle nativePeripheral)
/// Discovers the specified services of the peripheral.
/// If the servicesUUIDs parameter is nil, this method returns all of the peripheral’s available services. This is much slower than providing an array of service UUIDs to search for.
/// </summary>
public void DiscoverServices(string[] serviceUUIDs = null) => _nativePeripheral.DiscoverServices(serviceUUIDs);
public void DiscoverServices(string[] serviceUUIDs = null)
{
ExceptionUtils.ThrowObjectDisposedExceptionIf(_disposed, this);
_nativePeripheral.DiscoverServices(serviceUUIDs);
}

/// <summary>
/// Discovers the specified characteristics of a service.
/// </summary>
public void DiscoverCharacteristics(string[] characteristicUUIDs, CBService service) => _nativePeripheral.DiscoverCharacteristics(characteristicUUIDs, service);
public void DiscoverCharacteristics(string[] characteristicUUIDs, CBService service)
{
ExceptionUtils.ThrowObjectDisposedExceptionIf(_disposed, this);
_nativePeripheral.DiscoverCharacteristics(characteristicUUIDs, service);
}

/// <summary>
/// Discover all characteristics in a service (slow).
/// </summary>
public void DiscoverCharacteristics(CBService service) => DiscoverCharacteristics(null, service);
public void DiscoverCharacteristics(CBService service)
{
ExceptionUtils.ThrowObjectDisposedExceptionIf(_disposed, this);
DiscoverCharacteristics(null, service);
}

/// <summary>
/// Retrieves the value of a specified characteristic.
/// When you call this method to read the value of a characteristic, the peripheral calls the peripheral(_:didUpdateValueFor:error:) method of its delegate object.
/// If the peripheral successfully reads the value of the characteristic, you can access it through the characteristic’s value property.
/// </summary>
public void ReadValue(CBCharacteristic characteristic) => _nativePeripheral.ReadValue(characteristic);
public void ReadValue(CBCharacteristic characteristic)
{
ExceptionUtils.ThrowObjectDisposedExceptionIf(_disposed, this);
_nativePeripheral.ReadValue(characteristic);
}

public void WriteValue(byte[] data, CBCharacteristic characteristic, CBCharacteristicWriteType type)
{
ExceptionUtils.ThrowObjectDisposedExceptionIf(_disposed, this);
_nativePeripheral.WriteValue(data, characteristic, type);
}

Expand All @@ -100,6 +118,7 @@ public void WriteValue(byte[] data, CBCharacteristic characteristic, CBCharacter
/// </summary>
public int GetMaximumWriteValueLength(CBCharacteristicWriteType type)
{
ExceptionUtils.ThrowObjectDisposedExceptionIf(_disposed, this);
return _nativePeripheral.GetMaximumWriteValueLength(type);
}

Expand All @@ -108,6 +127,7 @@ public int GetMaximumWriteValueLength(CBCharacteristicWriteType type)
/// </summary>
public void SetNotifyValue(bool enabled, CBCharacteristic characteristic)
{
ExceptionUtils.ThrowObjectDisposedExceptionIf(_disposed, this);
_nativePeripheral.SetNotifyValue(enabled, characteristic);
}

Expand All @@ -123,6 +143,15 @@ public CBPeripheralState State
}
}

public bool CanSendWriteWithoutResponse
{
get
{
ExceptionUtils.ThrowObjectDisposedExceptionIf(_disposed, this);
return _nativePeripheral.CanSendWriteWithoutResponse;
}
}

internal CBCharacteristic FindCharacteristic(string serviceUUID, string characteristicUUID)
{
if (string.IsNullOrEmpty(serviceUUID))
Expand Down Expand Up @@ -187,6 +216,12 @@ void INativePeripheralDelegate.DidWriteValueForCharacteristic(string serviceUUID
Delegate?.DidWriteValueForCharacteristic(this, characteristic, error);
}

void INativePeripheralDelegate.IsReadyToSendWriteWithoutResponse()
{
if (_disposed) return;
Delegate?.IsReadyToSendWriteWithoutResponse(this);
}

void INativePeripheralDelegate.DidUpdateNotificationStateForCharacteristic(string serviceUUID, string characteristicUUID, bool isNotifying, CBError error)
{
if (_disposed) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ int serviceUUIDsCount
internal delegate void CB4UPeripheralDidDiscoverCharacteristicsHandler(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr commaSeparatedCharacteristicUUIDsPtr, int errorCode);
internal delegate void CB4UPeripheralDidUpdateValueForCharacteristicHandler(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, IntPtr dataPtr, int dataLength, int errorCode);
internal delegate void CB4UPeripheralDidWriteValueForCharacteristicHandler(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, int errorCode);
internal delegate void CB4UPeripheralIsReadyToSendWriteWithoutResponseHandler(IntPtr peripheralPtr);
internal delegate void CB4UPeripheralDidUpdateNotificationStateForCharacteristicHandler(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, int notificationState, int errorCode);

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
Expand All @@ -83,6 +84,7 @@ internal static extern void cb4u_peripheral_register_handlers(
CB4UPeripheralDidDiscoverCharacteristicsHandler didDiscoverCharacteristicsHandler,
CB4UPeripheralDidUpdateValueForCharacteristicHandler didUpdateValueForCharacteristicHandler,
CB4UPeripheralDidWriteValueForCharacteristicHandler didWriteValueForCharacteristicHandler,
CB4UPeripheralIsReadyToSendWriteWithoutResponseHandler isReadyToSendWriteWithoutResponseHandler,
CB4UPeripheralDidUpdateNotificationStateForCharacteristicHandler didUpdateNotificationStateForCharacteristicHandler
);

Expand Down Expand Up @@ -146,6 +148,10 @@ internal static extern int cb4u_peripheral_set_notify_value(
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
internal static extern int cb4u_peripheral_state(SafeNativePeripheralHandle handle);

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
internal static extern bool cb4u_peripheral_can_send_write_without_response(SafeNativePeripheralHandle handle);

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
internal static extern int cb4u_peripheral_characteristic_properties(
SafeNativePeripheralHandle handle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,13 @@ internal CBPeripheralState State
return (CBPeripheralState)state;
}
}

internal bool CanSendWriteWithoutResponse
{
get
{
return NativeMethods.cb4u_peripheral_can_send_write_without_response(_handle);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ void DidDiscoverServices(string[] serviceUUIDs, CBError error) { }
void DidDiscoverCharacteristics(string serviceUUID, string[] characteristicUUIDs, CBError error) { }
void DidUpdateValueForCharacteristic(string serviceUUID, string characteristicUUID, byte[] data, CBError error) { }
void DidWriteValueForCharacteristic(string serviceUUID, string characteristicUUID, CBError error) { }
void IsReadyToSendWriteWithoutResponse() { }
void DidUpdateNotificationStateForCharacteristic(string serviceUUID, string characteristicUUID, bool enabled, CBError error) { }
}

Expand All @@ -32,6 +33,7 @@ void RegisterHandlers()
DidDiscoverCharacteristics,
DidUpdateValueForCharacteristic,
DidWriteValueForCharacteristic,
IsReadyToSendWriteWithoutResponse,
DidUpdateNotificationStateForCharacteristic
);
}
Expand Down Expand Up @@ -112,6 +114,12 @@ internal static void DidWriteValueForCharacteristic(IntPtr peripheralPtr, IntPtr
);
}

[AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralIsReadyToSendWriteWithoutResponseHandler))]
internal static void IsReadyToSendWriteWithoutResponse(IntPtr peripheralPtr)
{
GetDelegate(peripheralPtr)?.IsReadyToSendWriteWithoutResponse();
}

[AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UPeripheralDidUpdateNotificationStateForCharacteristicHandler))]
internal static void DidUpdateNotificationStateForCharacteristic(IntPtr peripheralPtr, IntPtr serviceUUIDPtr, IntPtr characteristicUUIDPtr, int notificationState, int errorCode)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class CB4UPeripheral : NSObject {
public var didDiscoverCharacteristicsHandler: CB4UPeripheralDidDiscoverCharacteristicsHandler?
public var didUpdateValueForCharacteristicHandler: CB4UPeripheralDidUpdateValueForCharacteristicHandler?
public var didWriteValueForCharacteristicHandler: CB4UPeripheralDidWriteValueForCharacteristicHandler?
public var isReadyToSendWriteWithoutResponseHandler: CB4UPeripheralIsReadyToSendWriteWithoutResponseHandler?
public var didUpdateNotificationStateForCharacteristicHandler: CB4UPeripheralDidUpdateNotificationStateForCharacteristicHandler?

let success: Int32 = 0
Expand Down Expand Up @@ -93,6 +94,10 @@ public class CB4UPeripheral : NSObject {
public var state: CBPeripheralState {
return peripheral.state
}

public var canSendWriteWithoutResponse: Bool {
return peripheral.canSendWriteWithoutResponse
}
}

extension CB4UPeripheral : CBPeripheralDelegate {
Expand Down Expand Up @@ -144,6 +149,10 @@ extension CB4UPeripheral : CBPeripheralDelegate {
}
}

public func peripheralIsReady(toSendWriteWithoutResponse peripheral: CBPeripheral) {
isReadyToSendWriteWithoutResponseHandler?(selfPointer())
}

public func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
let serviceId = characteristic.service?.uuid.uuidString ?? ""
let characteristicId = characteristic.uuid.uuidString
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ public typealias CB4UPeripheralDidDiscoverServicesHandler = @convention(c) (Unsa
public typealias CB4UPeripheralDidDiscoverCharacteristicsHandler = @convention(c) (UnsafeRawPointer, UnsafePointer<CChar>, UnsafePointer<CChar>, Int32) -> Void
public typealias CB4UPeripheralDidUpdateValueForCharacteristicHandler = @convention(c) (UnsafeRawPointer, UnsafePointer<CChar>, UnsafePointer<CChar>, UnsafePointer<UInt8>, Int32, Int32) -> Void
public typealias CB4UPeripheralDidWriteValueForCharacteristicHandler = @convention(c) (UnsafeRawPointer, UnsafePointer<CChar>, UnsafePointer<CChar>, Int32) -> Void
public typealias CB4UPeripheralIsReadyToSendWriteWithoutResponseHandler = @convention(c) (UnsafeRawPointer) -> Void
public typealias CB4UPeripheralDidUpdateNotificationStateForCharacteristicHandler = @convention(c) (UnsafeRawPointer, UnsafePointer<CChar>, UnsafePointer<CChar>, Int32, Int32) -> Void

@_cdecl("cb4u_peripheral_register_handlers")
Expand All @@ -125,6 +126,7 @@ public func cb4u_peripheral_register_handlers(
_ didDiscoverCharacteristicsHandler: @escaping CB4UPeripheralDidDiscoverCharacteristicsHandler,
_ didUpdateValueForCharacteristicHandler: @escaping CB4UPeripheralDidUpdateValueForCharacteristicHandler,
_ didWriteValueForCharacteristicHandler: @escaping CB4UPeripheralDidWriteValueForCharacteristicHandler,
_ isReadyToSendWriteWithoutResponseHandler: @escaping CB4UPeripheralIsReadyToSendWriteWithoutResponseHandler,
_ didUpdateNotificationStateForCharacteristicHandler: @escaping CB4UPeripheralDidUpdateNotificationStateForCharacteristicHandler
) {
let instance = Unmanaged<CB4UPeripheral>.fromOpaque(peripheralPtr).takeUnretainedValue()
Expand All @@ -133,6 +135,7 @@ public func cb4u_peripheral_register_handlers(
instance.didDiscoverCharacteristicsHandler = didDiscoverCharacteristicsHandler
instance.didUpdateValueForCharacteristicHandler = didUpdateValueForCharacteristicHandler
instance.didWriteValueForCharacteristicHandler = didWriteValueForCharacteristicHandler
instance.isReadyToSendWriteWithoutResponseHandler = isReadyToSendWriteWithoutResponseHandler
instance.didUpdateNotificationStateForCharacteristicHandler = didUpdateNotificationStateForCharacteristicHandler
}

Expand Down Expand Up @@ -258,6 +261,13 @@ public func cb4u_peripheral_state(_ peripheralPtr: UnsafeRawPointer) -> Int32 {
return Int32(instance.state.rawValue)
}

@_cdecl("cb4u_peripheral_can_send_write_without_response")
public func cb4u_peripheral_can_send_write_without_response(_ peripheralPtr: UnsafeRawPointer) -> Bool {
let instance = Unmanaged<CB4UPeripheral>.fromOpaque(peripheralPtr).takeUnretainedValue()

return instance.canSendWriteWithoutResponse
}

@_cdecl("cb4u_peripheral_characteristic_properties")
public func cb4u_peripheral_characteristic_properties(
_ peripheralPtr: UnsafeRawPointer,
Expand Down