Skip to content

Commit 537b3c0

Browse files
committed
tests: bluetooth: classic: sdp: add unregister_sdp shell command and test
Add a shell command to unregister SDP service records by index, and a pytest test case that verifies the full lifecycle: 1. Register a record and verify it is discoverable 2. Disconnect SDP, unregister, reconnect and verify it is gone 3. Re-register and verify it is discoverable again Initialize the error status variable before calling shell_strtoul(): unlike strtoul(), shell_strtoul() does not clear the output error code on the success path, so an uninitialized 'err' left a stale stack value that made the 'Invalid index' guard trip and silently skipped the actual unregister call. Also enable CONFIG_ZTEST_SHELL (so the native_sim image stays in the shell instead of exiting after an empty ztest run) and route the shell UART to stdin/stdout via CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT, so the pytest twister harness can drive the shell over the process pipes. Signed-off-by: Kai Cheng <chengkai@xiaomi.com>
1 parent 443efec commit 537b3c0

4 files changed

Lines changed: 105 additions & 0 deletions

File tree

tests/bluetooth/classic/sdp_s/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ CONFIG_BT_CLASSIC=y
33
CONFIG_BT_SHELL=y
44
CONFIG_LOG=y
55
CONFIG_ZTEST=y
6+
CONFIG_ZTEST_SHELL=y
67

78
CONFIG_BT_RFCOMM=y
89

tests/bluetooth/classic/sdp_s/pytest/test_sdp.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,13 +432,89 @@ async def sdp_discover_with_range(hci_port, shell, address) -> None:
432432
assert len(search_result) == 0
433433

434434

435+
async def sdp_unregister(hci_port, shell, address) -> None:
436+
logger.info('<<< connect...')
437+
async with await open_transport_or_link(hci_port) as hci_transport:
438+
device = Device.with_hci(
439+
'Bumble',
440+
Address('F0:F1:F2:F3:F4:F5'),
441+
hci_transport.source,
442+
hci_transport.sink,
443+
)
444+
445+
with open("bumble_hci_sdp_s_unregister.log", "wb") as snoop_file:
446+
device.host.snooper = BtSnooper(snoop_file)
447+
device.classic_enabled = True
448+
device.le_enabled = False
449+
await device_power_on(device)
450+
451+
target_address = address.split(" ")[0]
452+
logger.info(f'=== Connecting to {target_address}...')
453+
try:
454+
connection = await device.connect(target_address, transport=BT_BR_EDR_TRANSPORT)
455+
logger.info(f'=== Connected to {connection.peer_address}!')
456+
except CommandTimeoutError as e:
457+
logger.info('!!! Connection timed out')
458+
raise e
459+
460+
# Register record 0
461+
shell.exec_command("sdp_server register_sdp 0")
462+
463+
# Connect SDP and verify record is visible
464+
sdp_client = SDP_Client(connection)
465+
await sdp_client.connect()
466+
467+
logger.info("<<< 1 Verify record 0 is visible after register")
468+
service_record_handles = await sdp_client.search_services([SDP_PUBLIC_BROWSE_ROOT])
469+
logger.info(f'SERVICES: {service_record_handles}')
470+
assert len(service_record_handles) == 1
471+
472+
# Disconnect SDP L2CAP channel so unregister can succeed
473+
await sdp_client.disconnect()
474+
475+
# Unregister record 0
476+
shell.exec_command("sdp_server unregister_sdp 0")
477+
478+
# Reconnect SDP and verify record is gone
479+
await sdp_client.connect()
480+
481+
logger.info("<<< 2 Verify record 0 is gone after unregister")
482+
service_record_handles = await sdp_client.search_services([SDP_PUBLIC_BROWSE_ROOT])
483+
logger.info(f'SERVICES: {service_record_handles}')
484+
assert len(service_record_handles) == 0
485+
486+
# Disconnect SDP again
487+
await sdp_client.disconnect()
488+
489+
# Re-register record 0
490+
shell.exec_command("sdp_server register_sdp 0")
491+
492+
# Reconnect SDP and verify record is back
493+
await sdp_client.connect()
494+
495+
logger.info("<<< 3 Verify record 0 is visible after re-register")
496+
service_record_handles = await sdp_client.search_services([SDP_PUBLIC_BROWSE_ROOT])
497+
logger.info(f'SERVICES: {service_record_handles}')
498+
assert len(service_record_handles) == 1
499+
500+
# Unregister to clean up for other tests
501+
await sdp_client.disconnect()
502+
shell.exec_command("sdp_server unregister_sdp 0")
503+
504+
435505
class TestSdpServer:
436506
def test_discovery_device(self, sdp_server_dut):
437507
"""Test case to discover IUT"""
438508
logger.info(f'test_discovery_device {sdp_server_dut}')
439509
hci, iut_address = sdp_server_dut
440510
asyncio.run(start_discovery(hci, iut_address))
441511

