-
Notifications
You must be signed in to change notification settings - Fork 89
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
Bluetooth IP Address Advertisement #325
base: master
Are you sure you want to change the base?
Conversation
I'm not very good at C, so I had no idea how to constrict most of the code here to be only run on a Linux system as I know that will be a big problem as if this is merged it means that no other platform will be able to build. |
I guess this is "BTLE" (BLE) described here: https://support.apple.com/guide/deployment/use-airplay-dep9151c4ace/web https://www.bluetooth.com/bluetooth-resources/the-bluetooth-low-energy-primer/ https://github.com/microsoft/windows-universal-samples/tree/main/Samples/BluetoothAdvertisement it's present in windows and macOS too.
|
That's it, Apple describes it as the "Bluetooth IP Address Advertisement". BLE avertisements can be sent out on Windows and macOS too - I might have a go at implementing it on Windows later, I'll just need to take a look at existing code and figure out how one implements different libraries for each platform etc. as I've never worked in C before.
Currently, the code is set so that it attempts to set up a BLE interface, if it doesn't find one/an error occurs (usually that it doesn't have the privileges as the program needs to be run as sudo) then it sends a message in the console saying it is disabled for the session as there was an error and gives up using BLE. It doesn't exactly send a DNS-SD advertisement over bluetooth, the payload size of a BLE advertisement is very small due to power limitations and so instead all that gets sent in the payload is the following 8 bytes:
All that still needs to be implemented is using the Windows BLE library if on Windows and I assume using the linux library on mac (unless there is an alternative - Will need to look into this). Also I've just realised that it only gets the ethernet iface IP address atm, so people using Wi-Fi won't have their ip broadcast - I will fix this soon. |
can you take a look at SimpleBLE (a GPL v3 cross-platfom BLE implementation) ? https://github.com/OpenBluetoothToolbox/SimpleBLE Unfortunately the large number of "issues" suggests its not quite mature yet.... |
C++ with "extern C" wrappers for interface with C works. uxplay.cpp does this. |
I remember seeing this library when I began trying to put it all together, since I didn't really know anything about C I stayed away from it because of the no. of issues (fixing my own problems was going to be enough, let alone having problems because the library was causing them). Will take a look at it tonight and try to use this library instead as that will make it a lot easier than implementing it differently for each platform. |
BLE does look like a good feaure to add, thanks for your work on this |
Thank you - Off topic but I've been fighting for a while to try to figure out how H265 works, struggling with wrapping my head around the HomeKit pairing process as it's not easy. Will keep trying though as I'm keen on figuring it out. Whilst I've got you - How do you reverse engineer all of this? I'm sure at the start you could use existing docs and research, but the things you're doing currently like HLS aren't really that well documented, and so I'm interested to know how you figure the stuff like that out when it's behind an encrypted channel of communication? Do you have a custom proxy solution that you use? |
HLS was a total mystery. incomplete pieces of a code with no ancestry in our own code base had appeared on github from time to time, with no license or provenance., until late last year, when someone interested noticed the full C++ code was recently published with a GPL license as "apsdk-public", but not in a usable state, as a demo and the fairplay substitute (playfair) were stripped out. It seems that a single author had been working on it since 2017. Luckily, looking back in the code history we were able to restore an earlier working demo, and see how to put back fairplay, which was indeed what was being used. (It's the only partial "crack" of fairplay that has been achieved, so I believe all open source and non-apple closed source implementations use it). Finally, by filling up the working demo with printf statements at every function call, the HLS workings became traceable and understandable. A working example that one can add printf's to is the key, when there is not much documentation. apsdk-public has a C++ interface to a 2017 C hlsparser found on github. we borrowed this interface as apsdk is GPL, and gave C wrappers to it, and connected it to adapted UxPlay. . The remaining issues are GStreamer integration, so at some point uxplay will get HLS support (at least for youtube videos, since netflix has removed non-apple airplay support.) Homekit pairing (from the client viewpoint) is semi documented at https://github.com/ejurgensen/pair_ap with server and client implementation. This also includes a client-only implementation of legacy-pairing it calls "fruit pairing" with SRP that was very useful for using on a true AppleTV to see what its SRP server responses were (this is the one-time pairing protocol, also used in homekit) , and fill in undocumented details by guess-and-check. https://github.com/philippe44/libraop was also very useful, but does not do homekit. |
Unfortunately not. In legacy pairing (even with SRP authentication, which sets up what COULD be used for total communication encryption ) I was surprised to find that after all the work to implement SRP authentication, it doesnt enforce total encryption. But homekit does, as can been seen in https://github.com/ejurgensen/pair_ap, and seems to use (apple-modified) SRP with the "big random integer" upped from 2048 to 3072 bits. |
one design possibility is that the running uxplay writes its BLE message to a file that only exists while uxplay is running, and some helper function, running as root if that is needed, broadcasts it on bluetooth at appropriate intervals if it exists? something like that is implement in the -dacp option for interfacing with a remote controller for the iOS client. I am assuming that the client responds on the network, not with reverse BLE? |
|
I think apple generally uses the non-connectable BLE, for things like
e.g https://github.com/MarketStreetCyber/Blabber/blob/main/impersonate/setup_appletv.py uses "ADV_NONCONN_IND" which I assume is non connectable |
SimpleBLE won't be enough unfortunately - It doesn't seem to support broadcasting advertisements (and it took me 4 hours to include in the project). I'll have to have a go at writing an implementation for each platform. We're talking about non-connectable here, as @thiccaxe said the ADV_NONCONN_IND. Meaning that the listening device (iOS devices) cannot connect to the device - As such, like you said, the client responds by sending an HTTP request to the IP address in the BLE advertisement. |
This reverts commit efed512.
@connorh315 Confirming your observation that simpleBLE doesnt do advertising, I found this discussion on the simpleBLE discord server: It also seems that simpleBLE development was previously supported by developer's previous employer, and has now stalled (he comments: For a project like this to prosper, raw manpower is not enough if it’s not coordinated, as it leads to a steady degradation of the code quality. Either by managing people or coding myself, this is work that needs to put food on the table in one way or another.)
|
I think that BLE on Windows is going to be a bit of a pain to implement, I can't find any reliable docs/examples on using the Bluetooth libraries to broadcast an advertisement. Perhaps for now, I could just make the functions empty when building for Windows? It's a bit of a cheap cop out but I don't have long before I go back to work and don't want to leave this open - All this means is that the feature will only work on Linux. What do we all think? |
That's fine. If its activated by an option (e.g. -ble ) one can test for windows and reject the option with an error message at startup. I am more worried about your earlier mention of running as root, etc. can you explain a bit more ? |
is this a useful ref? https://punchthrough.com/creating-a-ble-peripheral-with-bluez/ ideally Uxplay would just write the advertisement that should be sent to a file that only exists while uxplay is running,and some bluez service (running as root) would detect that file, read it and transmit the contents with BLE. Is such a thing possible? |
I've had a look at the link that you've sent, I am probably able to rewrite it all to use the D-Bus, however I'm not entirely sure that this circumvents using sudo. I could give it a go though. As an alternative, I have discovered that a user can run Let me know whether this is suitable, as I do understand your concern with running UxPlay as sudo (especially since it seems to break GStreamer). |
once a working prototype is available, one can see how to improve it. Ideally uxplay would write a file with the BLE message to be sent, just like the -dacp option, and a separate helper script would periodically check for the existence of that file and if it is found send the BLE message. UxPlay works fine as root, with the firewall switched off, I checked. This is fine for testing. The main thing is to have a working prototype to start with. |
What's the problem with the current prototype so I know what needs to be done to improve that atm? And just so I understand as well what's the reason you want a separate helper script rather than the solution being a part of the UxPlay binary? |
BLE is tangential to UxPlay and not really core. I think it would make sense to use something like python for ble as it already has a (probably) better package (bleak). Also, I am going to say with some confidence that ble will eventually run into issues like needing to be rebroadcasted, restarted, what is Bluetooth is turned of, etc. let a user script take care of that. It also allows faster iteration and the feature can be published quicker. Dont want to use python? Any language can read / watch a file |
@connorh315 I haven't yet tested your prototype, if its working, that's great as a start. but writing the platform-independent BLE message text to a file that something else reads and sends the message is a truly cross-platform solution. |
7a14d4c
to
b1fb510
Compare
f2d8c03
to
35b1e9e
Compare
bc2843a
to
f63a91c
Compare
01d48c6
to
bc2d5a4
Compare
29b6d03
to
68ed1d5
Compare
Sometimes the service discovery is a bit slow (or non-existent on poorly managed networks). This is an alternative method for Airplay senders to detect receivers. It involves frequently sending out the IP address of the receiver over Bluetooth. If a sender is in range and has Bluetooth enabled it will pick up the BLE advert, and then send a special "GET /info" request to the IP address in question to receive data similar to that which is broadcast by the DNS-SD. The IP address advertisement leads to more reliable discovery from testing.
Only works on Linux currently, requires sudo (as well as a BLE interface too). Enable this with the -btip argument