Skip to content

Commit 37b6d40

Browse files
committed
Bluetooth: Rename bt_on_off test and add BT_SCAN_PAIR test
- Renamed existing Bluetooth validation script to bt_on_off for clarity - Added new BT_SCAN_PAIR test: - Supports dynamic BT device name input - Uses bluetoothctl and expect for pairing flow - Includes retry logic for hci0 up, scan, and pairing steps - Performs full scan-pair-cleanup lifecycle - Logs all intermediate steps for better CI debugging - Compatible with POSIX and ShellCheck guidelines Resolves issues in earlier pairing logic and supports robust CI execution with dynamic device handling. Signed-off-by: Srikanth Muppandam <[email protected]>
1 parent 8e078f4 commit 37b6d40

File tree

6 files changed

+368
-13
lines changed

6 files changed

+368
-13
lines changed
File renamed without changes.

Runner/suites/Connectivity/Bluetooth/run.sh renamed to Runner/suites/Connectivity/Bluetooth/BT_ON_FF/run.sh

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
44
# SPDX-License-Identifier: BSD-3-Clause-Clear
5-
6-
# Source init_env and functestlib.sh
5+
6+
# Robustly find and source init_env
77
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
88
INIT_ENV=""
99
SEARCH="$SCRIPT_DIR"
@@ -14,31 +14,32 @@ while [ "$SEARCH" != "/" ]; do
1414
fi
1515
SEARCH=$(dirname "$SEARCH")
1616
done
17-
17+
1818
if [ -z "$INIT_ENV" ]; then
1919
echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2
2020
exit 1
2121
fi
22-
23-
# shellcheck disable=SC1090
24-
. "$INIT_ENV"
25-
22+
23+
if [ -z "$__INIT_ENV_LOADED" ]; then
24+
# shellcheck disable=SC1090
25+
. "$INIT_ENV"
26+
fi
2627
# shellcheck disable=SC1090,SC1091
2728
. "$TOOLS/functestlib.sh"
28-
29-
TESTNAME="Bluetooth"
29+
30+
TESTNAME="BT_ON_FF"
3031
test_path=$(find_test_case_by_name "$TESTNAME") || {
3132
log_fail "$TESTNAME : Test directory not found."
3233
echo "$TESTNAME FAIL" > "./$TESTNAME.res"
3334
exit 1
3435
}
35-
36+
3637
cd "$test_path" || exit 1
3738
res_file="./$TESTNAME.res"
3839
rm -f "$res_file"
39-
40-
log_info "-----------------------------------------------------------------------------------------"
41-
log_info "-------------------Starting $TESTNAME Testcase----------------------------"
40+
41+
log_info "------------------------------------------------------------"
42+
log_info "Starting $TESTNAME Testcase"
4243
log_info "Checking dependency: bluetoothctl"
4344
check_dependencies bluetoothctl
4445

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
2+
# Bluetooth BT_SCAN_PAIR Test
3+
4+
This test automates Bluetooth scanning and pairing for embedded Linux devices using BlueZ and bluetoothctl. It is designed for use in the [qcom-linux-testkit](https://github.com/qualcomm-linux/qcom-linux-testkit) test suite.
5+
6+
## Features
7+
8+
- Scans for Bluetooth devices
9+
- Optionally pairs with a device by name or MAC address
10+
- Retries pairing on failure, including handling for busy/temporarily unavailable devices
11+
- Cleans up previous pairings for repeatable CI runs
12+
- Accepts device name/MAC as argument, environment variable, or in `bt_device_list.txt`
13+
- Generates summary and detailed logs (`scan.log`, `pair.log`, `found_devices.log`)
14+
15+
## Usage
16+
17+
```sh
18+
./run.sh [DEVICE_NAME_OR_MAC] [WHITELIST]
19+
```
20+
- `DEVICE_NAME_OR_MAC` – (optional) Device name or MAC address to pair.
21+
- Can also be set as `BT_NAME_ENV` or in `bt_device_list.txt`
22+
- `WHITELIST` – (optional) Comma-separated MACs/names allowed for pairing.
23+
- Can also be set as `BT_WHITELIST_ENV`
24+
25+
If no device name is given, only scanning is performed and the test passes if devices are found.
26+
27+
## Examples
28+
29+
```sh
30+
./run.sh [BT_NAME] [WHITELIST]
31+
```
32+
33+
- `BT_NAME` - Optional. Bluetooth name or MAC to search for.
34+
- `WHITELIST` - Optional. Comma-separated names/MACs allowed for pairing.
35+
36+
- Scan for any device (no pairing):
37+
38+
```
39+
./run.sh
40+
```
41+
42+
- Scan and pair with a device named "MySpeaker":
43+
44+
```
45+
./run.sh MySpeaker
46+
```
47+
48+
- Scan and pair only if device MAC is in whitelist:
49+
50+
```
51+
./run.sh MySpeaker 00:11:22:33:44:55,AnotherSpeaker
52+
```
53+
54+
- Use environment variables:
55+
56+
```
57+
export BT_NAME_ENV="MySpeaker"
58+
export BT_WHITELIST_ENV="00:11:22:33:44:55"
59+
./run.sh
60+
```
61+
62+
- Device list file (first line is used):
63+
64+
```
65+
echo "MySpeaker" > bt_device_list.txt
66+
./run.sh
67+
```
68+
69+
## Whitelist Usage
70+
71+
To ensure only known devices are considered during scan:
72+
73+
```sh
74+
./run.sh JBL_Speaker "JBL_Speaker,12:34:56:78:9A:BC"
75+
```
76+
77+
## Arguments & Variables
78+
79+
- Argument 1: Device name or MAC address (takes precedence)
80+
- `BT_NAME_ENV`: Device name or MAC from the environment
81+
- `bt_device_list.txt`: Fallback if argument or env is not set
82+
83+
## Example Summary Output
84+
85+
```
86+
[INFO] 2025-06-23 10:00:00 - Starting BT_SCAN_PAIR Testcase
87+
[INFO] 2025-06-23 10:00:02 - Unblocking and powering on Bluetooth
88+
[INFO] 2025-06-23 10:00:05 - Devices found during scan:
89+
Device 12:34:56:78:9A:BC SomeBTHeadset
90+
[INFO] 2025-06-23 10:00:06 - Expected device 'SomeBTHeadset' found in scan
91+
[PASS] 2025-06-23 10:00:08 - Pairing successful with 12:34:56:78:9A:BC
92+
```
93+
94+
## Result
95+
96+
- PASS: Device paired (or scan-only with no target)
97+
- FAIL: Device not found, not in whitelist, or pairing failed
98+
- All paired devices are removed after the test
99+
100+
## Files Generated
101+
102+
- `BT_SCAN_PAIR.res`: Test PASS/FAIL/SKIP result
103+
- `scan.log`: Output of Bluetooth device scan
104+
- `found_devices.log`: List of discovered device names/MACs
105+
- `pair.log`: Detailed pairing output and errors
106+
107+
## Troubleshooting
108+
109+
- Ensure `bluetoothctl`, `rfkill`, `expect`, and `hciconfig` are available.
110+
- For headless automation, the remote device must be in pairing/discoverable mode.
111+
- The script retries pairing if "busy" or "temporarily unavailable" errors are seen.
112+
- Check `pair.log` and `scan.log` for detailed debug info if a failure occurs.
113+
114+
## Helper Functions (in functestlib.sh)
115+
116+
- `bt_scan_devices` – Scans and logs found BT devices
117+
- `bt_pair_with_mac` – Attempts pairing via expect with retries
118+
- `bt_in_whitelist` – Checks if MAC/name is in whitelist
119+
- `bt_cleanup_paired_device` – Removes paired device by MAC
120+
121+
## Customization
122+
123+
- **Whitelist**: You can restrict scan to a whitelist of MAC addresses or names using environment variables or script customization.
124+
- **Retries/Timeouts**: Retry and timeout values can be set in the script for more robust pairing.
125+
126+
## Integration with LAVA
127+
128+
In your LAVA job:
129+
130+
```yaml
131+
deploy:
132+
to: tftp
133+
images:
134+
bt_device_list.txt:
135+
image: path/to/bt_device_list.txt
136+
compression: none
137+
```
138+
139+
Injects a per-DUT Bluetooth configuration.
140+
141+
## Dependencies
142+
143+
- `bluetoothctl`, `expect`, `rfkill`, `hciconfig`
144+
- BlueZ stack running on embedded Linux
145+
146+
## License
147+
148+
SPDX-License-Identifier: BSD-3-Clause-Clear
149+
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.

Runner/suites/Connectivity/Bluetooth/BT_SCAN_PAIR/bt_device_list.txt

Whitespace-only changes.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/bin/sh
2+
3+
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4+
# SPDX-License-Identifier: BSD-3-Clause-Clear
5+
6+
# Robustly find and source init_env
7+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8+
INIT_ENV=""
9+
SEARCH="$SCRIPT_DIR"
10+
while [ "$SEARCH" != "/" ]; do
11+
if [ -f "$SEARCH/init_env" ]; then
12+
INIT_ENV="$SEARCH/init_env"
13+
break
14+
fi
15+
SEARCH=$(dirname "$SEARCH")
16+
done
17+
18+
if [ -z "$INIT_ENV" ]; then
19+
echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2
20+
exit 1
21+
fi
22+
23+
if [ -z "$__INIT_ENV_LOADED" ]; then
24+
# shellcheck disable=SC1090
25+
. "$INIT_ENV"
26+
fi
27+
# shellcheck disable=SC1090,SC1091
28+
. "$TOOLS/functestlib.sh"
29+
30+
TESTNAME="BT_SCAN_PAIR"
31+
test_path=$(find_test_case_by_name "$TESTNAME") || {
32+
log_fail "$TESTNAME : Test directory not found."
33+
echo "$TESTNAME FAIL" > "./$TESTNAME.res"
34+
exit 1
35+
}
36+
cd "$test_path" || exit 1
37+
RES_FILE="./$TESTNAME.res"
38+
rm -f "$RES_FILE"
39+
40+
log_info "------------------------------------------------------------"
41+
log_info "Starting $TESTNAME Testcase"
42+
43+
BT_NAME=""
44+
BT_MAC=""
45+
WHITELIST=""
46+
PAIR_RETRIES="${PAIR_RETRIES:-3}"
47+
48+
# Check bt_device_list.txt if present
49+
if [ -f "./bt_device_list.txt" ]; then
50+
BT_NAME=$(awk '!/^#/ && NF {print $2}' ./bt_device_list.txt | head -n1)
51+
BT_MAC=$(awk '!/^#/ && NF {print $1}' ./bt_device_list.txt | head -n1)
52+
fi
53+
54+
# Command-line override
55+
[ -n "$1" ] && BT_NAME="$1"
56+
[ -n "$2" ] && WHITELIST="$2"
57+
58+
check_dependencies bluetoothctl rfkill expect hciconfig || {
59+
echo "$TESTNAME SKIP" > "$RES_FILE"
60+
exit 0
61+
}
62+
63+
cleanup_bt_test() {
64+
[ -n "$BT_MAC" ] && bt_cleanup_paired_device "$BT_MAC"
65+
killall -q bluetoothctl 2>/dev/null
66+
}
67+
trap cleanup_bt_test EXIT
68+
69+
rfkill unblock bluetooth
70+
retry_command_bt "hciconfig hci0 up" "Bring up hci0" || {
71+
log_fail "Failed to bring up hci0"
72+
echo "$TESTNAME FAIL" > "$RES_FILE"
73+
exit 1
74+
}
75+
76+
log_info "Scanning for Bluetooth devices..."
77+
bt_scan_devices
78+
log_info "Devices found during scan:"
79+
cat found_devices.log
80+
81+
if [ -z "$BT_NAME" ] && [ -z "$BT_MAC" ]; then
82+
log_pass "No device specified. Scan-only mode."
83+
echo "$TESTNAME PASS" > "$RES_FILE"
84+
exit 0
85+
fi
86+
87+
MATCH_FOUND=0
88+
while IFS= read -r line; do
89+
mac=$(echo "$line" | awk '{print $3}')
90+
name=$(echo "$line" | cut -d' ' -f4-)
91+
if { [ "$mac" = "$BT_MAC" ] || [ "$name" = "$BT_NAME" ]; } && \
92+
{ bt_in_whitelist "$mac" "$WHITELIST" || bt_in_whitelist "$name" "$WHITELIST"; }; then
93+
BT_MAC="$mac"
94+
MATCH_FOUND=1
95+
break
96+
fi
97+
done < found_devices.log
98+
99+
if [ "$MATCH_FOUND" -ne 1 ]; then
100+
log_fail "Expected device not found or not in whitelist"
101+
echo "$TESTNAME FAIL" > "$RES_FILE"
102+
exit 1
103+
fi
104+
105+
log_info "Attempting to pair with $BT_NAME ($BT_MAC)"
106+
if bt_pair_with_mac "$BT_MAC" "$PAIR_RETRIES"; then
107+
log_pass "Pairing successful"
108+
echo "$TESTNAME PASS" > "$RES_FILE"
109+
exit 0
110+
else
111+
log_fail "Pairing failed after $PAIR_RETRIES retries"
112+
echo "$TESTNAME FAIL" > "$RES_FILE"
113+
exit 1
114+
fi
115+
116+
log_info "Completed $TESTNAME Testcase"

0 commit comments

Comments
 (0)