512+
def test_sdp_unregister(self, shell: Shell, dut: DeviceAdapter, sdp_server_dut):
513+
"""Test case to unregister and re-register SDP records"""
514+
logger.info(f'test_sdp_unregister {sdp_server_dut}')
515+
hci, iut_address = sdp_server_dut
516+
asyncio.run(sdp_unregister(hci, shell, iut_address))
517+
442518
def test_sdp_discover(self, shell: Shell, dut: DeviceAdapter, sdp_server_dut):
443519
"""Test case to request SDP records"""
444520
logger.info(f'test_sdp_discover {sdp_server_dut}')

tests/bluetooth/classic/sdp_s/src/sdp_server.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,31 @@ static int cmd_register_sdp_all(const struct shell *sh, size_t argc, char *argv[
268268
return 0;
269269
}
270270

271+
static int cmd_unregister_sdp(const struct shell *sh, size_t argc, char *argv[])
272+
{
273+
int err = 0;
274+
unsigned long index;
275+
276+
index = shell_strtoul(argv[1], 16, &err);
277+
if (err || index >= MAX_SDP_RECORD_COUNT) {
278+
shell_error(sh, "Invalid index %s", argv[1]);
279+
return -EINVAL;
280+
}
281+
282+
if (!sdp_rec_reg[index]) {
283+
shell_error(sh, "The SDP record %lu is not registered", index);
284+
return -ENOEXEC;
285+
}
286+
287+
err = bt_sdp_unregister_service(&spp_rec[index]);
288+
if (err != 0) {
289+
shell_error(sh, "Unregister SDP record failed (err %d)", err);
290+
} else {
291+
sdp_rec_reg[index] = false;
292+
}
293+
return err;
294+
}
295+
271296
static int cmd_register_sdp_large(const struct shell *sh, size_t argc, char *argv[])
272297
{
273298
int err;
@@ -372,6 +397,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sdp_server_cmds,
372397
SHELL_CMD_ARG(register_sdp_large, NULL, "", cmd_register_sdp_large, 1, 0),
373398
SHELL_CMD_ARG(register_sdp_large_valid, NULL, "", cmd_register_sdp_large_valid, 1, 0),
374399
SHELL_CMD_ARG(register_sdp_uuid128, NULL, "", cmd_register_sdp_uuid128, 1, 0),
400+
SHELL_CMD_ARG(unregister_sdp, NULL, "<SDP Record Index>", cmd_unregister_sdp, 2, 0),
375401
SHELL_SUBCMD_SET_END
376402
);
377403

tests/bluetooth/classic/sdp_s/tests.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ tests:
1111
harness_config:
1212
pytest_dut_scope: session
1313
fixture: usb_hci
14+
extra_args:
15+
- CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT=y
1416
timeout: 900
1517
bluetooth.classic.sdp.server.no_blobs:
1618
platform_allow:

0 commit comments

Comments
 (0)