Modify the buffer for control point responses to exist per client.
This is a requirement to later support handling the control point
notifications in the system workqueue, which enables support for
proper handling of notifications in case that we run out of ATT
buffers, as we need to store the response until then, and that we
may have multiple clients connected.
CONFIG_BT_MAX_PAIRED was chosen over CONFIG_BT_MAX_CONN as we only
care about paired (encrypted) connections, and this may scale
better at the cost of doing lookups on address instead of e.g.
bt_conn_index.
The unit tests for ASCS are updated to pass without any
functional changes.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Add a sa_discovery_ranges shell command that splits the attribute ID
space into a given number of ranges, and a test that discovers a record
with the largest list a request carries and checks that one range more
is rejected by bt_sdp_discover().
Assisted-by: Claude:claude-fable-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Related err and NULL checks are confusing static analyzers so
to make it clear just initialize err to error value and
always rely on err value for error path.
Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
Remove the tests/bluetooth/host/id, keys and conn unit test suites.
They build the host sources against FFF fakes of the host's own
internals (bt_hci_cmd_send_sync, bt_le_adv_set_enable,
bt_le_scan_set_enable, bt_smp_*, bt_settings_*, k_sem_take,
k_sched_lock, ...) and assert on the call counts and arguments of those
fakes, so they pin the current implementation rather than the behavior
of the host: every internal change means updating the mocks in step,
after which the tests pass by construction. Of the 55 commits that have
touched these suites since the start of 2024, 29 are host changes that
had to update the mocks and most of the rest are fixes to keep the
suites building; only three add test cases, and no host fix in that
period credits these tests with finding a bug. The original author's
last commit to them is from October 2022.
The other suites under tests/bluetooth/host (crypto, cs, data,
monitor_buffer and adv) test parsers and pure logic and assert on their
outputs, with fakes limited to the crypto and HCI backends and to
caller-provided callbacks. They are kept, together with host_mocks
which they link against. Coverage of the id, keys and conn code is
better provided by tests that drive the host through its public API and
the HCI driver interface, i.e. the native_sim tests with a fake HCI
driver (tests/bluetooth/hci_prop_evt, tests/bluetooth/host_long_adv_recv)
and the bsim tests.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Convert the remaining k_sched_lock() sections that guard TX-path state
to the host lock in one step: tx_processor() with get_conn_ready(),
bt_conn_data_ready() and the L2CAP raise/cancel/lower data-ready
helpers. They all mutate the bt_dev.le.conn_ready and per-connection
l2cap data-ready lists from different threads, so converting one side
alone would replace the implicit cooperative exclusion with an actual
race; converting them together makes the exclusion explicit and
correct on SMP and with preemptible callers.
The host itself never blocks under the lock: the TX processor only
performs K_NO_WAIT acquisitions. An HCI driver's send() may still block
while the lock is held, as it could while the scheduler lock was held,
which bounds the hold time by the driver's transmit time; the native
controller's synchronous re-entry of the host from send() is covered by
the mutex being recursive.
The TX pass invokes one application callback on its normal path, the
L2CAP status() notification on credit exhaustion in chan_take_credit().
It ran under the scheduler lock and runs under the host lock now, and
re-entry into the host from it is covered by the mutex being recursive;
whether it keeps a hard non-blocking contract or moves out of the TX
processor is decided with the callback contracts (#116316).
The BR/EDR L2CAP data-ready helpers, which had no serialization at all,
take the lock the same way as the LE ones.
The fatal-error recovery paths of the TX processor, where a failed
send_buf() invokes the completion callback with an error and
disconnects synchronously, run under the lock as they ran under the
scheduler lock and are left as they are: the synchronous disconnect
already cannot complete from the TX processor thread, which would wait
for a command that only it sends, and both paths are to be reworked
with the asynchronous HCI command API (#116316).
The receive path keeps its scheduler lock; it is not converted here, as
the priority receive path is to become lock-free rather than take the
host lock.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
The test has carried CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 since
settings support was added in commit a29554360a ("Bluetooth: shell: Add
settings support"). How much stack the settings backend needs depends on
the flash driver, and therefore on the SoC: on SiWx91x the driver hands
the network coprocessor a 1408 byte request built on the caller's stack,
and 2048 is not enough.
An explicit assignment in prj.conf overrides any configdefault a SoC
supplies, so the pin silently defeats platform-level tuning. Drop it and
let the Kconfig defaults apply.
Platforms without a SoC-level default fall back to the Kconfig default of
1024, which is ample: measured with CONFIG_INIT_STACKS=y on
nrf52dk/nrf52832, the system workqueue peaks at 308 bytes running this
test.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Add support for asynchronous receive completion to allow applications
to control when RFCOMM data reception is considered complete.
Change the `recv` callback in `bt_rfcomm_dlc_ops` to return an `int`
instead of void. Applications can now return `-EINPROGRESS` to indicate
that data processing is asynchronous and will be completed later by
calling the new `bt_rfcomm_dlc_recv_complete()` API.
When `-EINPROGRESS` is returned:
- The application takes ownership of the buffer reference
- Increment `rx_credit_inprogress` counter
- For non-CFC sessions, send MSC command with FC bit set
- RX credits are decremented immediately but not refilled until
`bt_rfcomm_dlc_recv_complete()` is called
Update all existing RFCOMM recv callbacks (HFP AG, HFP HF, GOEP, SPP
shell, etc) to return 0 to maintain current behavior.
Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
Some combinations of doing access these APIs require both flags to be set.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
The bt_id_* related tests should use the READY flag instead of ENABLE,
since that indicates most accurately the initialization state of the host
stack and is also what the related APIs (under test) depend on.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Two-line copyright notices were wrapped in the SPDX "<text>...</text>"
construct, which is only valid in an SPDX document, not a file header.
The REUSE tool then folds the literal "<text>" into the holder name
and drops the second line from the SBOM.
Remove the markers and tag the continuation line. Holder, year and
e-mail are left unchanged; only the syntax is fixed.
Signed-off-by: Parthiban Nallathambi <parthiban@linumiz.com>
Since this a "get" function that does not, and never should,
modify the provided advertising set pointer, modify it to be
const.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
The ASSERT_LEVEL=2 and ASSERT_VERBOSE=y are the default options.
Remove them to avoid future deprecation warnings.
Signed-off-by: Måns Ansgariusson <mansgariusson@gmail.com>
memcpy does not take NULL pointers, so in the case that dataptr is NULL,
even if length is 0, we should omit the call.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
The bearers.tbs_bearers will always be non-NULL, and the function
should instead check the individual bearers.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Add ztest unit tests for the fragmented Periodic Advertising with
Responses (PAwR) response report reassembly logic in
bt_hci_le_per_adv_response_report().
The tests drive the HCI event handler directly with crafted LE Periodic
Advertising Response Report events and check the data delivered through
the pawr_response callback. They cover single and multi-fragment
reassembly, RX_FAILED handling, buffer overflow and truncation drop, and
the interleaving that arises from the single reassembly buffer per
advertising set (only one response chain can be reassembled at a time).
Signed-off-by: Alex Zhou <alex.zhou@nxp.com>
Add a unit test suite for bt_id_save_adv_addr(), covering the public
identity address types, the device-wide random address fallback on a
controller without the extended advertising feature - including an RPA
set through bt_id_set_private_addr() when privacy is enabled - and
that a per-set random address is left untouched.
Also extend the legacy branch test of bt_id_set_adv_random_addr() to
assert the saved address, not just the return value.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
bt_le_ext_adv_get_info() handed out a pointer to the advertising set's
random_addr, which is only written when a per-set random address is
programmed. When the set advertises with a public identity address the
reported address was never populated, and with a controller without the
extended advertising feature it was never written at all.
Instead of adding a second address field alongside random_addr, widen
the meaning of the existing one: rename it to adv_addr, the address the
set advertises with regardless of type. The per-set random address
cases keep being updated in bt_id_set_adv_random_addr(), so the
reported address stays correct across RPA and NRPA rotation, and
le_update_private_addr() refreshes the legacy advertiser, which
advertises with the device-wide random address.
The cases that do not program a per-set address - a public identity
address, and the device-wide random address on controllers without the
extended advertising feature, e.g. an RPA set through
bt_id_set_private_addr() when privacy is enabled - are saved by a new
bt_id_save_adv_addr(), which the advertising parameter setting calls
once the controller has accepted the parameters. Saving only at that
point ensures a failed parameter update does not overwrite the reported
address with one the controller never took into use.
Widening the field is safe for the existing readers: the connection
responder address and OOB paths that read it only execute in
configurations where the set advertises with a random address, in which
case the value is unchanged, and a pending random address is programmed
from the field before bt_id_save_adv_addr() runs.
For the BT_HCI_OWN_ADDR_RPA_OR_* types the controller substitutes a
locally generated RPA whenever the peer is in the resolving list, which
the host cannot observe; the configured fallback address is reported in
that case, as documented on the info struct.
Fixes: #112667
Assisted-by: Claude:claude-fable-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
The BIS data path setup event read the advertising address directly
from the host-internal bt_le_ext_adv structure. Use the public API
instead.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
The UART monitor backend sends every byte with uart_poll_out(). At
common UART rates this blocks the Bluetooth host while HCI traffic
and logs are serialized.
Add an opt-in interrupt-driven mode that buffers complete monitor
records and drains them from the UART interrupt handler. Record
fragments are copied in with ring_buf_put_ptr() and published with a
single ring_buf_commit(), so a record is either fully present in the
buffer or absent. This matters on panic: the panic handler flushes
only complete records before switching to polling, keeping the
stream parseable. Only the header-inline zero-copy ring buffer API
is used, so the option does not need to select RING_BUFFER.
A record that does not fit is dropped whole and reported through the
existing drop counters. Counts already consumed into a dropped
record's header are restored, keeping the accounting exact across
consecutive drops, and counts exceeding the 8-bit header field carry
over to the next record. Both kinds of loss previously also affected
the RTT backend, which shares this code.
Polling output remains the default and the panic-mode fallback,
since interrupts may no longer run during panic handling. It is also
the runtime fallback when the monitor UART driver lacks interrupt
support, since SERIAL_SUPPORT_INTERRUPT only guarantees that some
driver has it. The option depends on !LOG_MODE_MINIMAL because
minimal logging has no panic hook to flush buffered output.
Measured on nrf52dk/nrf52832 and xg24_rb4186c with a peripheral
flooding GATT notifications and the monitor sharing the 115200 baud
console UART: polling caps throughput at 5.9-6.6 KB/s, slows a paced
25 notifications/s workload to 15/s and blocks the producing context
~6 ms per large record (10-line printk burst: 58-65 ms). The
interrupt-driven mode restores radio-limited throughput (41 KB/s)
and the nominal paced rate, with the same burst at 0.8-1.3 ms. The
trade-off is load shedding: under sustained overload ~87% of
full-size ACL records are dropped (and accounted), while small
records such as Number of Completed Packets events keep flowing.
Unit tests cover contiguous and wrapped records, failed
reservations, zero-length fragments and exact-fit records; an
integration test runs the real producer/ISR path against the
emulated serial-test UART, covering drain, buffer-full drops with
accounting, and wrap-around consistency. The Bluetooth init test
builds the interrupt-driven path with the deferred log backend,
since tests default to minimal logging. Builds also pass with
polling UART and RTT.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Add support for getting the remote bearer tech.
Also slightly modified the test of the CCP samples
to properly catch issues (e.g. we disconnect on error,
and now we check for disconnect as the samples may reconnect
and thus have false positives).
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
btp_send_broadcast_receive_state_ev() right-shifted
subgroup->bis_sync by one before packing it into the
BTP event. BIS_Sync is a bitfield in which bit 0
represents BIS index 1, not an index, so the shift
silently corrupted the value: 0x00000001 (BIS 1 synced)
was reported as 0, and 0xFFFFFFFF was reported as 0x7FFFFFFF.
Signed-off-by: Alex Ciascai <alexandru.ciascai@nordicsemi.no>
The CAP unicast audio start and stop procedures consist of several
subprocedures, and applications may need to know when each of these have
completed, e.g. to reconfigure the unicast group after the streams have
been codec configured but before they are QoS configured.
Add new callbacks to bt_cap_initiator_cb for each subprocedure of the
unicast audio start and unicast audio stop procedures. The callbacks are
only called if at least one request was sent to a CAP acceptor as part of
the subprocedure, so that subprocedures that are skipped because all
streams are already in the requested state do not trigger a callback. To
support this a new subproc_initiated field has been added to the common
procedure struct, which is reset whenever a new subprocedure is set.
The unit tests have been extended to verify both that the callbacks are
called when the subprocedures are performed, and that they are not called
when the subprocedures are skipped, and the BSIM CAP initiator unicast
test now waits for the new callbacks as part of the start and stop
procedures.
Assisted-by: Copilot:claude-opus-4.5
Co-authored-by: Thalley <2520413+Thalley@users.noreply.github.com>
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Starting from QoS was not properly tested in the unit tests, and
thus did not catch a bug in the actual procedure.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
The Bluetooth controller unit tests build for unit_testing but exercise
the Nordic link layer, so each one fakes the SoC it is emulating with a
typeless 'config SOC_COMPATIBLE_NRF' carrying only a default.
A typeless config only assigns a value if the symbol is given a type
somewhere else, and the only place that types SOC_COMPATIBLE_NRF is
soc/nordic/Kconfig. The tests were therefore relying on the Nordic SoC
tree being loaded for a board that has nothing to do with Nordic. When
only the SoC tree of the board being targeted is loaded, the symbol stays
untyped, BT_LLL_VENDOR_NORDIC loses its dependency, none of the
BT_CTLR_*_SUPPORT symbols it selects come up, and Kconfig aborts on the
resulting unsatisfied dependencies.
Declare the symbol bool in the tests that fake it, which is the pattern
tests/bluetooth/controller/common/Kconfig already uses for
DT_HAS_ZEPHYR_BT_HCI_LL_SW_SPLIT_ENABLED.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Initially this was not enabled by default due to lack of
support in ZLL. However currently default test setup is
not using ZLL and thus this can be enabled for testing.
Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
The TF-PSA-Crypto revision bump in commit e603d04fa7 ("modules:
mbedtls: Allow custom TF-PSA-Crypto dispatch directory", PR #110328)
moved the driver dispatch headers to a dedicated dispatch directory,
which normal builds pick up from the tfpsacrypto CMake target. Tests
that mock crypto and hardcode the TF-PSA-Crypto include paths instead
of linking the library must add it explicitly.
Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
k_work_reschedule() withdraws a pending timeout, not a submission that
has already been made: once work_timeout() has fired it clears
K_WORK_DELAYED_BIT and queues the work, and a later reschedule arms a
new timeout while that submission stays queued. delayable_msg_handler()
can therefore run for an expiry that another context has already
consumed, and it popped the head of busy_ctx without looking at
fired_time.
A msg is then transmitted before its deadline, which truncates the
random delay the Access layer transmission rules require and defeats
the collision avoidance the module exists to provide. Any call to
reschedule_delayable_msg() between the timeout firing and the system
workqueue running leaves such a stale invocation behind; the purge path
in bt_mesh_delayable_msg_manage() is the easiest way to hit it, since
it consumes the head itself.
Split the two ways the queue is drained. take_expired_msg() pops the
head only if it is due, and the handler uses it, so a stale invocation
finds nothing to send and only re-arms. take_earliest_msg() pops the
head whatever its fired_time and keeps the purge path forcing out the
oldest msg as before. The due test runs in the same critical section as
the dequeue, so a concurrent context cannot swap the head in between,
and the sending half of push_msg_from_delayable_msgs() becomes
send_delayable_msg() for both callers.
The handler still sends at most one msg per invocation and re-arms;
when the next msg is already due the delay is K_NO_WAIT and the work
runs again straight away, as before.
msg_expired() and reschedule_delayable_msg() compare with a signed
delta, which the previous curr_time < fired_time test got wrong at the
32-bit uptime wrap.
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
Add test_concurrent_manage: two cooperative threads at the same
priority call bt_mesh_delayable_msg_manage() alternately via k_yield(),
and the mocked send yields as well, so a second enqueuer enters
push_msg_from_delayable_msgs() while the first is still working on the
head msg. Callbacks are counted per cb_data slot, because a msg sent
twice and a msg silently dropped balance out in the aggregate counters.
Add test_stop_during_in_flight_send: the ctx pool is filled so that the
next manage() takes the purge path, the mocked send yields to a thread
that suspends and stops the module, and the send then reports -ENOBUFS,
so the msg is queued again behind the drain. The test asserts that it
never reaches the transport after that, that every queued msg completes
exactly once with -ENODEV, and that the msg manage() was building is
not accepted either. The error it reports is left unpinned: -ENODEV if
the queueing is refused, -ENOMEM if no ctx can be freed for it.
Both interleavings are author-controlled yield sites rather than
preemption timing, so a regression reproduces on the first run.
test_stop_handler could not observe a message sent after stopping:
with accum_mask set, the callback never gives the semaphore that its
assertion waited on. Count the calls into the mocked send instead.
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
free_ctx, busy_ctx, free_chunks and the k_work_delayable are mutated
from two contexts: bt_mesh_delayable_msg_manage() on the BT RX
workqueue and delayable_msg_handler() on the system workqueue. Both are
cooperative, but the enqueuer blocks in bt_mesh_access_send() and
bt_rand(), which lets the handler interleave on unsynchronized state.
That produced two NULL dereferences. delayable_msg_handler() used the
result of sys_slist_get() on busy_ctx unchecked, so once the other
context had drained the list, the fired_time update faulted at a
NULL-based address. allocate_delayable_msg_ctx() tested
sys_slist_is_empty() and then assumed a separate sys_slist_get() would
succeed.
Guard every list mutation, and the fired_time of any ctx on busy_ctx,
with a k_spinlock that is never held across a blocking call.
push_msg_from_delayable_msgs() detaches the head atomically, so
concurrent pushers cannot send the same msg, and the handler no longer
touches busy_ctx.
Detaching before the send has a consequence. A msg being sent is on no
list, so the drain in bt_mesh_delayable_msg_stop() cannot see it, and
on -EBUSY or -ENOBUFS it was queued again behind that drain. On the
suspend path that never resolves, as adv_create_from_pool() refuses to
allocate while suspended. Drop a msg that reaches the front of the
queue while the stack is down instead, so nothing is handed to the
transport after a suspend or a reset, however it got queued.
bt_mesh_suspend() sets BT_MESH_SUSPENDED and bt_mesh_reset() clears
BT_MESH_VALID before stopping the module.
The release-and-report sequence this shares with the send path and with
the drain moves into complete_delayable_msg().
The unit test initialises the mesh flags in tc_setup(), since the
module only sends for a provisioned, running node.
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
Migrate the LE host's internal work items from the system workqueue to the
dedicated Bluetooth workqueue by using the bt_work_schedule(),
bt_work_reschedule() and bt_work_submit() helpers.
This covers advertising (limited advertising timeout), ATT (channel
timeout, EATT connection work), connections (deferred work and
auto-initiated procedures), GATT (service changed, delayed store,
database hash, multiple notifications), identity (RPA update), L2CAP (RTX
and RX work), settings (ID and IRK store), and SMP (timeout).
Migrating the per-connection deferred work is what keeps the existing
teardown code correct: that work item performs the L2CAP channel and
profile teardown (including the ATT and SMP disconnected callbacks), and
the non-blocking k_work_cancel*() calls in those paths only reliably stop
a concurrently running work item when both run on the same workqueue.
Keeping teardown on the system workqueue while the canceled work items
run on the Bluetooth workqueue would turn those cancellations into races.
For the same reason the SMP timeout moves along with it.
Additionally, cancel a dynamic L2CAP channel's RX work in
l2cap_chan_destroy() so that a queued work item cannot be left behind
with a reference to a channel object that the application may free or
re-use after teardown.
Update the id and conn host unit test mocks accordingly: id.c now uses
bt_work_schedule() and conn.c uses bt_work_submit(), bt_work_schedule()
and bt_work_reschedule(), so add fakes for these to the respective
hci_core.c mocks (and drop the now-unused k_work_schedule() and
k_work_reschedule() fakes from the kernel mocks).
Assisted-by: Claude:claude-fable-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Remove the BT_RECV_CONTEXT Kconfig choice and its BT_RECV_WORKQ_SYS
and BT_RECV_WORKQ_BT options. Low-priority HCI packets now always run
on the dedicated Bluetooth RX workqueue.
BT_RECV_WORKQ_SYS existed to save the RX thread stack on
memory-constrained targets, primarily nRF51. Removing the alternate path
simplifies the host threading model and removes a configuration-dependent
RX context and its associated test matrix. The following commit retunes
the affected in-tree nRF51 sample configurations.
This breaking Kconfig change is tracked by RFC #113007. Update the public
GATT callback context documentation, release notes and migration guide,
and remove tests specific to the system-workqueue RX path.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
The local and remote CIS Create procedures retain an RX node for the
later host notification, for example when accepting a CIS_IND with a
future instant, or while awaiting the Host reply to a CIS request.
If an unexpected LL Control PDU arrives before that retained node is
consumed, it is routed to the active procedure and takes the invalid
PDU path in llcp_lp_cc_rx() or llcp_rp_cc_rx(). Those paths
completed the procedure without releasing the retained RX node,
violating the invariant checked in llcp_lr_check_done() and
llcp_rr_check_done(), and leaking the referenced RX node memory.
Release the retained RX node before completing the procedure,
mirroring the fix already applied to the remote Connection Update and
the PHY Update procedures.
Add unit tests to tests/bluetooth/controller/ctrl_cis_create that
inject an unexpected LL Control PDU while a retained RX node is
pending. Without the fix each test triggers the retained node
assertion in ull_llcp_local.c or ull_llcp_remote.c; with the fix the
connection is terminated with BT_HCI_ERR_LMP_PDU_NOT_ALLOWED and all
procedure contexts are released.
Assisted-by: GitHub Copilot: Claude Opus 4.8
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
The local and remote PHY Update procedures retain the RX node for the
later host notification, for example when accepting a LL_PHY_UPDATE_IND
with a future instant.
If an unexpected LL Control PDU arrives before that retained node is
consumed, it is routed to the active procedure and takes the invalid
PDU path in llcp_lp_pu_rx() / llcp_rp_pu_rx(). Those paths completed
the procedure without releasing the retained RX node, violating the
invariant checked in llcp_lr_check_done() / llcp_rr_check_done() and
leaking the referenced RX node memory.
Release the retained RX node and clear the reference before completing
the procedure, mirroring the same fix in the Connection Update
procedure.
Add a unit test to tests/bluetooth/controller/ctrl_phy_update that
completes the remote PHY Update request with a future instant, then
sends an unexpected LL_LENGTH_REQ before the instant is reached.
Without the fix the test triggers the retained node assertion in
ull_llcp_remote.c; with the fix the connection is terminated with
BT_HCI_ERR_LMP_PDU_NOT_ALLOWED and all procedure contexts are released.
Add tests/bluetooth/controller/ctrl_phy_update case
test_phy_update_periph_loc_unexpected_pdu_awaiting_instant: a
peripheral initiates a local PHY Update, the central replies with a
LL_PHY_UPDATE_IND at a future instant so the local procedure retains
the RX node, and then an unexpected LL_REJECT_IND is routed to the
active local procedure before the instant is reached.
Assisted-by: GitHub Copilot: Claude Opus 5
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
The remote Connection Update / Connection Parameter procedure retains
the RX node for later host notification, for example when accepting a
LL_CONNECTION_UPDATE_IND with a future instant.
If an unexpected LL Control PDU arrives before that retained node is
consumed, it is routed to the active remote procedure and takes the
invalid PDU path in llcp_rp_cu_rx(). That path completed the procedure
without releasing the retained RX node, violating the invariant checked
in llcp_rr_check_done() and leaking the referenced RX node memory.
Release the retained RX node and clear the reference before completing
the procedure.
Add a unit test to tests/bluetooth/controller/ctrl_conn_update that
sends a valid LL_CONNECTION_UPDATE_IND with a future instant, followed
by an unexpected LL_LENGTH_REQ before the instant is reached. Without
the fix the test triggers the retained node assertion in
ull_llcp_remote.c; with the fix the connection is terminated with
BT_HCI_ERR_LMP_PDU_NOT_ALLOWED and all procedure contexts are released.
Verified with the ctrl_conn_update, ctrl_invalid, ctrl_collision and
ctrl_terminate controller unit tests, all passing.
Assisted-by: GitHub Copilot: Claude Opus 5
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
Some tests for latency and PHY were disabled pending a bug
report which is no longer valid. Fix the validation functions
and enable the tests.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
All the ID tests had additional compile options added, which
did not serve any purpose, so they were removed.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
The compiler cannot figure out which branches of that logging switch may
be taken when and warns about conn_index being maybe used unitialized.
That switch combining both error paths is a bit convoluted also for humans
to follow, so let's just split it, so it is evident for both.
There is no practical functional change with this.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
Use #include <> instead of #include "" to include a header file which path
is not relative to the directory path of the file emitting the #include
directive.
This change was made running scripts/check_quoted_includes.py script
proposed in https://github.com/zephyrproject-rtos/zephyr/pull/112135
with the Linux shell command below and manually selecting the applicable
changes:
$ $ ./scripts/check_quoted_includes.py -w tests/bluetooth/classic
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Raise the minimum required CMake version from 3.20.0 (documented as
3.20.5) to 3.28.0, which is satisfied by the CMake 3.28.3 package
shipped in the Ubuntu 24.04 LTS repositories. Ubuntu 24.04 is the
current Ubuntu LTS release targeted by the Zephyr getting started
guide, and by the time of the next Zephyr release, Ubuntu 22.04 will be
within months of its end of standard support. Users of distributions
shipping an older CMake can use the Kitware APT repository or a
pip-installed CMake, as the documentation already suggests.
Raising the floor to 3.28 unlocks a range of modern CMake features for
the build system, among which the cmake_file_api() command (3.27),
file(COPY_FILE) (3.21), block()/endblock() (3.25), and allows removal
of several version-conditional workarounds.
The tree-wide cmake_minimum_required() occurrences in samples, tests
and boards are updated accordingly, together with the documentation
and the sysbuild CMake presets. The IAR C-STAT integration keeps its
own higher requirement (4.1.0).
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Rename the `configured` and `qos_set` callbacks of
`struct bt_bap_stream_ops` to `codec_configured` and `qos_configured`
respectively, so that the names align with the ASE state machine names
defined by the ASCS specification.
All in-tree users (host implementation, shell, samples and tests) have
been updated accordingly, including the local callback function names
that mirror the operation names.
Assisted-by: Copilot:claude-opus-4.8
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Restrict BIS channel allocation injection to LC3
broadcast setup only. For VS codecs, keep BIS-specific
codec data empty so broadcast source setup does not fail
with BTP error.
Signed-off-by: Alex Ciascai <ext-alexandru.ciascai@nordicsemi.no>
Header file include/zephyr/sys_clock.h is deprecated and will be removed
someday. Update the whole file tree to include zephyr/sys/clock.h
straight instead of zephyr/sys_clock.h.
This change was made running the sed shell command below:
$ sed -i 's/zephyr\/sys_clock\.h/zephyr\/sys\/clock\.h/' \
`grep -rsl "zephyr/sys_clock\.h" tests/`
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>