Adds HCI support for:
- LE CS Read Remote Supported Capabilities
- LE CS Read Remote FAE Table
Callbacks have been added to the conn object to allow upper layers to
make use of the cache commands, with which it will be possible to store
this information and provide it again in the case of a disconnect
and reconnect to the same device.
Signed-off-by: Olivier Lesage <olivier.lesage@nordicsemi.no>
Aligns the logging unhandled vs events with the regular ones.
Now it prints out the code and length.
Signed-off-by: Olivier Lesage <olivier.lesage@nordicsemi.no>
`conn_auto_initiate()` starts a bunch of controller procedures (read: HCI
commands) that are fired off right after connection establishment.
Right now, it's called from the RX context, which is the same context where
resources (cmd & acl buffers) are freed. This not ideal.
But the procedures are all async, so it should be fine to schedule this
function on the system workqueue, where we have less risk of deadlocks.
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
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>
Rename `BT_CONN_AUTO_FEATURE_EXCH` to `BT_CONN_LE_FEATURES_EXCHANGED`,
and add some comments for readability.
Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
To make the scanner module more understandable and more streamlined, I
reworked the update mechanism of the scanner. The scanner tracks now the
parameters that were used to enable it and the reason why it is running.
This facilitates state logic and allows other modules to "start the
scanner", altough it is already running.
This is mostly a refactoring and not a functional change.
Added a test to verify the behavior.
Signed-off-by: Jan Müller <jan.mueller@nordicsemi.no>
add to task
This test create a setup where an ISO broadcaster will send fragmented
data and get stopped after sending the first fragment and repeating that
operation multiple time to verify that buffers are not leaked.
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>
Adds support for LE Connection Subrating as defined in Core 5.4
Vol 6, Part B, Section 5.1.19.
As this is primarily a controller feature, the host support is mostly
a wrapper around the relevant HCI commands.
Note that subrating provides a new method to update the connection's
peripheral latency and supervision timeout alongside subrating parameters.
Signed-off-by: Aleksandar Stanoev <aleksandar.stanoev@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>
The Softdevice Controller now sends the disconnect event only after
receiving all Host Num Completes for the packets it sent to the host.
This is done for security reasons.
In our current reassembly logic, it does not really matter when we
withhold the num complete.
Before this patch, it's the first fragment that is withheld, and after
the patch it will be the last fragment that is withheld until the host
is done processing.
The flow control properties are maintained, just in a different way.
Co-authored-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
The functionality is moved in preparation of the next commit which will
re-use this function from somewhere else.
Also add (default-on) asserts that we are able to allocate and send the
command. If that is not the case, we will leak buffers from the PoV of
the controller, leading to a stall in data transfer.
Depending on the error, we could probably recover using a disconnection.
For now, do the safe thing and stop the whole stack.
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
The spec only guarantees the connection complete event parameters
are valid if the status is BT_HCI_ERR_SUCCESS. When the status is
not BT_HCI_ERR_SUCCESS, the host shall ignore the other parameters.
See Vol 4, Part E, 4.5 Command error handling:
"""
If an error occurs for a command for which an HCI_Command_Complete event
is returned, the Return Parameters field may only contain some of the
return parameters specified for the command.
...
The above also applies to commands that have associated command specific
completion events with a Status parameter in their completion event, with
the exceptions shown in Table 4.1, Event Valid parameters
...
Event | Valid parameters
------------------------------------------------------------
LE_Connection_Complete | none
LE_Enhanced_Connection_Complete | none
"""
Refactor `le_legacy_conn_complete`, `le_enh_conn_complete_v2` and
`le_enh_conn_complete` to check and handle the status before handling
any other parameters.
An issue was seen where SDC returned event with status
`BT_HCI_ERR_UNKNOWN_CONN_ID`, but because adv_handle and sync_handle
were not invalid the event was not handled.
Signed-off-by: Sean Madigan <sean.madigan@nordicsemi.no>
When implementing vendor specific HCI APIs and events,
we want to be able to convert between host objects,
handles and back again.
Exposing this API makes that possible.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
The function `bt_hci_le_past_received_v2()` is not compiled
in for this configuration, so the reference needs to be removed.
Fixes#76268.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
Some HCI drivers issue HCI reset when disabling, like the IPC HCI
driver. We need to keep the RX thread running to allow receiving
the command complete.
This commit postpones aborting the RX thread until this is done.
The issue happens started occuring after commit
d0e75ab87c4b53d66008c941c38709a2fca9dbea.
Fixes#76202.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
When syncing to a PA using PAST then the sync_info.recv_enabled
was always just set to true, regardless of what mode was set
during the subscribe parameters.
The mode(s) are now stored in an array (with the default value
as well) so that we can retrieve that information when the PA
has synced via PAST.
It was considered to put the `mode` value into the `bt_conn`
struct, but that would require an API change as the `bt_conn`
parameter for the subcribe function uses `const`.
This commit also modifies the guard for PAST to be the more
correct value CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER instead
of just CONFIG_BT_CONN.
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>
Fix Bluetooth initialization problem caused by PR#72090
for at least ST boards that are using BlueNRG BLE modules.
For more information, please refer to issue #74528.
Signed-off-by: Ali Hozhabri <ali.hozhabri@st.com>
`cmd(buf)` depends on this since it uses `net_buf_id`, which would alias
multiple pools.
Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
Use K_WORK defined. This delayed work is never used with any
other timeout than K_NO_WAIT, so the "delayed" part of it
is never actually needed
Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
This makes it more clear what is happening when the host cancels
connection creation where the controller raises
the connection complete event with status set to
"UNKNOWN CONNECTION IDENTIFIER (0x02)".
This is especially useful for developers not familiar with this
detail in the spec.
See also: Core_v5.4, Vol 4, Part E, Section 7.8.13,
LE Create Connection Cancel command.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
The same way as `bt_hci_get_adv_handle` and `bt_hci_get_conn_handle` add
a function to get the handle of a periodic advertising sync.
Signed-off-by: Théo Battrel <theo.battrel@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>
If the new encryption state is the same as the old one, there's no point in
doing additional processing or callbacks. Simply log a warning and ignore
the HCI event in such a case.
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Add support for HCI drivers which use the newly defined HCI driver API.
Since Zephyr (currently) only supports a single HCI driver instance,
boards are expected to indicate the instance using a new devicetree
chosen property `zephyr,bt_hci`.
In order to maintain compatibility with not-yet-converted drivers the
code has been placed behind `#if DT_HAS_CHOSEN(zephyr_bt_hci)`
conditionals.
Signed-off-by: Johan Hedberg <johan.hedberg@gmail.com>
This commit adds host support for the Path Loss Monitoring
feature see Bluetooth Core specification, Version 5.4,
Vol 6, Part B, Section 4.6.32.
Limited logic is required, just adding a wrapper around the
HCI command and callback for HCI event.
Add new zone - BT_CONN_LE_PATH_LOSS_ZONE_UNAVAILABLE, to
convert 0xFF path loss to a useful zone.
Add new Kconfigs and functionality to the bt shell.
Signed-off-by: Sean Madigan <sean.madigan@nordicsemi.no>
When reading the error message:
"ASSERTION_FAIL: command opcode 0x0c03 timeout with err -11" it may not be
obvious what is wrong with their setup unless you are very familiar
with HCI.
This commit adds some more documentation to make this more obvious.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
Before this commit, the following bugs were present:
- When `CONFIG_BT_FILTER_ACCEPT_LIST` was set, connection establishment
was cancelled upon RPA timeout. This required the application
to restart the initiator every RPA timeout.
- When `CONFIG_BT_FILTER_ACCEPT_LIST` was not set, the RPA was not updated
while the initiator was running.
This commit unifies the RPA timeout handling for both these cases.
Upon RPA timeout the initiator is cancelled and restarted when
the controller raises the LE Connection Complete event.
The workqueue state is checked when restarting the initiator to prevent
it being restarted when the timeout is hit.
Corresponding test cases have been added to ensure that this
feature works.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
Expectation: After calling `bt_disable()` it is possible to
use the Bluetooth APIs as if `bt_enable()` was never called.
This was not the case for `bt_id_create()`, it was not possible
to set the default identity. This prevented an application
developer to restart the stack as a different identity.
Keys also need to be cleared to avoid the following pattern:
1. Pair two devices
2. Central calls `bt_disable()` and `bt_enable()`.
The central will now generate a new identity address.
3. Connect the two devices.
4. Re-establish encryption. Now the central will try to use
the previously used keys. The procedure will fail
because the peripheral does not have any keys associated
with the new central address.
The API documentation is updated accordingly.
Signed-off-by: Rubin Gerritsen <rubin.gerritsen@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>
Enabling vendor-specific extensions also implies support for vendor
events, so a separate Kconfig option for that is unnecessary.
One small additional thing this requires is the use of the
__maybe_unused annotation, since there's no-longer a single Kconfig
option that the controller hci.c can use to know that the vendor event
helper symbols are needed.
Signed-off-by: Johan Hedberg <johan.hedberg@gmail.com>
The naming of these two options was problematic, since it's both of them
are about vendor extensions, even though one has _EXT in the name and
the other doesn't. Just merge one option into the other. This has a
slight overhead on the controller side of enabling some more vendor
features if BT_HCI_VS is enabled, but that should hopefully be
acceptable.
Signed-off-by: Johan Hedberg <johan.hedberg@gmail.com>
Make `bt_hci_cmd_send_sync` return `-EACCES` when receiving
`BT_HCI_ERR_CMD_DISALLOWED`.
Update some tests that were expecting `-EIO` when
getting `BT_HCI_ERR_CMD_DISALLOWED`.
Add a warning in `set_random_address` when getting that new error. This
is done in case someone try to set a new random address while legacy
advertising, scanning or initiating is enabled. This is illegal behavior
according to the Core Spec (see Vol 4, Part E 7.8.4).
Signed-off-by: Théo Battrel <theo.battrel@nordicsemi.no>
net_buf_alloc(K_FOREVER) can now fail (if run from the syswq). Propagate to
the caller instead of asserting.
Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
Send a `READ_MAX_ADV_DATA_LEN` command to the controller at the
initialization of the host to fetch the maximum advertising data length
the host can accept.
This is done because even if the Zephyr controller provide the
`CONFIG_BT_CTLR_ADV_DATA_LEN_MAX` Kconfig symbol, other controllers may
not have such Kconfig symbol. So this is a way for the host to be more
controller-agnostic and provide useful feedback to the users.
Signed-off-by: Théo Battrel <theo.battrel@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>
`bt_recv` is invoked from the BT long work queue, which is preemptible.
The host uses cooperative scheduling to ensure thread safety.
Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
Change the receive workque name to "BT RX WQ" to distinguish it from the
receive thread, and the long workque one to "BT LW WQ" to make the
format consistent with the other Bluetooth threads.
On an nRF52 now "kernel stacks" looks like:
0x200016c8 BT RX (real size 448): unused 280 )
0x20001780 BT RX pri (real size 448): unused 224 )
0x200012c0 BT RX WQ (real size 2240): unused 1360 )
0x20001208 BT TX (real size 768): unused 408 )
0x20001130 BT LW WQ (real size 1344): unused 408 )
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This commit removes `bt_hci_evt_get_flags`, and the associated flag
symbols. These symbols no longer serve a purpose in the driver interface
after the removal of `bt_recv_prio` from the interface.
The implementation of `bt_hci_evt_get_flags` is distributed to its
still-existing use sites, `hci_core` and the `hci_driver` in the
controller.
The duplication of code is intentional. This is no longer part of any
interface, and the host-developers expect the host copy of the function
to change or dissapear entierly. This will allow the host implementation
to progress without fear of breaking the controller implementation.
Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
This config selects a variant of the HCI driver interface that spills
out host internals unto the drivers and even the Zephyr controller. It
will now be removed in favor of driver interfaces that hide the
internals of the host.
The new default is `CONFIG_BT_RECV_WORKQ_BT`.
Any references to the removed kconfig are refactored out.
Any out-of-tree driver using the removed interface can be easily adapted
by copying the following implementations into the driver as private
functions:
- `hci_driver.h:BT_HCI_EVT_FLAG_RECV_PRIO`
- `hci_driver.h:BT_HCI_EVT_FLAG_RECV`
- `hci_driver.h:bt_hci_evt_get_flags`
- `hci_raw.c:bt_recv_prio`
In combination these symbols function as a interface adapter. These
symbols will be removed in this PR in subsequent commits.
Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
Check max_tx_octects and max_tx_time are in the valid range, according
to the BT Core spec 5.4 [Vol 4, Part E, 7.8.46]
Fix#70472
Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
This was part of the mega hwmv2 commit. Looks like hpet drivers heavily
relies on soc.h. Reverting this for now while we look for a proper fix
and remove reliance on soc.h for drivers.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>