#!/usr/bin/bash
#
# Give the Bluetooth controller its factory address.
#
# The WCN3990 has no burned-in Bluetooth address. The kernel brings the
# controller up, downloads its firmware, and then registers it *unconfigured* —
# it answers on /sys/class/bluetooth but does not appear in the management
# interface, so bluetoothctl reports "No default controller available" and
# nothing works until userspace supplies an address.
#
# The factory address is on the machine, in the Windows provisioning partition
# (GPT label DPP, FAT): QCOM/BT.PROVISION is nine bytes — a three-byte header
# followed by the six-byte address in display order. QCOM/WLAN.PROVISION holds
# the WiFi MAC in the same layout, sharing the same OUI block, which is how the
# layout was recognised.
#
# Setting it flips the controller from unconfigured to configured and powered.

set -euo pipefail

for _ in $(seq 30); do
    [ -d /sys/class/bluetooth/hci0 ] && break
    sleep 1
done
if [ ! -d /sys/class/bluetooth/hci0 ]; then
    echo "c630-bt-addr: no Bluetooth controller appeared; nothing to do"
    exit 0
fi

if ! btmgmt info | grep -q "Index list with 0 items"; then
    echo "c630-bt-addr: controller already configured; nothing to do"
    exit 0
fi

dpp=/dev/disk/by-partlabel/DPP
if [ ! -b "$dpp" ]; then
    echo "c630-bt-addr: no DPP partition; cannot recover the factory address" >&2
    exit 0
fi

mnt=$(mktemp -d)
trap 'umount "$mnt" 2>/dev/null || true; rmdir "$mnt"' EXIT
mount -o ro "$dpp" "$mnt"

prov="$mnt/QCOM/BT.PROVISION"
if [ ! -f "$prov" ] || [ "$(stat -c %s "$prov")" -lt 9 ]; then
    echo "c630-bt-addr: $prov missing or too short" >&2
    exit 0
fi

addr=$(od -An -tx1 -j3 -N6 "$prov" | tr -s ' ' '\n' | grep . | paste -sd:)
btmgmt --index 0 public-addr "$addr"
echo "c630-bt-addr: set hci0 public address to $addr"
