Move the network buffer header file from zephyr/net/buf.h to
zephyr/net_buf.h as the implementation now lives outside of the networking
subsystem.
Add (deprecated) zephyr/net/buf.h header to maintain compatibility with old
file path.
Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
When sending data using ISO and the data is fragmented, if the
connection is cut before all the fragments are sent, the data buffer
will be leaked.
Fix the issue by unref'ing the buffer when ISO is not in a connected
state.
Signed-off-by: Théo Battrel <theo.battrel@nordicsemi.no>
When disconnected while sending data, if ISO doesn't get the number of
completed packets it will not call `process_unack_tx` and thus will leak
TX context.
Fix that by setting the connection state in ISO disconnection which will
trigger a call to `process_unack_tx`.
Signed-off-by: Théo Battrel <theo.battrel@nordicsemi.no>
Convert users of net_buf_put() and net_buf_get() functions to use
non-wrapped putters and getters k_fifo_put() and k_fifo_get().
Special handling of net_bufs in k_fifos is no longer needed after commit
3d306c181f, since these actions are now
atomic regardless of any net_buf fragments.
Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
Don't push the TS flag on `buf` itself.
This messes up the MTU calculations: a packet that would exactly fit the
MTU and has a timestamp would be unnecessarily fragmented.
The MTU check is done on `buf` as a whole. At the point where the
fragmentation length is decided, `buf` includes one extra byte to pass the
TS bit around. That byte shouldn't count towards the MTU.
Instead, infer the presence of the timestamp by inspecting the amount of
headroom that the buffer has. This works because we always reserve
enough memory to push the timestamp, but not always push a timestamp on
the buffer. #tightlycoupled
This method is slightly uglier IMO, but eases MTU confusion and doesn't
rely on user_data.
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
When developing Bluetooth applications, you typically run into
some errors. If you are an experienced Bluetooth developer,
you would typically have an HCI error lookup table in your memory.
Others might not.
This commit utilizes defines CONFIG_BT_DEBUG_HCI_ERR_TO_STR
and utilizes bt_hci_err_to_str() to print out HCI error strings
when enabled to improve the user experience.
Several alternatives where considered. This approach was chosen
as it had the best balance between readability, code size, and
implementation complexity.
The alternatives are listed below as a reference.
1. Macro defined format specifier:
```c
#define HCI_ERR_FMT "%s"
#define BT_HCI_ERR_TO_STR(err) (err)
#define HCI_ERR_FMT "%d"
#define BT_HCI_ERR_TO_STR(err) bt_hci_err_to_str((err))
LOG_INF("The event contained " HCI_ERR_FMT " as status",
BT_HCI_ERR_TO_STR(err));
```
Advantage: Space efficient: Code size does not increase
Disadvantage: Code becomes hard to read
2. Format specifier to always include both integer and string:
```c
static inline const char bt_hci_err_to_str(err)
{
return "";
}
LOG_INF("The event contained %s(0x%02x) as status",
bt_hci_err_to_str(err), err);
```
Advantage: Simple to use, implement, and read,
Disadvantage: Increases code size when CONFIG_BT_DEBUG_HCI_ERR_TO_STR
is disabled. The compiler seems unable to optimize away the unused
format specifier. Note: The size increase is only present when
logging is enabled.
3. Always print as string, allocate a stack variable when printing:
```c
const char *bt_hci_err_to_str(char *dst, size_t dst_size, uint8_t err)
{
snprintf(dst, dst_size, 0x%02x, err);
return dst;
}
LOG_INF("The event contained %s as status", BT_HCI_ERR_TO_STR(err));
```
Advantage: Very easy to read.
Disadvantage: Printing error codes becomes slow as it involves calling
snprint.
4. Implement a custom printf specifier, for example E.
This requires a global CONFIG_ERR_AS_STR as I assume we cannot have
one specifier for each type of error code.
Also, I assume we cannot start adding specifiers for each subsystem.
```c
#define BT_HCI_ERR_TO_STR(err) (err)
#define BT_HCI_ERR_TO_STR(err) bt_hci_err_to_str((err))
LOG_INF("The event contained %E as status", BT_HCI_ERR_TO_STR(err));
```
Advantage: Both efficient code and readable code.
Disadvantage: This requires a global CONFIG_ERR_AS_STR as I assume
we cannot have one specifier for each type of error code.
Also, I assume we cannot start adding specifiers for each subsystem.
That is, this approach is hard to implement correctly in a scalable
way.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
Refactors teh BIS bitfield values used for ISO
and BAP.
Previously BIT(1) meant BIS index 1, which was a Zephyr choice
in the early days of ISO, as the BT Core spec did not use
a bitfield for BIS indexes.
Later the BASS specification came along and defined that
BIT(0) meant BIS index 1, which meant that we had to shift BIS
bitfields between BAP and ISO.
This commit refactors the ISO layer to use BIT(0) for Index 1 now,
which means that there is no longer a need for conversion
between the BAP and ISO layers, and that we can use a value
range defined by a BT Core spec (BASS).
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Several log statements were using the regualar LOG_DBG,
but when ISO is actually used, those were called every TX
which at 10ms SDU intervals would fill up the log really fast
and not provided much value outside of some specific debugging.
Modified those logs to use BT_ISO_DATA_DBG which is another
log level for ISO data.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
If the CIG only contains C to P CISes, then we should allow
setting the P to C interval and latency to 0, and vice versa.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Utilize a code spell-checking tool to scan for and correct spelling errors
in all files within the subsys/bluetooth/host directory.
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
ISO connections that were in the TX queue were not getting serviced in
time. This happens because `iso_data_pull()` returns `NULL` when that
particular connection (`conn`) is done sending.
But it doesn't trigger the TX processor again to process other channels in
the queue. This patch fixes that by calling `bt_tx_irq_raise()`.
We can't do this from `conn.c` as we don't know if the `NULL` returned is
because the current channel is out of data or because it has data but it
can't send it (e.g. the current buf is being "viewed" already).
Fixes https://github.com/zephyrproject-rtos/zephyr/issues/74321
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
We can get rid of the view pool for SDU segments :)
We have to make the code slightly more complex :'(
The basic idea is always giving the original SDU buffer to `conn.c` for it
to pull ACL fragments from.
In order to do this, we need to add the PDU headers just-in-time.
`bt_l2cap_send_pdu()` does not add them before putting the PDU on the queue
anymore. They are added by `l2cap_data_pull()` right before the data leaves
`l2cap.c` for `conn.c`.
We also have to inform `conn.c` "out of band" of the real L2CAP PDU size so
it doesn't fragment across segment boundaries. This oob is the new `length`
parameter to the `.pull()` method.
This is the added complexity mentioned above.
Since SDU segmentation concerns only LE-L2CAP, ISO and Classic L2CAP don't
need this extra logic.
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
We don't need the TX thread anymore.
Generalizing the pull-based architecture (ie. `tx_processor`) to HCI
commands makes it possible to run the whole TX path from the the system
workqueue, or any workqueue really.
There is an edge-case, where we call `bt_hci_cmd_send_sync()` from the
syswq, stalling the system. The proposed mitigation is to attempt to drain
the command queue from within `bt_hci_cmd_send_sync()`.
My spidey sense tingles however, and it would be better to just remove the
capability of calling this fn from the syswq. But doing this requires
refactoring a bunch of synchronous procedures in the stack (e.g. stack
init, connection establishment, address setting etc), dragging in more
work. I will do it, but in a later patch.
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
The current TX pattern in the host is to try to push a buffer through all
the layers up until it is ingested by the controller.
Since sending can fail at any layer, we need error-handling and separate
retry logic on pretty much all layers. That logic obscures the "happy path"
for people trying ot understand the code.
This commit inverts the control, in a way that doesn't require changing the
host or HCI driver API (yet):
Layers don't send buffers synchronously, they instead put their buffer in a
private queue of their own and raise a TX flag on the lower layer. Think of
it as a `READY` interrupt line that has to be serviced by the lower layer.
Sending is now non-blocking, rate depends on the size of buffer pools.
There is a single TX processing function. This can be thought as the
Interrupt Service Routine that will handle the `READY` interrupt from the
layers above.
That `tx_processor()` will then attempt to allocate enough resources in
order to send the buffer through to the controller. This allocation logic
does not block.
After acquiring all the resources, the TX processor will attempt to pull
data from the upper layer. The upper layer has to figure out which buffer
to pass to the controller. This is a good spot to put scheduling or QoS
logic in the upper layer.
Notes:
- user-facing API for tuning QoS will be implemented in a future patch
- this scheme could (and probably will) be extended to upper layers (e.g.
ATT, L2CAP CoC segmentation).
- this patch removes the `pending_no_cb()` memory optimization for
clarity/correctness. It might get re-implemented after a stabilization
period. Hopefully with more documentation.
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
Co-authored-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
Instead of allocating segments/fragments and copying data into them, we
allocate segments as "views" (or slices) into the original buffer.
The view also gives access to the headroom of the original buffer, allowing
lower layers to push their headers.
We choose not to allow multiple views into the same buffer as the headroom
of a view would overlap with the data of the previous view.
We mark a buffer as locked (or "in-view") by temporarily setting its
headroom to zero. This effectively stops create_view because the requested
headroom is not available.
Each layer that does some kind of fragmentation and wants to use views for
that needs to maintain a buffer pool (bufsize 0, count = max views) and a
metadata array (size = max views) for the view mechanism to work.
Maximum number of views: number of parallel buffers from the upper layer,
e.g. number of L2CAP channels for L2CAP segmentation or number of ACL
connections for HCI fragmentation.
Reason for the change:
1. prevent deadlocks or (ATT/SMP) requests timing out
2. save time (zero-copy)
3. save memory (gets rid of frag pools)
L2CAP CoC: would either allocate from the `alloc_seg` application callback,
or worse _steal_ from the same pool, or allocate from the global ACL pool.
Conn/HCI: would either allocate from `frag_pool` or the global ACL pool.
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
Co-authored-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
Add support for bt_disable in the ISO implementation.
This involves clearing all information related to states
in the controller, such as the BIGs and CIGs.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Rename struct bt_hci_iso_data_hdr to bt_hci_iso_sdu_hdr, and
struct bt_hci_iso_ts_data_hdr to bt_hci_iso_sdu_ts_hdr.
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
To make it easier to understand the code, the following was done:
- Use INITIATING/ADV for state names that are exclusive to central
or peripheral. Previously it was not necessarily clear that the state
BT_CONN_CONNECTING was for central only by just looking at where
it was used. The terms INITIATING/ADV were used in favor
of central and peripheral as these terms also work for SCO connection
establishment.
- BT_CONN_CONNECTING_SCAN -> BT_CONN_SCAN_BEFORE_INITIATING
to make it more clear that we are not scanning and connecting at
the same time. The new name should make it more clear why we are
scanning - only with the intention to start the initiator later.
- BT_CONN_CONNECTING_AUTO -> BT_CONN_INITIATING_FILTER_LIST.
This makes it clear that this state is something different than
BT_CONN_AUTO_CONNECT.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
Add 2 new Kconfig promptless options that are shorthand
for whether the ISO configuration can support RX and TX.
This also applies these new options as guards for existing
and missing code pieces.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Replaced checks for
CONFIG_BT_ISO_UNICAST || CONFIG_BT_ISO_BROADCASTER with
CONFIG_BT_CONN_TX, as they are effectively the same.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
The bt_iso_chan_send function could take an optional
timestamp by using 0 as an indicator. The issue with
this approach was that a timestamp value of 0 is valid,
and could cause potential issue with syncing streams
in a group.
To fully support transmitting with and without timestamp,
bt_iso_chan_send_ts has been introduced, which is the only
function of the two (bt_iso_chan_send being the other) that
supports timestamps.
A new function, rather than adding a boolean to the existing,
was chosen as it simplifies the individual functions as well
as making it more explicit what the function does.
Since the bt_iso_chan_send function is used by LE audio, both
the BAP and CAP send functions have similarly been updated.
Likewise, all tests and samples have been updated to use the
updated function(s), and BT_ISO_TIMESTAMP_NONE has been
removed.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
During local testing with UBSAN enabled, warning was reported:
bluetooth/host/iso.c:237:2: runtime error: null pointer passed
as argument 2, which is declared to never be null
It turned out that when datapath doesn't contain
codec information, cc_len is 0 and cc is NULL
In order to avoid UB,
now we call memcpy only when cp->codec_config_len > 0
Signed-off-by: Ivan Iushkov <ivan.iushkov@nordicsemi.no>
Modifies two log statements so that it is clear whether it
is failing to validate broadcast or unicast PDU sizes.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
When the central aborts the CIS setup during the CIS Creation
procedure after it has accepted the CIS request, the peripheral
will receive the HCI LE CIS Established event with an error code.
It does not receive a disconnection event.
See the message sequence chart in Core_v5.4, Vol 6, Part D,
Section 6.23.
This commit ensures that the perirpheral disconnected callback gets
called for this particular scenario.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
Use IN_RANGE instead of explicitly checking that a value is
in between two other values
Signed-off-by: Andries Kruithof <andries.kruithof@nordicsemi.no>
The BT Core Spec v5.4 allows separate SDU_Interval to
be set on C_To_P and P_To_C directions,
but this is not possible with the existing interface.
This PR splits the interval parameter in the call to
bt_iso_sig_create into one for C_To_P
and one for P_To_C
It also splits the latency parameter into one for
C_To_P and one for P_To_C
Signed-off-by: Andries Kruithof <andries.kruithof@nordicsemi.no>
Bluetooth: ISO: update UI for extended API
The API for setting the SDU interval and latency have been updated.
This PR also updates the setting of these by the user in the shell
and the iso_connected_benchmark sample
Signed-off-by: Andries Kruithof <andries.kruithof@nordicsemi.no>
Rename the Kconfig option from BT_ISO_ADVANCED to
BT_ISO_TEST_PARAMS to more explicitly denote that it
enables support for using the ISO test parameters.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
A few of the length checks that deal with HCI packets coming from the
controller were using assert statements. But the recommended practice is
to drop invalid packets and continue execution whenever a malformed
packet arrives from an external source, so replace those assert
statements with branches that will drop the packet and return.
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
bt_iso_cig_reconfigure would almost always fail due to invalid
checks that did not take the functioner properly into account.
The CIS provided to bt_iso_cig_reconfigure can now be allocated
beforehand, if the CIG for the CIS is the same as the one being
reconfigured.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
If the central disconnects a CIS while it is being
established, then we receive both a CIS established event
with BT_HCI_ERR_OP_CANCELLED_BY_HOST and a disconnect complete
event.
In this case we should not call bt_iso_disconnected in the
CIS established event handler, as that will also be
called from the disconnect complete event handler.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
As per the core spec, the CIS is not allowed to disconnect
a CIS if it is pending (i.e. in the connecting state).
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Add support for setting advanced broadcast ISO parameters
using the ISO test commands. This allows the host to set
ISO parameters that the controller normally would handle.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Add support for setting advanced unicast ISO parameters
using the ISO test commands. This allows the host to
set ISO parameters that the controller normally would
handle.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Adds a comment stating the state of the peripheral SDU size
and why it is being assigned the PDU size on CIS established.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Fail gracefully if an HCI event of one type arrives for a handle of a
different connection type. The requested types are currently based on
what fields are used, not on the usage context, in order to keep every
correct use so far still working.
A warning is logged if the connection identified by the handle does not
match the requested connection type.
Signed-off-by: Arkadiusz Kozdra <akozdra@antmicro.com>
Log status values in events as hex instead of decimal
to make it easier to compare to the spec and hci_err.h
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
On CIS disconnect, the central will clear all data paths.
However hci_le_remove_iso_data_path will fail if attempting to remove a
data path that has not been setup, so if only the CTLR_TO_HOST
direction was set, and the HOST_TO_CTLR bit was set, the
function returned an error and never attempted to clear the other
direction.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
The path_dir variable of BT_HCI_OP_LE_REMOVE_ISO_PATH must be bitflags,
with the following meaning:
- BIT(0) : DIR_HOST_TO_CTLR
- BIT(1) : DIR_CTLR_TO_HOST
Signed-off-by: Morten Priess <mtpr@oticon.com>
Use BT_CONN_TX_USER_DATA_SIZE when defining pools of buffers that will go
through `bt_conn_send_cb()`.
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
MTU doesn't count against the ISO and ISO data headers.
Then a config with CONFIG_BT_ISO_TX_MTU ==
CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE should not fragment SDUs over HCI.
Also set the TS_Flag bit if a timestamp is present.
Fixes#56749
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>