Skip to content

Commit 264cc7c

Browse files
authored
Ble-WiFi commissioning test in CI - dockerfile (#32890)
* Add docker img for qemu testing * Update version file * Compress qemu image and sort dependencies * Use stages during docker build * Remove unused script from docker img, add missing qemu pkg
1 parent ae50802 commit 264cc7c

File tree

11 files changed

+409
-1
lines changed

11 files changed

+409
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
47 : [Telink] Update Docker image (Zephyr update)
1+
48 : [QEMU] Add QEMU Dockerfile for ble-wifi testing on Linux
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
ARG VERSION=latest
2+
ARG UBUNTU_QEMU_DIR_DEFAULT="/opt/ubuntu-qemu"
3+
ARG UBUNTU_QEMU_IMG_DEFAULT="${UBUNTU_QEMU_DIR_DEFAULT}/ubuntu-20.04.img"
4+
5+
FROM ghcr.io/project-chip/chip-build:${VERSION} as build-env
6+
LABEL org.opencontainers.image.source https://github.com/project-chip/connectedhomeip
7+
8+
ARG BLUEZ_VERSION=5.72
9+
ARG ELL_VERSION=0.62
10+
ARG KERNEL_VERSION=6.7.3
11+
ARG UBUNTU_QEMU_DIR_DEFAULT
12+
ARG UBUNTU_QEMU_IMG_DEFAULT
13+
14+
ENV UBUNTU_QEMU_DIR=${UBUNTU_QEMU_DIR_DEFAULT}
15+
ENV UBUNTU_QEMU_IMG=${UBUNTU_QEMU_IMG_DEFAULT}
16+
17+
RUN mkdir -p /tmp/workdir/linux
18+
COPY files/linux/0001-Bluetooth-MGMT-Synchronize-scan-start-and-LE-Meta-ev.patch /tmp/workdir/linux/0001-Bluetooth-MGMT-Synchronize-scan-start-and-LE-Meta-ev.patch
19+
COPY files/bluetooth/main.conf /tmp/workdir/main.conf
20+
RUN set -x \
21+
&& apt-get update \
22+
&& DEBIAN_FRONTEND=noninteractive apt-get install -fy \
23+
bc \
24+
cpio \
25+
dwarves \
26+
elfutils \
27+
fakeroot \
28+
libdw-dev \
29+
libelf-dev \
30+
libell-dev \
31+
libell0 \
32+
libguestfs-tools \
33+
linux-image-generic \
34+
ncurses-dev \
35+
qemu \
36+
xz-utils \
37+
zstd \
38+
&& apt-get clean \
39+
&& rm -rf /var/lib/apt/lists/* \
40+
&& rm -rf /var/cache/apt/* \
41+
&& : # last line
42+
43+
# Download Linux kernel source
44+
RUN mkdir -p /tmp/workdir/linux \
45+
&& export MAKEFLAGS=-j$(nproc) \
46+
&& cd /tmp/workdir \
47+
&& curl https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz -o /tmp/workdir/linux-${KERNEL_VERSION}.tar.xz \
48+
&& tar -xJf linux-${KERNEL_VERSION}.tar.xz -C /tmp/workdir/linux --strip-components=1 \
49+
&& rm /tmp/workdir/linux-${KERNEL_VERSION}.tar.xz \
50+
# Set configuration for btvirt
51+
&& cd /tmp/workdir/linux \
52+
&& patch -p1 < /tmp/workdir/linux/0001-Bluetooth-MGMT-Synchronize-scan-start-and-LE-Meta-ev.patch \
53+
&& make x86_64_defconfig \
54+
&& ./scripts/config -e BT \
55+
&& ./scripts/config -e BT_BREDR \
56+
&& ./scripts/config -e BT_HCIVHCI \
57+
&& ./scripts/config -e CONFIG_BRIDGE \
58+
&& ./scripts/config -e CONFIG_CRYPTO_AES \
59+
&& ./scripts/config -e CONFIG_CRYPTO_CMAC \
60+
&& ./scripts/config -e CONFIG_CRYPTO_ECB \
61+
&& ./scripts/config -e CONFIG_CRYPTO_USER \
62+
&& ./scripts/config -e CONFIG_CRYPTO_USER_API_HASH \
63+
&& ./scripts/config -e CONFIG_CRYPTO_USER_API_SKCIPHER \
64+
&& ./scripts/config -e CONFIG_VETH \
65+
&& ./scripts/config -e MAC80211 \
66+
&& ./scripts/config -e MAC80211_HWSIM \
67+
# Compile
68+
&& make olddefconfig \
69+
&& make \
70+
&& mkdir -p /opt/ubuntu-qemu/rootfs \
71+
&& make modules_install INSTALL_MOD_PATH=/opt/ubuntu-qemu/rootfs \
72+
&& cp /tmp/workdir/linux/arch/x86/boot/bzImage /opt/ubuntu-qemu/bzImage \
73+
# Build bluez
74+
&& git clone git://git.kernel.org/pub/scm/libs/ell/ell.git /tmp/workdir/ell --depth 1 --branch ${ELL_VERSION} \
75+
&& git clone https://github.com/bluez/bluez.git /tmp/workdir/bluez --depth 1 --branch ${BLUEZ_VERSION} \
76+
&& cd /tmp/workdir/bluez \
77+
&& ./bootstrap \
78+
&& ./configure \
79+
--enable-backtrace \
80+
--enable-debug \
81+
--enable-deprecated \
82+
--enable-experimental \
83+
--enable-library \
84+
--enable-monitor \
85+
--enable-pie \
86+
--enable-test \
87+
--enable-testing \
88+
--enable-tools \
89+
--enable-tools \
90+
--enable-udev \
91+
--disable-a2dp \
92+
--disable-avrcp \
93+
--disable-bap \
94+
--disable-bass \
95+
--disable-csip \
96+
--disable-cups \
97+
--disable-cups \
98+
--disable-health \
99+
--disable-hid \
100+
--disable-hid2hci \
101+
--disable-hog \
102+
--disable-manpages \
103+
--disable-mcp \
104+
--disable-mesh \
105+
--disable-micp \
106+
--disable-midi \
107+
--disable-network \
108+
--disable-obex \
109+
--disable-optimization \
110+
--disable-sap \
111+
--disable-silent-rules \
112+
--disable-vcp \
113+
--prefix=/usr \
114+
--mandir=/usr/share/man \
115+
--sysconfdir=/etc \
116+
--localstatedir=/var \
117+
--with-systemdsystemunitdir=/lib/systemd/system \
118+
--with-systemduserunitdir=/usr/lib/systemd \
119+
&& make \
120+
&& make install DESTDIR=/opt/ubuntu-qemu/rootfs && mkdir -p /opt/ubuntu-qemu/rootfs/usr/bin && cp /tmp/workdir/bluez/emulator/btvirt /opt/ubuntu-qemu/rootfs/usr/bin \
121+
# Download Ubuntu image for QEMU
122+
&& curl https://cloud-images.ubuntu.com/minimal/releases/focal/release/ubuntu-20.04-minimal-cloudimg-amd64.img \
123+
-o /tmp/workdir/ubuntu-20.04-minimal-cloudimg-amd64.img \
124+
# Prepare ubuntu image
125+
&& qemu-img create -f qcow2 -o preallocation=off $UBUNTU_QEMU_IMG 10G \
126+
&& virt-resize --expand /dev/sda1 /tmp/workdir/ubuntu-20.04-minimal-cloudimg-amd64.img $UBUNTU_QEMU_IMG \
127+
&& guestfish -a $UBUNTU_QEMU_IMG \
128+
--mount /dev/sda3:/ \
129+
--network \
130+
copy-in /opt/ubuntu-qemu/rootfs/lib /usr : \
131+
copy-in /opt/ubuntu-qemu/rootfs/usr / : \
132+
sh 'apt-get remove -y snapd' : \
133+
sh 'apt-get update' : \
134+
sh 'DEBIAN_FRONTEND=noninteractive apt-get install -y dnsmasq hostapd wpasupplicant iw libdw1 rfkill' : \
135+
sh '/usr/bin/systemctl enable bluetooth.service' : \
136+
sh '/usr/bin/systemctl disable cloud-init.service' : \
137+
sh '/usr/bin/systemctl disable dbus-fi.w1.wpa_supplicant1.service' : \
138+
sh '/usr/bin/systemctl disable dnsmasq.service' : \
139+
sh '/usr/bin/systemctl disable hostapd.service' : \
140+
sh '/usr/bin/systemctl disable lxd-agent.service' : \
141+
sh '/usr/bin/systemctl disable systemd-networkd-wait-online.service' : \
142+
sh '/usr/bin/systemctl disable systemd-timesyncd.service' : \
143+
sh '/usr/bin/systemctl disable wpa_supplicant.service' : \
144+
sh '/usr/bin/systemctl mask cloud-init.service' : \
145+
sh '/usr/bin/systemctl mask dbus-fi.w1.wpa_supplicant1.service' : \
146+
sh '/usr/bin/systemctl mask dnsmasq.service' : \
147+
sh '/usr/bin/systemctl mask hostapd.service' : \
148+
sh '/usr/bin/systemctl mask lxd-agent.service' : \
149+
sh '/usr/bin/systemctl mask systemd-networkd-wait-online.service' : \
150+
sh '/usr/bin/systemctl mask systemd-timesyncd.service' : \
151+
sh '/usr/bin/systemctl mask wpa_supplicant.service' : \
152+
sh 'passwd -d root' : \
153+
sh 'ssh-keygen -A' : \
154+
sh '/bin/echo -e "PermitRootLogin yes\nPasswordAuthentication yes\nPermitEmptyPasswords yes" > /etc/ssh/sshd_config' : \
155+
mkdir-p "/etc/netplan" : \
156+
sh '/bin/echo -e "network:\n version: 2\n renderer: networkd\n ethernets:\n enp0s4:\n dhcp4: true\n" > /etc/netplan/01-netcfg.yaml' : \
157+
sh 'chmod -R 700 /etc/netplan' : \
158+
sh 'sed -i "s#^ExecStart=.*#ExecStart=-/sbin/agetty -o \"-p -- \\\\\\\\u\" -a root --keep-baud 115200,38400,9600 %I \$TERM#" "/usr/lib/systemd/system/serial-getty@.service"' : \
159+
mkdir-p "/etc/bluetooth" : \
160+
copy-in /tmp/workdir/main.conf /etc/bluetooth : \
161+
sh 'sed -i "s#^ExecStart=.*#ExecStart=-/usr/libexec/bluetooth/bluetoothd -E#" /lib/systemd/system/bluetooth.service' : \
162+
sh 'rm -f /etc/resolv.conf && /bin/echo -e "nameserver 8.8.8.8" > /etc/resolv.conf' : \
163+
sh '/bin/echo -e "host0 /chip 9p trans=virtio,version=9p2000.L 0 0" >> /etc/fstab' : \
164+
sh '/bin/echo -e "export PW_ENVIRONMENT_ROOT=/root/pw_root\n[ -x /launcher.sh ] && /launcher.sh\n" >> /root/.profile' : \
165+
sh 'DEBIAN_FRONTEND=noninteractive apt-get -y install git gcc g++ pkg-config libssl-dev libdbus-1-dev libglib2.0-dev libavahi-client-dev ninja-build python3 python3-venv python3-dev python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev' : \
166+
sh 'git config --file /root/.gitconfig --add safe.directory "*"' : \
167+
sh 'apt-get clean' : \
168+
sh 'rm -rf /var/lib/apt/lists/*' : \
169+
sh 'rm -rf /var/cache/apt/*' : \
170+
sh 'echo Configuration completed.' \
171+
&& mkdir -p /chip \
172+
&& rm -rf /opt/ubuntu-qemu/rootfs \
173+
&& echo -n \
174+
"#!/bin/bash\n" \
175+
"grep -q 'rootshell' /proc/cmdline && exit\n" \
176+
"if [[ -x /chip/runner.sh ]]; then\n" \
177+
" echo '### RUNNER START ###'\n" \
178+
" cd /chip\n" \
179+
" bash /chip/runner.sh\n" \
180+
" status=\$?\n" \
181+
" echo \"### RUNNER STOP, RETURN: \$status\"\n" \
182+
" echo \$status > /chip/runner_status\n" \
183+
"else\n" \
184+
" read -r -t 5 -p 'Press ENTER to access root shell...' && exit || echo ' timeout.'\n" \
185+
"fi\n" \
186+
"echo 'Shutting down emulated system...'\n" \
187+
"echo o > /proc/sysrq-trigger\n" \
188+
| guestfish --rw -a $UBUNTU_QEMU_IMG -m /dev/sda3:/ upload - /launcher.sh : chmod 0755 /launcher.sh \
189+
&& virt-sparsify --compress ${UBUNTU_QEMU_IMG} ${UBUNTU_QEMU_IMG}.compressed \
190+
&& mv ${UBUNTU_QEMU_IMG}.compressed ${UBUNTU_QEMU_IMG} \
191+
&& rm -rf /var/tmp/.guestfs-0/* \
192+
&& rm -rf /tmp/* \
193+
&& : # last line
194+
195+
FROM ghcr.io/project-chip/chip-build:${VERSION}
196+
197+
ARG UBUNTU_QEMU_DIR_DEFAULT
198+
ARG UBUNTU_QEMU_IMG_DEFAULT
199+
200+
ENV UBUNTU_QEMU_DIR=${UBUNTU_QEMU_DIR_DEFAULT}
201+
ENV UBUNTU_QEMU_IMG=${UBUNTU_QEMU_IMG_DEFAULT}
202+
ENV PW_ENVIRONMENT_ROOT="/root/pw_root"
203+
204+
RUN set -x \
205+
&& apt-get update \
206+
&& DEBIAN_FRONTEND=noninteractive apt-get install -fy \
207+
cpu-checker \
208+
qemu \
209+
qemu-system-x86 \
210+
&& apt-get clean \
211+
&& rm -rf /var/lib/apt/lists/* \
212+
&& rm -rf /var/cache/apt/* \
213+
&& : # last line
214+
COPY --from=build-env ${UBUNTU_QEMU_DIR} ${UBUNTU_QEMU_DIR}
215+
216+
WORKDIR /chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../build.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[GATT]
2+
Cache=no
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
From 4dc80d22bd964c0c3fcd0840b6728b3884d2ff1b Mon Sep 17 00:00:00 2001
2+
From: Arkadiusz Bokowy <a.bokowy@samsung.com>
3+
Date: Thu, 28 Sep 2023 13:38:17 +0200
4+
Subject: [PATCH] Bluetooth: MGMT: Synchronize scan start and LE Meta events
5+
6+
It is possible that the Bluetooth management will receive scan enabled
7+
signal and LE meta events one by another without any delay. Since the
8+
start discovery procedure is performed in an asynchronous manner, it is
9+
possible that these HCI events will be processed concurrently by two
10+
different worker threads. In such case, it is possible that the LE meta
11+
event, which reports new device, will be discarded, because discovering
12+
is still in the starting state.
13+
14+
The problem is most prominent with the btvirt userspace tool, which
15+
sends LE Meta events just after reporting scan as enabled. Testing
16+
scenario:
17+
18+
1. Create two HCI interfaces:
19+
> btvirt -l2
20+
21+
2. Setup BLE advertisement on hci1:
22+
> bluetoothctl
23+
>> select 00:AA:01:00:00:00
24+
>> menu advertise
25+
>> uuids 03B80E5A-EDE8-4B33-A751-6CE34EC4C700
26+
>> discoverable on
27+
>> back
28+
>> advertise peripheral
29+
30+
3. Start scanning on hci2:
31+
> bluetoothctl
32+
>> select 00:AA:01:01:00:01
33+
>> scan le
34+
// From time to time, new device is not reported
35+
36+
This patch adds synchronization for start discovery procedure and device
37+
found reporting by the Bluetooth management. In case of discovering
38+
being in the starting state, the worker which processes LE Meta event
39+
will wait for the cmd_sync_work on which the start discovery procedure
40+
is queued.
41+
42+
Signed-off-by: Arkadiusz Bokowy <a.bokowy@samsung.com>
43+
---
44+
include/net/bluetooth/hci_core.h | 5 +++++
45+
include/net/bluetooth/hci_sync.h | 1 +
46+
net/bluetooth/hci_sync.c | 7 +++++++
47+
net/bluetooth/mgmt.c | 17 +++++++++++++++--
48+
4 files changed, 28 insertions(+), 2 deletions(-)
49+
50+
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
51+
index f36c1fd5d64e..456bbdf56246 100644
52+
--- a/include/net/bluetooth/hci_core.h
53+
+++ b/include/net/bluetooth/hci_core.h
54+
@@ -916,6 +916,11 @@ static inline void hci_discovery_filter_clear(struct hci_dev *hdev)
55+
56+
bool hci_discovery_active(struct hci_dev *hdev);
57+
58+
+static inline bool hci_discovery_starting(struct hci_dev *hdev)
59+
+{
60+
+ return hdev->discovery.state == DISCOVERY_STARTING;
61+
+}
62+
+
63+
void hci_discovery_set_state(struct hci_dev *hdev, int state);
64+
65+
static inline int inquiry_cache_empty(struct hci_dev *hdev)
66+
diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
67+
index 6efbc2152146..67cf6689a692 100644
68+
--- a/include/net/bluetooth/hci_sync.h
69+
+++ b/include/net/bluetooth/hci_sync.h
70+
@@ -43,6 +43,7 @@ void hci_cmd_sync_init(struct hci_dev *hdev);
71+
void hci_cmd_sync_clear(struct hci_dev *hdev);
72+
void hci_cmd_sync_cancel(struct hci_dev *hdev, int err);
73+
void __hci_cmd_sync_cancel(struct hci_dev *hdev, int err);
74+
+void hci_cmd_sync_flush(struct hci_dev *hdev);
75+
76+
int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
77+
void *data, hci_cmd_sync_work_destroy_t destroy);
78+
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
79+
index 3640d73f9595..58905a5b7b1e 100644
80+
--- a/net/bluetooth/hci_sync.c
81+
+++ b/net/bluetooth/hci_sync.c
82+
@@ -681,6 +681,13 @@ void hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
83+
}
84+
EXPORT_SYMBOL(hci_cmd_sync_cancel);
85+
86+
+/* Wait for all pending HCI commands to complete.
87+
+ */
88+
+void hci_cmd_sync_flush(struct hci_dev *hdev)
89+
+{
90+
+ flush_work(&hdev->cmd_sync_work);
91+
+}
92+
+
93+
/* Submit HCI command to be run in as cmd_sync_work:
94+
*
95+
* - hdev must _not_ be unregistered
96+
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
97+
index ba2e00646e8e..fc494348f2f7 100644
98+
--- a/net/bluetooth/mgmt.c
99+
+++ b/net/bluetooth/mgmt.c
100+
@@ -10374,18 +10374,31 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
101+
{
102+
struct sk_buff *skb;
103+
struct mgmt_ev_device_found *ev;
104+
- bool report_device = hci_discovery_active(hdev);
105+
+ bool report_device;
106+
107+
if (hci_dev_test_flag(hdev, HCI_MESH) && link_type == LE_LINK)
108+
mesh_device_found(hdev, bdaddr, addr_type, rssi, flags,
109+
eir, eir_len, scan_rsp, scan_rsp_len,
110+
instant);
111+
112+
+ /* Discovery start procedure is perfomed on a workqueue in an
113+
+ * asynchronous manner. This procedure is finished when the scan
114+
+ * enabled signal is received from the controller. Just after
115+
+ * this signal, the controller might send another event (e.g. LE
116+
+ * Meta). In such case, we need to make sure that the discovery
117+
+ * procedure is finished, because otherwise we might omit some
118+
+ * scan results.
119+
+ */
120+
+ if (hci_discovery_starting(hdev))
121+
+ hci_cmd_sync_flush(hdev);
122+
+
123+
+ report_device = hci_discovery_active(hdev);
124+
+
125+
/* Don't send events for a non-kernel initiated discovery. With
126+
* LE one exception is if we have pend_le_reports > 0 in which
127+
* case we're doing passive scanning and want these events.
128+
*/
129+
- if (!hci_discovery_active(hdev)) {
130+
+ if (!report_device) {
131+
if (link_type == ACL_LINK)
132+
return;
133+
if (link_type == LE_LINK && !list_empty(&hdev->pend_le_reports))
134+
--
135+
2.34.1
136+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
port=0
2+
interface=wlan1
3+
listen-address=192.168.200.1
4+
dhcp-range=192.168.200.10,192.168.200.200
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
interface=wlan1
2+
driver=nl80211
3+
country_code=DE
4+
ssid=Virtual_Wifi
5+
channel=1
6+
hw_mode=g
7+
wpa=3
8+
wpa_key_mgmt=WPA-PSK
9+
wpa_pairwise=TKIP CCMP
10+
wpa_passphrase=ExamplePassword
11+
auth_algs=3
12+
beacon_int=100
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ctrl_interface=DIR=/run/wpa_supplicant
2+
ctrl_interface_group=root
3+
update_config=1

0 commit comments

Comments
 (0)