Skip to content

Commit

Permalink
Merge branch 'master' into add-service-uuid-value-notification
Browse files Browse the repository at this point in the history
  • Loading branch information
night-crawler committed Jan 4, 2024
2 parents 2ef55b8 + 9537a23 commit dbb86ab
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 38 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# 0.11.4 (2024-01-01)

## Bugfixes

- Fix issue with manufacturer data not being consistently found on windows
- Fix UUID used for finding characteristics on windows
- Peripheral connection failure now returns an error
- Peripheral service discovery failure now returns an error

# 0.11.3 (2023-11-18)

## Bugfixes
Expand Down
24 changes: 12 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "btleplug"
version = "0.11.3"
version = "0.11.4"
authors = ["Nonpolynomial, LLC <[email protected]>"]
license = "MIT/Apache-2.0/BSD-3-Clause"
repository = "https://github.com/deviceplug/btleplug"
Expand All @@ -22,18 +22,18 @@ path = "src/lib.rs"
serde = ["uuid/serde", "serde_cr", "serde_bytes"]

[dependencies]
async-trait = "0.1.74"
async-trait = "0.1.76"
log = "0.4.20"
bitflags = "2.4.1"
thiserror = "1.0.50"
uuid = "1.5.0"
serde_cr = { package = "serde", version = "1.0.192", features = ["derive"], default-features = false, optional = true }
serde_bytes = { version = "0.11.12", optional = true }
thiserror = "1.0.53"
uuid = "1.6.1"
serde_cr = { package = "serde", version = "1.0.193", features = ["derive"], default-features = false, optional = true }
serde_bytes = { version = "0.11.13", optional = true }
dashmap = "5.5.3"
futures = "0.3.29"
futures = "0.3.30"
static_assertions = "1.1.0"
# rt feature needed for block_on in macOS internal thread
tokio = { version = "1.34.0", features = ["sync", "rt"] }
tokio = { version = "1.35.1", features = ["sync", "rt"] }
tokio-stream = { version = "0.1.14", features = ["sync"] }

[target.'cfg(target_os = "linux")'.dependencies]
Expand All @@ -42,19 +42,19 @@ bluez-async = "0.7.2"

[target.'cfg(target_os = "android")'.dependencies]
jni = "0.19.0"
once_cell = "1.18.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.150"
libc = "0.2.151"

