Compare commits

...

71 Commits

Author SHA1 Message Date
Christopher Friedt
aa8c3fa22e release: Zephyr 2.7.0-rc4
Set version to 2.7.0-rc4

Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
2021-10-01 21:55:17 -04:00
Christopher Friedt
5a5eaa3c58 tests: net: dns_sd, mdns: support service type enumeration
Tests for DNS-SD Service Type Enumeration.

Fixes #38673

Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
2021-10-01 20:40:14 -04:00
Christopher Friedt
efd77e0958 net: dns_sd, mdns: support service type enumeration
Support DNS-SD Service Type Enumeration in the dns_sd library
and mdns_responder sample application.

For more information, please see Section 9, "Service Type
Enumeration" in RFC 6763.

https://datatracker.ietf.org/doc/html/rfc6763

Fixes #38673

Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
2021-10-01 20:40:14 -04:00
Torsten Rasmussen
b3affe6b94 devicetree: remove support for DTC_OVERLAY_FILE in environment
Setting of DTC_OVERLAY_FILE as an environment setting was deprecated
before Zephyr 1.14 LTS.

This commit remove the support for this possibility and thus cleans up
the build system.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-10-01 20:39:40 -04:00
Aleksander Wasaznik
5969c3b941 Bluetooth: Host: Fix resource leak in bt_gatt_unsubscribe
There are two simmilar functions for unsubscribing from GATT handles.

 - `gatt_sub_remove`, which is called on disconnect for every
 subscription will free the `subscriptions` entry when the entry
 represents no subscriptions.

 - `bt_gatt_unsubscribe`, called by the application, which forgets to
 free the `subscriptions` entry.

If all subscriptions grouped in a `subscriptions` entry are removed
using `bt_gatt_unsubscribe` before disconnect, there are no
subscriptions left to call `gatt_sub_remove` on. The `subscriptions`
entry is then never freed.

The above results in a resource leak of a `subscriptions` entry.

This fix makes explicit and enforces the invariant that there should not
be entries in `subscriptions` with an empty subscription list.

Fixes #38688

Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
2021-10-01 20:37:56 -04:00
Piotr Pryga
6db7778c81 tests: Bluetooth: df: Add test to verify correctness of relase of PDUs
Add unit tests that will ensure the CTE disable operation does not
cause breaking of LLL operations by too early release of chained PDUs.
The tests verify if numbers of PDUs in free PDUs fifo and free PDUs
memory pool are correct.

Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
2021-10-01 20:37:32 -04:00
Piotr Pryga
bd6523195c Bluetooth: controller: Fix ASSERT caused by ULL releasing chain PDUs
When CTE is enabled for periodic advertising and number of CTE is
greater than number of PDUs in a chain, that are needed to transport
advertising data, there are additional empty PDUs used for transport
CTE.

CTE transmission may be disabled when periodic advertising event is
pending in LLL. rem_cte_info_from_per_adv_chain removed CTEInfo field
from extended advertising header in chained PDUs. When there were found
empty PDUs (created to transport CTE only), they were released from
the chain that was currently used by LLL. That caused an assert in
isr_tx handler due to broken advertising chain.

The rem_cte_info_from_per_adv_chain may not relese PDUs that are in
use by LLL. The PDUs may be released by LLL in prepare step when
advertising pdu double buffer is swapped by lll_adv_sync_data_latest-
_get.

This PR fixes that issue.

Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
2021-10-01 20:37:32 -04:00
Vinayak Kariappa Chettimada
701c560901 Bluetooth: Controller: Fix assert on aux LLL scheduled chain reception
Fix asserted in ULL due to incorrect resumption of scan
window when auxiliary channel chain PDU is LLL scheduled by
a ULL scheduled auxiliary channel PDU reception.

The issue is solved by having `is_chain_sched` flag in the
auxiliary channel scan context and using the already present
`is_aux_sched` in the primary channel scan context to
differentiate if the auxiliary PDU Rx ISR is to return back
to primary channel scan window or to close the auxiliary
chain PDU reception radio event.

Relates to #38146.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-10-01 20:37:12 -04:00
Vinayak Kariappa Chettimada
b24bbad815 Bluetooth: Controller: Fix to ignore aux ptr in scannable advertising
Fix to ignore aux pointer struct in scanning advertising, to
avoid ULL scheduling from setting up ticker to receive chain
PDUs while LLL is receiving scan response PDU.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-10-01 20:37:12 -04:00
Daniel Leung
a7baa3628d doc: release: 2.7: add release notes for IPM
Add release notes for IPM drivers based on commit history.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2021-10-01 20:35:45 -04:00
Daniel Leung
7aee51ea82 doc: release: 2.7: add release notes for PCI/PCIe
Add release notes for PCI/PCIe based on commit history.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2021-10-01 20:35:27 -04:00
Daniel Leung
7c62429a75 doc: release: 2.7: add release notes for serial
Add release notes for serial/UART drivers based on commit
history.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2021-10-01 20:35:11 -04:00
Erwan Gouriou
82f3165b79 doc: release notes: Shields updates for v2.7.0
Update V2.7.0 release notes document with noticeable changes
related to shields.

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
2021-10-01 20:34:50 -04:00
Erwan Gouriou
e858321f83 doc: release notes: STM32 updates for v2.7.0
Update V2.7.0 release notes document with noticeable changes
related to STM32.

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
2021-10-01 20:34:50 -04:00
Erwan Gouriou
d2c5f05b1b boards: stm32u5: Fix instructions to use openocd
Instructions to use openocd on stm32u5 based platforms were missing
an instruction on the branch to use.
Also, the console excerpt were not rendering correctly, so fix
them.

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
2021-10-01 20:34:34 -04:00
Vinayak Kariappa Chettimada
708951ecd2 Bluetooth: Controller: Use defines for scanning state types
Use defines for scanning state types of passive, active,
initiator and synchronization state.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-10-01 20:34:18 -04:00
Vinayak Kariappa Chettimada
ad2b77e7f8 Bluetooth: Controller: Allow resolving list update during passive scan
Allow resolving list update  when passive scanning,
otherwise deny if advertising, active scanning, initiating
or periodic sync create is active.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-10-01 20:34:18 -04:00
Torsten Rasmussen
eb85f9a47e Revert "drivers: pinmux: build as static library"
This reverts commit 43309296b8.

Fixes: #38403

The referred commit introduced `zephyr_library()` for pinmux drivers but
also resulting in #38403 because several boards has `CONFIG_PINMUX=y`
without selecting any pinmux drivers from `drivers/pinmux` thus
generating the following warning:
> No SOURCES given to Zephyr library: drivers__pinmux
>
> Excluding target from build.

This commit reverts the changes so that this warning disappears.
This results in pinmux drivers from `drivers/pinmux` to be located in
libzephyr.a which is messy, but has been so for a long time, even before
Zephyr 1.14 LTS.

The future pinctrl API will be designed in such a way that this problem
will not occur. Thus the old behavior is acceptable until the transition
to pinctrl API has completed.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-10-01 20:33:36 -04:00
Agata Ponitka
9ad64e8809 Bluetooth: Tester: Add the OOB Authentication method
Adding support for automatic testing OOB Authentication method.

Signed-off-by: Agata Ponitka <agata.ponitka@codecoup.pl>
2021-10-01 20:33:00 -04:00
Torsten Rasmussen
cf112e2a06 drivers: console: remove unused CONSOLE selection
Fixes: #38403

Removing unneeded `CONFIG_CONSOLES=y` occurrences where no console
driver is selected.

Such selection results in an empty drivers__console zephyr library,
which again results in the following warning message.

> No SOURCES given to Zephyr library: drivers__console
>
> Excluding target from build.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-10-01 20:22:03 -04:00
Torsten Rasmussen
0ad4b4438a drivers: gpio: remove unused GPIO selection
Fixes: #38403

Removing unneeded `imply GPIO` and `CONFIG_GPIO=y` occurrences where no
files are added to the gpio zephyr library.

Also removed `CONFIG_GPIO=y` occurences where this is handled by
defconfigs for the soc or board.

Selection of GPIO without selecting any drivers results in the warning:

> No SOURCES given to Zephyr library: drivers__gpio
>
> Excluding target from build.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-10-01 20:22:03 -04:00
Torsten Rasmussen
f7d0ae5e6c drivers: ethernet: remove dedicated drivers__ethernet__native_posix lib
Fixes: #38403

The two eth_native_posix.c and eth_native_posix_adapt.c are now added
to the common drivers__ethernet Zephyr library.

Instead of creating a dedicated library for just two files those files
are now added to the common ethernet library, see also #8826.
Instead, the dedicated compile definitions required for those files are
specified using COMPILE_DEFINITIONS on the source files.

This also avoids the following warning as the ethernet library is no
longer empty.

> No SOURCES given to Zephyr library: drivers__ethernet
>
> Excluding target from build.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-10-01 20:22:03 -04:00
Torsten Rasmussen
a084ec5483 modules: hal_nxp: removing always empty zephyr_library
No sources were ever added to the `zephyr_library()` defined in
modules/hal_nxp/usb/CMakeLists.txt, thus removing this lib to avoid
the warning:

> No SOURCES given to Zephyr library: modules__hal_nxp__usb
>
> Excluding target from build.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-10-01 20:22:03 -04:00
Torsten Rasmussen
c3fac651ee drivers: net: adding NET_DRIVERS menuconfig
Fixes: #38403

Adding NET_DRIVERS menuconfig so that network drivers are grouped
together in its own menu entry under drivers, similar to most other
drivers.

This further has the advantages that `CONFIG_NET_DRIVERS` can be used
for testing to determine if network drivers has been selected.

