#!/usr/bin/env bash # Script to introspect bluez into specs/*.xml and generate src/*.rs from # them. # # Introspection requires a running bluez daemon that is connected to devices # with the features that you want to inspect. It also requires Bash >= 4 with # associative array support. Bash >= 4 does not come with osx because of its # GPLv3 license. Install it via homebrew. ## Set GDBUS='ssh pi@raspberrypi.local gdbus' to use remote gdbus. ## Set INTROSPECT=0 to skip introspection. # # Code generation requires dbus-codegen-rust. # Install with `cargo install dbus-codegen`. ## Set GENERATE=0 to skip code generation. set -euo pipefail GDBUS=${GDBUS:-gdbus} INTROSPECT=${INTROSPECT:-1} GENERATE=${GENERATE:-1} if [ $# != 0 ]; then echo "ERROR: $0 should be configured via the following environment variables:" echo grep '^## ' "$0" | sed 's/^## / /' echo exit 1 fi cd "$(dirname "$0")" if [ "$INTROSPECT" = 1 ]; then $GDBUS introspect --system --dest org.bluez --object-path / --recurse \ | grep -E '^ *(node|interface) .* {$' \ | ( declare -A interface_to_path while read -r keyword value _bracket; do if [ "$keyword" = 'node' ]; then current_path=$value elif [ "$keyword" = 'interface' ]; then interface_to_path[${value}]=$current_path else echo "unexpected line $keyword $value $_bracket" exit 1 fi done for interface in "${!interface_to_path[@]}"; do [[ $interface == org.bluez* ]] || continue echo "$interface" -- "${interface_to_path[${interface}]}" $GDBUS introspect \ --system \ --dest=org.bluez \ --object-path="${interface_to_path[${interface}]}" \ --xml \ | xmllint --format - \ | grep -v '^ *$' \ > "specs/$interface.xml" done ) fi if [ "$GENERATE" = 1 ]; then echo "// Generated by introspect.sh" > src/lib.rs echo "#![allow(clippy::upper_case_acronyms, clippy::needless_borrow)]" >> src/lib.rs for file in specs/org.bluez.*.xml; do interface=$( echo "$file" \ | sed -e 's:^specs/::' -e 's:[.]xml$::' ) modname=$( echo "$interface" \ | sed -e 's/^org.bluez.//' \ | tr '[:upper:]' '[:lower:]' ) dbus-codegen-rust \ --file="$file" \ --interfaces="$interface" \ --client=nonblock \ --methodtype=none \ --prop-newtype \ | grep -v '^use dbus as dbus;$' \ | rustfmt \ > "src/$modname.rs" echo "pub mod $modname;" >> src/lib.rs echo "pub use $modname::*;" >> src/lib.rs done cargo fmt fi