[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"] }

[dev-dependencies]
rand = "0.8.5"
pretty_env_logger = "0.5.0"
tokio = { version = "1.34.0", features = ["macros", "rt", "rt-multi-thread"] }
serde_json = "1.0.108"
tokio = { version = "1.35.1", features = ["macros", "rt", "rt-multi-thread"] }
serde_json = "1.0.109"
16 changes: 13 additions & 3 deletions src/corebluetooth/central_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pub enum CentralDelegateEvent {
},
ConnectionFailed {
peripheral_uuid: Uuid,
error_description: Option<String>,
},
DisconnectedDevice {
peripheral_uuid: Uuid,
Expand Down Expand Up @@ -176,9 +177,13 @@ impl Debug for CentralDelegateEvent {
.debug_struct("ConnectedDevice")
.field("peripheral_uuid", peripheral_uuid)
.finish(),
CentralDelegateEvent::ConnectionFailed { peripheral_uuid } => f
CentralDelegateEvent::ConnectionFailed {
peripheral_uuid,
error_description,
} => f
.debug_struct("ConnectionFailed")
.field("peripheral_uuid", peripheral_uuid)
.field("error_description", error_description)
.finish(),
CentralDelegateEvent::DisconnectedDevice { peripheral_uuid } => f
.debug_struct("DisconnectedDevice")
Expand Down Expand Up @@ -486,13 +491,18 @@ pub mod CentralDelegate {
_cmd: Sel,
_central: id,
peripheral: id,
_error: id,
error: id,
) {
trace!("delegate_centralmanager_didfailtoconnectperipheral_error");
let peripheral_uuid = nsuuid_to_uuid(cb::peer_identifier(peripheral));
let error_description_ns = ns::error_localizeddescription(error);
let error_description = nsstring_to_string(error_description_ns);
send_delegate_event(
delegate,
CentralDelegateEvent::ConnectionFailed { peripheral_uuid },
CentralDelegateEvent::ConnectionFailed {
peripheral_uuid,
error_description,
},
);
}

Expand Down
9 changes: 9 additions & 0 deletions src/corebluetooth/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ pub mod ns {
uuidstring
}
}

// NSError

pub fn error_localizeddescription(nserror: id) -> id /* NSString* */ {
unsafe {
let description: id = msg_send![nserror, localizedDescription];
description
}
}
}

pub mod cb {
Expand Down
13 changes: 9 additions & 4 deletions src/corebluetooth/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,13 @@ impl CoreBluetoothInternal {
// itself when it receives all of its service/characteristic info.
}

fn on_peripheral_connection_failed(&mut self, peripheral_uuid: Uuid) {
fn on_peripheral_connection_failed(
&mut self,
peripheral_uuid: Uuid,
error_description: Option<String>,
) {
trace!("Got connection fail event!");
let error = error_description.unwrap_or(String::from("Connection failed"));
if self.peripherals.contains_key(&peripheral_uuid) {
let peripheral = self
.peripherals
Expand All @@ -619,7 +624,7 @@ impl CoreBluetoothInternal {
.unwrap()
.lock()
.unwrap()
.set_reply(CoreBluetoothReply::Err(String::from("Connection failed")));
.set_reply(CoreBluetoothReply::Err(error));
}
}

Expand Down Expand Up @@ -1026,8 +1031,8 @@ impl CoreBluetoothInternal {
CentralDelegateEvent::ConnectedDevice{peripheral_uuid} => {
self.on_peripheral_connect(peripheral_uuid)
},
CentralDelegateEvent::ConnectionFailed{peripheral_uuid} => {
self.on_peripheral_connection_failed(peripheral_uuid)
CentralDelegateEvent::ConnectionFailed{peripheral_uuid, error_description} => {
self.on_peripheral_connection_failed(peripheral_uuid, error_description)
},
CentralDelegateEvent::DisconnectedDevice{peripheral_uuid} => {
self.on_peripheral_disconnect(peripheral_uuid).await
Expand Down
3 changes: 2 additions & 1 deletion src/corebluetooth/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ impl api::Peripheral for Peripheral {
self.shared
.emit_event(CentralEvent::DeviceConnected(self.shared.uuid.into()));
}
_ => panic!("Shouldn't get anything but connected!"),
CoreBluetoothReply::Err(msg) => return Err(Error::RuntimeError(msg)),
_ => panic!("Shouldn't get anything but connected or err!"),
}
trace!("Device connected!");
Ok(())
Expand Down
1 change: 1 addition & 0 deletions src/winrtble/ble/watcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl BLEWatcher {
self.watcher
.SetScanningMode(BluetoothLEScanningMode::Active)
.unwrap();
self.watcher.SetAllowExtendedAdvertisements(true)?;
let handler: TypedEventHandler<
BluetoothLEAdvertisementWatcher,
BluetoothLEAdvertisementReceivedEventArgs,
Expand Down
39 changes: 21 additions & 18 deletions src/winrtble/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,25 @@ impl Peripheral {
}
}
if let Ok(manufacturer_data) = advertisement.ManufacturerData() {
let mut manufacturer_data_guard = self.shared.latest_manufacturer_data.write().unwrap();

*manufacturer_data_guard = manufacturer_data
.into_iter()
.map(|d| {
let manufacturer_id = d.CompanyId().unwrap();
let data = utils::to_vec(&d.Data().unwrap());

(manufacturer_id, data)
})
.collect();

// Emit event of newly received advertisement
self.emit_event(CentralEvent::ManufacturerDataAdvertisement {
id: self.shared.address.into(),
manufacturer_data: manufacturer_data_guard.clone(),
});
if manufacturer_data.Size().unwrap() > 0 {
let mut manufacturer_data_guard =
self.shared.latest_manufacturer_data.write().unwrap();
*manufacturer_data_guard = manufacturer_data
.into_iter()
.map(|d| {
let manufacturer_id = d.CompanyId().unwrap();
let data = utils::to_vec(&d.Data().unwrap());

(manufacturer_id, data)
})
.collect();

// Emit event of newly received advertisement
self.emit_event(CentralEvent::ManufacturerDataAdvertisement {
id: self.shared.address.into(),
manufacturer_data: manufacturer_data_guard.clone(),
});
}
}

// The Windows Runtime API (as of 19041) does not directly expose Service Data as a friendly API (like Manufacturer Data above)
Expand Down Expand Up @@ -454,6 +456,7 @@ impl ApiPeripheral for Peripheral {
}
Err(e) => {
error!("get_characteristics_async {:?}", e);
return Err(e);
}
}
}
Expand Down Expand Up @@ -572,7 +575,7 @@ impl ApiPeripheral for Peripheral {
.ok_or_else(|| Error::NotSupported("Service not found for read".into()))?;
let ble_characteristic = ble_service
.characteristics
.get(&descriptor.uuid)
.get(&descriptor.characteristic_uuid)
.ok_or_else(|| Error::NotSupported("Characteristic not found for read".into()))?;
let ble_descriptor = ble_characteristic
.descriptors
Expand Down

0 comments on commit dbb86ab

Please sign in to comment.