Category: Uncategorized

  • Getting Bluetooth Working on LineageOS Android TV on the NVIDIA Jetson Nano 2GB

    I wanted to use a Bluetooth Xbox controller with LineageOS Android TV running on an NVIDIA Jetson Nano 2GB. The Jetson Nano does not have built-in Bluetooth, so I used a TP-Link UB400 USB Bluetooth adapter.

    The UB400 showed up as:

    Vendor=0a12
    Product=0001
    Driver=btusb

    This is what finally worked.

    1. Confirm the adapter is detected

    With the UB400 plugged in, check USB devices:

    cat /sys/kernel/debug/usb/devices | grep -i -A14 -B4 -E 'bluetooth|0a12|csr|cambridge|tp-link'

    The important part is:

    Vendor=0a12 ProdID=0001
    Driver=btusb

    Then check for the Bluetooth HCI device:

    ls -l /sys/class/bluetooth

    A working result should show:

    hci0

    2. Load the Bluetooth modules at boot

    The needed modules were already included in the LineageOS build:

    btbcm
    btintel
    btrtl
    btusb

    The module load file was:

    /vendor/lib/modules/modules.load

    Remount /vendor as writable:

    mount -o rw,remount /vendor

    Then add these lines to the bottom of /vendor/lib/modules/modules.load:

    btbcm
    btintel
    btrtl
    btusb

    Order matters. btusb should come last.

    3. Patch SELinux for the Bluetooth HAL

    Bluetooth worked only after the Bluetooth HAL was allowed to create and use its HCI socket.

    The policy file was:

    /vendor/etc/selinux/vendor_sepolicy.cil

    Back it up:

    cp /vendor/etc/selinux/vendor_sepolicy.cil /vendor/etc/selinux/vendor_sepolicy.cil.bak-btfix
    mkdir -p /vendor/etc/selinux/backup-btfix

    Add this rule to the bottom of vendor_sepolicy.cil:

    ; Jetson Nano USB Bluetooth HAL socket fix
    (allow hal_bluetooth_default hal_bluetooth_default (socket (create bind read write)))

    Because Android was using a precompiled SELinux policy, move that out of the way:

    mv /vendor/etc/selinux/precompiled_sepolicy* /vendor/etc/selinux/backup-btfix/

    Then reboot:

    reboot

    4. Disable LE vendor capabilities

    The UB400 created hci0, but Android’s Bluetooth stack crashed while trying to query LE vendor capabilities.

    The fix was:

    setprop bluetooth.core.le.vendor_capabilities.enabled false

    To make it persistent, add it to /vendor/build.prop:

    mount -o rw,remount /vendor

    grep -q '^bluetooth.core.le.vendor_capabilities.enabled=' /vendor/build.prop \
    && sed -i 's/^bluetooth.core.le.vendor_capabilities.enabled=.*/bluetooth.core.le.vendor_capabilities.enabled=false/' /vendor/build.prop \
    || echo 'bluetooth.core.le.vendor_capabilities.enabled=false' >> /vendor/build.prop

    Then reboot again:

    reboot

    5. Test Bluetooth

    After reboot:

    getprop bluetooth.core.le.vendor_capabilities.enabled

    Expected:

    false

    Then check Bluetooth status:

    dumpsys bluetooth_manager | grep -i -E 'enabled|state|address|name'

    A working result should show:

    enabled: true
    state: ON
    name: SHIELD Android TV

    6. Pair accessories

    To open the Android TV pairing screen:

    am start -n com.android.tv.settings/.accessories.AddAccessoryActivity

    Then put the Xbox controller in pairing mode and select it from the list.

    Final working setup

    NVIDIA Jetson Nano 2GB
    LineageOS Android TV
    TP-Link UB400 USB Bluetooth adapter
    Xbox Wireless Controller

    After these changes, Bluetooth survived reboot and the Xbox controller connected normally.