Give Bluetooth its factory address from the DPP partition
The WCN3990 has no burned-in Bluetooth address, so the kernel registers the controller unconfigured and bluetoothd never sees it. The factory address is on the machine all along: QCOM/BT.PROVISION on the DPP partition, a three-byte header followed by the six-byte address. c630-bt-addr reads it and hands it to btmgmt before bluetooth.service starts. Verified on hardware: controller configures, powers, scans, and streams A2DP. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
This commit is contained in:
@@ -284,6 +284,7 @@ chroot "$ROOTFS" passwd -l root
|
|||||||
# without tqftpserv, since the modem fetches the WLAN firmware over TFTP.
|
# without tqftpserv, since the modem fetches the WLAN firmware over TFTP.
|
||||||
chroot "$ROOTFS" systemctl enable \
|
chroot "$ROOTFS" systemctl enable \
|
||||||
c630-growfs.service \
|
c630-growfs.service \
|
||||||
|
c630-bt-addr.service \
|
||||||
sshd.service \
|
sshd.service \
|
||||||
NetworkManager.service \
|
NetworkManager.service \
|
||||||
systemd-resolved.service \
|
systemd-resolved.service \
|
||||||
|
|||||||
15
overlay/etc/systemd/system/c630-bt-addr.service
Normal file
15
overlay/etc/systemd/system/c630-bt-addr.service
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Set the C630 Bluetooth factory address from the DPP partition
|
||||||
|
# The WCN3990 has no burned-in address; the controller stays unconfigured and
|
||||||
|
# invisible to bluetoothd until one is set. See /usr/local/sbin/c630-bt-addr.
|
||||||
|
Before=bluetooth.service
|
||||||
|
ConditionPathExists=/dev/disk/by-partlabel/DPP
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/sbin/c630-bt-addr
|
||||||
|
RemainAfterExit=yes
|
||||||
|
StandardOutput=journal
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
53
overlay/usr/local/sbin/c630-bt-addr
Executable file
53
overlay/usr/local/sbin/c630-bt-addr
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/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"
|
||||||
Reference in New Issue
Block a user