This changed revealed a dependency loop where both `select` (for SLIP)
and `depends` (for PPP) which both depends on NET_DRIVERS` where in use
in the dependency tree for Qemu networking, especially NET_SLIP_TAP.

This is handled by defaulting `NET_DRIVERS` to `y` when building for a
Qemu target.
`SLIP` had a dependency to `!QEMU_TARGET || NET_QEMU_SLIP`. This is
changed so that SLIP prompt depends on `!QEMU_TARGET` which provides
full user control in hardware but makes the symbol promptless on Qemu
targets.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-10-01 20:22:03 -04:00
Torsten Rasmussen
30eadf758a drivers: create BT_DRIVERS Kconfig entry
Fixes: #38403

Changing Bluetooth drivers from being a menu into a menuconfig.
This aligns the Bluetooth driver configuration with other driver
configurations as well as provides a setting which identifies if
Bluetooth drivers has been enable.

This further helps to avoid empty Zephyr libraries for bluetooth
samples.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-10-01 20:22:03 -04:00
Emil Gydesen
1a42926317 Bluetooth: ISO: Remove bt_conn_unref for ISO deferred work
Removed the bt_conn_unref from the deferred_work function.
For ISO, the conn unref for the peripheral will happen in
the bt_iso_disconnected function. For the central, the
unref shall only happen when the CIG is terminated.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
2021-10-01 07:42:40 -04:00
Vinayak Kariappa Chettimada
30b24920e8 Bluetooth: Controller: Fix multiple peripheral connection deadlock
Fix deadlock in multiple peripheral connection in a device
due to redundant double reservation of node rx buffer during
crossover scenario in Data Length Update procedure.

Data Length Update resize state was reset back to response
wait state when peripheral received an acknowledgment to
local initiated Data Length Request PDU after having already
transitioned to resize state.

Implementation is designed to transition to resize state
under both Data Length Response reception and crossover
scenario of Data Length Request reception when procedure is
local initiated.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-10-01 07:37:31 -04:00
Alexandre Bourdiol
41654b0dba tests: kernel: sched: schedule_api: enlarge timeslice criterion
From time to time, measured slice time is one less/more than requested.
Fixes #35793

Signed-off-by: Alexandre Bourdiol <alexandre.bourdiol@st.com>
2021-10-01 04:49:50 -04:00
Joakim Andersson
17c5a7c89e Bluetooth: host: Access local IRKs consistently
Change the way the local IRKs are accessed to be consistent with the
all other uses.
Coverity thinks using the pointer to the array is suspicious in this
case.

Fixes: #38130

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
2021-09-30 20:21:38 -04:00
Joakim Andersson
0d4db6b952 Bluetooth: host: Verify valid local identity loaded from settings
Verify that the local identity loaded from the settings key is
valid for the current configuration.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
2021-09-30 20:21:38 -04:00
Vinayak Kariappa Chettimada
e24df5272a Bluetooth: Controller: Separate address get and read functions
Have separate Bluetooth Device address get and read
functions, remove use of function just to return Extended
Advertising Random address and replace with simple
assignment statement.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-30 20:21:14 -04:00
Vinayak Kariappa Chettimada
a3e8f83e6b Bluetooth: Controller: Use defines for aux pointer offset unit value
Use defines for aux pointer offset unit value.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-30 20:21:14 -04:00
Vinayak Kariappa Chettimada
e8929c3360 Bluetooth: Controller: Fix Extended Advertising channel use
Add implementation defined channel index in the auxiliary
pointer of the common extended payload format in the primary
channel PDUs and the same be used in the transmission of
auxiliary PDUs.

Fixes #35668.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-30 20:21:14 -04:00
Vinayak Kariappa Chettimada
7597eef8b3 Bluetooth: Controller: Add FIXME for Per Adv chain channel use
Add FIXME comments for missing use of channel selection
algorithm for Periodic Advertising chained PDUs.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-30 20:21:14 -04:00
Vinayak Kariappa Chettimada
9ff7cb60fc Bluetooth: Controller: Add advertiser clock accuracy value
Add implementation to set correct Advertiser's clock
accuracy value in the auxiliary pointer field in the common
extended payload format.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-30 20:21:14 -04:00
Vinayak Kariappa Chettimada
71420c6b76 Bluetooth: controller: Fix populate offset in latest advertising PDU
Fix implementation to populate the aux, and sync offset
in the latest PDU. If both the current and latest of the
double buffer has been filled and LLL did not pick the
latest PDU, then the offset should be filled into the latest
PDU (and not into the first/current PDU).

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-30 20:21:14 -04:00
Vinayak Kariappa Chettimada
519f412ce8 Bluetooth: Controller: Minor indentation fixes
Minor indentation fixes.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-30 20:21:14 -04:00
Vinayak Kariappa Chettimada
c0e44d9462 Bluetooth: Controller: Explicitly typecast void return for memcpy calls
Explicitly typecast void return for memcpy calls.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-30 20:21:14 -04:00
Vinayak Kariappa Chettimada
47f4ddafdd Bluetooth: Controller: Minor rename of ULL internal function
Rename ULL internal helper function to get the random
address.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-30 20:21:14 -04:00
Szymon Janc
1a15d367e2 tests: bluetooth: tester: Add support for L2CAP Credits command
This allows IUT to return credits on specified L2CAP channel when
requested by Upper Tester.

Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
2021-09-30 20:20:49 -04:00
Andrzej Głąbek
7ac8c2f51b drivers: i2s_nrfx: Fix a few minor fixes
- correct the names of buffers used by message queues so that it
  is possible to have multiple instances of the driver (in case
  such need appears in the future)
- make `stop` and `discard_rx` normal structure members, not bit
  fields, as they are modified in the interrupt handler and that
  could lead to overwriting of other bit fields located in the
  same memory unit
- add a log message providing the actual frame clock (WS) frequency
  (i.e. PCM rate) that the driver was able to configure (due to
  hardware limitations, it is not always possible to achieve the
  exact requested frequency and the driver selects the closest one
  available, so make it more visible to users

Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
2021-09-30 20:20:26 -04:00
Andrzej Głąbek
4c52fb9fd1 drivers: i2s_nrfx: Do not enforce two channels for I2S format
Remove unnecessary condition that effectively limits the usability
of the I2S format to two channels mode only.
Although the description of the `i2s_config` structure contains
a remark that for the I2S format the specified number of channels
is ignored and always two are used, in fact only one other in-tree
driver (i2s_sam_ssc) applies such limitation.
The nRF I2S hardware has no problem with handling the I2S format
with audio data for only one channel, so there is no need for having
this limitation in the driver, and without such mode of operation of
the driver it is impossible to feed it with PCM data directly from
the PDM peripheral working in one channel mode.

Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
2021-09-30 20:20:26 -04:00
Gerard Marull-Paretas
cb657057b3 tests: pm: power_mgmt: use PM_STATE_SUSPEND_TO_IDLE
Since the tests expects devices to change states, PM_STATE_RUNTIME_IDLE
can't be used. The first state that cares about devices is
PM_STATE_SUSPEND_TO_IDLE.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2021-09-30 20:20:04 -04:00
Gerard Marull-Paretas
69996900c8 pm: stop handling devices on PM_STATE_RUNTIME_IDLE
According to the state documentation, this state does not need to handle
devices:

> Runtime idle is a system sleep state in which all of the cores enter
deepest possible idle state and wait for interrupts, no requirements for
the devices, leaving them at the states where they are.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2021-09-30 20:20:04 -04:00
Robert Lubos
70979b9047 doc: release: 2.7: Add release notes for networking
Add networking relase notes based on commit history, for commits
including "net" phrase in the title.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2021-09-30 20:19:25 -04:00
Peter Mitsis
e601ca8e11 doc: Add deadline scheduling information
Adds information to the kernel scheduling documentation explaining
how a thread's deadline is used to determine the thread's relative
priority.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
2021-09-30 20:16:41 -04:00
Peter Mitsis
369d5d038f kernel: fix deadline typo
Corrects the spelling of "dealine" to "deadline".

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
2021-09-30 20:16:41 -04:00
Chen Peng1
27a2271093 timer: mask interrupts in timer's timeout handler.
before running timer's timeout function, we need to make
sure that those threads waiting on this timer have been
added into the timer's wait queue, so add operations to
use timer lock to mask interrupts in z_timer_expiration_handler
function to synchronize timer's wait queue.

Signed-off-by: Chen Peng1 <peng1.chen@intel.com>
2021-09-29 14:51:01 -04:00
Vinayak Kariappa Chettimada
f4a03dfa32 Bluetooth: Controller: Update Bluetooth version to 5.3
Update the Bluetooth HCI Version to 5.3.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-29 13:11:05 -04:00
Vinayak Kariappa Chettimada
192cad6cda Bluetooth: Controller: Fix imprecise data bus error in periodic sync
Fix imprecise data bus error when receiving Periodic
Advertising Report caused due to uninitialized `extra` field
member in the node rx struct passed from ULL to LL thread
context.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-29 13:10:14 -04:00
Vinayak Kariappa Chettimada
1e2c698e95 Bluetooth: Controller: Fix repeated per sync drift compensations
Fix repeated periodic sync drift compensation invoked when
receiving chain PDUs which caused memory corruptions and
bus faults.

Use `is_aux_sched` flag in Periodic Sync's LLL context to
differentiate between the first AUX_SYNC_IND PDU followed by
use of LLL scheduling to receive following AUX_CHAIN_IND PDU
versus ULL scheduling being used to receive AUX_CHAIN_IND
PDUs.

Drift compensation to be done only using the AUX_SYNC_IND
PDU and not on reception of AUX_CHAIN_IND PDU using ULL
scheduling.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2021-09-29 13:10:14 -04:00
Andrzej Głąbek
0c0a990c4b soc: nrf53: Add missing HAS_HW_NRF_* entries
A few HAS_HW_NRF_* Kconfig options for peripherals available in nRF5340
are not selected. Fix it.

Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
2021-09-29 10:42:51 -04:00
Pavel Vasilyev
dbf08a18c3 Bluetooth: Mesh: Return ETIMEDOUT if k_sem_take call times out
EAGAIN is used in some other places in the code, e.g. if node is not
provisioned when a model tries to send a message. This change helps to
differentiated if the acknowledged message timed out from other failers.

Signed-off-by: Pavel Vasilyev <pavel.vasilyev@nordicsemi.no>
2021-09-29 10:42:11 -04:00
Krzysztof Chruscinski
6c4d190493 lib: os: mpsc_pbuf: Add const qualifier to API calls
Add const qualifier where it was missing. Updating
relevant code.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
2021-09-29 10:41:27 -04:00
Erwan Gouriou
5d0100e12c boards: nucleo_l073rz: Set LSI as LPTIM clock source
For some reason, LSE can't be used as LPTIM clock source
on nucleo_l073rz.
As a consequence, low power operations are not functional on
this platform.
Waiting for the original issue to be fixed, set LSI as LPTIM
clock source.

Partially fixes #38930

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
2021-09-29 10:32:41 -04:00
Ramiro Merello
b11983d71a subsys/fs/nvs: nvs_write return missing documentation
- Documentation of the 0 return value for ns_write function
- Ajusted lines length limit from 80 to 100
- Fixed extra and missing parameters for nvs_fs
- Misc spelling/grammar changes

Signed-off-by: Ramiro Merello <rmerello@itba.edu.ar>
2021-09-29 09:54:45 -04:00
Joakim Andersson
8691e3e0d2 Bluetooth: host: compile out check for multiple identities
Add check that can be removed by the compiler since the rest is only
needed when multiple identities have been enabled.

Fixes: #38134

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
2021-09-29 09:53:37 -04:00
Robert Lubos
c1fa585917 net: sockets: tls: Ignore empty iovec entries in sendmsg
According to `sendmsg()` man pages, the `struct msghdr` can contain
empty records (iov_len equal to 0). Ignore them in TLS `sendmsg()`
implementation to avoid unnecessary calls to mbed TLS.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2021-09-29 09:50:58 -04:00
Robert Lubos
8a9c1e7721 net: mqtt: Handle incomplete zsock_sendmsg write
In case zsock_sendmsg did not send all of the data requested, update the
`struct msghdr` content and retry.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2021-09-29 09:50:58 -04:00
Robert Lubos
8a0dc430b2 net: context: Do not overflow net_pkt when using msghdr
If data for `context_sendto()` was provided in a form of
`struct msghdr` (for instance via `sendmsg()`), it was not verified that
the provided data would actually fit into allocated net_pkt. In result,
and error could be returned in case the provided data was larger than
net_pkt allows.

Fix this, by verifying the remaining buffer length when iterating over
`struct msghdr`. Once the buffer is filled up, break the loop. In
result, functions like `sendmsg()` will return the actual length of data
sent instead of an error.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2021-09-29 09:50:58 -04:00
Francois Ramu
e6638715d9 drivers: adc: stm32 adc disable causing endless loop
Setting Oversampling also applies on stm32L5 but disabling
the ADC will cause endless loop except for the stm32L0 serie.
Errata applies only on stm32G0 soc series when
writing ADC_CFGR1 register.

Signed-off-by: Francois Ramu <francois.ramu@st.com>
2021-09-29 09:49:55 -04:00
Erwan Gouriou
5b78f62138 tests/drivers: gpio_basic_api: Upudate nucleo_f103rb configuration
For some reason, provided pin configuration for nucleo_f103rb
is not able to detect gpio callback issues.
Move to other pin combination which detect pin callback issues.

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
2021-09-29 09:49:22 -04:00
Erwan Gouriou
01be872f01 drivers/gpio: stm32f1: AFIO init should happen before GPIO inits
GPIO initialization was moved to PRE_KERNEL_1 with commit
590162a5cc.
This had the consequence of having AFIO init done after GPIO init
as a consequence, this sequence ends up with AFIO clock disabled,
and hence negative impact on AFIO expected services.

Additionally, to save some flash, compile out afio init when not
required.

Fixes #38870

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
2021-09-29 09:49:22 -04:00
Carlo Caione
317749e1e8 reserved-memory: Fix layering violation
Move memory.h out of the way in a more "private" space
(include/linker/devicetree_reserved.h) to prevent polluting the
devicetree space.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2021-09-29 06:13:57 -04:00
Torsten Rasmussen
7d3606a74a scripts: twister: print message from CMake verify toolchain on failures
Fixes: #38924

When the `verify-toolchain.cmake` script fails, then twister will print
a standard message to the user regardless of the reason.
> E: Variable ZEPHYR_TOOLCHAIN_VARIANT is not defined

The `verify-toolchain.cmake` already prints detailed information
regarding the cause of the failure, so twister should just pass that
message as-is.

For example, the message that is provided by verify-toolchain.cmake
when Zephyr SDK 0.13.0 is installed but 0.13.1 is required looks like:
> CMake Error at cmake/verify-toolchain.cmake:75 (find_package):
>  Could not find a configuration file for package "Zephyr-sdk" that is
>  compatible with requested version "0.13.1".
>
>  The following configuration files were considered but not accepted:
>
> /opt/zephyr-sdk-0.13.0/cmake/Zephyr-sdkConfig.cmake, version: 0.13.0

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-09-29 06:13:26 -04:00
Piotr Golyzniak
08917e0708 twister: Fix missing testcases with error status
If timeout error was occured during performing testsuite on QEMU or
other simulator (e.g. Renode), information about this error will be not
placed in final report. It can be fixed, by set status of testcases,
which were not performed due to this error as "BLOCK".

Simmilar solution is alredy used in DeviceHandler when Twister works
with real platform. So I think that it is resonable to use the same
approach, when tests are performed on simulators.

I move loop which iterate through all testcases and set their tests
status as BLOCK into the parent Handler class, because the same
activity is performed in each children class (BinaryHandler,
DeviceHandler and QEMUHandler).

Fixes #38756

Signed-off-by: Piotr Golyzniak <piotr.golyzniak@nordicsemi.no>
2021-09-29 06:12:35 -04:00
Enjia Mai
b868419ac7 docs: acrn: update the documentation of setting the ACRN hypervisor
Add some descriptions of hybrid scenario of ACRN hypervisor, and
completed the configurations that we are using to build ACRN. This
configuration change for ACRN hypervisor is necessary when our Zephyr
application is using over than one CPU for it.

Signed-off-by: Enjia Mai <enjia.mai@intel.com>
2021-09-28 13:09:59 -04:00
Fabio Baltieri
16efab0493 samples: modbus: update/fix samples.yaml configs
Update the sample.yaml files for the modbus samples:
- depends_on entries should just be space separated, drop the comma
- add the platform referenced in the documentation to platform_allow
- replace the deprecated dt_compat_enabled_with_alias with
  dt_enabled_alias_with_parent_compat

Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com>
2021-09-28 06:25:43 -04:00
Fabio Baltieri
916dbab23a samples: modbus: rtu_server: drop unused variable
This has been unreferenced since:

4ff616b647 modbus: rework interface configuration

This generates a compiler warning, but it went unnoticed because the
sample test is configured incorrectly and not running.

Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com>
2021-09-28 06:25:43 -04:00
Fabio Baltieri
62680344a6 samples: canopennode: fix the sample path
The sample code got moved in 613f1cde4a, update the old path to the
current one.

Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com>
2021-09-28 06:25:43 -04:00
Henrik Brix Andersen
d8ee47459c twister: ignore ROM region overflows
Add ROM region to list of regions to optionally ignore overflows on.

Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
2021-09-27 20:50:31 -04:00
135 changed files with 2133 additions and 698 deletions

View File

@@ -2,4 +2,4 @@ VERSION_MAJOR = 2
VERSION_MINOR = 7
PATCHLEVEL = 0
VERSION_TWEAK = 0
EXTRAVERSION = rc3
EXTRAVERSION = rc4

View File

@@ -14,6 +14,13 @@ config QEMU_TARGET
Mark all QEMU targets with this variable for checking whether we are
running in an emulated environment.
config NET_DRIVERS
bool
default y if QEMU_TARGET && NETWORKING
help
When building for a qemu target then NET_DRIVERS will be default
enabled to allow for easy use of SLIP or PPP
# Note: $BOARD_DIR might be a glob pattern
choice

View File

@@ -11,7 +11,6 @@ CONFIG_HW_STACK_PROTECTION=y
# enable peripherals
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
# enable sam-ba bootloader on legacy mode
CONFIG_BOOTLOADER_BOSSA=y

View File

@@ -255,9 +255,9 @@ Debugging
STM32U5 support is not currently supported in openocd. As a temporary workaround,
user can use `STMicroelectronics customized version of OpenOCD`_ to debug the
the B_U585I_IOT02A Discovery kit.
For this you need to fetch this repo and build openocd following the instructions
provided in the README of the project. Then, build zephyr project indicating the
openocd location in west build command.
For this you need to fetch this repo, checkout branch "openocd-cubeide-r3" and
build openocd following the instructions provided in the README of the project.
Then, build zephyr project indicating the openocd location in west build command.
Here is an example for the :ref:`blinky-sample` application.
@@ -269,17 +269,11 @@ Here is an example for the :ref:`blinky-sample` application.
Then, indicate openocd as the chosen runner in flash and debug commands:
.. zephyr-app-commands::
:zephyr-app: samples/basic/blinky
:board: b_u585i_iot02a
:gen-args: -r openocd
:goals: flash
.. zephyr-app-commands::
:zephyr-app: samples/basic/blinky
:board: nucleo_u575zi_q
:gen-args: -r openocd
:goals: debug
.. code-block:: console
$ west flash -r openocd
$ west debug -r openocd
.. _B U585I IOT02A Discovery kit website:

View File

@@ -7,7 +7,6 @@
CONFIG_SOC_LPC54114_M0=y
CONFIG_SOC_SERIES_LPC54XXX=y
CONFIG_BOARD_LPCXPRESSO54114_M0=y
CONFIG_CONSOLE=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_SERIAL=n
CONFIG_CORTEX_M_SYSTICK=y

View File

@@ -13,9 +13,6 @@ CONFIG_HW_STACK_PROTECTION=y
# enable GPIO
CONFIG_GPIO=y
# enable console
CONFIG_CONSOLE=y
# additional board options
CONFIG_GPIO_AS_PINRESET=y
CONFIG_NFCT_PINS_AS_GPIOS=y

View File

@@ -12,4 +12,10 @@ config SPI_STM32_INTERRUPT
default y
depends on SPI
# FIXME: LSE not working as LPTIM clock source. Use LSI instead.
choice STM32_LPTIM_CLOCK
default STM32_LPTIM_CLOCK_LSI
depends on STM32_LPTIM_TIMER
endchoice
endif # BOARD_NUCLEO_L073RZ

View File

@@ -240,9 +240,9 @@ Debugging
STM32U5 support is not currently supported in openocd. As a temporary workaround,
user can use `STMicroelectronics customized version of OpenOCD`_ to debug the
the Nucleo U575ZI Q.
For this you need to fetch this repo and build openocd following the instructions
provided in the README of the project. Then, build zephyr project indicating the
openocd location in west build command.
For this you need to fetch this repo, checkout branch "openocd-cubeide-r3" and
build openocd following the instructions provided in the README of the project.
Then, build zephyr project indicating the openocd location in west build command.
Here is an example for the :ref:`blinky-sample` application.
@@ -254,17 +254,11 @@ Here is an example for the :ref:`blinky-sample` application.
Then, indicate openocd as the chosen runner in flash and debug commands:
.. zephyr-app-commands::
:zephyr-app: samples/basic/blinky
:board: nucleo_u575zi_q
:gen-args: -r openocd
:goals: flash
.. zephyr-app-commands::
:zephyr-app: samples/basic/blinky
:board: nucleo_u575zi_q
:gen-args: -r openocd
:goals: debug
.. code-block:: console
$ west flash -r openocd
$ west debug -r openocd
.. _STM32 Nucleo-144 board User Manual:

View File

@@ -12,6 +12,3 @@ CONFIG_HW_STACK_PROTECTION=y
# Enable GPIO
CONFIG_GPIO=y
# Enable console
CONFIG_CONSOLE=y

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@@ -5,6 +5,28 @@ Zephyr's is capable of running as a guest under the x86 ACRN
hypervisor (see https://projectacrn.org/). The process for getting
this to work is somewhat involved, however.
ACRN hypervisor supports a hybrid scenario where Zephyr runs in a so-
called "pre-launched" mode. This means Zephyr will access the ACRN
hypervisor directly without involving the SOS VM. This is the most
practical user scenario in the real world because Zephyr's real-time
and safety capability can be assured without influence from other
VMs. The following figure from ACRN's official documentation shows
how a hybrid scenario works:
.. figure:: ACRN-Hybrid.png
:align: center
:alt: ACRN Hybrid User Scenario
:figclass: align-center
:width: 80%
ACRN Hybrid User Scenario
In this tutorial, we will show you how to build a minimal running instance of Zephyr
and ACRN hypervisor to demonstrate that it works successfully. To learn more about
other features of ACRN, such as building and using the SOS VM or other guest VMs,
please refer to the Getting Started Guide for ACRN:
https://projectacrn.github.io/latest/tutorials/using_hybrid_mode_on_nuc.html
Build your Zephyr App
*********************
@@ -15,6 +37,10 @@ normally would, selecting an appropriate board:
west build -b acrn_ehl_crb samples/hello_world
In this tutorial, we will use the Intel Elkhart Lake Reference Board
(`EHL`_ CRB) since it is one of the suggested platform for this
type of scenario. Use ``acrn_ehl_crb`` as the target board parameter.
Note the kconfig output in ``build/zephyr/.config``, you will need to
reference that to configure ACRN later.
@@ -31,6 +57,9 @@ First you need the source code, clone from:
git clone https://github.com/projectacrn/acrn-hypervisor
We suggest that you use versions v2.5.1 or later of the ACRN hypervisor
as they have better support for SMP in Zephyr.
Like Zephyr, ACRN favors build-time configuration management instead
of runtime probing or control. Unlike Zephyr, ACRN has single large
configuration files instead of small easily-merged configuration
@@ -102,10 +131,51 @@ many CPUs in the ``<cpu_affinity>`` tag. For example:
.. code-block:: xml
<cpu_affinity>
<pcpu_id>0</pcpu_id>
<pcpu_id>1</pcpu_id>
</cpu_affinity>
<vm id="0">
<vm_type>SAFETY_VM</vm_type>
<name>ACRN PRE-LAUNCHED VM0</name>
<guest_flags>
<guest_flag>0</guest_flag>
</guest_flags>
<cpu_affinity>
<pcpu_id>0</pcpu_id>
<pcpu_id>1</pcpu_id>
</cpu_affinity>
...
<clos>
<vcpu_clos>0</vcpu_clos>
<vcpu_clos>0</vcpu_clos>
</clos>
...
</vm>
To use SMP, we have to change the pcpu_id of VM0 to 0 and 1.
This configures ACRN to run Zephyr on CPU0 and CPU1. The ACRN hypervisor
and Zephyr application will not boot successfully without this change.
If you plan to run Zephyr with one CPU only, you can skip it.
Since Zephyr is using CPU0 and CPU1, we also have to change
VM1's configuration so it runs on CPU2 and CPU3. If your ACRN set up has
additional VMs, you should change their configurations as well.
.. code-block:: xml
<vm id="1">
<vm_type>SOS_VM</vm_type>
<name>ACRN SOS VM</name>
<guest_flags>
<guest_flag>0</guest_flag>
</guest_flags>
<cpu_affinity>
<pcpu_id>2</pcpu_id>
<pcpu_id>3</pcpu_id>
</cpu_affinity>
<clos>
<vcpu_clos>0</vcpu_clos>
<vcpu_clos>0</vcpu_clos>
</clos>
...
</vm>
Note that these indexes are physical CPUs on the host. When
configuring multiple guests, you probably don't want to overlap these
@@ -228,3 +298,6 @@ command:
----- Entering VM 0 Shell -----
*** Booting Zephyr OS build v2.6.0-rc1-324-g1a03783861ad ***
Hello World! acrn
.. _EHL: https://www.intel.com/content/www/us/en/products/docs/processors/embedded/enhanced-for-iot-platform-brief.html

View File

@@ -489,10 +489,7 @@ zephyr_boilerplate_watch(CONF_FILE)
if(DTC_OVERLAY_FILE)
# DTC_OVERLAY_FILE has either been specified on the cmake CLI or is already
# in the CMakeCache.txt. This has precedence over the environment
# variable DTC_OVERLAY_FILE
elseif(DEFINED ENV{DTC_OVERLAY_FILE})
set(DTC_OVERLAY_FILE $ENV{DTC_OVERLAY_FILE})
# in the CMakeCache.txt.
elseif(APP_BOARD_DTS)
set(DTC_OVERLAY_FILE ${APP_BOARD_DTS})
elseif(EXISTS ${APPLICATION_SOURCE_DIR}/${BOARD}.overlay)

View File

@@ -210,7 +210,6 @@ Here are some ways to set it:
(``-DDTC_OVERLAY_FILE="file1.overlay;file2.overlay"``)
#. with the CMake ``set()`` command in the application ``CMakeLists.txt``,
before including zephyr's :file:`boilerplate.cmake` file
#. using a ``DTC_OVERLAY_FILE`` environment variable (deprecated)
#. create a ``boards/<BOARD>_<revision>.overlay`` file in the application
folder for the current board revision. This requires that the board supports
multiple revisions, see :ref:`porting_board_revisions`.

View File

@@ -39,6 +39,15 @@ The kernel's scheduler selects the highest priority ready thread
to be the current thread. When multiple ready threads of the same priority
exist, the scheduler chooses the one that has been waiting longest.
A thread's relative priority is primarily determined by its static priority.
However, when both earliest-deadline-first scheduling is enabled
(:kconfig:`CONFIG_SCHED_DEADLINE`) and a choice of threads have equal
static priority, then the thread with the earlier deadline is considered
to have the higher priority. Thus, when earliest-deadline-first scheduling is
enabled, two threads are only considered to have the same priority when both
their static priorities and deadlines are equal. The routine
:c:func:`k_thread_deadline_set` is used to set a thread's deadline.
.. note::
Execution of ISRs takes precedence over thread execution,
so the execution of the current thread may be replaced by an ISR

View File

@@ -177,6 +177,7 @@ Boards & SoC Support
* Added support for these SoC series:
* Added STM32U5 basic SoC support
* Removed support for these SoC series:
@@ -192,13 +193,26 @@ Boards & SoC Support
* Enabled Atmel SAM ``clock-frequency`` support from devicetree
* Free Atmel SAM TRACESWO pin when unused
* Enabled Cypress PSoC-6 Cortex-M4 support
* Added low power support to STM32L0, STM32G0 and STM32WL series
* STM32: Enabled ART Flash accelerator by default when available (F2, F4, F7, H7, L5)
* STM32: Added Kconfig option to enable STM32Cube asserts (CONFIG_USE_STM32_ASSERT)
* Changes for ARC boards:
* Changes for ARM boards:
* Added SPI support on Arduino standard SPI when possible
* Added support for these ARM boards:
* Dragino NBSN95 NB-IoT Sensor Node
* Seeedstudio LoRa-E5 Dev Board
* ST B_U585I_IOT02A Discovery kit
* ST Nucleo F446ZE
* ST Nucleo U575ZI Q
* ST STM32H735G Discovery
* Added support for these ARM64 boards:
@@ -229,12 +243,16 @@ Boards & SoC Support
* Added support for these following shields:
* 4.2inch epaper display (GDEW042T2)
* X-NUCLEO-EEPRMA2 EEPROM memory expansion board
Drivers and Sensors
*******************
* ADC
* Added STM32WL ADC driver
* STM32: Added support for oversampling
* Bluetooth
@@ -251,13 +269,17 @@ Drivers and Sensors
* Counter
* Add Atmel SAM counter (TC) Driver
* Added STM32WL RTC counter driver
* Crypto
* STM23: Add support for SOCs with AES hardware block (STM32G0, STM32L5 and STM32WL)
* DAC
* Added Atmel SAM DAC (DACC) driver
* Added support for Microchip MCP4725
* Added support for STM32F3 series
* Disk
@@ -269,17 +291,23 @@ Drivers and Sensors
* Disk
* STM32 SDMMC now supports SDIO enabled devices
* DMA
* Added Atmel SAM XDMAC reload support
* Added support on STM32G0 and STM32H7
* Added support on STM32F3, STM32G0, STM32H7 and STM32L5
* STM32: Reviewed bindings definitions, "st,stm32-dma-v2bis" introduced.
* EEPROM
* Added support for EEPROM emulated in flash.
* Entropy
* Added support for STM32F2, STM32G0, STM32WB and STM32WL
* ESPI
* Added support for Microchip eSPI SAF
@@ -294,6 +322,9 @@ Drivers and Sensors
* Flash
* Added STM32F2, STM32L5 and STM32WL Flash driver support
* STM32: Max erase time parameter was moved to device tree
* Added quad SPI support for STM32F4
* GPIO
@@ -311,10 +342,17 @@ Drivers and Sensors
* IEEE 802.15.4
* IPM
* Added STM32 HSEM IPM driver.
* Interrupt Controller
* IPM
* STM32: Add HSEM based IPM driver for STM32H7 series
* LED
@@ -322,25 +360,45 @@ Drivers and Sensors
* lora_send now blocks until the transmission is complete. lora_send_async
can be used for the previous, non-blocking behaviour.
* Enabled support for STM32WL series
* MEMC
* Added STM32F4 support
* Modem
* Added gsm_ppp devicetree support
* PCI/PCIe
* Fixed an issue that MSI-X was used even though it is not available.
* Improved MBAR retrieval for MSI-X.
* Added ability to retrieve extended PCI/PCIe capabilities.
* Pinmux
* Added Atmel SAM0 pinctrl support
* STM32: Deprecated definitions like 'STM32F2_PINMUX_FUNC_PA0_UART4_TX'
are now removed.
* PWM
* Property "st,prescaler" of binding "st,stm32-pwm" now defaults to "0".
* Sensor
* Serial
* Added kconfig to disable runtime re-configuration of UART
to reduce footprint if so desired.
* Added ESP32-C3 polling only UART driver.
* Added ESP32-S2 polling only UART driver.
* Added Microchip XEC UART driver.
* SPI
@@ -355,6 +413,8 @@ Drivers and Sensors
* Watchdog
* Added STM32L5 watchdog support
* WiFi
@@ -362,38 +422,131 @@ Drivers and Sensors
Networking
**********
* 802.15.4 L2:
* Fixed a bug, where the net_pkt structure contained invalid LL address
pointers after being processed by 802.15.4 L2.
* Added an optional destination address filtering in the 802.15.4 L2.
* CoAP:
* Added ``user_data`` field to the :c:struct:`coap_packet` structure.
* Fixed processing of out-of-order notifications.
* Fixed :c:func:`coap_packet_get_payload` function.
* Converted CoAP test suite to ztest API.
* Improved :c:func:`coap_packet_get_payload` function to minimize number
of RNG calls.
* Fixed retransmissions in the ``coap_server`` sample.
* Fixed observer removal in the ``coap_server`` sample (on notification
timeout).
* DHCPv4:
* Fixed a bug, where DHPCv4 library removed statically configured gateway
before obtaining a new one from the server.
* DNS:
* Fixed a bug, where the same IP address was used to populate the result
address info entries, when multiple IP addresses were obtained from the
server.
* HTTP:
* Switched the library to use ``zsock_*`` API, to improve compatibility with
various POSIX configurations.
* Fixed a bug, where ``HTTP_DATA_FINAL`` notification was triggered even for
intermediate response fragments.
* IPv4:
* IPv6:
* Multiple IPv6 fixes, addressing failures in IPv6Ready compliance tests.
* LwM2M:
* Added support for notification timeout reporting to the application.
* Fixed a bug, where a multi instance resource with only one active instance
was incorrectly encoded on reads.
* Fixed a bug, where notifications were generated on changes to non-readable
resources.
* Added mutex protection for the state variable of the ``lwm2m_rd_client``
module.
* Removed LWM2M_RES_TYPE_U64 type, as it's not possible to encode it properly
for large values.
* Fixed a bug, where large unsigned integers were incorrectly encoded in TLV.
* Multiple fixes for FLOAT type processing in the LwM2M engine and encoders.
* Fix a bug, where IPSO Push Button counter resource was not triggering
notification on incrementation.
* Fixed a bug, where Register failures were reported as success to the
application.
* Misc:
* Added RX/TX timeout on a socket in ``big_http_download`` sample.
* Introduced :c:func:`net_pkt_remove_tail` function.
Added IEEE 802.15.4 security-related flags to the :c:struct:`net_pkt`
structure.
* Added bridging support to the Ethernet L2.
* Fixed a bug in mDNS, where an incorrect address type could be set as a
response destination.
* Added an option to suppress ICMP destination unreachable errors.
* Fixed possible assertion in ``net nbr`` shell command.
* Major refactoring of the TFTP library.
* MQTT:
* Added an option to register a custom transport type.
* Fixed a bug in :c:func:`mqtt_abort`, where the function could return without
releasing a lock.
* OpenThread:
* Update OpenThread module up to commit ``9ea34d1e2053b6b2a80e1d46b65a6aee99fc504a``.
Added several new Kconfig options to align with new OpenThread
configurations.
* Added OpenThread API mutex protection during initialization.
* Converted OpenThread thread to a dedicated work queue.
* Implemented missing :c:func:`otPlatAssertFail` platform function.
* Fixed a bug, where NONE level OpenThread logs were not processed.
* Added possibility to disable CSL sampling, when used.
* Fixed a potential bug, where invalid error code could be returned by the
platform radio layer to OpenThread.
* Reworked UART configuration in the OpenThread Coprocessor sample.
* Socket:
* Added microsecond accuracy in :c:func:`zsock_select` function.
* Reworked :c:func:`zsock_select` into a syscall.
* Fixed a bug, where :c:func:`poll` events were not signalled correctly
for socketpair sockets.
* Fixed a bug, where socket mutex could be used after being initialized by a
new owner after being deallocated in :c:func:`zsock_close`.
* Fixed a possible assert after enabling CAN sockets.
* Fixed IPPROTO_RAW usage in packet socket implementation.
* TCP:
* Fixed a bug, where ``unacked_len`` could be set to a negative value.
* Fixed possible assertion failure in :c:func:`tcp_send_data`.
* Fixed a bug, where [FIN, PSH, ACK] was not handled properly in
TCP_FIN_WAIT_2 state.
* TLS:
* Reworked TLS sockets to use secure random generator from Zephyr.
* Fixed busy looping during DTLS handshake with offloaded sockets.
* Fixed busy looping during TLS/DTLS handshake on non blocking sockets.
* Reset mbed TLS session on timed out DTLS handshake, to allow a retry without
closing a socket.
* Fixed TLS/DTLS :c:func:`sendmsg` implementation for larger payloads.
* Fixed TLS/DTLS sockets ``POLLHUP`` notification.
* WebSocket:
* Fixed :c:func:`poll` implementation for WebSocket, which did not work
correctly with offloaded sockets.
* Fixed :c:func:`ioctl` implementation for WebSocket, which did not work
correctly with offloaded sockets.
USB
***

View File

@@ -49,8 +49,8 @@ add_subdirectory_ifdef(CONFIG_PM_CPU_OPS pm_cpu_ops)
add_subdirectory_ifdef(CONFIG_FLASH_HAS_DRIVER_ENABLED flash)
add_subdirectory_ifdef(CONFIG_SERIAL_HAS_DRIVER serial)
add_subdirectory_ifdef(CONFIG_BT bluetooth)
add_subdirectory_ifdef(CONFIG_NETWORKING net)
add_subdirectory_ifdef(CONFIG_BT_DRIVERS bluetooth)
add_subdirectory_ifdef(CONFIG_NET_DRIVERS net)
add_subdirectory_ifdef(CONFIG_NET_L2_ETHERNET ethernet)
add_subdirectory_ifdef(CONFIG_ENTROPY_HAS_DRIVER entropy)
add_subdirectory_ifdef(CONFIG_SYS_CLOCK_EXISTS timer)

View File

@@ -409,18 +409,10 @@ static int start_read(const struct device *dev,
return err;
}
#if defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32G4X) || \
defined(CONFIG_SOC_SERIES_STM32H7X) || \
defined(CONFIG_SOC_SERIES_STM32L0X) || \
defined(CONFIG_SOC_SERIES_STM32L4X) || \
defined(CONFIG_SOC_SERIES_STM32L5X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \
defined(CONFIG_SOC_SERIES_STM32WLX)
#if defined(CONFIG_SOC_SERIES_STM32G0X)
/*
* Errata: Writing ADC_CFGR1 register while ADEN bit is set
* resets RES[1:0] bitfield. We need to disable and enable adc.
* On all those stm32 devices it is allowed to write these bits only when ADEN = 0.
*/
if (LL_ADC_IsEnabled(adc) == 1UL) {
LL_ADC_Disable(adc);
@@ -436,6 +428,15 @@ static int start_read(const struct device *dev,
LL_ADC_SetResolution(adc, resolution);
#endif
#ifdef CONFIG_SOC_SERIES_STM32L0X
/*
* setting OVS bits is conditioned to ADC state: ADC must be disabled
* or enabled without conversion on going : disable it, it will stop
*/
LL_ADC_Disable(adc);
while (LL_ADC_IsEnabled(adc) == 1UL) {
}
#endif /* CONFIG_SOC_SERIES_STM32L0X */
#if defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32G4X) || \
defined(CONFIG_SOC_SERIES_STM32H7X) || \
@@ -444,13 +445,7 @@ static int start_read(const struct device *dev,
defined(CONFIG_SOC_SERIES_STM32L5X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \
defined(CONFIG_SOC_SERIES_STM32WLX)
/*
* setting OVS bits is conditioned to ADC state: ADC must be disabled
* or enabled without conversion on going : disable it, it will stop
*/
LL_ADC_Disable(adc);
while (LL_ADC_IsEnabled(adc) == 1UL) {
}
switch (sequence->oversampling) {
case 0:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_DISABLE);

View File

@@ -9,9 +9,13 @@
# Controller support is an HCI driver in itself, so these HCI driver
# options are only applicable if controller support hasn't been enabled.
menu "Bluetooth Drivers"
menuconfig BT_DRIVERS
bool "Bluetooth Drivers"
default y
depends on BT && !BT_CTLR
if BT_DRIVERS
if BT_HCI
source "drivers/bluetooth/hci/Kconfig"
endif
@@ -20,4 +24,4 @@ if BT_CUSTOM
# Insert here any custom (non-HCI) offload drives
endif
endmenu
endif # BT_DRIVERS

View File

@@ -26,16 +26,12 @@ zephyr_library_sources_ifdef(CONFIG_ETH_SAM_GMAC eth_sam_gmac.c)
zephyr_library_sources_ifdef(CONFIG_DSA_KSZ8XXX dsa_ksz8xxx.c)
if(CONFIG_ETH_NATIVE_POSIX)
zephyr_library_named(drivers__ethernet__native_posix)
zephyr_library_compile_definitions(
NO_POSIX_CHEATS
_BSD_SOURCE
_DEFAULT_SOURCE
)
zephyr_library_sources(
eth_native_posix.c
eth_native_posix_adapt.c
)
set(native_posix_source_files eth_native_posix.c eth_native_posix_adapt.c)
set_source_files_properties(${native_posix_source_files}
PROPERTIES COMPILE_DEFINITIONS
"NO_POSIX_CHEATS;_BSD_SOURCE;_DEFAULT_SOURCE"
)
zephyr_library_sources(${native_posix_source_files})
endif()
add_subdirectory(phy)

View File

@@ -1,5 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_sources_ifdef(CONFIG_PHY_GENERIC_MII phy_mii.c)

View File

@@ -692,7 +692,8 @@ GPIO_DEVICE_INIT_STM32(k, K);
#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpiok), okay) */
#if defined(CONFIG_SOC_SERIES_STM32F1X)
#if defined(CONFIG_SOC_SERIES_STM32F1X) && \
!defined(CONFIG_GPIO_STM32_SWJ_ENABLE)
static int gpio_stm32_afio_init(const struct device *dev)
{
@@ -716,6 +717,6 @@ static int gpio_stm32_afio_init(const struct device *dev)
return 0;
}
SYS_DEVICE_DEFINE("gpio_stm32_afio", gpio_stm32_afio_init, NULL, PRE_KERNEL_2, 0);
SYS_DEVICE_DEFINE("gpio_stm32_afio", gpio_stm32_afio_init, NULL, PRE_KERNEL_1, 0);
#endif /* CONFIG_SOC_SERIES_STM32F1X */
#endif /* CONFIG_SOC_SERIES_STM32F1X && !CONFIG_GPIO_STM32_SWJ_ENABLE */

View File

@@ -27,12 +27,12 @@ struct i2s_nrfx_drv_data {
const uint32_t *last_tx_buffer;
enum i2s_state state;
enum i2s_dir active_dir;
bool stop; /* stop after the current (TX or RX) block */
bool discard_rx; /* discard further RX blocks */
volatile bool next_tx_buffer_needed;
bool tx_configured : 1;
bool rx_configured : 1;
bool stop : 1; /* stop after the current (TX or RX) block */
bool discard_rx : 1; /* discard further RX blocks */
bool request_clock : 1;
volatile bool next_tx_buffer_needed;
};
struct i2s_nrfx_drv_cfg {
@@ -81,6 +81,7 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg,
uint32_t best_diff = UINT32_MAX;
uint8_t r, best_r = 0;
nrf_i2s_mck_t best_mck_cfg = 0;
uint32_t best_mck = 0;
for (r = 0; r < ARRAY_SIZE(ratios); ++r) {
/* Only multiples of the frame width can be used as ratios. */
@@ -110,6 +111,7 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg,
if (diff < best_diff) {
best_mck_cfg = mck_factor * 4096;
best_mck = actual_mck;
best_r = r;
/* Stop if an exact match is found. */
if (diff == 0) {
@@ -150,6 +152,7 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg,
if (diff < best_diff) {
best_mck_cfg = dividers[d].divider_enum;
best_mck = mck_freq;
best_r = r;
/* Stop if an exact match is found. */
if (diff == 0) {
@@ -173,6 +176,8 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg,
config->mck_setup = best_mck_cfg;
config->ratio = ratios[best_r].ratio_enum;
LOG_INF("I2S MCK frequency: %u, actual PCM rate: %u",
best_mck, best_mck / ratios[best_r].ratio_val);
}
static bool get_next_tx_buffer(struct i2s_nrfx_drv_data *drv_data,
@@ -465,9 +470,7 @@ static int i2s_nrfx_configure(const struct device *dev, enum i2s_dir dir,
return -EINVAL;
}
if (i2s_cfg->channels == 2 ||
(i2s_cfg->format & I2S_FMT_DATA_FORMAT_MASK)
== I2S_FMT_DATA_FORMAT_I2S) {
if (i2s_cfg->channels == 2) {
nrfx_cfg.channels = NRF_I2S_CHANNELS_STEREO;
} else if (i2s_cfg->channels == 1) {
nrfx_cfg.channels = NRF_I2S_CHANNELS_LEFT;
@@ -878,8 +881,8 @@ static const struct i2s_driver_api i2s_nrf_drv_api = {
#define I2S_CLK_SRC(idx) DT_STRING_TOKEN(I2S(idx), clock_source)
#define I2S_NRFX_DEVICE(idx) \
static void *tx_msgs[CONFIG_I2S_NRFX_TX_BLOCK_COUNT]; \
static void *rx_msgs[CONFIG_I2S_NRFX_RX_BLOCK_COUNT]; \
static void *tx_msgs##idx[CONFIG_I2S_NRFX_TX_BLOCK_COUNT]; \
static void *rx_msgs##idx[CONFIG_I2S_NRFX_RX_BLOCK_COUNT]; \
static struct i2s_nrfx_drv_data i2s_nrfx_data##idx = { \
.state = I2S_STATE_READY, \
}; \
@@ -889,11 +892,11 @@ static const struct i2s_driver_api i2s_nrf_drv_api = {
nrfx_isr, nrfx_i2s_irq_handler, 0); \
irq_enable(DT_IRQN(I2S(idx))); \
k_msgq_init(&i2s_nrfx_data##idx.tx_queue, \
(char *)tx_msgs, sizeof(void *), \
CONFIG_I2S_NRFX_TX_BLOCK_COUNT); \
(char *)tx_msgs##idx, sizeof(void *), \
ARRAY_SIZE(tx_msgs##idx)); \
k_msgq_init(&i2s_nrfx_data##idx.rx_queue, \
(char *)rx_msgs, sizeof(void *), \
CONFIG_I2S_NRFX_RX_BLOCK_COUNT); \
(char *)rx_msgs##idx, sizeof(void *), \
ARRAY_SIZE(rx_msgs##idx)); \
init_clock_manager(dev); \
return 0; \
} \

View File

@@ -10,7 +10,6 @@ config MODEM_QUECTEL_BG9X
select MODEM_IFACE_UART
select MODEM_SOCKET
select NET_SOCKETS_OFFLOAD
imply GPIO
help
Choose this setting to enable quectel BG9x LTE-CatM1/NB-IoT modem
driver.

View File

@@ -11,7 +11,6 @@ config MODEM_UBLOX_SARA
select MODEM_SOCKET
select NET_OFFLOAD
select NET_SOCKETS_OFFLOAD
imply GPIO
help
Choose this setting to enable u-blox SARA-R4 LTE-CatM1/NB-IoT modem
driver.

View File

@@ -1,6 +1,11 @@
# Misc network drivers configuration options
# SPDX-License-Identifier: Apache-2.0
menuconfig NET_DRIVERS
bool "Network Drivers"
if NET_DRIVERS
#
# PPP options
#
@@ -90,8 +95,7 @@ endif # NET_PPP
# SLIP options
#
menuconfig SLIP
bool "SLIP driver"
depends on (!QEMU_TARGET || NET_QEMU_SLIP)
bool "SLIP driver" if !QEMU_TARGET
depends on NET_NATIVE
select UART_PIPE
select UART_INTERRUPT_DRIVEN
@@ -149,3 +153,5 @@ module-help = Sets log level for network loopback driver.
source "subsys/net/Kconfig.template.log_config.net"
endif
endif # NET_DRIVERS

View File

@@ -1,19 +1,17 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
# Board initialization
zephyr_library_sources_ifdef(CONFIG_PINMUX_CC13XX_CC26XX pinmux_cc13xx_cc26xx.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_ESP32 pinmux_esp32.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_HSDK pinmux_hsdk.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_INTEL_S1000 pinmux_intel_s1000.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_ITE_IT8XXX2 pinmux_ite_it8xxx2.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_LPC11U6X pinmux_lpc11u6x.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_MCUX pinmux_mcux.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_MCUX_LPC pinmux_mcux_lpc.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_RV32M1 pinmux_rv32m1.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_SAM0 pinmux_sam0.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_SIFIVE pinmux_sifive.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_STM32 pinmux_stm32.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_TELINK_B91 pinmux_b91.c)
zephyr_library_sources_ifdef(CONFIG_PINMUX_XEC pinmux_mchp_xec.c)
zephyr_sources_ifdef(CONFIG_PINMUX_TELINK_B91 pinmux_b91.c)
zephyr_sources_ifdef(CONFIG_PINMUX_CC13XX_CC26XX pinmux_cc13xx_cc26xx.c)
zephyr_sources_ifdef(CONFIG_PINMUX_ESP32 pinmux_esp32.c)
zephyr_sources_ifdef(CONFIG_PINMUX_HSDK pinmux_hsdk.c)
zephyr_sources_ifdef(CONFIG_PINMUX_INTEL_S1000 pinmux_intel_s1000.c)
zephyr_sources_ifdef(CONFIG_PINMUX_ITE_IT8XXX2 pinmux_ite_it8xxx2.c)
zephyr_sources_ifdef(CONFIG_PINMUX_LPC11U6X pinmux_lpc11u6x.c)
zephyr_sources_ifdef(CONFIG_PINMUX_MCUX pinmux_mcux.c)
zephyr_sources_ifdef(CONFIG_PINMUX_MCUX_LPC pinmux_mcux_lpc.c)
zephyr_sources_ifdef(CONFIG_PINMUX_RV32M1 pinmux_rv32m1.c)
zephyr_sources_ifdef(CONFIG_PINMUX_SAM0 pinmux_sam0.c)
zephyr_sources_ifdef(CONFIG_PINMUX_SIFIVE pinmux_sifive.c)
zephyr_sources_ifdef(CONFIG_PINMUX_STM32 pinmux_stm32.c)
zephyr_sources_ifdef(CONFIG_PINMUX_XEC pinmux_mchp_xec.c)

View File

@@ -1,139 +0,0 @@
/**
* @file
* @brief reserved-memory Devicetree macro public API header file.
*/
/*
* Copyright (c) 2021 Carlo Caione <ccaione@baylibre.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_
#define ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup devicetree-reserved Devicetree reserved-memory API
* @ingroup devicetree
* @{
*/
/**
* @brief Get the pointer to the reserved-memory region
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* n: node {
* reg = <0x42000000 0x1000>;
* };
* };
*
* Example usage:
*
* DT_RESERVED_MEM_GET_PTR(DT_NODELABEL(n)) // (uint8_t *) 0x42000000
*
* @param node_id node identifier
* @return pointer to the beginning of the reserved-memory region
*/
#define DT_RESERVED_MEM_GET_PTR(node_id) _DT_RESERVED_START(node_id)
/**
* @brief Get the size of the reserved-memory region
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* n: node {
* reg = <0x42000000 0x1000>;
* };
* };
*
* Example usage:
*
* DT_RESERVED_MEM_GET_SIZE(DT_NODELABEL(n)) // 0x1000
*
* @param node_id node identifier
* @return the size of the reserved-memory region
*/
#define DT_RESERVED_MEM_GET_SIZE(node_id) DT_REG_SIZE(node_id)
/**
* @brief Get the pointer to the reserved-memory region from a memory-reserved
* phandle
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* res0: res {
* reg = <0x42000000 0x1000>;
* label = "res0";
* };
* };
*
* n: node {
* memory-region = <&res0>;
* };
*
* Example usage:
*
* DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(DT_NODELABEL(n), memory_region) // (uint8_t *) 0x42000000
*
* @param node_id node identifier
* @param ph phandle to reserved-memory region
*
* @return pointer to the beginning of the reserved-memory region
*/
#define DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(node_id, ph) \
DT_RESERVED_MEM_GET_PTR(DT_PHANDLE(node_id, ph))
/**
* @brief Get the size of the reserved-memory region from a memory-reserved
* phandle
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* res0: res {
* reg = <0x42000000 0x1000>;
* label = "res0";
* };
* };
*
* n: node {
* memory-region = <&res0>;
* };
*
* Example usage:
*
* DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(DT_NODELABEL(n), memory_region) // (uint8_t *) 0x42000000
*
* @param node_id node identifier
* @param ph phandle to reserved-memory region
*
* @return size of the reserved-memory region
*/
#define DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(node_id, ph) \
DT_RESERVED_MEM_GET_SIZE(DT_PHANDLE(node_id, ph))
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_DEVICETREE_MEMORY_H_ */

View File

@@ -34,26 +34,23 @@ extern "C" {
* @brief Non-volatile Storage File system structure
*
* @param offset File system offset in flash
* @param ate_wra: Allocation table entry write address. Addresses are stored
* as uint32_t: high 2 bytes are sector, low 2 bytes are offset in sector,
* @param data_wra: Data write address.
* @param sector_size File system is divided into sectors each sector should be
* multiple of pagesize
* @param sector_count Amount of sectors in the file systems
* @param write_block_size Alignment size
* @param ate_wra Allocation table entry write address. Addresses are stored as uint32_t:
* high 2 bytes correspond to the sector, low 2 bytes are the offset in the sector
* @param data_wra Data write address
* @param sector_size File system is split into sectors, each sector must be multiple of pagesize
* @param sector_count Number of sectors in the file systems
* @param ready Flag indicating if the filesystem is initialized
* @param nvs_lock Mutex
* @param flash_device Flash Device
* @param flash_device Flash Device runtime structure
* @param flash_parameters Flash memory parameters structure
*/
struct nvs_fs {
off_t offset; /* filesystem offset in flash */
uint32_t ate_wra; /* next alloc table entry write address */
uint32_t data_wra; /* next data write address */
uint16_t sector_size; /* filesystem is divided into sectors,
* sector size should be multiple of pagesize
*/
uint16_t sector_count; /* amount of sectors in the filesystem */
bool ready; /* is the filesystem initialized ? */
off_t offset;
uint32_t ate_wra;
uint32_t data_wra;
uint16_t sector_size;
uint16_t sector_count;
bool ready;
struct k_mutex nvs_lock;
const struct device *flash_device;
const struct flash_parameters *flash_parameters;
@@ -102,10 +99,10 @@ int nvs_clear(struct nvs_fs *fs);
* @param data Pointer to the data to be written
* @param len Number of bytes to be written
*
* @return Number of bytes written. On success, it will be equal to the number
* of bytes requested to be written. On error returns -ERRNO code.
* @return Number of bytes written. On success, it will be equal to the number of bytes requested
* to be written. When a rewrite of the same data already stored is attempted, nothing is written
* to flash, thus 0 is returned. On error, returns negative value of errno.h defined error codes.
*/
ssize_t nvs_write(struct nvs_fs *fs, uint16_t id, const void *data, size_t len);
/**
@@ -130,10 +127,10 @@ int nvs_delete(struct nvs_fs *fs, uint16_t id);
* @param data Pointer to data buffer
* @param len Number of bytes to be read
*
* @return Number of bytes read. On success, it will be equal to the number
* of bytes requested to be read. When the return value is larger than the
* number of bytes requested to read this indicates not all bytes were read,
* and more data is available. On error returns -ERRNO code.
* @return Number of bytes read. On success, it will be equal to the number of bytes requested
* to be read. When the return value is larger than the number of bytes requested to read this
* indicates not all bytes were read, and more data is available. On error, returns negative
* value of errno.h defined error codes.
*/
ssize_t nvs_read(struct nvs_fs *fs, uint16_t id, void *data, size_t len);
@@ -146,15 +143,14 @@ ssize_t nvs_read(struct nvs_fs *fs, uint16_t id, void *data, size_t len);
* @param id Id of the entry to be read
* @param data Pointer to data buffer
* @param len Number of bytes to be read
* @param cnt History counter: 0: latest entry, 1:one before latest ...
* @param cnt History counter: 0: latest entry, 1: one before latest ...
*
* @return Number of bytes read. On success, it will be equal to the number
* of bytes requested to be read. When the return value is larger than the
* number of bytes requested to read this indicates not all bytes were read,
* and more data is available. On error returns -ERRNO code.
* @return Number of bytes read. On success, it will be equal to the number of bytes requested
* to be read. When the return value is larger than the number of bytes requested to read this
* indicates not all bytes were read, and more data is available. On error, returns negative
* value of errno.h defined error codes.
*/
ssize_t nvs_read_hist(struct nvs_fs *fs, uint16_t id, void *data, size_t len,
uint16_t cnt);
ssize_t nvs_read_hist(struct nvs_fs *fs, uint16_t id, void *data, size_t len, uint16_t cnt);
/**
* @brief nvs_calc_free_space
@@ -163,10 +159,9 @@ ssize_t nvs_read_hist(struct nvs_fs *fs, uint16_t id, void *data, size_t len,
*
* @param fs Pointer to file system
*
* @return Number of bytes free. On success, it will be equal to the number
* of bytes that can still be written to the file system. Calculating the
* free space is a time consuming operation, especially on spi flash.
* On error returns -ERRNO code.
* @return Number of bytes free. On success, it will be equal to the number of bytes that can
* still be written to the file system. Calculating the free space is a time consuming operation,
* especially on spi flash. On error, returns negative value of errno.h defined error codes.
*/
ssize_t nvs_calc_free_space(struct nvs_fs *fs);

View File

@@ -743,7 +743,7 @@ __syscall void k_thread_priority_set(k_tid_t thread, int prio);
* integers. The number of cycles between the "first" deadline in the
* scheduler queue and the "last" deadline must be less than 2^31 (i.e
* a signed non-negative quantity). Failure to adhere to this rule
* may result in scheduled threads running in an incorrect dealine
* may result in scheduled threads running in an incorrect deadline
* order.
*
* @note Despite the API naming, the scheduler makes no guarantees the

View File

@@ -46,14 +46,122 @@
/**
* @brief Generate region definitions for all the reserved memory regions
*/
#define DT_RESERVED_MEM_REGIONS() _RESERVED_REGION_APPLY(_RESERVED_REGION_DECLARE)
#define LINKER_DT_RESERVED_MEM_REGIONS() _RESERVED_REGION_APPLY(_RESERVED_REGION_DECLARE)
/**
* @brief Generate section definitions for all the reserved memory regions
*/
#define DT_RESERVED_MEM_SECTIONS() _RESERVED_REGION_APPLY(_RESERVED_SECTION_DECLARE)
#define LINKER_DT_RESERVED_MEM_SECTIONS() _RESERVED_REGION_APPLY(_RESERVED_SECTION_DECLARE)
/**
* @brief Generate linker script symbols for all the reserved memory regions
*/
#define DT_RESERVED_MEM_SYMBOLS() _RESERVED_REGION_APPLY(_RESERVED_SYMBOL_DECLARE)
#define LINKER_DT_RESERVED_MEM_SYMBOLS() _RESERVED_REGION_APPLY(_RESERVED_SYMBOL_DECLARE)
/**
* @brief Get the pointer to the reserved-memory region
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* n: node {
* reg = <0x42000000 0x1000>;
* };
* };
*
* Example usage:
*
* LINKER_DT_RESERVED_MEM_GET_PTR(DT_NODELABEL(n)) // (uint8_t *) 0x42000000
*
* @param node_id node identifier
* @return pointer to the beginning of the reserved-memory region
*/
#define LINKER_DT_RESERVED_MEM_GET_PTR(node_id) _DT_RESERVED_START(node_id)
/**
* @brief Get the size of the reserved-memory region
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* n: node {
* reg = <0x42000000 0x1000>;
* };
* };
*
* Example usage:
*
* LINKER_DT_RESERVED_MEM_GET_SIZE(DT_NODELABEL(n)) // 0x1000
*
* @param node_id node identifier
* @return the size of the reserved-memory region
*/
#define LINKER_DT_RESERVED_MEM_GET_SIZE(node_id) DT_REG_SIZE(node_id)
/**
* @brief Get the pointer to the reserved-memory region from a memory-reserved
* phandle
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* res0: res {
* reg = <0x42000000 0x1000>;
* label = "res0";
* };
* };
*
* n: node {
* memory-region = <&res0>;
* };
*
* Example usage:
*
* LINKER_DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(DT_NODELABEL(n), \
* memory_region) // (uint8_t *) 0x42000000
*
* @param node_id node identifier
* @param ph phandle to reserved-memory region
*
* @return pointer to the beginning of the reserved-memory region
*/
#define LINKER_DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(node_id, ph) \
LINKER_DT_RESERVED_MEM_GET_PTR(DT_PHANDLE(node_id, ph))
/**
* @brief Get the size of the reserved-memory region from a memory-reserved
* phandle
*
* Example devicetree fragment:
*
* reserved: reserved-memory {
* compatible = "reserved-memory";
* ...
* res0: res {
* reg = <0x42000000 0x1000>;
* label = "res0";
* };
* };
*
* n: node {
* memory-region = <&res0>;
* };
*
* Example usage:
*
* LINKER_DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(DT_NODELABEL(n), \
* memory_region) // (uint8_t *) 0x42000000
*
* @param node_id node identifier
* @param ph phandle to reserved-memory region
*
* @return size of the reserved-memory region
*/
#define LINKER_DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(node_id, ph) \
LINKER_DT_RESERVED_MEM_GET_SIZE(DT_PHANDLE(node_id, ph))

View File

@@ -259,7 +259,7 @@ extern char _vector_start[];
extern char _vector_end[];
#if DT_NODE_HAS_STATUS(_NODE_RESERVED, okay)
DT_RESERVED_MEM_SYMBOLS()
LINKER_DT_RESERVED_MEM_SYMBOLS()
#endif
#ifdef CONFIG_SW_VECTOR_RELAY

View File

@@ -542,7 +542,7 @@ static inline uint32_t log_msg2_get_total_wlen(const struct log_msg2_desc desc)
*
* @return Length in 32 bit words.
*/
static inline uint32_t log_msg2_generic_get_wlen(union mpsc_pbuf_generic *item)
static inline uint32_t log_msg2_generic_get_wlen(const union mpsc_pbuf_generic *item)
{
union log_msg2_generic *generic_msg = (union log_msg2_generic *)item;

View File

@@ -50,6 +50,38 @@ extern "C" {
/** RFC 1034 Section 3.1, RFC 6763 Section 7.2 */
#define DNS_SD_DOMAIN_MAX_SIZE 63
/**
* Minimum number of segments in a fully-qualified name
*
* This reqpresents FQN's of the form below
* ```
* <sn>._tcp.<domain>.
* ```
* Currently sub-types and service domains are unsupported and only the
* "local" domain is supported. Specifically, that excludes the following:
* ```
* <sub>._sub.<sn>._tcp.<servicedomain>.<parentdomain>.
* ```
* @see <a href="https://datatracker.ietf.org/doc/html/rfc6763">RFC 6763</a>, Section 7.2.
*/
#define DNS_SD_MIN_LABELS 3
/**
* Maximum number of segments in a fully-qualified name
*
* This reqpresents FQN's of the form below
* ```
* <instance>.<sn>._tcp.<domain>.
* ```
*
* Currently sub-types and service domains are unsupported and only the
* "local" domain is supported. Specifically, that excludes the following:
* ```
* <sub>._sub.<sn>._tcp.<servicedomain>.<parentdomain>.
* ```
* @see <a href="https://datatracker.ietf.org/doc/html/rfc6763">RFC 6763</a>, Section 7.2.
*/
#define DNS_SD_MAX_LABELS 4
/**
* @brief Register a service for DNS Service Discovery
*
@@ -209,6 +241,12 @@ struct dns_sd_rec {
* @internal
*/
extern const char dns_sd_empty_txt[1];
/**
* @brief Wildcard Port specifier for DNS-SD
*
* @internal
*/
extern const uint16_t dns_sd_port_zero;
/** @endcond */
@@ -223,6 +261,32 @@ static inline size_t dns_sd_txt_size(const struct dns_sd_rec *rec)
return rec->text_size;
}
/**
* @brief Check if @a rec is a DNS-SD Service Type Enumeration
*
* DNS-SD Service Type Enumeration is used by network tooling to
* acquire a list of all mDNS-advertised services belonging to a
* particular host on a particular domain.
*
* For example, for the domain '.local', the equivalent query
* would be '_services._dns-sd._udp.local'.
*
* Currently, only the '.local' domain is supported.
*
* @see <a href="https://datatracker.ietf.org/doc/html/rfc6763#section-9">Service Type Enumeration, RFC 6763</a>.
*
* @param rec the record to in question
* @return true if @a rec is a DNS-SD Service Type Enumeration
*/
bool dns_sd_is_service_type_enumeration(const struct dns_sd_rec *rec);
/**
* @brief Create a wildcard filter for DNS-SD records
*
* @param filter a pointer to the filter to use
*/
void dns_sd_create_wildcard_filter(struct dns_sd_rec *filter);
/**
* @}
*/

View File

@@ -69,7 +69,7 @@ struct mpsc_pbuf_buffer;
*
* @return Size of the packet in 32 bit words.
*/
typedef uint32_t (*mpsc_pbuf_get_wlen)(union mpsc_pbuf_generic *packet);
typedef uint32_t (*mpsc_pbuf_get_wlen)(const union mpsc_pbuf_generic *packet);
/** @brief Callback called when packet is dropped.
*
@@ -77,8 +77,8 @@ typedef uint32_t (*mpsc_pbuf_get_wlen)(union mpsc_pbuf_generic *packet);
*
* @param packet Packet that is being dropped.
*/
typedef void (*mpsc_pbuf_notify_drop)(struct mpsc_pbuf_buffer *buffer,
union mpsc_pbuf_generic *packet);
typedef void (*mpsc_pbuf_notify_drop)(const struct mpsc_pbuf_buffer *buffer,
const union mpsc_pbuf_generic *packet);
/** @brief MPSC packet buffer structure. */
struct mpsc_pbuf_buffer {
@@ -179,7 +179,7 @@ void mpsc_pbuf_commit(struct mpsc_pbuf_buffer *buffer,
* and data on remaining bits.
*/
void mpsc_pbuf_put_word(struct mpsc_pbuf_buffer *buffer,
union mpsc_pbuf_generic word);
const union mpsc_pbuf_generic word);
/** @brief Put a packet consisting of a word and a pointer.
* *
@@ -194,7 +194,8 @@ void mpsc_pbuf_put_word(struct mpsc_pbuf_buffer *buffer,
* @param data User data.
*/
void mpsc_pbuf_put_word_ext(struct mpsc_pbuf_buffer *buffer,
union mpsc_pbuf_generic word, void *data);
const union mpsc_pbuf_generic word,
const void *data);
/** @brief Put a packet into a buffer.
*
@@ -203,18 +204,20 @@ void mpsc_pbuf_put_word_ext(struct mpsc_pbuf_buffer *buffer,
*
* @param buffer Buffer.
*
* @param data First word of data must contain MPSC_PBUF_HDR with valid set.
* @param data First word of data must contain MPSC_PBUF_HDR with valid bit set.
*
* @param wlen Packet size in words.
*/
void mpsc_pbuf_put_data(struct mpsc_pbuf_buffer *buffer,
uint32_t *data, size_t wlen);
const uint32_t *data, size_t wlen);
/** @brief Claim the first pending packet.
*
* @param buffer Buffer.
*
* @return Pointer to the claimed packet or null if none available.
*/
union mpsc_pbuf_generic *mpsc_pbuf_claim(struct mpsc_pbuf_buffer *buffer);
const union mpsc_pbuf_generic *mpsc_pbuf_claim(struct mpsc_pbuf_buffer *buffer);
/** @brief Free a packet.
*

View File

@@ -26,6 +26,7 @@ void z_timer_expiration_handler(struct _timeout *t)
{
struct k_timer *timer = CONTAINER_OF(t, struct k_timer, timeout);
struct k_thread *thread;
k_spinlock_key_t key = k_spin_lock(&lock);
/*
* if the timer is periodic, start it again; don't add _TICK_ALIGN
@@ -46,27 +47,23 @@ void z_timer_expiration_handler(struct _timeout *t)
}
if (!IS_ENABLED(CONFIG_MULTITHREADING)) {
k_spin_unlock(&lock, key);
return;
}
thread = z_waitq_head(&timer->wait_q);
if (thread == NULL) {
k_spin_unlock(&lock, key);
return;
}
/*
* Interrupts _DO NOT_ have to be locked in this specific
* instance of thread unpending because a) this is the only
* place a thread can be taken off this pend queue, and b) the
* only place a thread can be put on the pend queue is at
* thread level, which of course cannot interrupt the current
* context.
*/
z_unpend_thread_no_timeout(thread);
arch_thread_return_value_set(thread, 0);
k_spin_unlock(&lock, key);
z_ready_thread(thread);
}

View File

@@ -185,7 +185,7 @@ static union mpsc_pbuf_generic *drop_item_locked(struct mpsc_pbuf_buffer *buffer
}
void mpsc_pbuf_put_word(struct mpsc_pbuf_buffer *buffer,
union mpsc_pbuf_generic item)
const union mpsc_pbuf_generic item)
{
bool cont;
uint32_t free_wlen;
@@ -305,7 +305,8 @@ void mpsc_pbuf_commit(struct mpsc_pbuf_buffer *buffer,
}
void mpsc_pbuf_put_word_ext(struct mpsc_pbuf_buffer *buffer,
union mpsc_pbuf_generic item, void *data)
const union mpsc_pbuf_generic item,
const void *data)
{
static const size_t l =
(sizeof(item) + sizeof(data)) / sizeof(uint32_t);
@@ -327,7 +328,7 @@ void mpsc_pbuf_put_word_ext(struct mpsc_pbuf_buffer *buffer,
void **p =
(void **)&buffer->buf[buffer->tmp_wr_idx + 1];
*p = data;
*p = (void *)data;
buffer->tmp_wr_idx =
idx_inc(buffer, buffer->tmp_wr_idx, l);
buffer->wr_idx = idx_inc(buffer, buffer->wr_idx, l);
@@ -352,7 +353,7 @@ void mpsc_pbuf_put_word_ext(struct mpsc_pbuf_buffer *buffer,
} while (cont);
}
void mpsc_pbuf_put_data(struct mpsc_pbuf_buffer *buffer, uint32_t *data,
void mpsc_pbuf_put_data(struct mpsc_pbuf_buffer *buffer, const uint32_t *data,
size_t wlen)
{
bool cont;
@@ -395,7 +396,7 @@ void mpsc_pbuf_put_data(struct mpsc_pbuf_buffer *buffer, uint32_t *data,
} while (cont);
}
union mpsc_pbuf_generic *mpsc_pbuf_claim(struct mpsc_pbuf_buffer *buffer)
const union mpsc_pbuf_generic *mpsc_pbuf_claim(struct mpsc_pbuf_buffer *buffer)
{
union mpsc_pbuf_generic *item;
bool cont;

View File

@@ -3,6 +3,4 @@
#
# SPDX-License-Identifier: Apache-2.0
#
zephyr_library()
zephyr_include_directories(.)

View File

@@ -13,12 +13,12 @@
MEMORY
{
DT_RESERVED_MEM_REGIONS()
LINKER_DT_RESERVED_MEM_REGIONS()
}
SECTIONS
{
DT_RESERVED_MEM_SECTIONS()
LINKER_DT_RESERVED_MEM_SECTIONS()
}
#include <arch/arm64/scripts/linker.ld>

View File

@@ -5,7 +5,6 @@
*/
#include <zephyr.h>
#include <devicetree/memory.h>
#include <linker/linker-defs.h>
/* Variables placed in reserved sections */
@@ -18,17 +17,17 @@ void main(void)
uint32_t res_size_outer, res_size_inner;
res_ptr_outer =
DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(DT_NODELABEL(sample_driver_outer),
memory_region);
LINKER_DT_RESERVED_MEM_GET_PTR_BY_PHANDLE(DT_NODELABEL(sample_driver_outer),
memory_region);
res_size_outer =
DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(DT_NODELABEL(sample_driver_outer),
memory_region);
LINKER_DT_RESERVED_MEM_GET_SIZE_BY_PHANDLE(DT_NODELABEL(sample_driver_outer),
memory_region);
printk("Reserved memory address for the outer driver: %p\n", res_ptr_outer);
printk("Reserved memory size for the outer driver: %d\n", res_size_outer);
res_ptr_inner = DT_RESERVED_MEM_GET_PTR(DT_NODELABEL(res1));
res_size_inner = DT_RESERVED_MEM_GET_SIZE(DT_NODELABEL(res1));
res_ptr_inner = LINKER_DT_RESERVED_MEM_GET_PTR(DT_NODELABEL(res1));
res_size_inner = LINKER_DT_RESERVED_MEM_GET_SIZE(DT_NODELABEL(res1));
printk("Reserved memory address for the inner driver: %p\n", res_ptr_inner);
printk("Reserved memory size for the inner driver: %d\n", res_size_inner);

View File

@@ -1,5 +1,3 @@
CONFIG_GPIO=y
CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_DEVICE_RUNTIME=y

View File

@@ -34,7 +34,7 @@ LEDs). The sample can be built and executed for the TWR-KE18F as
follows:
.. zephyr-app-commands::
:zephyr-app: samples/subsys/canbus/canopen
:zephyr-app: samples/modules/canopennode
:board: twr_ke18f
:goals: build flash
:compact:
@@ -53,7 +53,7 @@ LED indicators (red and green LEDs)
The sample can be built and executed for the FRDM-K64F as follows:
.. zephyr-app-commands::
:zephyr-app: samples/subsys/canbus/canopen
:zephyr-app: samples/modules/canopennode
:board: frdm_k64f
:goals: build flash
:compact:
@@ -66,7 +66,7 @@ Building and Running for boards without storage partition
The sample can be built for boards without a flash storage partition by using a different configuration file:
.. zephyr-app-commands::
:zephyr-app: samples/subsys/canbus/canopen
:zephyr-app: samples/modules/canopennode
:board: <your_board_name>
:conf: "prj_no_storage.conf"
:goals: build flash
@@ -352,7 +352,7 @@ for the FRDM-K64F as follows:
#. Rebuild the CANopen sample with MCUboot support:
.. zephyr-app-commands::
:zephyr-app: samples/subsys/canbus/canopen
:zephyr-app: samples/modules/canopennode
:board: frdm_k64f
:goals: build
:gen-args: -DCONFIG_BOOTLOADER_MCUBOOT=y
@@ -392,20 +392,20 @@ for the FRDM-K64F as follows:
Modifying the Object Dictionary
*******************************
The CANopen object dictionary used in this sample application can be
found under :zephyr_file:`samples/subsys/canbus/canopen/objdict` in
found under :zephyr_file:`samples/modules/canopennode/objdict` in
the Zephyr tree. The object dictionary can be modified using any
object dictionary editor supporting CANopenNode object dictionary code
generation.
A popular choice is the EDS editor from the `libedssharp`_
project. With that, the
:zephyr_file:`samples/subsys/canbus/canopen/objdict/objdicts.xml`
:zephyr_file:`samples/modules/canopennode/objdict/objdicts.xml`
project file can be opened and modified, and new implementation files
(:zephyr_file:`samples/subsys/canbus/canopen/objdict/CO_OD.h` and
:zephyr_file:`samples/subsys/canbus/canopen/objdict/CO_OD.c`) can be
(:zephyr_file:`samples/modules/canopennode/objdict/CO_OD.h` and
:zephyr_file:`samples/modules/canopennode/objdict/CO_OD.c`) can be
generated. The EDS editor can also export an updated Electronic Data
Sheet (EDS) file
(:zephyr_file:`samples/subsys/canbus/canopen/objdict/objdicts.eds`).
(:zephyr_file:`samples/modules/canopennode/objdict/objdicts.eds`).
.. _CANopenNode:
https://github.com/CANopenNode/CANopenNode

View File

@@ -1018,7 +1018,7 @@ The counter can be reset by writing the value 0.</description>
</CANopenObject>
</CANopenObjectList>
<other>
<file fileName="objdict.xml" fileCreator="" fileCreationDate="09-18-2019" fileCreationTime="2:52PM" fileModifedBy="" fileMotifcationDate="02-20-2020" fileModificationTime="12:28PM" fileVersion="1" fileRevision="1" exportFolder="/home/hebad/Projects/zephyrproject/zephyr/samples/subsys/canbus/canopen/objdict" EdsFile="/home/hebad/Projects/zephyrproject/zephyr/samples/subsys/canbus/canopen/objdict/objdict.eds" />
<file fileName="objdict.xml" fileCreator="" fileCreationDate="09-18-2019" fileCreationTime="2:52PM" fileModifedBy="" fileMotifcationDate="02-20-2020" fileModificationTime="12:28PM" fileVersion="1" fileRevision="1" exportFolder="samples/modules/canopennode/objdict" EdsFile="samples/modules/canopennode/objdict/objdict.eds" />
<DeviceIdentity>
<vendorName />
<vendorNumber>0</vendorNumber>

View File

@@ -14,6 +14,7 @@ CONFIG_NET_CONNECTION_MANAGER=y
# PPP networking support
CONFIG_NET_NATIVE=y
CONFIG_NET_DRIVERS=y
CONFIG_NET_PPP=y
CONFIG_NET_L2_PPP=y
CONFIG_NET_L2_PPP_TIMEOUT=10000

View File

@@ -6,6 +6,7 @@ CONFIG_MODEM=y
CONFIG_MODEM_GSM_PPP=y
# PPP networking support
CONFIG_NET_DRIVERS=y
CONFIG_NET_PPP=y
CONFIG_NET_L2_PPP=y
CONFIG_NET_NATIVE=y

View File

@@ -1,3 +1,4 @@
CONFIG_NET_DRIVERS=y
CONFIG_NET_PPP=y
CONFIG_NET_L2_PPP=y
CONFIG_NET_STATISTICS_PPP=y

View File

@@ -6,7 +6,6 @@
CONFIG_PRINTK=y
CONFIG_LOG=y
CONFIG_GPIO=y
# OSDP config
CONFIG_OSDP=y

View File

@@ -6,7 +6,6 @@
CONFIG_PRINTK=y
CONFIG_LOG=y
CONFIG_GPIO=y
# OSDP config
CONFIG_OSDP=y

View File

@@ -18,6 +18,7 @@ CONFIG_MODEM_GSM_PPP=y
CONFIG_MODEM_GSM_APN="<Your Access Point Network>"
# PPP networking support
CONFIG_NET_DRIVERS=y
CONFIG_NET_NATIVE=y
CONFIG_NET_PPP=y
CONFIG_NET_L2_PPP=y

View File

@@ -2,5 +2,6 @@ sample:
name: Modbus RTU Client Sample
tests:
sample.modbus.rtu_client:
platform_allow: nrf52840dk_nrf52840 frdm_k64f
tags: uart modbus
depends_on: gpio, arduino_serial
depends_on: gpio arduino_serial

View File

@@ -2,8 +2,9 @@ sample:
name: Modbus RTU Server Sample
tests:
sample.modbus.rtu_server:
platform_allow: nrf52840dk_nrf52840 frdm_k64f
tags: uart modbus
filter: dt_compat_enabled_with_alias("gpio-leds", "led0") and
dt_compat_enabled_with_alias("gpio-leds", "led1") and
dt_compat_enabled_with_alias("gpio-leds", "led2")
depends_on: gpio, arduino_serial
filter: dt_enabled_alias_with_parent_compat("led0", "gpio-leds") and
dt_enabled_alias_with_parent_compat("led1", "gpio-leds") and
dt_enabled_alias_with_parent_compat("led2", "gpio-leds")
depends_on: gpio arduino_serial

View File

@@ -109,7 +109,6 @@ const static struct modbus_iface_param server_param = {
static int init_modbus_server(void)
{
const uint32_t mb_rtu_br = 19200;
const char iface_name[] = {DT_PROP(DT_INST(0, zephyr_modbus_serial), label)};
int iface;

View File

@@ -2,7 +2,8 @@ sample:
name: Modbus TCP to serial line gateway sample
tests:
sample.modbus.tcp_gateway:
platform_allow: frdm_k64f
tags: modbus
depends_on: gpio, netif, arduino_serial
depends_on: gpio netif arduino_serial
integration_platforms:
- frdm_k64f

View File

@@ -2,8 +2,9 @@ sample:
name: Modbus TCP Server Sample
tests:
sample.modbus.tcp_server:
platform_allow: frdm_k64f
tags: modbus
filter: dt_compat_enabled_with_alias("gpio-leds", "led0") and
dt_compat_enabled_with_alias("gpio-leds", "led1") and
dt_compat_enabled_with_alias("gpio-leds", "led2")
depends_on: gpio, netif
filter: dt_enabled_alias_with_parent_compat("led0", "gpio-leds") and
dt_enabled_alias_with_parent_compat("led1", "gpio-leds") and
dt_enabled_alias_with_parent_compat("led2", "gpio-leds")
depends_on: gpio netif

View File

@@ -436,6 +436,16 @@ class Handler:
proc.kill()
self.terminated = True
def add_missing_testscases(self, harness):
"""
If testsuite was broken by some error (e.g. timeout) it is necessary to
add information about next testcases, which were not be
performed due to this error.
"""
for c in self.instance.testcase.cases:
if c not in harness.tests:
harness.tests[c] = "BLOCK"
class BinaryHandler(Handler):
def __init__(self, instance, type_str):
@@ -590,6 +600,7 @@ class BinaryHandler(Handler):
else:
self.set_state("timeout", handler_time)
self.instance.reason = "Timeout"
self.add_missing_testscases(harness)
self.record(harness)
@@ -859,9 +870,7 @@ class DeviceHandler(Handler):
handler_time = time.time() - start_time
if out_state in ["timeout", "flash_error"]:
for c in self.instance.testcase.cases:
if c not in harness.tests:
harness.tests[c] = "BLOCK"
self.add_missing_testscases(harness)
if out_state == "timeout":
self.instance.reason = "Timeout"
@@ -1152,6 +1161,7 @@ class QEMUHandler(Handler):
self.instance.reason = "Timeout"
else:
self.instance.reason = "Exited with {}".format(self.returncode)
self.add_missing_testscases(harness)
def get_fifo(self):
return self.fifo_fn
@@ -1986,7 +1996,7 @@ class CMake():
log.write(log_msg)
if log_msg:
res = re.findall("region `(FLASH|RAM|ICCM|DCCM|SRAM)' overflowed by", log_msg)
res = re.findall("region `(FLASH|ROM|RAM|ICCM|DCCM|SRAM)' overflowed by", log_msg)
if res and not self.overflow_as_errors:
logger.debug("Test skipped due to {} Overflow".format(res[0]))
self.instance.status = "skipped"
@@ -2108,7 +2118,7 @@ class CMake():
else:
logger.error("Cmake script failure: %s" % (args[0]))
results = {"returncode": p.returncode}
results = {"returncode": p.returncode, "returnmsg": out}
return results
@@ -2898,7 +2908,7 @@ class TestSuite(DisablePyTestCollectionMixin):
try:
if result['returncode']:
raise TwisterRuntimeError("E: Variable ZEPHYR_TOOLCHAIN_VARIANT is not defined")
raise TwisterRuntimeError(f"E: {result['returnmsg']}")
except Exception as e:
print(str(e))
sys.exit(2)

