Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(corebluetooth): Use objc2 and its framework crates #381

Merged
merged 5 commits into from
May 14, 2024
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
18 changes: 14 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,20 @@ jni = "0.19.0"
once_cell = "1.19.0"
jni-utils = "0.1.1"

[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies]
cocoa = "0.25.0"
objc = "0.2.7"
libc = "0.2.151"
[target.'cfg(target_vendor = "apple")'.dependencies]
objc2 = "0.5.1"
objc2-foundation = { version = "0.2.0", features = [
"block2",
"NSArray",
"NSData",
"NSDictionary",
"NSEnumerator",
"NSError",
"NSObject",
"NSString",
"NSUUID",
"NSValue",
] }

[target.'cfg(target_os = "windows")'.dependencies]
windows = { version = "0.52.0", features = ["Devices_Bluetooth", "Devices_Bluetooth_GenericAttributeProfile", "Devices_Bluetooth_Advertisement", "Devices_Radios", "Foundation_Collections", "Foundation", "Storage_Streams"] }
Expand Down
261 changes: 121 additions & 140 deletions src/corebluetooth/central_delegate.rs

Large diffs are not rendered by default.

191 changes: 61 additions & 130 deletions src/corebluetooth/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,98 +16,17 @@
// This file may not be copied, modified, or distributed except
// according to those terms.

use cocoa::{
base::{id, nil},
foundation::{NSArray, NSData, NSDictionary, NSString, NSUInteger},
};
use objc::runtime::BOOL;
use objc::{class, msg_send, sel, sel_impl};
use std::os::raw::{c_char, c_int, c_uint};

pub mod ns {
use super::*;

// NSNumber

pub fn number_withbool(value: BOOL) -> id {
unsafe { msg_send![class!(NSNumber), numberWithBool: value] }
}

pub fn number_as_i64(value: id) -> i64 {
unsafe {
let i: cocoa::foundation::NSInteger = msg_send![&*value, integerValue];
i as i64
}
}

// NSArray

pub fn array_count(nsarray: impl NSArray) -> NSUInteger {
unsafe { nsarray.count() }
}

pub fn array_objectatindex(nsarray: impl NSArray, index: NSUInteger) -> id {
unsafe { nsarray.objectAtIndex(index) }
}

// NSDictionary

pub fn dictionary_allkeys(nsdict: impl NSDictionary) -> id /* NSArray* */ {
unsafe { nsdict.allKeys() }
}

pub fn dictionary_objectforkey(nsdict: impl NSDictionary, key: id) -> id {
unsafe { nsdict.objectForKey_(key) }
}

// NSMutableDictionary : NSDictionary

pub fn mutabledictionary() -> id {
unsafe { msg_send![class!(NSMutableDictionary), dictionaryWithCapacity:0] }
}

pub fn mutabledictionary_setobject_forkey(nsmutdict: id, object: id, key: id) {
unsafe { msg_send![nsmutdict, setObject:object forKey:key] }
}

// NSData

pub fn data(bytes: &[u8]) -> id /* NSData* */ {
unsafe {
msg_send![class!(NSData), dataWithBytes:bytes.as_ptr() length:bytes.len() as NSUInteger]
}
}

pub fn data_length(nsdata: impl NSData) -> NSUInteger {
unsafe { nsdata.length() }
}

pub fn data_bytes(nsdata: id) -> *const u8 {
unsafe { msg_send![nsdata, bytes] }
}

// NSUUID

pub fn uuid_uuidstring(nsuuid: id) -> id /* NSString* */ {
unsafe {
let uuidstring: id = msg_send![nsuuid, UUIDString];
uuidstring
}
}

// NSError

pub fn error_localizeddescription(nserror: id) -> id /* NSString* */ {
unsafe {
let description: id = msg_send![nserror, localizedDescription];
description
}
}
}
use super::utils::{id, nil};
use objc2::encode::{Encode, Encoding};
use objc2::rc::Id;
use objc2::runtime::AnyObject;
use objc2::{class, msg_send, msg_send_id};
use objc2_foundation::{NSArray, NSData, NSDictionary, NSString, NSUInteger, NSUUID};
use std::ffi::CString;
use std::os::raw::c_char;

