Home

Awesome

bluetuith-shim-windows

A shim and command-line tool to use Bluetooth Classic features on Windows.<br /> Part of the cross-platform work for the bluetuith project.

This is alpha-grade software.

Funding

This project is funded through NGI Zero Core, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program. Learn more at the NLnet project page.

<img src="https://nlnet.nl/logo/banner.png" alt="NLnet foundation logo" width="20%" /> <img src="https://nlnet.nl/image/logos/NGI0_tag.svg" alt="NGI Zero Logo" width="20%" />

Requirements

Download and Installation

All downloads can be found within the 'Releases' page of the repository.

Documentation

This documentation is mostly a quick-start guide. Detailed documentation will come later.

Interaction with the shim can be done via:

Command-line

As with most command-line tools,

The 'help' option can be used with subcommands as well, for example:

bluetuith-shim adapter --help

Adapter commands

bluetuith-shim adapter set-power-state <on|off>
bluetuith-shim adapter info
bluetuith-shim adapter start-discovery

(Press Ctrl-C to stop discovery)

bluetuith-shim adapter get-paired-devices

Device commands

Most subcommands of the 'device' command have a mandatory --address or -a parameter to specify the Bluetooth address of the device.<br />

bluetuith-shim device pair -a <address>

While pairing, a prompt may appear (to confirm whether PINs match between host and remote device, for example).<br /> Press "y" or "n" to accept or decline pairing with the remote device.<br /> Note that a default timeout of 10 seconds is set to wait for a reply from the user.<br />

bluetuith-shim device remove -a <address>
bluetuith-shim device info -a <address>

(Use --services to list all Bluetooth services associated with the device. If the device is unpaired, use --issue-inquiry to start scanning for the specific remote device.)

Once a device has been paired, a connection can be made to the device.<br /> To connect to a Bluetooth device, a Bluetooth profile must be specified.<br /> Currently, within the shim, each connectable profile appears as a subcommand of the connect command.<br />

To view all connectable/supported profiles:

bluetuith-shim device connect --help

Some connection examples:

bluetuith-shim device connect a2dp -a <address>

(Note that the application has to remain open to maintain the session. Closing the app will close the session.)

More subcommands for the pbap command can be listed using: bluetuith-shim device connect pbap --help.<br /> Similarly, more subcommands for each profile can be listed using: bluetuith-shim device connect <profile-name> --help.<br />

bluetuith-shim device disconnect -a <address>

RPC

A Unix Domain socket is required, currently, to perform RPC with the shim.<br /> Future versions may support named pipes as well.

JSON is the primary data format used to exchange information to and from the shim.<br />

Start the server

To start the server over a socket:

bluetuith-shim rpc start-session --socket-path=<path-to-socket>

Once the server has started, commands can be sent to the shim via the socket.

Request format

To send a request to execute a command to the shim, the message should look like:

{ "command": ["device", "info", "-a", "AA:BB:CC:DD:EE:FF"], "requestId": 1 }

Where:

The message must be serialized to UTF-8 bytes before sending it to the shim.

If the command is parsed correctly, the shim replies back with:

{ "operationId": 1, "requestId": 1, "status": "ok", "data": { "command": "info" } }

To indicate that the command was parsed and is being executed.<br /> Note that all calls are asynchronous, so use the requestId or operationId to keep track of requests and replies.

Reply format

Once an operation has finished, the shim will encode the command's result to JSON and send it to the client.

The reply payload consists of two parts:

Which should look like this:

[<4-byte length header>]{JSON payload}

The length header is appended primarily for outputs from the pbap and map commands, where outputs can be large (like contact and message listings).

If the command outputs any events, the JSON payload will look like:

{ "operationId": 1, "requestId": 1, "eventId": 0, "event": { "fileTransferEvent": { "fileName": "customFile.mp4", "fileSize": 100 ...} } }

If the command does not return any error, the JSON payload will look like:

{ "operationId": 1, "requestId": 1, "status": "ok", "data": { "deviceProperties": { "name": "Bluetooth Device", "address": "AA:BB:CC:DD:EE:FF" ...} } }

If the commands returns an error, the JSON payload will look like:

{ "operationId": 1, "requestId": 1, "status": "error", "error": { "code": 10, "name": "ERROR_DEVICE_NOT_FOUND", "description": "" ...} }

A sample program to parse a reply payload is provided in the 'Samples' directory.

Authentication

This section mainly applies to the pairing operation.

During a pairing operation, if the device asks to perform additional authentication (like confirming if PINs match),<br /> an authentication event is emitted.

An authentication event usually is in the following format:

{ "operationId": 1, "requestId": 1, "eventId": 1, "event": { "pairingAuthenticationEvent": { "pin": 0000, "timeout": 10000, "authenticationType": "ConfirmYesNo" } } }

Note the operation ID of the event.

There are two authentication request types: ConfirmYesNo and ConfirmInput.

To reply to the ConfirmYesNo authentication request for example, the following JSON payload should be sent:

{ "command": ["rpc", "auth", "--operation-id", 1, "--response", "yes"], "requestId": 1 }

Cancelling operations

To cancel any long running operations, the operation ID of the running operation will have to be obtained first.

For example, if a device discovery operation has been started:

{ "command": ["adapter", "start-discovery"], "requestId": 1 }

And a reply has been obtained as soon as the command request was sent:

{ "operationId": 1, "requestId": 1, "status": "ok", "data": { "command": "start-discovery" } }

Note the operation ID of the response.

To stop the device discovery, the following payload should be sent:

{ "command": ["rpc", "cancel", "--operation-id", 1], "requestId": 1 }

Version querying

While in RPC mode, do not use the -v switch to query the version. Instead use rpc version to get a version number serialized to JSON, that can be parsed.

Credits

These repositories were invaluable during the development of the shim.<br /> Please star these repositories individually, and possibly submit contributions to them.<br />