View File

@@ -10,6 +10,7 @@ config SOC_NRF5340_CPUAPP
select CPU_HAS_FPU
select ARMV8_M_DSP
select HAS_HW_NRF_CC312
select HAS_HW_NRF_COMP
select HAS_HW_NRF_CLOCK
select HAS_HW_NRF_DPPIC
select HAS_HW_NRF_EGU0
@@ -24,6 +25,7 @@ config SOC_NRF5340_CPUAPP
select HAS_HW_NRF_I2S
select HAS_HW_NRF_IPC
select HAS_HW_NRF_KMU
select HAS_HW_NRF_LPCOMP
select HAS_HW_NRF_NFCT
select HAS_HW_NRF_NVMC_PE
select HAS_HW_NRF_PDM
@@ -76,6 +78,7 @@ config SOC_NRF5340_CPUNET
select HAS_HW_NRF_CCM
select HAS_HW_NRF_CCM_LFLEN_8BIT
select HAS_HW_NRF_DPPIC
select HAS_HW_NRF_ECB
select HAS_HW_NRF_EGU0
select HAS_HW_NRF_GPIO0
select HAS_HW_NRF_GPIO1
@@ -91,6 +94,10 @@ config SOC_NRF5340_CPUNET
select HAS_HW_NRF_RTC1
select HAS_HW_NRF_SPIM0
select HAS_HW_NRF_SPIS0
select HAS_HW_NRF_SWI0
select HAS_HW_NRF_SWI1
select HAS_HW_NRF_SWI2
select HAS_HW_NRF_SWI3
select HAS_HW_NRF_TEMP
select HAS_HW_NRF_TIMER0
select HAS_HW_NRF_TIMER1