pub mod cb {
use super::*;
use std::ffi::CString;

#[allow(non_camel_case_types)]
pub enum dispatch_object_s {}
Expand All @@ -118,7 +37,6 @@ pub mod cb {
pub const DISPATCH_QUEUE_SERIAL: dispatch_queue_attr_t = 0 as dispatch_queue_attr_t;

#[cfg_attr(target_os = "macos", link(name = "AppKit", kind = "framework"))]
#[link(name = "Foundation", kind = "framework")]
#[link(name = "CoreBluetooth", kind = "framework")]
extern "C" {
pub fn dispatch_queue_create(
Expand All @@ -132,11 +50,11 @@ pub mod cb {

#[link(name = "CoreBluetooth", kind = "framework")]
extern "C" {
pub static CBAdvertisementDataManufacturerDataKey: id;
pub static CBAdvertisementDataServiceDataKey: id;
pub static CBAdvertisementDataServiceUUIDsKey: id;
pub static CBAdvertisementDataManufacturerDataKey: &'static NSString;
pub static CBAdvertisementDataServiceDataKey: &'static NSString;
pub static CBAdvertisementDataServiceUUIDsKey: &'static NSString;

pub static CBCentralManagerScanOptionAllowDuplicatesKey: id;
pub static CBCentralManagerScanOptionAllowDuplicatesKey: &'static NSString;
}
}

Expand All @@ -148,6 +66,7 @@ pub mod cb {
unsafe {
let cbcentralmanager: id = msg_send![class!(CBCentralManager), alloc];
let queue = dispatch_queue_create(label.as_ptr(), DISPATCH_QUEUE_SERIAL);
let queue: id = queue.cast();

msg_send![cbcentralmanager, initWithDelegate:delegate queue:queue]
}
Expand All @@ -156,7 +75,7 @@ pub mod cb {
pub fn centralmanager_scanforperipheralswithservices_options(
cbcentralmanager: id,
service_uuids: id, /* NSArray<CBUUID *> */
options: id, /* NSDictionary<NSString*,id> */
options: &NSDictionary<NSString, AnyObject>,
) {
unsafe {
msg_send![cbcentralmanager, scanForPeripheralsWithServices:service_uuids options:options]
Expand Down Expand Up @@ -195,16 +114,20 @@ pub mod cb {
AllowedAlways = 3,
}

unsafe impl Encode for CBManagerAuthorization {
const ENCODING: Encoding = i64::ENCODING;
}

// CBPeer

pub fn peer_identifier(cbpeer: id) -> id /* NSUUID* */ {
unsafe { msg_send![cbpeer, identifier] }
pub fn peer_identifier(cbpeer: id) -> Id<NSUUID> {
unsafe { msg_send_id![cbpeer, identifier] }
}

// CBPeripheral : CBPeer

pub fn peripheral_name(cbperipheral: id) -> id /* NSString* */ {
unsafe { msg_send![cbperipheral, name] }
pub fn peripheral_name(cbperipheral: id) -> Option<Id<NSString>> {
unsafe { msg_send_id![cbperipheral, name] }
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Expand All @@ -216,6 +139,10 @@ pub mod cb {
Disconnecting = 3,
}

unsafe impl Encode for CBPeripheralState {
const ENCODING: Encoding = i64::ENCODING;
}

pub fn peripheral_state(cbperipheral: id) -> CBPeripheralState {
unsafe { msg_send![cbperipheral, state] }
}
Expand All @@ -230,18 +157,19 @@ pub mod cb {

pub fn peripheral_discoverincludedservicesforservice(
cbperipheral: id,
service: id, /* CBService* */
service: &AnyObject, /* CBService* */
) {
unsafe { msg_send![cbperipheral, discoverIncludedServices:nil forService:service] }
}

pub fn peripheral_services(cbperipheral: id) -> id /* NSArray<CBService*>* */ {
unsafe { msg_send![cbperipheral, services] }
pub fn peripheral_services(cbperipheral: id) -> Option<Id<NSArray<AnyObject>>> /* NSArray<CBService*>* */
{
unsafe { msg_send_id![cbperipheral, services] }
}

pub fn peripheral_discovercharacteristicsforservice(
cbperipheral: id,
service: id, /* CBService* */
service: &AnyObject, /* CBService* */
) {
unsafe { msg_send![cbperipheral, discoverCharacteristics:nil forService:service] }
}
Expand All @@ -255,7 +183,7 @@ pub mod cb {

pub fn peripheral_writevalue_forcharacteristic(
cbperipheral: id,
value: id, /* NSData* */
value: &NSData,
characteristic: id, /* CBCharacteristic* */
write_type: usize,
) {
Expand All @@ -267,15 +195,15 @@ pub mod cb {

pub fn peripheral_setnotifyvalue_forcharacteristic(
cbperipheral: id,
value: BOOL,
value: bool,
characteristic: id, /* CBCharacteristic* */
) {
unsafe { msg_send![cbperipheral, setNotifyValue:value forCharacteristic:characteristic] }
}

pub fn peripheral_discoverdescriptorsforcharacteristic(
cbperipheral: id,
characteristic: id, /* CBCharacteristic* */
characteristic: &AnyObject, /* CBCharacteristic* */
) {
unsafe {
msg_send![
Expand All @@ -294,15 +222,15 @@ pub mod cb {

pub fn peripheral_writevalue_fordescriptor(
cbperipheral: id,
value: id, /* NSData* */
value: &NSData,
descriptor: id, /* CBCharacteristic* */
) {
unsafe { msg_send![cbperipheral, writeValue:value forDescriptor:descriptor] }
}

// CBPeripheralState = NSInteger from CBPeripheral.h

pub const PERIPHERALSTATE_CONNECTED: c_int = 2; // CBPeripheralStateConnected
pub const PERIPHERALSTATE_CONNECTED: isize = 2; // CBPeripheralStateConnected

// CBAttribute

Expand All @@ -312,38 +240,41 @@ pub mod cb {

// CBService : CBAttribute

pub fn service_isprimary(cbservice: id) -> BOOL {
pub fn service_isprimary(cbservice: id) -> bool {
unsafe { msg_send![cbservice, isPrimary] }
}

pub fn service_includedservices(cbservice: id) -> id /* NSArray<CBService*>* */ {
unsafe { msg_send![cbservice, includedServices] }
pub fn service_includedservices(cbservice: id) -> Option<Id<NSArray<AnyObject>>> /* NSArray<CBService*>* */
{
unsafe { msg_send_id![cbservice, includedServices] }
}

pub fn service_characteristics(cbservice: id) -> id /* NSArray<CBCharacteristic*>* */ {
unsafe { msg_send![cbservice, characteristics] }
pub fn service_characteristics(cbservice: id) -> Option<Id<NSArray<AnyObject>>> /* NSArray<CBCharacteristic*>* */
{
unsafe { msg_send_id![cbservice, characteristics] }
}

// CBCharacteristic : CBAttribute

pub fn characteristic_isnotifying(cbcharacteristic: id) -> BOOL {
pub fn characteristic_isnotifying(cbcharacteristic: id) -> bool {
unsafe { msg_send![cbcharacteristic, isNotifying] }
}

pub fn characteristic_value(cbcharacteristic: id) -> id /* NSData* */ {
unsafe { msg_send![cbcharacteristic, value] }
pub fn characteristic_value(cbcharacteristic: id) -> Option<Id<NSData>> {
unsafe { msg_send_id![cbcharacteristic, value] }
}

pub fn characteristic_properties(cbcharacteristic: id) -> c_uint {
pub fn characteristic_properties(cbcharacteristic: id) -> NSUInteger {
unsafe { msg_send![cbcharacteristic, properties] }
}

pub fn characteristic_service(cbcharacteristic: id) -> id /* CBService* */ {
unsafe { msg_send![cbcharacteristic, service] }
}

pub fn characteristic_descriptors(cbcharacteristic: id) -> id /* NSArray<CBDescriptor*>* */ {
unsafe { msg_send![cbcharacteristic, descriptors] }
pub fn characteristic_descriptors(cbcharacteristic: id) -> Option<Id<NSArray<AnyObject>>> /* NSArray<CBDescriptor*>* */
{
unsafe { msg_send_id![cbcharacteristic, descriptors] }
}

// CBDescriptor : CBAttribute
Expand All @@ -354,22 +285,22 @@ pub mod cb {

// CBCharacteristicProperties = NSUInteger from CBCharacteristic.h

pub const CHARACTERISTICPROPERTY_BROADCAST: c_uint = 0x01; // CBCharacteristicPropertyBroadcast
pub const CHARACTERISTICPROPERTY_READ: c_uint = 0x02; // CBCharacteristicPropertyRead
pub const CHARACTERISTICPROPERTY_WRITEWITHOUTRESPONSE: c_uint = 0x04; // CBCharacteristicPropertyWriteWithoutResponse
pub const CHARACTERISTICPROPERTY_WRITE: c_uint = 0x08; // CBCharacteristicPropertyWrite
pub const CHARACTERISTICPROPERTY_NOTIFY: c_uint = 0x10; // CBCharacteristicPropertyNotify
pub const CHARACTERISTICPROPERTY_INDICATE: c_uint = 0x20; // CBCharacteristicPropertyIndicate
pub const CHARACTERISTICPROPERTY_AUTHENTICATEDSIGNEDWRITES: c_uint = 0x40; // CBCharacteristicPropertyAuthenticatedSignedWrites
pub const CHARACTERISTICPROPERTY_BROADCAST: usize = 0x01; // CBCharacteristicPropertyBroadcast
pub const CHARACTERISTICPROPERTY_READ: usize = 0x02; // CBCharacteristicPropertyRead
pub const CHARACTERISTICPROPERTY_WRITEWITHOUTRESPONSE: usize = 0x04; // CBCharacteristicPropertyWriteWithoutResponse
pub const CHARACTERISTICPROPERTY_WRITE: usize = 0x08; // CBCharacteristicPropertyWrite
pub const CHARACTERISTICPROPERTY_NOTIFY: usize = 0x10; // CBCharacteristicPropertyNotify
pub const CHARACTERISTICPROPERTY_INDICATE: usize = 0x20; // CBCharacteristicPropertyIndicate
pub const CHARACTERISTICPROPERTY_AUTHENTICATEDSIGNEDWRITES: usize = 0x40; // CBCharacteristicPropertyAuthenticatedSignedWrites

// CBUUID

pub fn uuid_uuidstring(cbuuid: id) -> id /* NSString* */ {
unsafe { msg_send![cbuuid, UUIDString] }
pub fn uuid_uuidstring(cbuuid: id) -> Id<NSString> {
unsafe { msg_send_id![cbuuid, UUIDString] }
}

pub fn uuid_uuidwithstring(s: impl NSString) -> id /* CBUUID */ {
unsafe { msg_send![class!(CBUUID), UUIDWithString: s] }
pub fn uuid_uuidwithstring(s: &NSString) -> Id<AnyObject> /* CBUUID */ {
unsafe { msg_send_id![class!(CBUUID), UUIDWithString: s] }
}

// CBCentralManagerScanOption...Key
Expand Down
Loading
Loading