Skip to content

Commit

Permalink
feat: Support winrt-rs v0.7 (tentative NZSmartie#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
kaz399 authored and qdot committed Feb 4, 2021
1 parent abe899f commit b5ec1fb
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 159 deletions.
4 changes: 1 addition & 3 deletions Cargo.toml
Expand Up @@ -39,9 +39,7 @@ futures = "0.3.12"
parking_lot = "0.11.1"

[dependencies.winrt]
# This is stuck at 0.6 until we update the UWP core
version = "^0.6"
features = ["windows-devices", "windows-storage"]
version = "0.7"

[target.'cfg(target_os = "linux")'.dependencies]
dbus = "0.9.1"
Expand Down
4 changes: 2 additions & 2 deletions src/winrtble/adapter.rs
Expand Up @@ -41,12 +41,12 @@ impl Central<Peripheral> for Adapter {
let watcher = self.watcher.lock().unwrap();
let manager = self.manager.clone();
watcher.start(Box::new(move |args| {
let bluetooth_address = args.get_bluetooth_address().unwrap();
let bluetooth_address = args.bluetooth_address().unwrap();
let address = utils::to_addr(bluetooth_address);
let peripheral = manager
.peripheral(address)
.unwrap_or_else(|| Peripheral::new(manager.clone(), address));
peripheral.update_properties(&args);
peripheral.update_properties(args);
if !manager.has_peripheral(&address) {
manager.add_peripheral(address, peripheral);
manager.emit(CentralEvent::DeviceDiscovered(address));
Expand Down
47 changes: 47 additions & 0 deletions src/winrtble/bindings.rs
@@ -0,0 +1,47 @@
// btleplug Source Code File
//
// Copyright 2020 Nonpolynomial Labs LLC. All rights reserved.
//
// Licensed under the BSD 3-Clause license. See LICENSE file in the project root
// for full license information.
//
// Some portions of this file are taken and/or modified from Rumble
// (https://github.com/mwylde/rumble), using a dual MIT/Apache License under the
// following copyright:
//
// Copyright (c) 2014 The Rust Project Developers

use winrt::*;

import!(
dependencies
os
types
windows::devices::bluetooth::generic_attribute_profile::{
GattCharacteristic,
GattCharacteristicProperties,
GattClientCharacteristicConfigurationDescriptorValue,
GattCommunicationStatus,
GattDeviceService,
GattDeviceServicesResult,
GattValueChangedEventArgs,
}
windows::devices::bluetooth::advertisement::*
windows::devices::bluetooth::{
BluetoothConnectionStatus,
BluetoothLEDevice,
}
windows::devices::radios::{
Radio,
RadioKind
}
windows::foundation::{
EventRegistrationToken,
TypedEventHandler,
}
windows::storage::streams::{
DataReader,
DataWriter,
}
);

53 changes: 26 additions & 27 deletions src/winrtble/ble/characteristic.rs
Expand Up @@ -12,43 +12,42 @@
// Copyright (c) 2014 The Rust Project Developers

use crate::{Error, Result};
use winrt::{
windows::devices::bluetooth::genericattributeprofile::{
use super::super::bindings;

use bindings::windows::devices::bluetooth::generic_attribute_profile::{
GattCharacteristic, GattClientCharacteristicConfigurationDescriptorValue,
GattCommunicationStatus, GattValueChangedEventArgs,
},
windows::foundation::{EventRegistrationToken, TypedEventHandler},
windows::storage::streams::{DataReader, DataWriter},
ComPtr, RtAsyncOperation, RtDefaultConstructible,
};
use bindings::windows::foundation::{EventRegistrationToken, TypedEventHandler};
use bindings::windows::storage::streams::{DataReader, DataWriter};

pub type NotifiyEventHandler = Box<dyn Fn(Vec<u8>) + Send>;

pub struct BLECharacteristic {
characteristic: ComPtr<GattCharacteristic>,
characteristic: GattCharacteristic,
notify_token: Option<EventRegistrationToken>,
}

unsafe impl Send for BLECharacteristic {}
unsafe impl Sync for BLECharacteristic {}

impl BLECharacteristic {
pub fn new(characteristic: ComPtr<GattCharacteristic>) -> Self {
pub fn new(characteristic: GattCharacteristic) -> Self {
BLECharacteristic {
characteristic,
notify_token: None,
}
}

pub fn write_value(&self, data: &[u8]) -> Result<()> {
let writer = DataWriter::new();
let writer = DataWriter::new().unwrap();
writer.write_bytes(data).unwrap();
let buffer = writer.detach_buffer().unwrap().unwrap();
let buffer = writer.detach_buffer().unwrap();
let result = self
.characteristic
.write_value_async(&buffer)
.unwrap()
.blocking_get()
.get()
.unwrap();
if result == GattCommunicationStatus::Success {
Ok(())
Expand All @@ -62,13 +61,12 @@ impl BLECharacteristic {
.characteristic
.read_value_async()
.unwrap()
.blocking_get()
.unwrap()
.get()
.unwrap();
if result.get_status().unwrap() == GattCommunicationStatus::Success {
let value = result.get_value().unwrap().unwrap();
let reader = DataReader::from_buffer(&value).unwrap().unwrap();
let len = reader.get_unconsumed_buffer_length().unwrap() as usize;
if result.status().unwrap() == GattCommunicationStatus::Success {
let value = result.value().unwrap();
let reader = DataReader::from_buffer(&value).unwrap();
let len = reader.unconsumed_buffer_length().unwrap() as usize;
let mut input = vec![0u8; len];
reader.read_bytes(&mut input[0..len]).unwrap();
Ok(input)
Expand All @@ -79,11 +77,12 @@ impl BLECharacteristic {

pub fn subscribe(&mut self, on_value_changed: NotifiyEventHandler) -> Result<()> {
let value_handler = TypedEventHandler::new(
move |_: *mut GattCharacteristic, args: *mut GattValueChangedEventArgs| {
let args = unsafe { &*args };
let value = args.get_characteristic_value().unwrap().unwrap();
let reader = DataReader::from_buffer(&value).unwrap().unwrap();
let len = reader.get_unconsumed_buffer_length().unwrap() as usize;
move |_: &GattCharacteristic, args: &GattValueChangedEventArgs| {
//let args = unsafe { &*args };
let args = &*args;
let value = args.characteristic_value().unwrap();
let reader = DataReader::from_buffer(&value).unwrap();
let len = reader.unconsumed_buffer_length().unwrap() as usize;
let mut input = vec![0u8; len];
reader.read_bytes(&mut input[0..len]).unwrap();
info!("changed {:?}", input);
Expand All @@ -93,22 +92,22 @@ impl BLECharacteristic {
);
let token = self
.characteristic
.add_value_changed(&value_handler)
.value_changed(&value_handler)
.unwrap();
self.notify_token = Some(token);
let config = GattClientCharacteristicConfigurationDescriptorValue::Notify;
let status = self
.characteristic
.write_client_characteristic_configuration_descriptor_async(config)
.unwrap()
.blocking_get()
.get()
.unwrap();
info!("subscribe {:?}", status);
Ok(())
}

pub fn unsubscribe(&mut self) -> Result<()> {
if let Some(token) = self.notify_token {
if let Some(token) = &self.notify_token {
self.characteristic.remove_value_changed(token).unwrap();
}
self.notify_token = None;
Expand All @@ -117,7 +116,7 @@ impl BLECharacteristic {
.characteristic
.write_client_characteristic_configuration_descriptor_async(config)
.unwrap()
.blocking_get()
.get()
.unwrap();
info!("unsubscribe {:?}", status);
Ok(())
Expand All @@ -126,7 +125,7 @@ impl BLECharacteristic {

impl Drop for BLECharacteristic {
fn drop(&mut self) {
if let Some(token) = self.notify_token {
if let Some(token) = &self.notify_token {
let result = self.characteristic.remove_value_changed(token);
if let Err(err) = result {
info!("Drop:remove_connection_status_changed {:?}", err);
Expand Down

0 comments on commit b5ec1fb

Please sign in to comment.