View File

@@ -112,6 +112,8 @@ if(CONFIG_BT_LL_SW_SPLIT)
)
endif()
if(CONFIG_BT_CONN OR
(CONFIG_BT_BROADCASTER AND
CONFIG_BT_CTLR_ADV_EXT) OR
CONFIG_BT_CTLR_ADV_PERIODIC OR
CONFIG_BT_CTLR_SYNC_PERIODIC)
zephyr_library_sources(

View File

@@ -430,7 +430,7 @@ config BT_CTLR_PHY_CODED
config BT_CTLR_CHAN_SEL_2
bool "Channel Selection Algorithm #2"
depends on (BT_CONN || BT_CTLR_ADV_PERIODIC || BT_CTLR_SYNC_PERIODIC) && BT_CTLR_CHAN_SEL_2_SUPPORT
depends on (BT_CONN || (BT_BROADCASTER && BT_CTLR_ADV_EXT) || BT_CTLR_ADV_PERIODIC || BT_CTLR_SYNC_PERIODIC) && BT_CTLR_CHAN_SEL_2_SUPPORT
default y
help
Enable support for Bluetooth 5.0 LE Channel Selection Algorithm #2 in

View File

@@ -852,7 +852,7 @@ static void read_bd_addr(struct net_buf *buf, struct net_buf **evt)
rp->status = 0x00;
ll_addr_get(0, &rp->bdaddr.val[0]);
(void)ll_addr_read(0, &rp->bdaddr.val[0]);
}
#if defined(CONFIG_BT_CTLR_HCI_CODEC_AND_DELAY_INFO)

