Commit Graph

2808 Commits

Author SHA1 Message Date
Flavio Ceolin
bb56c3898c bluetooth: host/classic: Fix possible buffer overflow
Fix possible buffer overflow in rfcomm. Check the buffer len
before read it.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2024-07-01 09:13:22 +02:00
Jordan Yates
cf870e8350 bluetooth: correct bt_le_scan_param scan type
The `type` parameter of `struct bt_le_scan_param` is documented as
taking a `BT_LE_SCAN_TYPE_*` value, not a `BT_HCI_LE_SCAN_*` value.

In practice this makes no difference as the values are defined as the
same integer, but does result in `<zephyr/bluetooth/hci.h>` not needing
to be included.

Signed-off-by: Jordan Yates <jordan@embeint.com>
2024-06-28 11:34:36 +02:00
Lyle Zhu
1d1dc7a875 Bluetooth: Classic: HF_AG: Fix unexpected return
When `buf->len` is 0, the function of the while-loop
will be returned with error code `-ENOTSUP`.
The code block after while-loop cannot be reached
event though it is a correct command.

Use `buf->len` as the end condition of the while-loop.

Fixes #74730.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-27 10:53:17 +02:00
Lyle Zhu
a3a08b93ed Bluetooth: Classic: HF_AG: Fix incorrect status judgment
Wrong condition of AG status is used for status
checking.

Fixes #74727.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-27 10:53:05 +02:00
Lyle Zhu
599812281b Bluetooth: Classic: HF_AG: Fix incorrect status judgment
Wrong condition of AG status is used for status
checking.

Fixes #74726.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-27 10:52:56 +02:00
Jordan Yates
40eededf01 bluetooth: bt_le_ext_adv_start_param is const
`bt_le_ext_adv_start` does not modify the `param` argument, which can
therefore be marked as `const`. This allows the struct to exist purely
in ROM.

Signed-off-by: Jordan Yates <jordan@embeint.com>
2024-06-26 13:05:14 -04:00
Emil Gydesen
68a0741d4f Bluetooth: ISO: Allow 0 interval and latency in CIG for unused dir
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>
2024-06-26 09:01:53 -04:00
Pisit Sawangvonganan
521b9e2c04 bluetooth: host: fix typo
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>
2024-06-25 10:27:23 -04:00
Sebastian Panceac
9ce338d416 Bluetooth: Fix CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY build warnings
This commit fixes compilation warnings that are present when compiling
with CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY as can be seen in this
compiler log:

"""
In file included from /zephyr-sdk-0.16.1/arm-zephyr-eabi/picolibc/
include/string.h:215,
                 from /zephyr/subsys/bluetooth/host/smp.c:15:
In function '__memcpy_ichk',
    inlined from 'sc_send_public_key' at /zephyr/subsys/bluetooth/host/
smp.c:3006:2:
/zephyr-sdk-0.16.1/arm-zephyr-eabi/picolibc/include/ssp/string.h:83:1:
warning: argument 2 null where non-null expected [-Wnonnull]
   83 | __ssp_bos_icheck3_restrict(memcpy, void *, const void *)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~
/zephyr-sdk-0.16.1/arm-zephyr-eabi/picolibc/include/ssp/string.h:83:1:
note: in a call to built-in function '__builtin_memcpy'
/zephyr/subsys/bluetooth/host/smp.c: In function 'smp_public_key':
/zephyr/subsys/bluetooth/host/smp.c:4214:21: warning: argument 2
null where non-null expected [-Wnonnull]
 4214 | memcmp(smp->pkey, sc_public_key, BT_PUB_KEY_COORD_LEN) == 0) {
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/zephyr-sdk-0.16.1/arm-zephyr-eabi/picolibc/include/string.h:62:10: note:
in a call to function 'memcmp' declared 'nonnull'
   62 | int memcmp (const void *, const void *, size_t);
      |     ^~~~~~
"""

The warning is caused by the potential use of NULL "sc_public_key"
global pointer that is not assigned a value in "smp_init()" if
CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY is enabled. This commit
conditionally changes the behavior of function "smp_public_key()"
if CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY is activated to simply return
and not use the "sc_public_key" variable. Other functions that are not
called anymore by "smp_public_key()" are also conditionally
deactivated when CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY is enabled

