godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.13k stars 93 forks source link

Add a Bluetooth server and module #6711

Open PierceLBrooks opened 1 year ago

PierceLBrooks commented 1 year ago

Describe the project you are working on

I am assisting in the creation of a platform-agnostic Bluetooth discovery framework that will be used in a game to facilitate peer-to-peer communications in a manner similar to that of the now defunct Nintendo 3DS StreetPass feature.

Describe the problem or limitation you are having in your project

Godot does not natively offer Bluetooth service advertisement or device enumeration.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Introduce GDScript-exposed classes that can be called upon to both query for Bluetooth availability at the system level, and initiate connectivity operations such as reading and writing characteristics or just scanning for devices.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

I intend to use the existing WebCam server and module implementation as a referential basis like in https://github.com/godotengine/godot-ios-plugins/tree/master/plugins/camera

My work has actually already begun in an experimental capacity at https://github.com/PierceLBrooks/godot/tree/plb/bluetooth

If this enhancement will not be used often, can it be worked around with a few lines of script?

No, Bluetooth must be carefully integrated with different API usages for each platform.

Is there a reason why this should be core and not an add-on in the asset library?

This proposal would provide for a very new and useful form of networked programming that is much less common than the usual socket-based approach but is still quite interesting like the WebRTC multiplayer stack.

PierceLBrooks commented 1 year ago

The plb/bluetooth branch of my personal Godot engine repository fork is now exhibiting fully functional GDScript-exposed Bluetooth device/service enumeration & advertisement on the MacOS platform using Apple's CoreBluetooth peripheral & central manager delegate API. This makes networkless peer-to-peer communication between games running on physically proximal machines possible via Bluetooth characteristics! I will attach the scripts that I used to test this scenario below in case anyone would care to attempt a reproduction. Also, here are some log samples:

Advertiser:

BluetoothServer: Registered advertiser "" with ID 1 at index 0
add: 1
[<BluetoothAdvertiser#-9223372010480991105>]
Advertise 29D7544B-6870-45A4-BB7E-D981535F4525
start: 29D7544B-6870-45A4-BB7E-D981535F4525 @ 1
write: B81672D5-396B-4803-82C2-029D34319015 @ 1 = 5C30D81E-8296-D8E5-43D4-336C0B58B0C8 & Hello, world!
read: B81672D5-396B-4803-82C2-029D34319015 @ 1 = 5C30D81E-8296-D8E5-43D4-336C0B58B0C8
BluetoothServer: Removed advertiser "29D7544B-6870-45A4-BB7E-D981535F4525" with ID 1
--- Debugging process stopped ---

Enumerator:

2023-06-04 14:37:17.423 godot.macos.editor.dev.x86_64[6567:110110] Found: Mac
discover: 1 @ 62E81CF3-80FE-8780-FE74-DB5A9E7A7001 & Mac & "{  }"
stop: 1
connect: 1 @ 62E81CF3-80FE-8780-FE74-DB5A9E7A7001
2023-06-04 14:37:17.986 godot.macos.editor.dev.x86_64[6567:110137] Service discovery error: (null)
2023-06-04 14:37:17.986 godot.macos.editor.dev.x86_64[6567:110137] Service found with UUID: 29D7544B-6870-45A4-BB7E-D981535F4525
characteristic: 1 @ 62E81CF3-80FE-8780-FE74-DB5A9E7A7001 & 29D7544B-6870-45A4-BB7E-D981535F4525 & B81672D5-396B-4803-82C2-029D34319015
2023-06-04 14:37:18.168 godot.macos.editor.dev.x86_64[6567:110110] Service: 29D7544B-6870-45A4-BB7E-D981535F4525 with Char: B81672D5-396B-4803-82C2-029D34319015
write: 1 @ 62E81CF3-80FE-8780-FE74-DB5A9E7A7001 & 29D7544B-6870-45A4-BB7E-D981535F4525 & B81672D5-396B-4803-82C2-029D34319015
read: 1 @ 62E81CF3-80FE-8780-FE74-DB5A9E7A7001 & 29D7544B-6870-45A4-BB7E-D981535F4525 & B81672D5-396B-4803-82C2-029D34319015 = Hello, world!
BluetoothServer: Removed enumerator with ID 1

advertisement-enumeration.zip

PierceLBrooks commented 10 months ago

I've resumed work on this, but for the Android platform now. I have recently discovered that on Windows, a GATT advertising server role will not be possible due to driver restrictions there outside of the context of UWP applications. The only people I've found who have managed to achieve that are here... https://www.btframework.com/ However, their implementation is proprietary - which naturally precludes the possibility of incorporating it as a first party dependency - and I am not confident in the feasibility of either reproducing or maintaining that approach as an open source alternative under the umbrella of Godot.

For extra clarity, my goal here is to integrate Bluetooth LE GATT client and/or server role support on as many platforms as I can. Currently, I see RFCOMM sockets as out of scope particularly due to their lack of support by MacOS/iOS's CoreBluetooth framework. Also, L2CAP cannot be done on Windows without extensive driver intimacy which would necessitate administrative privleges ( https://stackoverflow.com/questions/56525608/how-to-open-a-l2cap-channel-in-a-windows-10-gatt-service ).

With Linux, my plan will likely eventually be to use BlueZ through DBus ( https://github.com/weliem/bluez_inc & https://stackoverflow.com/questions/72815105/dbus-introspection-incomplete-wrong ).

PierceLBrooks commented 10 months ago

FYI, the folks working on https://github.com/OpenBluetoothToolbox/SimpleBLE have already done a great job trying to make GATT client role functionality available in a platform-agnostic fashion, and there has even been some work by others to offer that as an extension package for Godot: https://github.com/GDWired/GDSimpleBLE

JeffBusch commented 10 months ago

Looking forward to your work on this proposal. As far as I can tell Unity doesn't have any first party support for cross platform Bluetooth. So this would be a pretty unique feature for Godot to have.

There's very few mobile games using Bluetooth but if it's more accessible I think game devs could find some interesting uses for it. 👍