View File

@@ -15,8 +15,9 @@ void ll_reset(void);
uint8_t ll_set_host_feature(uint8_t bit_number, uint8_t bit_value);
uint64_t ll_feat_get(void);
uint8_t *ll_addr_get(uint8_t addr_type, uint8_t *p_bdaddr);
uint8_t ll_addr_set(uint8_t addr_type, uint8_t const *const p_bdaddr);
uint8_t *ll_addr_get(uint8_t addr_type);
uint8_t *ll_addr_read(uint8_t addr_type, uint8_t *const bdaddr);
#if defined(CONFIG_BT_CTLR_HCI_ADV_HANDLE_MAPPING)
uint8_t ll_adv_set_by_hci_handle_get(uint8_t hci_handle, uint8_t *handle);

View File

@@ -5,7 +5,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#define LL_VERSION_NUMBER BT_HCI_VERSION_5_2
#define LL_VERSION_NUMBER BT_HCI_VERSION_5_3
#if defined(CONFIG_BT_CTLR_LE_ENC)
#define LL_FEAT_BIT_ENC BIT64(BT_LE_FEAT_BIT_ENC)

View File

@@ -34,27 +34,6 @@
static uint8_t pub_addr[BDADDR_SIZE];
static uint8_t rnd_addr[BDADDR_SIZE];
uint8_t *ll_addr_get(uint8_t addr_type, uint8_t *bdaddr)
{
if (addr_type > 1) {
return NULL;
}
if (addr_type) {
if (bdaddr) {
memcpy(bdaddr, rnd_addr, BDADDR_SIZE);
}
return rnd_addr;
}
if (bdaddr) {
memcpy(bdaddr, pub_addr, BDADDR_SIZE);
}
return pub_addr;
}
uint8_t ll_addr_set(uint8_t addr_type, uint8_t const *const bdaddr)
{
if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
@@ -81,6 +60,31 @@ uint8_t ll_addr_set(uint8_t addr_type, uint8_t const *const bdaddr)
return 0;
}
uint8_t *ll_addr_get(uint8_t addr_type)
{
if (addr_type > BT_ADDR_LE_RANDOM) {
return NULL;
}
if (addr_type) {
return rnd_addr;
}
return pub_addr;
}
uint8_t *ll_addr_read(uint8_t addr_type, uint8_t *const bdaddr)
{
uint8_t *addr;
addr = ll_addr_get(addr_type);
if (addr) {
memcpy(bdaddr, addr, BDADDR_SIZE);
}
return addr;
}
void bt_ctlr_set_public_addr(const uint8_t *addr)
{
(void)memcpy(pub_addr, addr, sizeof(pub_addr));

View File

@@ -56,6 +56,14 @@ struct lll_adv_aux {
struct lll_hdr hdr;
struct lll_adv *adv;
/* Implementation defined radio event counter to calculate auxiliary
* PDU channel index.
*/
uint16_t data_chan_counter;
/* Temporary stored use by primary channel PDU event to fill the
* auxiliary offset to this auxiliary PDU event.
*/
uint32_t ticks_offset;
struct lll_adv_pdu data;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 Nordic Semiconductor ASA
* Copyright (c) 2018-2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,5 +10,6 @@ void lll_adv_aux_prepare(void *param);
extern uint8_t ull_adv_aux_lll_handle_get(struct lll_adv_aux *lll);
extern struct pdu_adv_aux_ptr *
ull_adv_aux_lll_offset_fill(uint32_t ticks_offset, uint32_t start_us,
struct pdu_adv *pdu);
ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu,
uint32_t ticks_offset,
uint32_t start_us);

View File

@@ -62,6 +62,7 @@ struct lll_scan_aux {
uint8_t chan:6;
uint8_t state:1;
uint8_t is_chain_sched:1;
uint8_t phy:3;

View File

@@ -10,6 +10,10 @@ struct lll_sync {
uint8_t access_addr[4];
uint8_t crc_init[3];
uint8_t phy:3;
uint8_t is_rx_enabled:1;
uint8_t is_aux_sched:1;
uint16_t skip_prepare;
uint16_t skip_event;
uint16_t event_counter;
@@ -32,9 +36,6 @@ struct lll_sync {
/* used to store lll_aux when chain is being scanned */
struct lll_scan_aux *lll_aux;
uint8_t phy:3;
uint8_t is_rx_enabled:1;
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
struct lll_df_sync df_cfg;
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */

View File

@@ -1217,9 +1217,13 @@ static void isr_done(void *param)
start_us = radio_tmr_start_now(1);
#if defined(CONFIG_BT_CTLR_ADV_EXT)
if (lll->aux) {
ull_adv_aux_lll_offset_fill(lll->aux->ticks_offset,
start_us, pdu);
struct lll_adv_aux *lll_aux;
lll_aux = lll->aux;
if (lll_aux) {
(void)ull_adv_aux_lll_offset_fill(pdu,
lll_aux->ticks_offset,
start_us);
}
#else /* !CONFIG_BT_CTLR_ADV_EXT */
ARG_UNUSED(pdu);
@@ -1538,3 +1542,15 @@ static inline bool isr_rx_ci_adva_check(uint8_t tx_addr, uint8_t *addr,
return (tx_addr == ci->rx_addr) &&
!memcmp(addr, ci->connect_ind.adv_addr, BDADDR_SIZE);
}
#if defined(CONFIG_ZTEST)
uint32_t lll_adv_free_pdu_fifo_count_get(void)
{
return MFIFO_AVAIL_COUNT_GET(pdu_free);
}
uint32_t lll_adv_pdu_mem_free_count_get(void)
{
return mem_free_count_get(mem_pdu.free);
}
#endif /* CONFIG_ZTEST */

View File

@@ -164,6 +164,9 @@ static int prepare_cb(struct lll_prepare_param *p)
return 0;
}
/* Increment counter used in ULL for channel index calculation */
lll->data_chan_counter++;
/* Set up Radio H/W */
radio_reset();

View File

@@ -78,3 +78,8 @@ bool lll_adv_connect_ind_check(struct lll_adv *lll, struct pdu_adv *ci,
uint8_t tx_addr, uint8_t *addr,
uint8_t rx_addr, uint8_t *tgt_addr,
uint8_t devmatch_ok, uint8_t *rl_idx);
#if defined(CONFIG_ZTEST)
uint32_t lll_adv_free_pdu_fifo_count_get(void);
uint32_t lll_adv_pdu_mem_free_count_get(void);
#endif /* CONFIG_ZTEST */

View File

@@ -65,6 +65,28 @@ static inline struct pdu_adv *lll_adv_scan_rsp_peek(struct lll_adv *lll)
return (void *)lll->scan_rsp.pdu[lll->scan_rsp.last];
}
static inline struct pdu_adv *
lll_adv_pdu_latest_peek(const struct lll_adv_pdu *const pdu)
{
uint8_t first;
first = pdu->first;
if (first != pdu->last) {
first += 1U;
if (first == DOUBLE_BUFFER_SIZE) {
first = 0U;
}
}
return (void *)pdu->pdu[first];
}
static inline struct pdu_adv *
lll_adv_data_latest_peek(const struct lll_adv *const lll)
{
return lll_adv_pdu_latest_peek(&lll->adv_data);
}
#if defined(CONFIG_BT_CTLR_ADV_EXT)
static inline struct pdu_adv *lll_adv_aux_data_alloc(struct lll_adv_aux *lll,
uint8_t *idx)
@@ -83,6 +105,12 @@ static inline struct pdu_adv *lll_adv_aux_data_peek(struct lll_adv_aux *lll)
return (void *)lll->data.pdu[lll->data.last];
}
static inline struct pdu_adv *
lll_adv_aux_data_latest_peek(const struct lll_adv_aux *const lll)
{
return lll_adv_pdu_latest_peek(&lll->data);
}
static inline struct pdu_adv *lll_adv_aux_data_curr_get(struct lll_adv_aux *lll)
{
return (void *)lll->data.pdu[lll->data.first];
@@ -139,11 +167,22 @@ static inline struct pdu_adv *lll_adv_sync_data_peek(struct lll_adv_sync *lll,
return (void *)lll->data.pdu[last];
}
static inline struct pdu_adv *
lll_adv_sync_data_latest_peek(const struct lll_adv_sync *const lll)
{
return lll_adv_pdu_latest_peek(&lll->data);
}
#if defined(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
static inline void *lll_adv_sync_extra_data_peek(struct lll_adv_sync *lll)
{
return lll->data.extra_data[lll->data.last];
}
static inline void *lll_adv_sync_extra_data_curr_get(struct lll_adv_sync *lll)
{
return lll->data.extra_data[lll->data.first];
}
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#endif /* CONFIG_BT_CTLR_ADV_EXT */

View File

@@ -334,7 +334,7 @@ static void isr_tx(void *param)
lll_sync = param;
lll = lll_sync->adv;
/* TODO: do not hardcode to single value */
/* FIXME: Use implementation defined channel index */
lll_chan_set(0);
pdu = lll_adv_pdu_linked_next_get(lll_sync->last_pdu);
@@ -393,6 +393,7 @@ static void isr_tx(void *param)
static void pdu_b2b_update(struct lll_adv_sync *lll, struct pdu_adv *pdu, uint32_t cte_len_us)
{
while (pdu) {
/* FIXME: Use implementation defined channel index */
pdu_b2b_aux_ptr_update(pdu, lll->adv->phy_s, lll->adv->phy_flags, 0,
ADV_SYNC_PDU_B2B_AFS, cte_len_us);
pdu = lll_adv_pdu_linked_next_get(pdu);
@@ -403,8 +404,8 @@ static void pdu_b2b_aux_ptr_update(struct pdu_adv *pdu, uint8_t phy, uint8_t fla
uint8_t chan_idx, uint32_t offset_us, uint32_t cte_len_us)
{
struct pdu_adv_com_ext_adv *com_hdr;
struct pdu_adv_aux_ptr *aux_ptr;
struct pdu_adv_ext_hdr *hdr;
struct pdu_adv_aux_ptr *aux;
uint8_t *dptr;
com_hdr = &pdu->adv_ext_ind;
@@ -426,7 +427,7 @@ static void pdu_b2b_aux_ptr_update(struct pdu_adv *pdu, uint8_t phy, uint8_t fla
LL_ASSERT(!hdr->adi);
/* Update AuxPtr */
aux = (void *)dptr;
aux_ptr = (void *)dptr;
offset_us += PDU_AC_US(pdu->len, phy, flags);
/* Add CTE length to PDUs that have CTE attached.
* Periodic advertising chain may include PDUs without CTE.
@@ -436,15 +437,16 @@ static void pdu_b2b_aux_ptr_update(struct pdu_adv *pdu, uint8_t phy, uint8_t fla
}
offset_us = offset_us / OFFS_UNIT_30_US;
if ((offset_us >> 13) != 0) {
aux->offs = offset_us / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
aux->offs_units = 1U;
aux_ptr->offs = offset_us / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
aux_ptr->offs_units = OFFS_UNIT_VALUE_300_US;
} else {
aux->offs = offset_us;
aux->offs_units = 0U;
aux_ptr->offs = offset_us;
aux_ptr->offs_units = OFFS_UNIT_VALUE_30_US;
}
aux->chan_idx = chan_idx;
aux->ca = 0;
aux->phy = find_lsb_set(phy) - 1;
aux_ptr->chan_idx = chan_idx;
aux_ptr->ca = (lll_clock_ppm_local_get() <= SCA_50_PPM) ?
SCA_VALUE_50_PPM : SCA_VALUE_500_PPM;
aux_ptr->phy = find_lsb_set(phy) - 1;
}
static void switch_radio_complete_and_b2b_tx(const struct lll_adv_sync *lll, uint8_t phy_s)

View File

@@ -92,7 +92,7 @@ void lll_df_cte_tx_enable(struct lll_adv_sync *lll_sync, const struct pdu_adv *p
if (ext_hdr->cte_info) {
const struct lll_df_adv_cfg *df_cfg;
df_cfg = lll_adv_sync_extra_data_peek(lll_sync);
df_cfg = lll_adv_sync_extra_data_curr_get(lll_sync);
LL_ASSERT(df_cfg);
df_cte_tx_configure(df_cfg);

View File

@@ -586,33 +586,36 @@ void lll_scan_aux_isr_aux_setup(void *param)
static void isr_rx_ull_schedule(void *param)
{
struct lll_scan_aux *lll;
struct lll_scan *scan_lll;
struct lll_scan_aux *lll_aux;
struct lll_scan *lll;
lll = param;
scan_lll = ull_scan_aux_lll_parent_get(lll, NULL);
lll_aux = param;
lll = ull_scan_aux_lll_parent_get(lll_aux, NULL);
isr_rx(scan_lll, lll, lll->phy);
isr_rx(lll, lll_aux, lll_aux->phy);
}
static void isr_rx_lll_schedule(void *param)
{
struct lll_scan_aux *lll;
struct node_rx_pdu *node_rx;
struct lll_scan *scan_lll;
struct lll_scan *lll;
uint8_t phy_aux;
node_rx = param;
scan_lll = node_rx->hdr.rx_ftr.param;
lll = scan_lll->lll_aux;
lll = node_rx->hdr.rx_ftr.param;
phy_aux = node_rx->hdr.rx_ftr.aux_phy; /* PHY remembered in node rx */
if (lll) {
phy_aux = lll->phy;
/* scan context has used LLL scheduling for aux reception */
if (lll->is_aux_sched) {
isr_rx(lll, NULL, phy_aux);
} else {
phy_aux = node_rx->hdr.rx_ftr.aux_phy;
/* `lll->lll_aux` would be allocated in ULL for LLL scheduled
* auxiliary PDU reception by scan context and for case
* where LLL scheduled chain PDU reception by aux context, it
* is assigned with the current aux context's LLL context.
*/
isr_rx(lll, lll->lll_aux, phy_aux);
}
isr_rx(scan_lll, NULL, phy_aux);
}
static void isr_rx(struct lll_scan *lll, struct lll_scan_aux *lll_aux,
@@ -710,8 +713,16 @@ isr_rx_do_close:
ull_rx_sched();
}
/* Resume scan if scanning ADV_AUX_IND chain */
radio_isr_set(lll_scan_isr_resume, lll);
/* Check if LLL scheduled auxiliary PDU reception by scan
* context or auxiliary PDU reception by aux context
*/
if (lll->is_aux_sched) {
/* Go back to resuming primary channel scanning */
radio_isr_set(lll_scan_isr_resume, lll);
} else {
/* auxiliary channel radio event done */
radio_isr_set(isr_done, NULL);
}
}
radio_disable();
}
@@ -1051,18 +1062,33 @@ static int isr_rx_pdu(struct lll_scan *lll, struct lll_scan_aux *lll_aux,
/* Passive scanner or scan responses */
#if defined(CONFIG_BT_CENTRAL)
} else if (!lll->conn &&
lll_scan_ext_tgta_check(lll, false, false, pdu, rl_idx)) {
((lll_aux && lll_aux->is_chain_sched) ||
(lll->lll_aux && lll->lll_aux->is_chain_sched) ||
lll_scan_ext_tgta_check(lll, false, false, pdu, rl_idx))) {
#else /* !CONFIG_BT_CENTRAL */
} else if (lll_scan_ext_tgta_check(lll, false, false, pdu, rl_idx)) {
} else if ((lll_aux && lll_aux->is_chain_sched) ||
(lll->lll_aux && lll->lll_aux->is_chain_sched) ||
lll_scan_ext_tgta_check(lll, false, false, pdu, rl_idx)) {
#endif /* !CONFIG_BT_CENTRAL */
ftr = &(node_rx->hdr.rx_ftr);
if (lll_aux) {
ftr->param = lll_aux;
ftr->scan_rsp = lll_aux->state;
/* Further auxiliary PDU reception will be chain PDUs */
lll_aux->is_chain_sched = 1U;
} else if (lll->lll_aux) {
ftr->param = lll;
ftr->scan_rsp = lll->lll_aux->state;
/* Auxiliary PDU received by LLL scheduling by scan
* context.
*/
lll->is_aux_sched = 1U;
/* Further auxiliary PDU reception will be chain PDUs */
lll->lll_aux->is_chain_sched = 1U;
} else {
/* Return -ECHILD, as ULL execution has not yet assigned
* an aux context. This can happen only under LLL
@@ -1113,7 +1139,6 @@ static int isr_rx_pdu(struct lll_scan *lll, struct lll_scan_aux *lll_aux,
* disable so prevent caller from doing it again.
*/
if (ftr->aux_lll_sched) {
lll->is_aux_sched = 1U;
return 0;
}

View File

@@ -112,6 +112,9 @@ void lll_sync_aux_prepare_cb(struct lll_sync *lll,
{
struct node_rx_pdu *node_rx;
/* Initialize Trx count */
trx_cnt = 0U;
/* Start setting up Radio h/w */
radio_reset();
@@ -201,6 +204,9 @@ static int prepare_cb(struct lll_prepare_param *p)
lll->window_widening_event_us = lll->window_widening_max_us;
}
/* Reset chain PDU being scheduled by lll_sync context */
lll->is_aux_sched = 0U;
/* Initialize Trx count */
trx_cnt = 0U;
@@ -453,7 +459,7 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t *crc_ok)
{
uint8_t rssi_ready;
uint8_t trx_done;
int err = 0;
int err;
/* Read radio status and events */
trx_done = radio_is_done();
@@ -469,14 +475,11 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t *crc_ok)
/* No Rx */
if (!trx_done) {
/* TODO: Combine the early exit with above if-then-else block
*/
err = -EINVAL;
goto isr_rx_done;
}
/* Rx-ed */
trx_cnt++;
/* Check CRC and generate Periodic Advertising Report */
if (*crc_ok) {
struct node_rx_pdu *node_rx;
@@ -507,29 +510,34 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t *crc_ok)
isr_aux_setup,
lll);
if (ftr->aux_lll_sched) {
lll->is_aux_sched = 1U;
err = -EBUSY;
} else {
err = 0;
}
ull_rx_put(node_rx->hdr.link, node_rx);
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
create_iq_report(lll, rssi_ready, BT_HCI_LE_CTE_CRC_OK);
(void)create_iq_report(lll, rssi_ready,
BT_HCI_LE_CTE_CRC_OK);
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
ull_rx_sched();
} else {
err = 0;
}
}
} else {
#if defined(CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC)
else {
err = create_iq_report(lll, rssi_ready,
BT_HCI_LE_CTE_CRC_ERR_CTE_BASED_TIME);
if (!err) {
ull_rx_sched();
}
#endif /* CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC */
err = 0;
}
#endif /* CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC */
isr_rx_done:
return err;
@@ -548,8 +556,12 @@ static void isr_rx_adv_sync(void *param)
/* Save radio ready and address capture timestamp for later use for
* drift compensation.
*/
radio_tmr_aa_save(radio_tmr_aa_get());
radio_tmr_ready_save(radio_tmr_ready_get());
if (err != -EINVAL) {
trx_cnt = 1U;
radio_tmr_aa_save(radio_tmr_aa_get());
radio_tmr_ready_save(radio_tmr_ready_get());
}
if (err == -EBUSY) {
return;
@@ -560,14 +572,14 @@ static void isr_rx_adv_sync(void *param)
static void isr_rx_aux_chain(void *param)
{
struct lll_scan_aux *aux_lll;
struct lll_scan_aux *lll_aux;
struct lll_sync *lll;
uint8_t crc_ok;
int err;
lll = param;
aux_lll = lll->lll_aux;
if (!aux_lll) {
lll_aux = lll->lll_aux;
if (!lll_aux) {
/* auxiliary context not assigned (yet) in ULL execution
* context, drop current reception and abort further chain PDU
* receptions, if any.
@@ -583,7 +595,7 @@ static void isr_rx_aux_chain(void *param)
return;
}
if (!trx_cnt || !crc_ok) {
if (!crc_ok) {
struct node_rx_pdu *node_rx;
node_rx = ull_pdu_rx_alloc();
@@ -599,7 +611,13 @@ static void isr_rx_aux_chain(void *param)
}
isr_rx_aux_chain_done:
isr_rx_done_cleanup(lll, 1U);
if (lll->is_aux_sched) {
lll->is_aux_sched = 0U;
isr_rx_done_cleanup(lll, 1U);
} else {
lll_isr_cleanup(lll);
}
}
static void isr_rx_done_cleanup(struct lll_sync *lll, uint8_t crc_ok)

View File

@@ -103,10 +103,18 @@
#define EVENT_INSTANT_LATENCY_MAX 0x7fff
/* Offset Units field encoding */
#define OFFS_UNIT_30_US 30
#define OFFS_UNIT_300_US 300
#define OFFS_UNIT_30_US 30
#define OFFS_UNIT_300_US 300
#define OFFS_UNIT_VALUE_30_US 0
#define OFFS_UNIT_VALUE_300_US 1
/* Value specified in BT Spec. Vol 6, Part B, section 2.3.4.6 */
#define OFFS_ADJUST_US 245760
#define OFFS_ADJUST_US 245760
/* Advertiser's Sleep Clock Accuracy Value */
#define SCA_500_PPM 500 /* 51 ppm to 500 ppm */
#define SCA_50_PPM 50 /* 0 ppm to 50 ppm */
#define SCA_VALUE_500_PPM 0 /* 51 ppm to 500 ppm */
#define SCA_VALUE_50_PPM 1 /* 0 ppm to 50 ppm */
/* Sleep Clock Accuracy, calculate drift in microseconds */
#define SCA_DRIFT_50_PPM_US(t) (((t) * 50UL) / 1000000UL)

View File

@@ -2709,10 +2709,10 @@ static const uint8_t *adva_update(struct ll_adv_set *adv, struct pdu_adv *pdu)
if (0) {
#if defined(CONFIG_BT_CTLR_ADV_EXT)
} else if (ll_adv_cmds_is_ext() && pdu->tx_addr) {
own_id_addr = ll_adv_aux_random_addr_get(adv, NULL);
own_id_addr = adv->rnd_addr;
#endif
} else {
own_id_addr = ll_addr_get(pdu->tx_addr, NULL);
own_id_addr = ll_addr_get(pdu->tx_addr);
}
}

View File

@@ -22,7 +22,9 @@
#include "pdu.h"
#include "lll.h"
#include "lll_clock.h"
#include "lll/lll_vendor.h"
#include "lll_chan.h"
#include "lll/lll_adv_types.h"
#include "lll_adv.h"
#include "lll/lll_adv_pdu.h"
@@ -32,6 +34,7 @@
#include "ull_adv_types.h"
#include "ull_internal.h"
#include "ull_chan_internal.h"
#include "ull_adv_internal.h"
#include "ll.h"
@@ -76,23 +79,13 @@ uint8_t ll_adv_aux_random_addr_set(uint8_t handle, uint8_t const *const addr)
return BT_HCI_ERR_CMD_DISALLOWED;
}
memcpy(adv->rnd_addr, addr, BDADDR_SIZE);
(void)memcpy(adv->rnd_addr, addr, BDADDR_SIZE);
return 0;
}
uint8_t const *ll_adv_aux_random_addr_get(struct ll_adv_set const *const adv,
uint8_t *const addr)
{
if (addr) {
memcpy(addr, adv->rnd_addr, BDADDR_SIZE);
}
return adv->rnd_addr;
}
uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t len,
uint8_t const *const data)
uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref,
uint8_t len, uint8_t const *const data)
{
struct ll_adv_set *adv;
uint8_t value[1 + sizeof(data)];
@@ -124,7 +117,7 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, ui
val_ptr = value;
*val_ptr++ = len;
memcpy(val_ptr, &data, sizeof(data));
(void)memcpy(val_ptr, &data, sizeof(data));
err = ull_adv_aux_hdr_set_clear(adv, ULL_ADV_PDU_HDR_FIELD_AD_DATA,
0, value, NULL, &pri_idx);
if (err) {
@@ -186,8 +179,8 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, ui
return 0;
}
uint8_t ll_adv_aux_sr_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t len,
uint8_t const *const data)
uint8_t ll_adv_aux_sr_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref,
uint8_t len, uint8_t const *const data)
{
struct pdu_adv_com_ext_adv *sr_com_hdr;
struct pdu_adv *pri_pdu_prev;
@@ -289,8 +282,8 @@ uint8_t ll_adv_aux_sr_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, ui
sr_prev = lll_adv_scan_rsp_peek(lll);
/* AdvA */
memcpy(sr_dptr, &sr_prev->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
BDADDR_SIZE);
(void)memcpy(sr_dptr, &sr_prev->adv_ext_ind.ext_hdr.data[ADVA_OFFSET],
BDADDR_SIZE);
sr_dptr += BDADDR_SIZE;
#if defined(CONFIG_BT_CTRL_ADV_ADI_IN_SCAN_RSP)
@@ -310,7 +303,7 @@ uint8_t ll_adv_aux_sr_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, ui
}
/* Copy data */
memcpy(sr_dptr, data, len);
(void)memcpy(sr_dptr, data, len);
sr_dptr += len;
/* Finish Common ExtAdv Payload header */
@@ -448,6 +441,43 @@ int ull_adv_aux_reset_finalize(void)
return 0;
}
uint8_t ull_adv_aux_chm_update(void)
{
/* For each created extended advertising set */
for (uint8_t handle = 0; handle < BT_CTLR_ADV_SET; ++handle) {
struct ll_adv_aux_set *aux;
struct ll_adv_set *adv;
uint8_t chm_last;
adv = ull_adv_is_created_get(handle);
if (!adv || !adv->lll.aux) {
continue;
}
aux = HDR_LLL2ULL(adv->lll.aux);
if (aux->chm_last != aux->chm_first) {
/* TODO: Handle previous Channel Map Update being in
* progress
*/
continue;
}
/* Append the channelMapNew that will be picked up by ULL */
chm_last = aux->chm_last + 1;
if (chm_last == DOUBLE_BUFFER_SIZE) {
chm_last = 0U;
}
aux->chm[chm_last].data_chan_count =
ull_chan_map_get(aux->chm[chm_last].data_chan_map);
aux->chm_last = chm_last;
}
/* TODO: Should failure due to Channel Map Update being already in
* progress be returned to caller?
*/
return 0;
}
uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
uint16_t sec_hdr_add_fields,
uint16_t sec_hdr_rem_fields,
@@ -668,7 +698,7 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
/* return the pointer to sync info struct inside the PDU
* buffer
*/
memcpy(value, &sec_dptr, sizeof(sec_dptr));
(void)memcpy(value, &sec_dptr, sizeof(sec_dptr));
value = (uint8_t *)value + sizeof(sec_dptr);
sec_dptr += sizeof(*sync_info);
@@ -857,7 +887,7 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
sec_dptr -= BDADDR_SIZE;
memcpy(sec_dptr, bdaddr, BDADDR_SIZE);
(void)memcpy(sec_dptr, bdaddr, BDADDR_SIZE);
}
/* No AdvA in primary channel due to AuxPtr being added */
@@ -878,7 +908,7 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
sec_dptr -= BDADDR_SIZE;
memcpy(sec_dptr, bdaddr, BDADDR_SIZE);
(void)memcpy(sec_dptr, bdaddr, BDADDR_SIZE);
}
/* Update auxiliary channel event time reservation */
@@ -902,16 +932,19 @@ void ull_adv_aux_ptr_fill(uint8_t **dptr, uint8_t phy_s)
{
struct pdu_adv_aux_ptr *aux_ptr;
/* NOTE: Channel Index and Aux Offset will be set on every advertiser's
* event prepare when finding the auxiliary event's ticker offset.
*/
*dptr -= sizeof(struct pdu_adv_aux_ptr);
aux_ptr = (void *)*dptr;
/* FIXME: implementation defined */
aux_ptr->chan_idx = 0U;
aux_ptr->ca = 0U;
/* NOTE: Aux Offset will be set in advertiser LLL event
*/
aux_ptr->offs_units = 0U;
aux_ptr->ca = (lll_clock_ppm_local_get() <= SCA_50_PPM) ?
SCA_VALUE_50_PPM : SCA_VALUE_500_PPM;
aux_ptr->offs_units = OFFS_UNIT_VALUE_30_US;
aux_ptr->offs = 0U;
aux_ptr->phy = find_lsb_set(phy_s) - 1;
@@ -1012,6 +1045,7 @@ struct ll_adv_aux_set *ull_adv_aux_acquire(struct lll_adv *lll)
{
struct lll_adv_aux *lll_aux;
struct ll_adv_aux_set *aux;
uint8_t chm_last;
int err;
aux = aux_acquire();
@@ -1029,6 +1063,18 @@ struct ll_adv_aux_set *ull_adv_aux_acquire(struct lll_adv *lll)
return NULL;
}
/* Initialize data channel calculation counter, data channel identifier,
* and channel map to use.
*/
lll_csrand_get(&lll_aux->data_chan_counter,
sizeof(lll_aux->data_chan_counter));
lll_csrand_get(&aux->data_chan_id, sizeof(aux->data_chan_id));
chm_last = aux->chm_first;
aux->chm_last = chm_last;
aux->chm[chm_last].data_chan_count =
ull_chan_map_get(aux->chm[chm_last].data_chan_map);
/* NOTE: ull_hdr_init(&aux->ull); is done on start */
lll_hdr_init(lll_aux, aux);
@@ -1060,12 +1106,12 @@ void ull_adv_aux_offset_get(struct ll_adv_set *adv)
LL_ASSERT(!ret);
}
struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(uint32_t ticks_offset,
uint32_t start_us,
struct pdu_adv *pdu)
struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu,
uint32_t ticks_offset,
uint32_t start_us)
{
struct pdu_adv_com_ext_adv *pri_com_hdr;
struct pdu_adv_aux_ptr *aux;
struct pdu_adv_aux_ptr *aux_ptr;
struct pdu_adv_ext_hdr *h;
uint32_t offs;
uint8_t *ptr;
@@ -1082,18 +1128,18 @@ struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(uint32_t ticks_offset,
ptr += sizeof(struct pdu_adv_adi);
}
aux = (void *)ptr;
aux_ptr = (void *)ptr;
offs = HAL_TICKER_TICKS_TO_US(ticks_offset) - start_us;
offs = offs / OFFS_UNIT_30_US;
if (!!(offs >> 13)) {
aux->offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
aux->offs_units = 1U;
aux_ptr->offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
aux_ptr->offs_units = OFFS_UNIT_VALUE_300_US;
} else {
aux->offs = offs;
aux->offs_units = 0U;
aux_ptr->offs = offs;
aux_ptr->offs_units = OFFS_UNIT_VALUE_30_US;
}
return aux;
return aux_ptr;
}
void ull_adv_aux_done(struct node_rx_event_done *done)
@@ -1208,16 +1254,22 @@ static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu,
static void mfy_aux_offset_get(void *param)
{
struct ll_adv_set *adv = param;
struct pdu_adv_aux_ptr *aux_ptr;
struct lll_adv_aux *lll_aux;
struct ll_adv_aux_set *aux;
uint32_t ticks_to_expire;
uint8_t data_chan_count;
uint8_t *data_chan_map;
uint32_t ticks_current;
struct ll_adv_set *adv;
struct pdu_adv *pdu;
uint8_t ticker_id;
uint8_t retry;
uint8_t id;
aux = HDR_LLL2ULL(adv->lll.aux);
adv = param;
lll_aux = adv->lll.aux;
aux = HDR_LLL2ULL(lll_aux);
ticker_id = TICKER_ID_ADV_AUX_BASE + ull_adv_aux_handle_get(aux);
id = TICKER_NULL;
@@ -1256,19 +1308,32 @@ static void mfy_aux_offset_get(void *param)
/* Store the ticks offset for population in other advertising primary
* channel PDUs.
*/
aux->lll.ticks_offset = ticks_to_expire;
lll_aux->ticks_offset = ticks_to_expire;
/* NOTE: as remainder used in scheduling primary PDU not available,
* compensate with a probable jitter of one ticker resolution unit that
* would be included in the packet timer capture when scheduling next
* advertising primary channel PDU.
*/
aux->lll.ticks_offset +=
lll_aux->ticks_offset +=
HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US);
/* FIXME: we are in ULL_LOW context, fill offset in LLL context */
pdu = lll_adv_data_curr_get(&adv->lll);
ull_adv_aux_lll_offset_fill(ticks_to_expire, 0, pdu);
/* FIXME: we are in ULL_LOW context, fill offset in LLL context? */
pdu = lll_adv_data_latest_peek(&adv->lll);
aux_ptr = ull_adv_aux_lll_offset_fill(pdu, ticks_to_expire, 0);
/* Process channel map update, if any */
if (aux->chm_first != aux->chm_last) {
/* Use channelMapNew */
aux->chm_first = aux->chm_last;
}
/* Calculate the radio channel to use */
data_chan_map = aux->chm[aux->chm_first].data_chan_map;
data_chan_count = aux->chm[aux->chm_first].data_chan_count;
aux_ptr->chan_idx = lll_chan_sel_2(lll_aux->data_chan_counter,
aux->data_chan_id,
data_chan_map, data_chan_count);
}
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,