Signed-off-by: Sebastian Panceac <sebastian.panceac@ext.grandcentrix.net>
2024-06-25 10:26:41 -04:00
Eunkyu Lee
e491f220d8 Bluetooth: Host: Add missing buffer length check
Modified to check the length of the remaining data in buffer
before processing the next report. The length check is missing
in the cont routine.

Signed-off-by: Eunkyu Lee <mochaccino.00.00@gmail.com>
2024-06-25 06:06:06 -04:00
Lingao Meng
302422ad9d everywhere: replace double words
import os
import re

common_words = set([
    'about', 'after', 'all', 'also', 'an', 'and',
     'any', 'are', 'as', 'at',
    'be', 'because', 'but', 'by', 'can', 'come',
    'could', 'day', 'do', 'even',
    'first', 'for', 'get', 'give', 'go', 'has',
    'have', 'he', 'her',
    'him', 'his', 'how', 'I', 'in', 'into', 'it',
    'its', 'just',
    'know', 'like', 'look', 'make', 'man', 'many',
    'me', 'more', 'my', 'new',
    'no', 'not', 'now', 'of', 'one', 'only', 'or',
    'other', 'our', 'out',
    'over', 'people', 'say', 'see', 'she', 'so',
    'some', 'take', 'tell', 'than',
    'their', 'them', 'then', 'there', 'these',
    'they', 'think',
    'this', 'time', 'two', 'up', 'use', 'very',
    'want', 'was', 'way',
    'we', 'well', 'what', 'when', 'which', 'who',
    'will', 'with', 'would',
    'year', 'you', 'your'
])

valid_extensions = set([
    'c', 'h', 'yaml', 'cmake', 'conf', 'txt', 'overlay',
    'rst', 'dtsi',
    'Kconfig', 'dts', 'defconfig', 'yml', 'ld', 'sh', 'py',
    'soc', 'cfg'
])

def filter_repeated_words(text):
    # Split the text into lines
    lines = text.split('\n')

    # Combine lines into a single string with unique separator
    combined_text = '/*sep*/'.join(lines)

    # Replace repeated words within a line
    def replace_within_line(match):
        return match.group(1)

    # Regex for matching repeated words within a line
    within_line_pattern =
	re.compile(r'\b(' +
		'|'.join(map(re.escape, common_words)) +
		r')\b\s+\b\1\b')
    combined_text = within_line_pattern.
		sub(replace_within_line, combined_text)

    # Replace repeated words across line boundaries
    def replace_across_lines(match):
        return match.group(1) + match.group(2)

    # Regex for matching repeated words across line boundaries
    across_lines_pattern = re.
		compile(r'\b(' + '|'.join(
			map(re.escape, common_words)) +
			r')\b(\s*[*\/\n\s]*)\b\1\b')
    combined_text = across_lines_pattern.
		sub(replace_across_lines, combined_text)

    # Split the text back into lines
    filtered_text = combined_text.split('/*sep*/')

    return '\n'.join(filtered_text)

def process_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        text = file.read()

    new_text = filter_repeated_words(text)

    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(new_text)

def process_directory(directory_path):
    for root, dirs, files in os.walk(directory_path):
        dirs[:] = [d for d in dirs if not d.startswith('.')]
        for file in files:
            # Filter out hidden files
            if file.startswith('.'):
                continue
            file_extension = file.split('.')[-1]
            if
	file_extension in valid_extensions:  # 只处理指定后缀的文件
                file_path = os.path.join(root, file)
                print(f"Processed file: {file_path}")
                process_file(file_path)

