@@ -31,7 +31,7 @@ use objc2_core_bluetooth::{
3131 CBCharacteristicProperties , CBCharacteristicWriteType , CBDescriptor , CBManager ,
3232 CBManagerAuthorization , CBManagerState , CBPeripheral , CBPeripheralState , CBService , CBUUID ,
3333} ;
34- use objc2_foundation:: { NSArray , NSData , NSMutableDictionary , NSNumber } ;
34+ use objc2_foundation:: { NSArray , NSData , NSMutableDictionary , NSNumber , NSProcessInfo } ;
3535use std:: {
3636 collections:: { BTreeSet , HashMap , VecDeque } ,
3737 ffi:: CString ,
@@ -362,6 +362,12 @@ impl PeripheralInternal {
362362 }
363363}
364364
365+ /// Optional CoreBluetooth API capabilities that are available depending on the macOS version.
366+ struct CoreBluetoothFeatures {
367+ /// `peripheral.canSendWriteWithoutResponse` property is available (since macOS 11.2.0)
368+ can_send_write_without_response : bool ,
369+ }
370+
365371// All of CoreBluetooth is basically async. It's all just waiting on delegate
366372// events/callbacks. Therefore, we should be able to round up all of our wacky
367373// ass mut *Object values, keep them in a single struct, in a single thread, and
@@ -376,6 +382,7 @@ struct CoreBluetoothInternal {
376382 // task::block this when sending even though it'll never actually block.
377383 event_sender : Sender < CoreBluetoothEvent > ,
378384 message_receiver : Fuse < Receiver < CoreBluetoothMessage > > ,
385+ features : CoreBluetoothFeatures ,
379386}
380387
381388impl Debug for CoreBluetoothInternal {
@@ -474,6 +481,16 @@ pub enum CoreBluetoothEvent {
474481 } ,
475482}
476483
484+ fn get_features ( ) -> CoreBluetoothFeatures {
485+ let process_info = NSProcessInfo :: processInfo ( ) ;
486+ let version = process_info. operatingSystemVersion ( ) ;
487+ let current = ( version. majorVersion , version. minorVersion ) ;
488+
489+ CoreBluetoothFeatures {
490+ can_send_write_without_response : current >= ( 11 , 2 ) ,
491+ }
492+ }
493+
477494impl CoreBluetoothInternal {
478495 pub fn new (
479496 message_receiver : Receiver < CoreBluetoothMessage > ,
@@ -499,6 +516,7 @@ impl CoreBluetoothInternal {
499516 event_sender,
500517 message_receiver : message_receiver. fuse ( ) ,
501518 delegate,
519+ features : get_features ( ) ,
502520 }
503521 }
504522
@@ -888,7 +906,9 @@ impl CoreBluetoothInternal {
888906 {
889907 trace ! ( "Writing value! With kind {:?}" , kind) ;
890908 unsafe {
891- if kind == WriteType :: WithoutResponse {
909+ if kind == WriteType :: WithoutResponse
910+ && self . features . can_send_write_without_response
911+ {
892912 // probably better idea would be to wait for the result of peripheral.peripheralIsReadyToSendWriteWithoutResponse
893913 let mut attempts = 0 ;
894914 while !peripheral. peripheral . canSendWriteWithoutResponse ( )
0 commit comments