Compare commits
71 Commits
v3.4-branc
...
v2.7.0-rc4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa8c3fa22e | ||
|
|
5a5eaa3c58 | ||
|
|
efd77e0958 | ||
|
|
b3affe6b94 | ||
|
|
5969c3b941 | ||
|
|
6db7778c81 | ||
|
|
bd6523195c | ||
|
|
701c560901 | ||
|
|
b24bbad815 | ||
|
|
a7baa3628d | ||
|
|
7aee51ea82 | ||
|
|
7c62429a75 | ||
|
|
82f3165b79 | ||
|
|
e858321f83 | ||
|
|
d2c5f05b1b | ||
|
|
708951ecd2 | ||
|
|
ad2b77e7f8 | ||
|
|
eb85f9a47e | ||
|
|
9ad64e8809 | ||
|
|
cf112e2a06 | ||
|
|
0ad4b4438a | ||
|
|
f7d0ae5e6c | ||
|
|
a084ec5483 | ||
|
|
c3fac651ee | ||
|
|
30eadf758a | ||
|
|
1a42926317 | ||
|
|
30b24920e8 | ||
|
|
41654b0dba | ||
|
|
17c5a7c89e | ||
|
|
0d4db6b952 | ||
|
|
e24df5272a | ||
|
|
a3e8f83e6b | ||
|
|
e8929c3360 | ||
|
|
7597eef8b3 | ||
|
|
9ff7cb60fc | ||
|
|
71420c6b76 | ||
|
|
519f412ce8 | ||
|
|
c0e44d9462 | ||
|
|
47f4ddafdd | ||
|
|
1a15d367e2 | ||
|
|
7ac8c2f51b | ||
|
|
4c52fb9fd1 | ||
|
|
cb657057b3 | ||
|
|
69996900c8 | ||
|
|
70979b9047 | ||
|
|
e601ca8e11 | ||
|
|
369d5d038f | ||
|
|
27a2271093 | ||
|
|
f4a03dfa32 | ||
|
|
192cad6cda | ||
|
|
1e2c698e95 | ||
|
|
0c0a990c4b | ||
|
|
dbf08a18c3 | ||
|
|
6c4d190493 | ||
|
|
5d0100e12c | ||
|
|
b11983d71a | ||
|
|
8691e3e0d2 | ||
|
|
c1fa585917 | ||
|
|
8a9c1e7721 | ||
|
|
8a0dc430b2 | ||
|
|
e6638715d9 | ||
|
|
5b78f62138 | ||
|
|
01be872f01 | ||
|
|
317749e1e8 | ||
|
|
7d3606a74a | ||
|
|
08917e0708 | ||
|
|
b868419ac7 | ||
|
|
16efab0493 | ||
|
|
916dbab23a | ||
|
|
62680344a6 | ||
|
|
d8ee47459c |
2
VERSION
2
VERSION
@@ -2,4 +2,4 @@ VERSION_MAJOR = 2
|
||||
VERSION_MINOR = 7
|
||||
PATCHLEVEL = 0
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = rc3
|
||||
EXTRAVERSION = rc4
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -12,6 +12,3 @@ CONFIG_HW_STACK_PROTECTION=y
|
||||
|
||||
# Enable GPIO
|
||||
CONFIG_GPIO=y
|
||||
|
||||
# Enable console
|
||||
CONFIG_CONSOLE=y
|
||||
|
||||
BIN
boards/x86/acrn/doc/ACRN-Hybrid.png
Normal file
BIN
boards/x86/acrn/doc/ACRN-Hybrid.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 113 KiB |
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
***
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_PHY_GENERIC_MII phy_mii.c)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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; \
|
||||
} \
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -3,6 +3,4 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
zephyr_library()
|
||||
|
||||
zephyr_include_directories(.)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
CONFIG_GPIO=y
|
||||
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_DEVICE=y
|
||||
CONFIG_PM_DEVICE_RUNTIME=y
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
CONFIG_NET_DRIVERS=y
|
||||
CONFIG_NET_PPP=y
|
||||
CONFIG_NET_L2_PPP=y
|
||||
CONFIG_NET_STATISTICS_PPP=y
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_GPIO=y
|
||||
|
||||
# OSDP config
|
||||
CONFIG_OSDP=y
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_GPIO=y
|
||||
|
||||
# OSDP config
|
||||
CONFIG_OSDP=y
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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?
|
||||
*/
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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[]);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user