View File

@@ -72,9 +72,8 @@ int ull_adv_aux_reset_finalize(void);
/* Return the aux set handle given the aux set instance */
uint8_t ull_adv_aux_handle_get(struct ll_adv_aux_set *aux);
/* Helper to read back random address */
uint8_t const *ll_adv_aux_random_addr_get(struct ll_adv_set const *const adv,
uint8_t *const addr);
/* Helper function to apply Channel Map Update for auxiliary PDUs */
uint8_t ull_adv_aux_chm_update(void);
/* helper function to initialize event timings */
uint32_t ull_adv_aux_evt_init(struct ll_adv_aux_set *aux);

View File

@@ -903,7 +903,7 @@ void ull_adv_sync_info_fill(struct ll_adv_sync_set *sync,
* If sync_info is part of ADV PDU the offs_adjust field
* is always set to 0.
*/
si->offs_units = 0U;
si->offs_units = OFFS_UNIT_VALUE_30_US;
si->offs_adjust = 0U;
si->offs = 0U;
@@ -1545,7 +1545,7 @@ static void mfy_sync_offset_get(void *param)
*/
lll_sync->ticks_offset = ticks_to_expire + 1;
pdu = lll_adv_aux_data_curr_get(adv->lll.aux);
pdu = lll_adv_aux_data_latest_peek(adv->lll.aux);
si = sync_info_get(pdu);
sync_info_offset_fill(si, ticks_to_expire, 0);
si->evt_cntr = lll_sync->event_counter + lll_sync->latency_prepare +
@@ -1610,10 +1610,10 @@ static inline void sync_info_offset_fill(struct pdu_adv_sync_info *si,
offs = offs / OFFS_UNIT_30_US;
if (!!(offs >> 13)) {
si->offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
si->offs_units = 1U;
si->offs_units = OFFS_UNIT_VALUE_300_US;
} else {
si->offs = offs;
si->offs_units = 0U;
si->offs_units = OFFS_UNIT_VALUE_30_US;
}
}

View File

@@ -71,6 +71,14 @@ struct ll_adv_aux_set {
uint16_t interval;
uint16_t data_chan_id;
struct {
uint8_t data_chan_map[PDU_CHANNEL_MAP_SIZE];
uint8_t data_chan_count:6;
} chm[DOUBLE_BUFFER_SIZE];
uint8_t chm_first;
uint8_t chm_last;
uint8_t is_started:1;
};

View File

@@ -98,7 +98,7 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window,
const uint8_t *own_id_addr;
/* Do not connect twice to the same peer */
own_id_addr = ll_addr_get(own_id_addr_type, NULL);
own_id_addr = ll_addr_get(own_id_addr_type);
if (ull_conn_peer_connected(own_id_addr_type, own_id_addr,
peer_addr_type, peer_addr)) {
return BT_HCI_ERR_CONN_ALREADY_EXISTS;

View File

@@ -52,6 +52,10 @@ uint8_t ll_chm_update(uint8_t const *const chm)
(void)ull_adv_sync_chm_update();
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
#if (CONFIG_BT_CTLR_ADV_AUX_SET > 0)
(void)ull_adv_aux_chm_update();
#endif /*(CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
/* TODO: Should failure due to Channel Map Update being already in
* progress be returned to caller?
*/

View File

@@ -5903,7 +5903,9 @@ static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
case PDU_DATA_LLCTRL_TYPE_LENGTH_REQ:
/* wait for response */
conn->llcp_length.state = LLCP_LENGTH_STATE_RSP_WAIT;
if (conn->llcp_length.state == LLCP_LENGTH_STATE_REQ_ACK_WAIT) {
conn->llcp_length.state = LLCP_LENGTH_STATE_RSP_WAIT;
}
break;
case PDU_DATA_LLCTRL_TYPE_LENGTH_RSP:

View File

@@ -835,14 +835,18 @@ static uint8_t rem_cte_info_from_per_adv_chain(struct lll_adv_sync *lll_sync,
while (pdu_chained) {
if (pdu_ext_adv_is_empty_without_cte(pdu_chained)) {
/* If there is an empty PDU then all remaining PDUs shoudl be released. */
lll_adv_pdu_linked_release_all(pdu_chained);
if (!new_chain) {
lll_adv_pdu_linked_release_all(pdu_chained);
/* Set new end of chain in PDUs linked list. If pdu differs from
* prev_pdu then it is already end of a chain. If it doesn't differ,
* then chain end is changed in right place by use of pdu_prev.
* That makes sure there is no PDU released twice (here and when LLL
* swaps PDU buffers).
*/
lll_adv_pdu_linked_append(NULL, *pdu_prev);
}
pdu_chained = NULL;
/* Set new end of chain in PDUs linked list. If pdu differs from prev_pdu
* then it is alread end of a chain. If it doesn't differ, then chain end
* is changed in rigth place by use of pdu_prev. That makes sure there
* is no PDU released twice (here and when LLL swaps PDU buffers).
*/
lll_adv_pdu_linked_append(NULL, *pdu_prev);
} else {
/* Update one before pdu_chained */
err = ull_adv_sync_pdu_set_clear(lll_sync, *pdu_prev, *pdu, 0,

View File

@@ -1014,8 +1014,12 @@ static int rl_access_check(bool check_ar)
}
}
/* NOTE: Allowed when passive scanning, otherwise deny if advertising,
* active scanning, initiating or periodic sync create is active.
*/
return ((IS_ENABLED(CONFIG_BT_BROADCASTER) && ull_adv_is_enabled(0)) ||
(IS_ENABLED(CONFIG_BT_OBSERVER) && ull_scan_is_enabled(0)))
(IS_ENABLED(CONFIG_BT_OBSERVER) &&
(ull_scan_is_enabled(0) & ~ULL_SCAN_IS_PASSIVE)))
? 0 : 1;
}

View File

@@ -188,7 +188,7 @@ uint8_t ll_scan_enable(uint8_t enable)
if ((is_coded_phy && (own_addr_type & 0x1)) ||
(!is_coded_phy && (scan->own_addr_type & 0x1))) {
if (!mem_nz(ll_addr_get(1, NULL), BDADDR_SIZE)) {
if (!mem_nz(ll_addr_get(BT_ADDR_LE_RANDOM), BDADDR_SIZE)) {
return BT_HCI_ERR_INVALID_PARAM;
}
}
@@ -362,7 +362,7 @@ uint8_t ull_scan_enable(struct ll_scan_set *scan)
uint32_t ret;
lll->init_addr_type = scan->own_addr_type;
ll_addr_get(lll->init_addr_type, lll->init_addr);
(void)ll_addr_read(lll->init_addr_type, lll->init_addr);
lll->chan = 0U;
lll->is_stop = 0U;
@@ -620,18 +620,23 @@ uint32_t ull_scan_is_enabled(uint8_t handle)
scan = ull_scan_is_enabled_get(handle);
if (!scan) {
return 0;
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
scan = ull_scan_set_get(handle);
return scan->per_scan.sync ? ULL_SCAN_IS_SYNC : 0U;
#else
return 0U;
#endif
}
/* NOTE: BIT(0) - passive scanning enabled
* BIT(1) - active scanning enabled
* BIT(2) - initiator enabled
*/
return (((uint32_t)scan->is_enabled << scan->lll.type) |
#if defined(CONFIG_BT_CENTRAL)
(scan->lll.conn ? BIT(2) : 0) |
(scan->lll.conn ? ULL_SCAN_IS_INITIATOR : 0U) |
#endif
0);
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
(scan->per_scan.sync ? ULL_SCAN_IS_SYNC : 0U) |
#endif
0U);
}
uint32_t ull_scan_filter_pol_get(uint8_t handle)

View File

@@ -137,7 +137,8 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx)
*/
lll_aux = ftr->param;
aux = HDR_LLL2ULL(lll_aux);
/* FIXME: pick the aux somehow */
/* aux parent will be NULL for periodic sync */
lll = aux->parent;
} else if (ull_scan_is_valid_get(HDR_LLL2ULL(ftr->param))) {
/* Node that does not have valid aux context but has
@@ -157,6 +158,7 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx)
*/
lll = NULL;
sync_lll = ftr->param;
lll_aux = sync_lll->lll_aux;
aux = HDR_LLL2ULL(lll_aux);
}
@@ -340,7 +342,11 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx)
ull_sync_chm_update(rx->handle, ptr, acad_len);
}
if (!aux_ptr || !aux_ptr->offs ||
/* Do not ULL schedule auxiliary PDU reception if no aux pointer
* or aux pointer is zero or scannable advertising has erroneous aux
* pointer being present or PHY in the aux pointer is invalid.
*/
if (!aux_ptr || !aux_ptr->offs || is_scan_req ||
(aux_ptr->phy > EXT_ADV_AUX_PHY_LE_CODED)) {
if (is_scan_req) {
LL_ASSERT(aux && aux->rx_last);
@@ -362,6 +368,7 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx)
aux->rx_head = aux->rx_last = NULL;
lll_aux = &aux->lll;
lll_aux->is_chain_sched = 0U;
ull_hdr_init(&aux->ull);
lll_hdr_init(lll_aux, aux);
@@ -405,6 +412,10 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx)
} else {
lll->lll_aux = lll_aux;
}
/* Reset auxiliary channel PDU scan state which otherwise is
* done in the prepare_cb when ULL scheduling is used.
*/
lll_aux->state = 0U;
return;
@@ -522,8 +533,6 @@ ull_scan_aux_rx_flush:
if (aux) {
struct ull_hdr *hdr;
hdr = &aux->ull;
/* Enqueue last rx in aux context if possible, otherwise send
* immediately since we are in sync context.
*/
@@ -544,6 +553,7 @@ ull_scan_aux_rx_flush:
* callback. Flushing here would release aux context and thus
* ull_hdr before done event was processed.
*/
hdr = &aux->ull;
LL_ASSERT(ull_ref_get(hdr) < 2);
if (ull_ref_get(hdr) == 0) {
flush(aux);
@@ -658,7 +668,12 @@ void ull_scan_aux_release(memq_link_t *link, struct node_rx_hdr *rx)
* data properly.
*/
rx->type = NODE_RX_TYPE_SYNC_REPORT;
rx->handle = ull_sync_handle_get(HDR_LLL2ULL(lll));
rx->handle = ull_sync_handle_get(param_ull);
/* Dequeue will try releasing list of node rx, set the extra
* pointer to NULL.
*/
rx->rx_ftr.extra = NULL;
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
} else {
LL_ASSERT(0);
@@ -673,6 +688,7 @@ void ull_scan_aux_release(memq_link_t *link, struct node_rx_hdr *rx)
hdr = &aux->ull;
LL_ASSERT(ull_ref_get(hdr) < 2);
/* Flush from here of from done event, if one is pending */
if (ull_ref_get(hdr) == 0) {
flush(aux);

View File

@@ -62,6 +62,10 @@ struct ll_scan_set *ull_scan_is_enabled_get(uint8_t handle);
struct ll_scan_set *ull_scan_is_disabled_get(uint8_t handle);
/* Return flags if enabled */
#define ULL_SCAN_IS_PASSIVE BIT(0)
#define ULL_SCAN_IS_ACTIVE BIT(1)
#define ULL_SCAN_IS_INITIATOR BIT(2)
#define ULL_SCAN_IS_SYNC BIT(3)
uint32_t ull_scan_is_enabled(uint8_t handle);
/* Return filter policy used */

View File

@@ -1524,8 +1524,11 @@ static void deferred_work(struct k_work *work)
struct bt_conn *iso;
if (conn->type == BT_CONN_TYPE_ISO) {
/* bt_iso_disconnected is responsible for unref'ing the
* connection pointer, as it is conditional on whether
* the connection is a central or peripheral.
*/
bt_iso_disconnected(conn);
bt_conn_unref(conn);
return;
}

View File

@@ -70,6 +70,11 @@ struct gatt_sub {
#define SUB_MAX 0
#endif /* CONFIG_BT_GATT_CLIENT */
/**
* Entry x is free for reuse whenever (subscriptions[x].peer == BT_ADDR_LE_ANY).
* Invariant: (sys_slist_is_empty(subscriptions[x].list))
* <=> (subscriptions[x].peer == BT_ADDR_LE_ANY).
*/
static struct gatt_sub subscriptions[SUB_MAX];
static sys_slist_t callback_list;
@@ -2699,6 +2704,19 @@ bool bt_gatt_is_subscribed(struct bt_conn *conn,
return false;
}
static bool gatt_sub_is_empty(struct gatt_sub *sub)
{
return sys_slist_is_empty(&sub->list);
}
/** @brief Free sub for reuse.
*/
static void gatt_sub_free(struct gatt_sub *sub)
{
__ASSERT_NO_MSG(gatt_sub_is_empty(sub));
bt_addr_le_copy(&sub->peer, BT_ADDR_LE_ANY);
}
static void gatt_sub_remove(struct bt_conn *conn, struct gatt_sub *sub,
sys_snode_t *prev,
struct bt_gatt_subscribe_params *params)
@@ -2710,9 +2728,8 @@ static void gatt_sub_remove(struct bt_conn *conn, struct gatt_sub *sub,
params->notify(conn, params, NULL, 0);
}
if (sys_slist_is_empty(&sub->list)) {
/* Reset address if there are no subscription left */
bt_addr_le_copy(&sub->peer, BT_ADDR_LE_ANY);
if (gatt_sub_is_empty(sub)) {
gatt_sub_free(sub);
}
}
@@ -4597,6 +4614,10 @@ int bt_gatt_unsubscribe(struct bt_conn *conn,
return -EINVAL;
}
if (gatt_sub_is_empty(sub)) {
gatt_sub_free(sub);
}
if (has_subscription) {
/* Notify with NULL data to complete unsubscribe */
params->notify(conn, params, NULL, 0);
@@ -4757,7 +4778,14 @@ static int ccc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
} else if (!next) {
load.addr_with_id.id = BT_ID_DEFAULT;
} else {
load.addr_with_id.id = strtol(next, NULL, 10);
unsigned long next_id = strtoul(next, NULL, 10);
if (next_id >= CONFIG_BT_ID_MAX) {
BT_ERR("Invalid local identity %lu", next_id);
return -EINVAL;
}
load.addr_with_id.id = (uint8_t)next_id;
}
err = bt_settings_decode_key(name, &addr);
@@ -5138,7 +5166,14 @@ static int sc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
if (!next) {
id = BT_ID_DEFAULT;
} else {
id = strtol(next, NULL, 10);
unsigned long next_id = strtoul(next, NULL, 10);
if (next_id >= CONFIG_BT_ID_MAX) {
BT_ERR("Invalid local identity %lu", next_id);
return -EINVAL;
}
id = (uint8_t)next_id;
}
cfg = find_sc_cfg(id, &addr);
@@ -5216,7 +5251,14 @@ static int cf_set(const char *name, size_t len_rd, settings_read_cb read_cb,
if (!next) {
id = BT_ID_DEFAULT;
} else {
id = strtol(next, NULL, 10);
unsigned long next_id = strtoul(next, NULL, 10);
if (next_id >= CONFIG_BT_ID_MAX) {
BT_ERR("Invalid local identity %lu", next_id);
return -EINVAL;
}
id = (uint8_t)next_id;
}
cfg = find_cf_cfg_by_addr(id, &addr);

View File

@@ -656,7 +656,7 @@ static int hci_id_add(uint8_t id, const bt_addr_le_t *addr, uint8_t peer_irk[16]
memcpy(cp->peer_irk, peer_irk, 16);
#if defined(CONFIG_BT_PRIVACY)
memcpy(cp->local_irk, bt_dev.irk[id], 16);
(void)memcpy(cp->local_irk, &bt_dev.irk[id], 16);
#else
(void)memset(cp->local_irk, 0, 16);
#endif
@@ -1636,6 +1636,7 @@ int bt_le_oob_get_local(uint8_t id, struct bt_le_oob *oob)
}
if (IS_ENABLED(CONFIG_BT_OBSERVER) &&
CONFIG_BT_ID_MAX > 1 &&
id != BT_ID_DEFAULT &&
(atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) ||
atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING))) {

View File

@@ -374,7 +374,14 @@ static int keys_set(const char *name, size_t len_rd, settings_read_cb read_cb,
if (!next) {
id = BT_ID_DEFAULT;
} else {
id = strtol(next, NULL, 10);
unsigned long next_id = strtoul(next, NULL, 10);
if (next_id >= CONFIG_BT_ID_MAX) {
BT_ERR("Invalid local identity %lu", next_id);
return -EINVAL;
}
id = (uint8_t)next_id;
}
if (!len) {

View File

@@ -64,6 +64,10 @@ int bt_mesh_msg_ack_ctx_wait(struct bt_mesh_msg_ack_ctx *ack, k_timeout_t timeou
err = k_sem_take(&ack->sem, timeout);
bt_mesh_msg_ack_ctx_clear(ack);
if (err == -EAGAIN) {
return -ETIMEDOUT;
}
return err;
}

View File

@@ -24,7 +24,7 @@
#include "bt.h"
int cmd_ll_addr_get(const struct shell *sh, size_t argc, char *argv[])
int cmd_ll_addr_read(const struct shell *sh, size_t argc, char *argv[])
{
uint8_t addr_type;
const char *str_type;
@@ -44,7 +44,7 @@ int cmd_ll_addr_get(const struct shell *sh, size_t argc, char *argv[])
return -EINVAL;
}
(void)ll_addr_get(addr_type, addr.val);
(void)ll_addr_read(addr_type, addr.val);
bt_addr_to_str(&addr, str_addr, sizeof(str_addr));
shell_print(sh, "Current %s address: %s", str_type, str_addr);

View File

@@ -13,7 +13,7 @@
#ifndef __LL_H
#define __LL_H
int cmd_ll_addr_get(const struct shell *sh, size_t argc, char *argv[]);
int cmd_ll_addr_read(const struct shell *sh, size_t argc, char *argv[]);
int cmd_advx(const struct shell *sh, size_t argc, char *argv[]);
int cmd_scanx(const struct shell *sh, size_t argc, char *argv[]);

View File

@@ -98,8 +98,8 @@ struct mpsc_pbuf_buffer log_buffer;
static uint32_t __aligned(Z_LOG_MSG2_ALIGNMENT)
buf32[CONFIG_LOG_BUFFER_SIZE / sizeof(int)];
static void notify_drop(struct mpsc_pbuf_buffer *buffer,
union mpsc_pbuf_generic *item);
static void notify_drop(const struct mpsc_pbuf_buffer *buffer,
const union mpsc_pbuf_generic *item);
static const struct mpsc_pbuf_buffer_config mpsc_config = {
.buf = (uint32_t *)buf32,
@@ -859,9 +859,12 @@ bool z_log_dropped_pending(void)
return dropped_cnt > 0;
}
static void notify_drop(struct mpsc_pbuf_buffer *buffer,
union mpsc_pbuf_generic *item)
static void notify_drop(const struct mpsc_pbuf_buffer *buffer,
const union mpsc_pbuf_generic *item)
{
ARG_UNUSED(buffer);
ARG_UNUSED(item);
z_log_dropped();
}

View File

@@ -1257,11 +1257,18 @@ static int context_write_data(struct net_pkt *pkt, const void *buf,
int i;
for (i = 0; i < msghdr->msg_iovlen; i++) {
int len = MIN(msghdr->msg_iov[i].iov_len, buf_len);
ret = net_pkt_write(pkt, msghdr->msg_iov[i].iov_base,
msghdr->msg_iov[i].iov_len);
len);
if (ret < 0) {
break;
}
buf_len -= len;
if (buf_len == 0) {
break;
}
}
} else {
ret = net_pkt_write(pkt, buf, buf_len);

View File

@@ -159,6 +159,17 @@ config MDNS_RESPONDER_DNS_SD
By doing so, Zephyr network services are discoverable
using e.g. 'avahi-browse -t -r _greybus._tcp'.
if MDNS_RESPONDER_DNS_SD
config MDNS_RESPONDER_DNS_SD_SERVICE_TYPE_ENUMERATION
bool "Enable DNS SD Service Type Enumeration"
default y
help
Selecting this option ensures that the MDNS Responder
performs DNS-SD Service Type Enumeration according to RFC 6763,
Chapter 9. By doing so, Zephyr network services are discoverable
using e.g. 'avahi-browse -t -r _services._dns-sd._udp.local'.
endif # MDNS_RESPONDER_DNS_SD
module = MDNS_RESPONDER
module-dep = NET_LOG
module-str = Log level for mDNS responder

View File

@@ -25,6 +25,7 @@
LOG_MODULE_REGISTER(net_dns_sd, CONFIG_DNS_SD_LOG_LEVEL);
const char dns_sd_empty_txt[1];
const uint16_t dns_sd_port_zero;
#ifndef CONFIG_NET_TEST
@@ -699,9 +700,9 @@ static inline bool port_in_use(uint16_t proto, uint16_t port, const struct in_ad
}
#endif /* CONFIG_NET_TEST */
int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst,
const struct in_addr *addr4, const struct in6_addr *addr6,
uint8_t *buf, uint16_t buf_size)
int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst, const struct in_addr *addr4,
const struct in6_addr *addr6, uint8_t *buf, uint16_t buf_size)
{
/*
* RFC 6763 Section 12.1
@@ -734,9 +735,8 @@ int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst,
}
if (*(inst->port) == 0) {
NET_DBG("Ephemeral port %u for %s.%s.%s.%s "
"not initialized", ntohs(*(inst->port)),
inst->instance, inst->service, inst->proto,
NET_DBG("Ephemeral port %u for %s.%s.%s.%s not initialized",
ntohs(*(inst->port)), inst->instance, inst->service, inst->proto,
inst->domain);
return -EHOSTDOWN;
}
@@ -756,10 +756,8 @@ int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst,
}
/* first add the answer record */
r = add_ptr_record(inst, DNS_SD_PTR_TTL, buf, offset,
buf_size - offset,
&service_offset, &instance_offset,
&domain_offset);
r = add_ptr_record(inst, DNS_SD_PTR_TTL, buf, offset, buf_size - offset, &service_offset,
&instance_offset, &domain_offset);
if (r < 0) {
return r; /* LCOV_EXCL_LINE */
}
@@ -768,9 +766,7 @@ int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst,
offset += r;
/* then add the additional records */
r = add_txt_record(inst, DNS_SD_TXT_TTL, instance_offset, buf,
offset,
buf_size - offset);
r = add_txt_record(inst, DNS_SD_TXT_TTL, instance_offset, buf, offset, buf_size - offset);
if (r < 0) {
return r; /* LCOV_EXCL_LINE */
}
@@ -778,9 +774,8 @@ int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst,
rsp->arcount++;
offset += r;
r = add_srv_record(inst, DNS_SD_SRV_TTL, instance_offset,
domain_offset,
buf, offset, buf_size - offset, &host_offset);
r = add_srv_record(inst, DNS_SD_SRV_TTL, instance_offset, domain_offset, buf, offset,
buf_size - offset, &host_offset);
if (r < 0) {
return r; /* LCOV_EXCL_LINE */
}
@@ -789,12 +784,10 @@ int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst,
offset += r;
if (addr6 != NULL) {
r = add_aaaa_record(inst, DNS_SD_AAAA_TTL, host_offset,
addr6->s6_addr,
buf, offset,
r = add_aaaa_record(inst, DNS_SD_AAAA_TTL, host_offset, addr6->s6_addr, buf, offset,
buf_size - offset); /* LCOV_EXCL_LINE */
if (r < 0) {
return r; /* LCOV_EXCL_LINE */
return r; /* LCOV_EXCL_LINE */
}
rsp->arcount++;
@@ -803,8 +796,7 @@ int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst,
if (addr4 != NULL) {
tmp = htonl(*(addr4->s4_addr32));
r = add_a_record(inst, DNS_SD_A_TTL, host_offset,
tmp, buf, offset,
r = add_a_record(inst, DNS_SD_A_TTL, host_offset, tmp, buf, offset,
buf_size - offset);
if (r < 0) {
return r; /* LCOV_EXCL_LINE */
@@ -822,6 +814,93 @@ int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst,
return offset;
}
int dns_sd_handle_service_type_enum(const struct dns_sd_rec *inst,
const struct in_addr *addr4, const struct in6_addr *addr6,
uint8_t *buf, uint16_t buf_size)
{
static const char query[] = { "\x09_services\x07_dns-sd\x04_udp\x05local" };
/* offset of '.local' in the above */
uint16_t domain_offset = DNS_SD_PTR_MASK | 35;
uint16_t proto;
int name_size;
uint16_t service_size;
uint16_t offset = sizeof(struct dns_header);
struct dns_rr *rr;
struct dns_header *const rsp = (struct dns_header *)buf;
if (!rec_is_valid(inst)) {
return -EINVAL;
}
if (*(inst->port) == 0) {
NET_DBG("Ephemeral port %u for %s.%s.%s.%s "
"not initialized",
ntohs(*(inst->port)), inst->instance, inst->service, inst->proto,
inst->domain);
return -EHOSTDOWN;
}
if (strncmp("_tcp", inst->proto, DNS_SD_PROTO_SIZE) == 0) {
proto = IPPROTO_TCP;
} else if (strncmp("_udp", inst->proto, DNS_SD_PROTO_SIZE) == 0) {
proto = IPPROTO_UDP;
} else {
NET_DBG("invalid protocol %s", inst->proto);
return -EINVAL;
}
if (!port_in_use(proto, ntohs(*(inst->port)), addr4, addr6)) {
/* Service is not yet bound, so do not advertise */
return -EHOSTDOWN;
}
service_size = strlen(inst->service);
name_size =
/* uncompressed. e.g. "._foo._tcp.local." */
sizeof(query)
+ sizeof(*rr)
/* compressed e.g. ._googlecast._tcp" followed by (DNS_SD_PTR_MASK | 0x0abc) */
+ DNS_LABEL_LEN_SIZE + service_size
+ DNS_LABEL_LEN_SIZE + DNS_SD_PROTO_SIZE
+ DNS_POINTER_SIZE;
if (offset > buf_size || name_size >= buf_size - offset) {
NET_DBG("Buffer too small. required: %u available: %d", name_size,
(int)buf_size - (int)offset);
return -ENOSPC;
}
memset(rsp, 0, sizeof(*rsp));
memcpy(&buf[offset], query, sizeof(query));
offset += sizeof(query);
rr = (struct dns_rr *)&buf[offset];
rr->type = htons(DNS_RR_TYPE_PTR);
rr->class_ = htons(DNS_CLASS_IN);
rr->ttl = htonl(DNS_SD_PTR_TTL);
rr->rdlength = htons(0
+ DNS_LABEL_LEN_SIZE + service_size
+ DNS_LABEL_LEN_SIZE + DNS_SD_PROTO_SIZE
+ DNS_POINTER_SIZE);
offset += sizeof(*rr);
buf[offset++] = service_size;
memcpy(&buf[offset], inst->service, service_size);
offset += service_size;
buf[offset++] = DNS_SD_PROTO_SIZE;
memcpy(&buf[offset], inst->proto, DNS_SD_PROTO_SIZE);
offset += DNS_SD_PROTO_SIZE;
domain_offset = htons(domain_offset);
memcpy(&buf[offset], &domain_offset, sizeof(domain_offset));
offset += sizeof(domain_offset);
/* Set the Response and AA bits */
rsp->flags = htons(BIT(15) | BIT(10));
rsp->ancount = htons(1);
return offset;
}
/* TODO: dns_sd_handle_srv_query() */
/* TODO: dns_sd_handle_txt_query() */
@@ -893,82 +972,202 @@ bool dns_sd_rec_match(const struct dns_sd_rec *record,
return true;
}
int dns_sd_extract_service_proto_domain(const uint8_t *query,
size_t query_size, struct dns_sd_rec *record, char *service,
size_t service_size, char *proto, size_t proto_size, char *domain,
size_t domain_size)
int dns_sd_query_extract(const uint8_t *query, size_t query_size, struct dns_sd_rec *record,
char **label, size_t *size, size_t *n)
{
uint16_t offs;
uint8_t label_size;
size_t i;
size_t offset;
size_t qlabels;
size_t qsize;
const size_t N = (n) ? (*n) : 0;
if (query == NULL || record == NULL || service == NULL
|| proto == NULL || domain == NULL) {
NET_DBG("one or more arguments are NULL");
/*
* See RFC 6763, 7.2. Service Name Length Limits
*
* <sn>._tcp.<servicedomain>.<parentdomain>.
* <Instance>.<sn>._tcp.<servicedomain>.<parentdomain>.
* <sub>._sub.<sn>._tcp.<servicedomain>.<parentdomain>.
*/
__ASSERT(DNS_SD_MIN_LABELS <= N, "invalid number of labels %zu", N);
__ASSERT(!(query == NULL || label == NULL || size == NULL || n == NULL),
"one or more required arguments are NULL");
__ASSERT(query + query_size >= query, "query %p + query_size %zu wraps NULL", query,
query_size);
__ASSERT(label + N >= label, "label %p + n %zu wraps NULL", label, N);
__ASSERT(size + N >= size, "size %p + n %zu wraps NULL", size, N);
for (i = 0; i < N; ++i) {
if (label[i] == NULL) {
__ASSERT(label[i] != NULL, "label[%zu] is NULL", i);
}
}
if (query_size <= DNS_MSG_HEADER_SIZE) {
NET_DBG("query size %zu is less than DNS_MSG_HEADER_SIZE %d", query_size,
DNS_MSG_HEADER_SIZE);
return -EINVAL;
}
if (query_size <= DNS_MSG_HEADER_SIZE
|| service_size < DNS_SD_SERVICE_MAX_SIZE + 1
|| proto_size < DNS_SD_PROTO_SIZE + 1
|| domain_size < DNS_SD_DOMAIN_MAX_SIZE + 1
) {
NET_DBG("one or more size arguments are too small");
return -EINVAL;
query += DNS_MSG_HEADER_SIZE;
query_size -= DNS_MSG_HEADER_SIZE;
offset = DNS_MSG_HEADER_SIZE;
dns_sd_create_wildcard_filter(record);
/* valid record must have non-NULL port */
record->port = &dns_sd_port_zero;
/* also counts labels */
for (i = 0, qlabels = 0; query_size > 0;) {
qsize = *query;
++offset;
++query;
--query_size;
if (qsize == 0) {
break;
}
++qlabels;
if (qsize >= query_size) {
NET_DBG("claimed query size %zu > query buffer size %zu", qsize,
query_size);
return -EINVAL;
}
if (qsize > size[i] - 1) {
NET_DBG("qsize %zu > size[%zu] - 1 %zu", qsize, i, size[i] - 1);
return -ENOBUFS;
}
if (i < N) {
/* only extract the label if there is storage for it */
memcpy(label[i], query, qsize);
label[i][qsize] = '\0';
size[i] = qsize;
++i;
}
offset += qsize;
query += qsize;
query_size -= qsize;
}
memset(record, 0, sizeof(*record));
offs = DNS_MSG_HEADER_SIZE;
/* Copy service label to '\0'-terminated buffer */
label_size = query[offs];
if (label_size == 0 || label_size > service_size - 1
|| offs + label_size > query_size) {
NET_DBG("could not get service");
return -EINVAL;
} else {
strncpy(service, &query[offs + 1], label_size);
service[label_size] = '\0';
offs += label_size + 1;
/* write-out the actual number of labels in 'n' */
for (*n = i; i < N; ++i) {
label[i] = NULL;
size[i] = 0;
}
/* Copy proto label to '\0'-terminated buffer */
label_size = query[offs];
if (label_size == 0 || label_size > proto_size - 1
|| offs + label_size > query_size) {
NET_DBG("could not get proto for '%s...'", log_strdup(service));
if (qlabels < DNS_SD_MIN_LABELS) {
NET_DBG("too few labels in query %zu, DNS_SD_MIN_LABELS: %d", qlabels,
DNS_SD_MIN_LABELS);
return -EINVAL;
} else {
strncpy(proto, &query[offs + 1], label_size);
proto[label_size] = '\0';
offs += label_size + 1;
} else if (qlabels == DNS_SD_MIN_LABELS) {
/* e.g. _zephyr._tcp.local */
record->service = label[0];
record->proto = label[1];
record->domain = label[2];
if (!service_is_valid(record->service)) {
NET_DBG("service '%s' is invalid", record->service);
return -EINVAL;
}
if (!proto_is_valid(record->proto)) {
NET_DBG("proto '%s' is invalid", record->proto);
return -EINVAL;
}
if (!domain_is_valid(record->domain)) {
NET_DBG("domain '%s' is invalid", record->domain);
return -EINVAL;
}
} else if (qlabels > DNS_SD_MIN_LABELS && qlabels < DNS_SD_MAX_LABELS) {
NET_DBG("unsupported number of labels %zu", qlabels);
return -EINVAL;
} else if (qlabels >= DNS_SD_MAX_LABELS) {
/* e.g.
* "Zephyr 42"._zephyr._tcp.local, or
* _domains._dns-sd._udp.local
*/
record->instance = label[0];
record->service = label[1];
record->proto = label[2];
record->domain = label[3];
if (!instance_is_valid(record->instance)) {
NET_DBG("service '%s' is invalid", record->instance);
return -EINVAL;
}
if (!service_is_valid(record->service)) {
NET_DBG("service '%s' is invalid", record->service);
return -EINVAL;
}
if (!proto_is_valid(record->proto)) {
NET_DBG("proto '%s' is invalid", record->proto);
return -EINVAL;
}
if (!domain_is_valid(record->domain)) {
NET_DBG("domain '%s' is invalid", record->domain);
return -EINVAL;
}
} else if (qlabels > N) {
NET_DBG("too few buffers to extract query: qlabels: %zu, N: %zu",
qlabels, N);
return -ENOBUFS;
}
/* Copy domain label to '\0'-terminated buffer */
label_size = query[offs];
if (label_size == 0 || label_size > domain_size - 1
|| offs + label_size > query_size) {
NET_DBG("could not get domain for '%s.%s...'",
log_strdup(service), log_strdup(proto));
return -EINVAL;
} else {
strncpy(domain, &query[offs + 1], label_size);
domain[label_size] = '\0';
offs += label_size + 1;
}
/* Check that we have reached the DNS terminator */
if (query[offs] != 0) {
NET_DBG("ignoring request for '%s.%s.%s...'",
log_strdup(service),
log_strdup(proto),
log_strdup(domain));
return -EINVAL;
}
offs++;
record->service = service;
record->proto = proto;
record->domain = domain;
return offs;
return offset;
}
int dns_sd_extract_service_proto_domain(const uint8_t *query, size_t query_size,
struct dns_sd_rec *record, char *service,
size_t service_size, char *proto, size_t proto_size,
char *domain, size_t domain_size)
{
char instance[DNS_SD_INSTANCE_MAX_SIZE + 1];
char *label[4];
size_t size[] = {
ARRAY_SIZE(instance),
service_size,
proto_size,
domain_size,
};
size_t n = ARRAY_SIZE(label);
BUILD_ASSERT(ARRAY_SIZE(label) == ARRAY_SIZE(size),
"label and size arrays are different size");
/*
* work around for bug in compliance scripts which say that the array
* should be static const (incorrect)
*/
label[0] = instance;
label[1] = service;
label[2] = proto;
label[3] = domain;
return dns_sd_query_extract(query, query_size, record, label, size, &n);
}
bool dns_sd_is_service_type_enumeration(const struct dns_sd_rec *rec)
{
static const struct dns_sd_rec filter = {
.instance = "_services",
.service = "_dns-sd",
.proto = "_udp",
.domain = "local",
};
return dns_sd_rec_match(rec, &filter);
}
void dns_sd_create_wildcard_filter(struct dns_sd_rec *filter)
{
if (filter != NULL) {
memset(filter, 0, sizeof(*filter));
filter->text = dns_sd_empty_txt;
filter->text_size = sizeof(dns_sd_empty_txt);
}
}

View File

@@ -32,6 +32,35 @@ extern "C" {
#define DNS_SD_FOREACH(it) \
STRUCT_SECTION_FOREACH(dns_sd_rec, it)
/**
* @brief Extract labels from a DNS-SD PTR query
*
* ```
* <sn>._tcp.<domain>.
* <instance>.<sn>._tcp.<domain>.
* ```
*
* Currently sub-types and service domains are unsupported and only the
* "local" domain is supported. Specifically, that excludes the following:
* ```
* <sub>._sub.<sn>._tcp.<servicedomain>.<parentdomain>.
* ```
*
* @param query a pointer to the start of the query
* @param query_size the number of bytes contained in the query
* @param[out] record the DNS-SD record to initialize and populate
* @param label array of pointers to suitably sized buffers
* @param size array of sizes for each buffer in @p label
* @param[inout] n number of elements in @p label and @p size
*
* @return on success, number of bytes read from @p query
* @return on failure, a negative errno value
*
* @see <a href="https://datatracker.ietf.org/doc/html/rfc6763">RFC 6763</a>, Section 7.2.
*/
int dns_sd_query_extract(const uint8_t *query, size_t query_size, struct dns_sd_rec *record,
char **label, size_t *size, size_t *n);
/**
* @brief Extract the Service, Protocol, and Domain from a DNS-SD PTR query
*
@@ -57,6 +86,7 @@ extern "C" {
* @return on success, a positive number representing length of the query
* @return on failure, a negative errno value
*/
__deprecated
int dns_sd_extract_service_proto_domain(const uint8_t *query,
size_t query_size, struct dns_sd_rec *record, char *service,
size_t service_size, char *proto, size_t proto_size,
@@ -121,7 +151,7 @@ bool dns_sd_rec_match(const struct dns_sd_rec *record,
* If there is no IPv6 address to advertise, then @p addr6 should be
* NULL.
*
* @param inst the DNS-SD record for to advertise
* @param inst the DNS-SD record to advertise
* @param addr4 pointer to the IPv4 address
* @param addr6 pointer to the IPv6 address
* @param buf output buffer
@@ -134,6 +164,24 @@ int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst,
const struct in_addr *addr4, const struct in6_addr *addr6,
uint8_t *buf, uint16_t buf_size);
/**
* @brief Handle a Service Type Enumeration with DNS Service Discovery
*
* This function should be called once for each type of advertised service.
*
* @param service the DNS-SD service to advertise
* @param addr4 pointer to the IPv4 address
* @param addr6 pointer to the IPv6 address
* @param buf output buffer
* @param buf_size size of the output buffer
*
* @return on success, number of bytes written to @p buf
* @return on failure, a negative errno value
*/
int dns_sd_handle_service_type_enum(const struct dns_sd_rec *service,
const struct in_addr *addr4, const struct in6_addr *addr6,
uint8_t *buf, uint16_t buf_size);
#ifdef __cplusplus
};
#endif

View File

@@ -306,11 +306,32 @@ static void send_sd_response(struct net_context *ctx,
struct dns_sd_rec filter;
struct sockaddr dst;
socklen_t dst_len;
bool service_type_enum = false;
const struct in6_addr *addr6 = NULL;
const struct in_addr *addr4 = NULL;
char instance_buf[DNS_SD_SERVICE_MAX_SIZE + 1];
char service_buf[DNS_SD_SERVICE_MAX_SIZE + 1];
char proto_buf[DNS_SD_PROTO_SIZE + 1];
char domain_buf[DNS_SD_DOMAIN_MAX_SIZE + 1];
char *label[4];
size_t size[] = {
ARRAY_SIZE(instance_buf),
ARRAY_SIZE(service_buf),
ARRAY_SIZE(proto_buf),
ARRAY_SIZE(domain_buf),
};
size_t n = ARRAY_SIZE(label);
BUILD_ASSERT(ARRAY_SIZE(label) == ARRAY_SIZE(size), "");
/*
* work around for bug in compliance scripts which say that the array
* should be static const (incorrect)
*/
label[0] = instance_buf;
label[1] = service_buf;
label[2] = proto_buf;
label[3] = domain_buf;
/* This actually is used but the compiler doesn't see that */
ARG_UNUSED(record);
@@ -333,14 +354,28 @@ static void send_sd_response(struct net_context *ctx,
&ip_hdr->ipv6->src);
}
ret = dns_sd_extract_service_proto_domain(dns_msg->msg,
dns_msg->msg_size, &filter, service_buf, sizeof(service_buf),
proto_buf, sizeof(proto_buf), domain_buf, sizeof(domain_buf));
ret = dns_sd_query_extract(dns_msg->msg,
dns_msg->msg_size, &filter, label, size, &n);
if (ret < 0) {
NET_DBG("unable to extract service.proto.domain (%d)", ret);
NET_DBG("unable to extract query (%d)", ret);
return;
}
if (IS_ENABLED(CONFIG_MDNS_RESPONDER_DNS_SD_SERVICE_TYPE_ENUMERATION)
&& dns_sd_is_service_type_enumeration(&filter)) {
/*
* RFC 6763, Section 9
*
* A DNS query for PTR records with the name
* "_services._dns-sd._udp.<Domain>" yields a set of PTR records,
* where the rdata of each PTR record is the two-label <Service> name,
* plus the same domain, e.g., "_http._tcp.<Domain>".
*/
dns_sd_create_wildcard_filter(&filter);
service_type_enum = true;
}
DNS_SD_FOREACH(record) {
/* Checks validity and then compare */
if (dns_sd_rec_match(record, &filter)) {
@@ -350,13 +385,21 @@ static void send_sd_response(struct net_context *ctx,
ntohs(*(record->port)));
/* Construct the response */
ret = dns_sd_handle_ptr_query(record,
addr4, addr6,
result->data, result->size);
if (ret < 0) {
NET_DBG("dns_sd_handle_ptr_query() failed (%d)",
ret);
continue;
if (service_type_enum) {
ret = dns_sd_handle_service_type_enum(record, addr4, addr6,
result->data, result->size);
if (ret < 0) {
NET_DBG("dns_sd_handle_service_type_enum() failed (%d)",
ret);
continue;
}
} else {
ret = dns_sd_handle_ptr_query(record, addr4, addr6,
result->data, result->size);
if (ret < 0) {
NET_DBG("dns_sd_handle_ptr_query() failed (%d)", ret);
continue;
}
}
result->len = ret;

Some files were not shown because too many files have changed in this diff Show More