directory_to_process = "/home/mi/works/github/zephyrproject/zephyr"
process_directory(directory_to_process)

Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
2024-06-25 06:05:35 -04:00
Lyle Zhu
37d62c6a16 Bluetooth: RFCOMM: check the validity of received frame
Check whether the received frame is complete by
comparing the length of the received data with
the frame data.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-25 09:03:44 +02:00
Ali Hozhabri
3b726dee53 Bluetooth: Host: Fix HCI command timeout usage
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>
2024-06-24 14:48:25 -04:00
Carles Cufi
06d7d763bd Bluetooth: gatt: Remove deprecated write struct member
The struct member was deprecated back in Zephyr 3.1.0.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2024-06-24 12:42:30 -04:00
Aleksander Wasaznik
a9c95c5c87 Bluetooth: Host: Enforce correct pool in bt_hci_cmd_send_sync
`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>
2024-06-24 14:26:11 +02:00
Jordan Yates
07870934e3 everywhere: replace double words
Treewide search and replace on a range of double word combinations:
    * `the the`
    * `to to`
    * `if if`
    * `that that`
    * `on on`
    * `is is`
    * `from from`

Signed-off-by: Jordan Yates <jordan@embeint.com>
2024-06-22 05:40:22 -04:00
Lingao Meng
cfd79e8bf0 bluetooth: host: Use K_WORK replace delayable
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>
2024-06-21 11:42:04 -04:00
Rubin Gerritsen
69fb606579 Bluetooth: Host: Define bt_security_err_to_str()
This can be useful if application developers
want to print them in the applications.

Later we can also use them in
the host to improve debuggability.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
2024-06-20 15:34:39 +02:00
Rubin Gerritsen
b25985ad6a Bluetooth: Host: Define bt_smp_err_to_str()
This API converts a SMP error code to a string.
This can be useful if application developers want
to print them in the applications.

BT_SMP_ERR_SUCCESS was added for completeness.

Later we can also use them in the host to improve debuggability.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
2024-06-20 15:34:39 +02:00
Rubin Gerritsen
94d712e5cf Bluetooth: Host: Define bt_att_err_to_str()
This can be useful if application developers
want to print them in the applications.

Later we can also use them in
the host to improve debuggability.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
2024-06-20 15:34:39 +02:00
Jonathan Rico
c6345c6371 Bluetooth: l2cap: service as much TX channels as possible
Similar to ISO connections, ACL connections are not serviced as fast as
possible. Change this, and try to send as much as we have resources for.

Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
2024-06-19 13:38:49 +02:00
Jonathan Rico
d3dbf890bf tests: Bluetooth: make an L2CAP multilink stress test
This test's purpose is to stress the TX data path in the case of multiple
connections.

Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
2024-06-19 13:38:49 +02:00
Jonathan Rico
8af7180531 Bluetooth: iso: make TX path service all connections
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>
2024-06-19 13:38:41 +02:00
Rubin Gerritsen
1b33616535 Bluetooth: Host: Add log entry for connection creation timeout
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>
2024-06-18 20:11:53 -04:00
Eunkyu Lee
88881257ab Bluetooth: Classic: Add length check in bluetooth classic
Added length checks for user input in `sdp_client_receive` and
`l2cap_br_info_rsp`.

Signed-off-by: Eunkyu Lee <mochaccino.00.00@gmail.com>
2024-06-18 15:54:27 +02:00
Valerio Setti
32b43564df bt: hci_ecc: add option to use PSA APIs instead of TinyCrypt
This commit adds CONFIG_BT_USE_PSA_API to allow the end
user to prefer PSA APIs over TinyCrypt for crypto operations
in bluetooth. Of course, this is possible only if
a PSA provider is available on the system, i.e.
CONFIG_PSA_CRYPTO_CLIENT is set.

This commit also extends
tests/bluetooth/mesh/basic/bluetooth.mesh.gatt adding a specific
case using PSA.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
2024-06-14 15:41:34 +02:00
Valerio Setti
814b2ed457 bt-host: add option to use PSA APIs instead of TinyCrypt
By enabling CONFIG_BT_USE_PSA_API the user can specify to use
PSA APIs instead of TinyCrypt for crypto operations in bluetooth
host module.

This commit also extends tests/bluetooth/gatt in order to
add a PSA test.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
2024-06-14 15:41:34 +02:00
Rubin Gerritsen
9984adf24e Bluetooth: Host: Support concurrent initiating and scanning
The HCI command LE Read Supported States command returns
if the controller supports running the scanner and initiator
roles in parallel.

This commit utilizes this information in the host:
- It does not prevent initiating a connection when the scanner is
  running
- It does not prevent the host from restarting the background
  scanner when there the host wants to auto-initiate a connection.
- It does not stop the scanner when the host wants to auto-initiate
  a connection.

To support this feature, the scanner and initiator
always have to use the same address.
This because the HCI command LE Set Random Address
cannot be issued after the initiator or scanner has started.
1. When privacy is disabled, the scanner has to use its identity
   address to ensure it uses the same address as the initiator.
2. Only one identity is supported.

To simplify the implementation, it is a requirement to use
extended advertising commands to avoid interfering with
the random address used by the advertiser(s).

Also, it is a requirement to never use time-limited scanning,
as RPA this feature does not work when privacy is being used.
See https://github.com/zephyrproject-rtos/zephyr/issues/73634.

The changes in this commit will be tested out of tree as the
Zephyr Bluetooth Controller does not support this functionality.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
2024-06-13 08:04:42 -04:00
Rubin Gerritsen
5098bf3539 Bluetooth: Host: Callback registering functions to return status
Returning a status code will allow the application developer
to detect logic issues.

We consider this as not breaking the API.
If `-Werror -Wunused-result` is enabled, the application developer needs
to validate the return code.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
2024-06-13 08:03:28 -04:00
Rubin Gerritsen
3eb975deb2 Bluetooth: Host: Rename callback_list -> conn_cbs
This improves consistency with other callback lists like
scan_cbs and pa_sync_cbs.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
2024-06-13 08:03:28 -04:00
Rubin Gerritsen
2ec3cd307c Bluetooth: Host: Avoid registering callback twice
Callbacks can only be registered once. Otherwise the slist
will become circular.

In this commit we have choosen to ignore the second registration
call if the callback has already been registed. The alternative
is to trigger an assertion. That doesn't work if the assertions
are turned off.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
2024-06-13 08:03:28 -04:00
Rubin Gerritsen
6e6bb26107 Bluetooth: Host: Conn callback list to use slist
This allows us to use functionality provided by slist.
First use case: Avoid adding an element twice.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
2024-06-13 08:03:28 -04:00
Théo Battrel
7c3a5d5c3a Bluetooth: Host: Add Per Adv Sync handle getter
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>
2024-06-13 05:34:14 -04:00
Lyle Zhu
6458c5ab1f Bluetooth: HFP_AG: fix building warning
Give `err` a initialization value 0.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-12 21:13:58 -04:00
Lyle Zhu
bbfa3bc1b9 Bluetooth: HFP_AG: Optimize lock/unlock of the SCO creating
When testing https://github.com/zephyrproject-rtos/zephyr/pull/72090/,
there is an issue found.

The change in the previous commit is to put all data sending
operations into the work queue context, and lock the current
AG before sending data.

And in change of #72090, the HCI TX thread is removed. All
sending sequence are happened in work queue context.

There is a possible problem when AG creates a SCO connection
by calling the function bt_conn_create_sco. Before the
function bt_conn_create_sco is called, AG will be locked to
avoid creating repeated SCO connection.
And the execution of the function bt_conn_create_sco
depends on the work queue. Because the HCI command of
function bt_conn_create_sco is sent in work queue context.

In the normal case, there is not any issue.
But there is a case that when the function
bt_conn_create_sco is being executed, there is a pending AG
TX waiting to be executed.

Once the work queue starts executing the handler, the AG TX
handler is executed first. Since the lock has been acquired
by other threads, the AG TX handler cannot acquire the lock.
As a result, the SCO connection creation fails.

Remove the AG lock from SCO creating. Instead, use a flag
to mark whether a SCO connection is be created.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-12 21:13:58 -04:00
Lyle Zhu
6939c8c02d Bluetooth: HFP_AG: Optimize the TX process
Due to the sent callback of RFCOMM is changed, the
sending buf need to be primed waiting for the
previous one to be completed. Add a worker for
this purpose.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-12 21:13:58 -04:00
Lyle Zhu
f055fe7165 bluetooth: hfp_hf: update channel sent callback prototype
Due to the parameter `buf` has been removed by rfcomm,
update the prototype of channel sent callback hfp_hf_sent.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-12 21:13:58 -04:00
Lyle Zhu
17e2564ff2 bluetooth: rfcomm: remove tx meta
Due to the sending buf cannot be referred
by sending layer.
It is unsafe to use `buf` identification
for a transmission, because the buf may
have been newly transmitted when the
sent callback is triggered.

Now instead, when the send completion
callback is received, the upper layer
is notified that a transfer is completed.
If multiple bufs are sent at the same
time, there is no guarantee which buf
is completed when the sent callback
triggered. Therefore, it is recommended
that the caller transfers the next data
block after the previous transfer is
completed.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-12 21:13:58 -04:00
Lyle Zhu
7f71ad38cc bluetooth: rfcomm: fix issue of sending buf invalid
There is a change (commit no.: 93d0eac834) that if
the `ref` of sending buf is not 1, the error code
`-EINVAL` will be returned from bt_conn_send_cb.

It causes the RFCOMM functionality cannot work
properly.

Remove the ref operation from the buf to be sent
to fix the issue.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
2024-06-12 21:13:58 -04:00
Jonathan Rico
9b3f41de55 Bluetooth: host: don't pull data if no view bufs
View buffers are now also a limited resource. Acquire them before
attempting to pull data. `CONFIG_BT_CONN_FRAG_COUNT` should be tuned on
a per-application basis to avoid this.

A possible optimization, that was present before, is to not create a
frag when the original buffer fits the controller's HCI size.

I prefer deferring this optimization to a future patchset.

Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
2024-06-12 18:51:34 +02:00
Jonathan Rico
5a7ef422bb Bluetooth: host: use __maybe_unused for convenience variables
In order to suppress compiler warnings w/o using void/ifdef.

Suggested in #72854

Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
2024-06-12 18:51:34 +02:00
Jonathan Rico
b6cdf10310 Bluetooth: L2CAP: remove seg_pool
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>
2024-06-12 18:51:34 +02:00
Jonathan Rico
28be8909a6 Bluetooth: host: remove TX thread
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>
2024-06-12 18:51:34 +02:00
Jonathan Rico
48d1cffb4d Bluetooth: L2CAP: remove CONFIG_BT_L2CAP_RESCHED_MS
We don't need it thanks to the new TX architecture.

Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
2024-06-12 18:51:34 +02:00
Jonathan Rico
38820efd8d Bluetooth: L2CAP: Make bt_l2cap_send_pdu()
This API replaces `bt_l2cap_send()` and `bt_l2cap_send_cb()`.

The difference is that it takes the `struct bt_l2cap_le_chan` object
directly instead of a connection + CID.

We need the channel object in order to put the PDU on the TX queue. It
is inefficient to do a search for every PDU when the caller knows the
channel object's address and can just pass it down.

Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
2024-06-12 18:51:34 +02:00
Jonathan Rico
28535fe2f2 Bluetooth: host: Change TX pattern (push -> pull)
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>
2024-06-12 18:51:34 +02:00
Jonathan Rico
1c8cae30a8 Bluetooth: host: Introduce "view" buffer concept
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>
2024-06-12 18:51:34 +02:00
Aleksander Wasaznik
52dc64f0d9 Bluetooth: conn: Allocate TX context JIT
`bt_conn_send_cb` used to allocate a TX context (K_FOREVER).
Instead, we now put the context in the userdata of the buffer.

This means that now this fn will never block and always succeed since the
tx_queue is a FIFO (infinite size). It just puts the buf on the queue.

The metadata is stored safely in there until we have acquired all the
necessary resources to send it to the controller without failing: TX
context and controller buffer.

I.e. when `bt_conn_process_tx` is called, that's when a TX context is
try-allocated and the contents of `buf->userdata` is moved into it.
The buffer is now ready to be sent to the lower layer.

`bt_conn_process_tx` will return -EWOULDBLOCK if it's not able to acquire a
TX context, this PR modifies `bt_conn_prepare_events` to respond to this by
also waiting on the TX context pool.

Unfortunately, this increases the required userdata size for any buffers
handed to `bt_conn_send_cb`. This will be fixed in a later commit.

Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
2024-06-12 18:51:34 +02:00
Johan Hedberg
bf363d7c3e Bluetooth: Host: Avoid processing "no change" encryption changes
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>
2024-06-11 19:45:09 -04:00
Johan Hedberg
f8befbd67a Bluetooth: host: hci_raw: Use existing H4 defines from hci_types.h
Use existing defines instead of redefining our own.

Signed-off-by: Johan Hedberg <johan.hedberg@gmail.com>
2024-06-11 19:42:49 -04:00