-
-
Notifications
You must be signed in to change notification settings - Fork 158
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
BlueZ: Replace raw HCI sockets with BlueZ over DBus #105
Conversation
9dd3f2c
to
d3ec17e
Compare
I had a look through other open issues and found two related issues that will be resolved with this PR |
@qdot, can you add |
dfef5db
to
e3d2fb5
Compare
I've done what I can to test this PR, and I'm now relying on others to help test it. Since it works for me™, I'm happy to submit future PRs to fix bugs or other issues that I've yet to face |
As well as some other house cleaning 🧹
I also had a misplaced `!`
0bab260
to
182c5e2
Compare
just rebased on to master |
Also closes #52. |
Awesome, thanks for the updates. I am definitely trying to get to reviewing this, hopefully in the next day or two. |
(Note: This is permission to yell at me in these here comments if I don't get to it soon :3 ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all looking really good! I've just got a few comments I'd like addressed, then it can land.
src/bluez/adapter/mod.rs
Outdated
let lock = listener.lock(); | ||
while lock.process(Duration::from_secs(0)).unwrap() {} | ||
drop(lock); | ||
thread::sleep(Duration::from_millis(100)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where'd the 100ms come from here? BLE packet timings can be less than that, so this may lag the system some. I think it could be reduced, would just like to know if there was a source for this.
Also, as the Drop trait needs to kill this, this should be a cancellable sleep. Maybe change it to a condition with a timed wait? That way you aren't blocking the join in the Drop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no source for this. I was going for a way to quickly process any messages there may be, and then sleeping on the thread for 100ms, so that other threads have a chance to use the listener to send/receive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking back at my code and later learning about parking_lot
I was dealing with mutex fairness, where, the while
loop was constantly locking the mutex, not giving any other threads a chance to get a lock, and thus, anything that needed listener
would block.
I'll see if parking_lot::ReentrantMutex
promotes fairness
src/bluez/adapter/mod.rs
Outdated
|
||
if args.interfaces.iter().any(|s| s == BLUEZ_INTERFACE_DEVICE) { | ||
adapter.remove_device(&path).unwrap(); | ||
} else if args.interfaces.iter().any(|s| s == BLUEZ_INTERFACE_SERVICE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should happen here? Can you at least comment the null blocks here and below to let us know whether these are null for a reason or just still need to be filled in?
src/bluez/adapter/mod.rs
Outdated
handle_map: Arc::new(DashMap::new()), | ||
manager: AdapterManager::new(), | ||
}; | ||
pub fn is_up(&self) -> Result<bool> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a situation where the adapter would be powered, but not up? Or would this throw if the adapter instance was for a device that has been disconnected?
Cargo.toml
Outdated
@@ -36,6 +37,7 @@ uuid = "0.8.2" | |||
serde = { version = "1.0.119", features = ["derive"], default-features = false, optional = true } | |||
dashmap = "4.0.2" | |||
futures = "0.3.12" | |||
parking_lot = "0.11.1" | |||
|
|||
[dependencies.nom] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we kill the nom dep here now?
.map(|(path, attribute)| Ok(self.add_attribute(path.as_str().unwrap(), attribute)?)) | ||
.collect::<Result<()>>()?; | ||
|
||
// TODO: Descriptors are nested behind characteristics, and their UUID may be used more than once. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's an issue about descriptor requests, we should probably call this out there. I haven't even looked at other platforms yet.
} | ||
|
||
pub fn connect(&self) -> Result<ConnectedAdapter> { | ||
ConnectedAdapter::new(self) | ||
fn active(&self, _enabled: bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and elsewhere, can we get some comments on the methods that need to be filled in? Makes it easier to file help wanted bugs or at least say issues are claimed later, if we know what needs to be filled in.
connection_tx: Arc<Mutex<Sender<u16>>>, | ||
connection_rx: Arc<Mutex<Receiver<u16>>>, | ||
message_queue: Arc<Mutex<VecDeque<ACLData>>>, | ||
attributes_map: Arc<Mutex<HashMap<u16, (String, Handle, Characteristic)>>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you wanted to lose the Mutex here, you could switch to DashMap. I use it heavily up in Buttplug, works great. That said, with everything else so lock heavy here, that's really just the lightest of nits and could be a followup.
src/bluez/adapter/peripheral.rs
Outdated
if let (Some(id), Some(data)) = (iter.next(), iter.next()) { | ||
// This API is terrible.. why can't I just get an array out, why is it all wrapped in a Variant? | ||
let data: Vec<u8> = data | ||
.as_iter() // 🎶 The Variant is connected to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this, please go through the rest of your patch and make your comments rhyme.
.characteristics | ||
.lock() | ||
.unwrap() | ||
.clone() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nit: You might be able to use cloned() after your map (and use refs up to that point), save the copy then discard? But it honestly doesn't matter much in this context, and I can't remember off the top of my head where cloned() comes in.
src/bluez/adapter/peripheral.rs
Outdated
.as_iter() // Lets convert the | ||
.unwrap() // integers to a | ||
.map(|b| b.as_u64().unwrap() as u8) // array of bytes... | ||
.collect(); // I got too lazy to make it rhyme... 🎶 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do this more nicely with dbus::arg::prop_cast
, or if you pass --prop-newtype
to dbus-codegen-rust
it will give you a type-safe wrapper for the HashMap
, and you can do OrgBluezDevice1Properties::manufacturer_data
to get a HashMap<u16, Variant<Box<dyn RefArg>>>
, and then you can just map the values with dbus::arg::cast::<Vec<u8>>(&v.0)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From memory, I gave this a try from the very start. but I think because i'm passing in a subset of the type that dbus::arg::cast/prop_cast
are expecting, i get compile errors. I'll have another go and see if I've missed something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, you may also need to make sure you have at least version 0.9.1 of the dbus
crate, to include the fix from diwic/dbus-rs#306.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've sent you NZSmartie#1 to fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @qwandor! Though i'm a bit sad to see my silly rhyming comment go away 😢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to keep some standards in this code, so I'm at least going to need some methods in iambic pentameter going forward.
@qwandor Thanks for the comment! If you or anyone else has additional guidance on the Bluez side, please feel free to add it here. I was mostly reviewing for structure, I'm far more familiar with the CoreBluetooth and UWP sides of the library, so I can't really comment much on the Bluez. |
…g into feature/bluez-dbus-qwandor
Ok, well, I'm cool with the changes and will land this, just gotta figure out why changing the base branch to dev borkt things because master and dev are on the same HEAD. I'd also like to keep my fast-forward only rule so I may rebase out the merge that comes in here. So, in short: Your code will be into the |
Ok, I just brought this in with the merges for now, turns out the prehistory of rumble is just lousy with them anyways. |
This is a complete rewrite of the "bluez" platform specific code.
A lot has happened and I did my best to commend code to explain how/why a well as keep commits subjective so that changes can be understood in context.
Things I want to do before merging:
Verify I didn't break the existing API(Maintaining a backwards compatible API is a lot harder than I thought and ends up with a lot of messy dead code)Closes #60, #69