Compare commits

...

81 Commits

Author SHA1 Message Date
Anas Nashif
a7dcd9d827 release: Zephyr 1.9.2
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-11-19 08:20:47 -05:00
Carles Cufi
2741498afc doc: 1.9.x release notes
Release notes for the following Zephyr kernel versions:

* 1.9.1
* 1.9.2

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-11-19 08:20:47 -05:00
Vinayak Kariappa Chettimada
44e8b69ecd Bluetooth: controller: Fix diff proc collision with enc proc
Fixes the following conformance test regression failure
introduced in commit 7dd5fbee26 ("Bluetooth: controller:
Fix MIC error due to parallel Enc Proc")

TP/CON/MAS/BV-28-C [Initiating Connection Parameter Request
different procedure collision encryption]

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-11-02 18:03:39 -04:00
Vinayak Kariappa Chettimada
19f7a6f3b9 Bluetooth: controller: Fix MIC error due to parallel Enc Proc
Fix to disallow initiating LE Start Encryption while another
procedure is in progress. Similarly, disallow initiating
another procedure while Encryption procedure is in progress.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-11-02 18:03:39 -04:00
Vinayak Kariappa Chettimada
4aaf544e8c Bluetooth: controller: Fix to enable Asym PHY on nRF52 Series
Fix the controller Kconfig to enable use of fast radio ramp
up by default, hence enabling support for Asym PHY updates
by default on nRF52 Series SoCs.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-30 14:40:13 -04:00
Vinayak Kariappa Chettimada
8d9cd870e4 Bluetooth: controller: Fix Ctrl PDU Tx starvation assert
Replace all controller asserts in control procedure responses
that checked for buffer availability with an implementation
that nacks request PDUs if there are no buffer to prepare
response PDUs.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-30 14:40:13 -04:00
Vinayak Kariappa Chettimada
ed94d2adb7 Bluetooth: controller: Remove assert on invalid LL id
Remove an assert on receiving invalid LL id, drop these
invalid PDUs.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-30 14:40:13 -04:00
Johan Hedberg
4b98d72156 Bluetooth: Mesh: Fix missing feature bits
The feature bits for Proxy and Friend were missing in the composition
data and heart beat messages.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Steve Brown
46ffe456f0 Bluetooth: Mesh: heartbeat fixes for message count
Both count and period must be non-zero for message publication
Stop publication when count becomes zero
Add count to debug message in hb_publish

Signed-off-by: Steve Brown <sbrown@cortland.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
218dd04b3e Bluetooth: Mesh: Fix mod sub status parameters upon failure
Mesh Profile Specification v1.0, 4.4.1.2.8:

"When an element receives a Config Model Subscription Add message
or a Config Model Subscription Virtual Address Add message that
is not successfully processed (i.e., it results in an error condition
listed in Table 4.113), it shall respond with the Config Model
Subscription Status message, setting its fields to the values
of the corresponding fields (i.e., the identically named fields)
of the incoming message and setting the Status field to a status code
(defined in Table 4.113), and setting all other fields to 0."

The same applies to other Model Subscription messages.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
b8bbd7439d Bluetooth: Mesh: Fix potential access to uninitialized variable
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
35c025fc07 Bluetooth: Mesh: Fix missing initialization of bt_mesh.local_queue
The local_queue was never being initialized.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
439fbddbb0 Bluetooth: Mesh: Fix revoking app keys
The needed code for taking updated app keys into use and revoking the
old ones was missing.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
c67f64ed36 Bluetooth: Mesh: Fix dropping valid proxy configration messages
Proxy configuration messages are allowed (in fact required) to use
unassigned addresses, so they should be exempt from this check.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
d68d799057 Bluetooth: Mesh: Don't send health status messages if a test fails
The test failure may be e.g. because of an unknown company id, and in
that case the spec expects us to ignore the message.

With this patch it should be possible to pass MESH/SR/HM/RFS/BI-01-C.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
bda57337f2 Bluetooth: Mesh: Fix setting health period divider
A previous patch which moved dispatching the health publish callback
to a later moment introduced a regression where the period divider
does not get updated when it should. In fact, having the divider as
part of the Health Server context is redundant, since the same
information is already stored generically in the model publication
context. Switching to using the model publication context makes things
simpler and ensures that the value is always up-to-date.

With this patch it is possible to pass MESH/SR/HM/CFS/BV-02-C.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
3e2305359e Bluetooth: Mesh: Fix Set LPNTimeout message handling
We should ignore invalid addresses (helps pass
MESH/NODE/CFG/LPNPT/BI-01-C). Also fix a copy-paste issue in an error
log.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
a23d390225 Bluetooth: Mesh: Fix resetting heartbeat subscription expiry properly
Set the value clearly to 0 instead of letting the old expiry time stay
around.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
2c86d827ec Bluetooth: Mesh: Fix zeroing heartbeat state
The values all need to be zeroed when heartbeat subscription is
disabled. This makes it possible to pass MESH/NODE/CFG/HBS/BV-01-C.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
84286b67fa Bluetooth: Mesh: Fix spelling of "heartbeat"
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
9199844d5b Bluetooth: Mesh: Fix encoding fault count to Health Current Status
There was a missing adjustment to buf->len after fetching the faults
from the app.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
f7279ea0fb Bluetooth: Mesh: Fix Health Period Set OpCode
This was a copy-paste mistake.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
271da26813 Bluetooth: Mesh: Remove local network interface Kconfig option
From section 3.4.5.3 in the Mesh Profile Specification 1.0:

    "A node shall implement a Local Network Interface."

Removing the Kconfig option also helps clean up quite a lot of code.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
061e8096be Bluetooth: Mesh: Allow TTL <= 1 for the local net interface
The bt_mesh_net_relay() function needs to allow TTL <= 1 for the local
network interface since that's the code path that locally originated
outgoing packets take.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
06c1d01a4d Bluetooth: Mesh: Send ack for every message with matching FCS
Mesh Profile Specification v1.0, 5.3.3:

"On the PB-ADV bearer, when the receiver has received all segments of
a transaction, the receiver shall calculate the FCS for the received
Provisioning PDU, and if it matches the FCS field in the Transaction
Start PDU, it shall send a Transaction Acknowledgment PDU after
a random delay between 20 and 50 milliseconds."

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
1f689c6f2e Bluetooth: Mesh: Always set company ID in health status message
The Mesh specification recommends defaulting to the company ID in the
composition data when no other ID is relevant (e.g. in error cases or
if the app has not provided a callback).

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
bddd8f4b37 Bluetooth: Mesh: Set timer for periodic publish before publishing
Encrypting and sending a message takes a considerable amount of time
which makes the publication period longer than expected.

With this patch it is possible to pass MESH/SR/HM/CFS/BV-02-C test.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
6e2eba45d0 Bluetooth: Mesh: Fix encoding health status when app has no callback
The branch for handling the case when the app has not provided a
callback for health faults was encoding the payload in a wrong way.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
14c96b17a2 Bluetooth: Mesh: Fix copy-paste mistake when assigning to cfg->frnd
The right value is BT_MESH_FRIEND_NOT_SUPPORTED.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
a78b466c1e Bluetooth: Mesh: Drop invalid destination addresses
This is required to pass certain PTS tests.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
971080ca44 Bluetooth: Mesh: Fix SDU length check
The code was passing the wrong first parameter to the sdu_len_is_ok()
function.

Fixes #3985
Fixes #3984

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Johan Hedberg
92f5487d07 Bluetooth: Mesh: Fix string signedness issue
Some compilers (like icx) may complain about unsigned vs signed
strings.

Fixes #3985

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-10-19 05:34:48 -04:00
Luiz Augusto von Dentz
051a5406ae tests: fifo: Add prj_poll.conf
This enables testing k_fifo test with CONFIG_POLL=y.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2017-10-18 16:38:57 -04:00
Luiz Augusto von Dentz
49ead11a00 queue: k_queue_cancel_wait: Fix not interrupting other threads
When k_poll is being used k_queue_cancel_wait shall mark the state as
K_POLL_STATE_NOT_READY so other threads will get properly notified with
a NULL pointer return.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2017-10-18 16:38:57 -04:00
Luiz Augusto von Dentz
0cc21ad9ba poll: k_poll: Return -EINTR if not ready
In case _handle_obj_poll_events is called with K_POLL_STATE_NOT_READY
set -EINTR as return to the poller thread.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2017-10-18 16:38:57 -04:00
Luiz Augusto von Dentz
ea6cf668c0 queue: k_queue_get: Fix NULL return
k_queue_get shall never return NULL when timeout is K_FOREVER which can
happen when a higher priority thread cancel/take an item before the
waiting thread.

Fixes issue #4358

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2017-10-18 16:38:57 -04:00
Paul Sokolovsky
2341411c39 kernel: queue: k_queue_poll: Fix slist access race condition
All sys_slist_*() functions aren't threadsafe and calls to them
must be protected with irq_lock. This is usually done in a wider
caller context, but k_queue_poll() is called with irq_lock already
relinquished, and is thus subject to hard to detect and explain
race conditions, as e.g. was tracked in #4022.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2017-10-18 16:38:57 -04:00
Carles Cufi
4195177a9b Bluetooth: controller: Fix flow control packet drop
The main purpose of recv_thread is to process incoming events from the
radio and also any buffered items waiting to be dispatched to the Host
and that are pending because of lack of Host buffers.
When an iteration of the recv_thread obtains a element from the radio it
needs to process it immediately, either sending it straight away to the
Host or appending it to the queue. This was not the case before this
patch, where the concurrency of a buffered packet with one coming from
the radio would cause the latter to be "dropped", causing missing
packets.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Carles Cufi
d3e9ade200 Bluetooth: controller: Fix Controller to Host flow control leak
When a connection is disconnected with outstanding unacked packets, the
Host has no way to signal or acknowledge their processing to the
Controller, since it is illegal to send a Host Number of Completed
Packets command when the connection is not up. Instead, consider the
outstanding packets as acked in order not to affect the correct flow
control.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
38609c09d1 Bluetooth: controller: Add Coded PHY packet tx time restrictions
Add implementation to support Coded PHY update procedure
with packet transmit time restrictions.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
49710776a5 Bluetooth: controller: Add encrypted Coded PHY support
Add support for encrypted Coded PHY connections on nRF52840
SoCs.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
c9234cc0ec Bluetooth: controller: Fix PA/LNA for Coded PHY
Use S8 coding Rx chain delay timings to calculate the PA
pin assertions when in Coded PHY.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
1885ebe67a Bluetooth: controller: Fix tIFS calc for Coded PHY
Always use S8 Rx Chain Delay instead of the actual Rx-ed
packet coding. I believe, as the packet always start with
S8, hence S8 timings when used the tIFS is near correct
value.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
5f6ee6d6b1 Bluetooth: controller: Fix Coded PHY supervision timeout
When calculating and setting up the header compelte timeout
use S8 coding Rx chain delay.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
cbb7568aec Bluetooth: controller: Fix connection update supervision timeout
In the commit dd52b8ea02 ("Bluetooth: controller: Fix
first connection interval timing"), instead of using just a
tick unit as workaround, microseconds corresponding to a
tick unit was used while calculating the window offset to be
used at the connection update instant. This introduced an
error in scheduling the first event with new connection
parameters, causing supervision timeout of connection update
procedure.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
20ef2f5faf Bluetooth: controller: Fix missing reset of FC feature
Fixed a missing reset of FC feature on HCI reset. This
feature provided a simple connection handle based event
exclusions, but this is no longer needed with the
support for controller to host flow control. This feature
should be removed in the future.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
6017e2db35 Bluetooth: controller: Fix missing PHY update procedure reset
When a peer master performed a PHY update procedure with no
change, the state machine was not released. This blocked
any future local initiation of the procedure and also
leading to termination of connection with reason LMP
response timeout.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
9d836af286 Bluetooth: controller: Fix NRF_AAR use
Fixed the usage of NRF_AAR peripheral for controller privacy
to clear events on configure and on every radio ISR entry.

Without this fix, there was spurious AAR matches leading to
controller asserts.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
827ddbf09c Bluetooth: controller: Fix PHY Update response state transition
PHY Update procedure timeout was started without transition
to the state that waits for the procedure to complete. This
prevented the timeout from being reset on successful
completion of the procedure and eventually leading to a
connection termination with reason LMP Response Timeout.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
1704a7c915 Bluetooth: controller: Fix CPR procedure's Conn Upd initiation
Fix Connection Parameter Request Procedure's Connection
Update Procedure initiation to calculate the offset rather
than selecting offsets from an out-of-bound memory area.

The symptoms of the bug was noticed as a supervision timeout
due to use of incorrect offset communicated to peer and a
wrong offset used in scheduling the connection events.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
041ad3d426 Bluetooth: controller: Fix Conn Param Req response timeout
When the peer slave rejects a Connection Parameter Request
Procedure, the controller proceeds to perform a Connection
Update Procedure without clearing the procedure timer that
causes the connection to terminate eventually. This is
fixed by clearing the procedure timeout when the Connection
Update Procedure completes.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Vinayak Kariappa Chettimada
cf3b3b93ca Bluetooth: controller: Fix slave from initiating conn upd ind
If a peer master role has support for Connection Parameter
Request Procedure set in its supported features but would
send an Extended Reject Ind as response to the procedure
then the controller incorrectly initiated a Connection
Update Procedure which is not permitted in a slave role.

This would lead to connection timeout after the used instant
in the invalid Connection Update Procedure.

This is fixed by initiating a Connection Update Procedure
only if in a master role.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-10-18 16:38:57 -04:00
Anas Nashif
1c0368764c ci: compliance: decode output to utf8
Fixes GH-1580.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-12 22:00:11 -05:00
Anas Nashif
ab35052b89 Zephyr 1.9.1
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-11 22:37:44 -04:00
Anas Nashif
b19f73de1d ci: compliance script should use python3
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-06 11:49:38 -04:00
Anas Nashif
be823dcffb ci: build commits, not only PR
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-06 11:49:38 -04:00
Anas Nashif
d7070b77eb doc: update release notes with ARC details
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-06 09:36:48 -04:00
Anas Nashif
d3831de32d doc: update release notes index with 1.9
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-06 09:36:48 -04:00
Jukka Rissanen
92ce3bc2d6 net: dns: Do not resolve IPv6 address if IPv6 is disabled
If IPv6 is disabled, then it is useless to try to resolve
IPv6 address because "struct sockaddr" does not have enough
space to store IPv6 address.

Fixes #1487

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-10-06 09:36:48 -04:00
Carles Cufi
b407d02637 Bluetooth: controller: Common config for VS extensions
Since the Zephyr HCI VS extensions apply to both the Host (using them
for additional functionality) and the Controller (implement the commands
and events), it make sense to make this a common setting in order for it
to be configurable in a way that applies to both.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-10-03 19:30:03 -04:00
Carles Cufi
416945ae75 Bluetooth: controller: Disable PA/LNA for nRF51x
The PA/LNA feature is not functional on nRF51x series due to added
interrupt latency. Disable this feature unconditionally for those ICs to
avoid unexpected behavior.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-10-03 19:30:03 -04:00
Vinayak Kariappa Chettimada
89689e0286 Bluetooth: controller: Fix HCI Reset hang
Issuing HCI reset command while having connections sometimes
hung the controller.

ll_reset supplied invalid stop ticker id to role_disable
when trying to stop all connections. Connection role does
not utilize stop ticker. The invalid ticker id supplied
referenced memory outside the pool of tickers and based on
what the content is in RAM there, the controller would hang
trying to stop connections.

Fixed by not calling the ticker_stop interface with invalid
ticker ids.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
91f4c387ae Bluetooth: controller: GPIO PA/LNA feature
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
d2c4dbe6d7 Bluetooth: controller: Add PA/LNA GPIO Kconfig option
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
ec53508b06 Bluetooth: controller: Implement Read Build Info cmd
Implement the Read Build Information VS command. This returns a UTF-8
encoded string, which is extendable by the user via a new Kconfig
option.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
7f65aa8f78 Bluetooth: controller: Implement Write BD_ADDR VS cmd
Implement the Zephyr VS command that allows a Host to write a public
Bluetooth Address to the Controller in order to allow Hosts to provide
their own public Bluetooth addresses.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
705fb8ec26 Bluetooth: controller: Move tIFS s/w switch PPI index up by one
Move the use of tIFS software switching PPI index set up by
one position to make place for use of PA/LNA implementation.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
d42bd89957 Bluetooth: controller: Use single PPI channel for AA capture
Earlier design captured AA twice in the first Rx in a slave
connection event and retained one of the capture until end
of event to calculate drift.

Design updated to use single capture of AA and save the
first AA capture in a slave connection event in RAM instead.

This frees up a PPI channel in the controller design.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
eebdb3b693 Bluetooth: controller: Internal document purpose of end capture
Document internal the purposes of various Tx/Rx PDU end
capture setup.

Also, removed any redundant capture of packet end.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
4d01527866 Bluetooth: controller: Minor refactor radio_tmr_start
Minor refactor of radio_tmr_start to reduced duplicate
assignments common in if-then-else control path.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
60b37e46ca Bluetooth: controller: Map debug pins to P3 pin head on nRF5x DK
Updated debug pin mapping so that the outputs are on P3 pin
head on all nRF5x Development Kits.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
7ee9fb5ced Bluetooth: controller: Add radio setup HAL interface
Added a new interface to perform setup of radio hardware.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
2d08b180b5 Bluetooth: controller: Fix NRF_CCM config for 2M PHY
Fixed the configuration of NRF_CCM for 2M PHY connections.
Now faster 2M data rate mode will be used when a connection
is in 2M PHY.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
8136c0913f Bluetooth: controller: Use correct NRF_AAR enable define
Use correct NRF_AAR enable macro defines from Nordic MDK.
Old code funtionally worked fine even though not setting
the correct enable value.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
59d10ea93a Bluetooth: controller: Remove unreachable workaround code
A workaround code for nRF52840 under nRF51 conditional
compilation is removed.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
c86b716481 Bluetooth: controller: Fix conn param req procedure timeout
Fixed a bug in the implementation of Connection Parameter
Request Procedure when initiated in master role caused the
connection to terminate with reason LL response timeout.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
ef7a6c485f Bluetooth: controller: Fix handling of Read Static Addrs cmd
The status in the Command Complete event was uninitialized, leading to
incorrect contents of the event parsed by the Host. Correctly initialize
the status to success.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
66817cbac9 Bluetooth: controller: Fix hang on directed adv timeout
During testing it was discovered that directed advertising
timeout is missing implementation to handle the timeout
happening while next event is already in preparation.
The consequence was that after the event ticker expired,
the counter is shutdown, stalling the setup PPI from
starting the erroneous advertising, leaving the controller
in an invalid hung state.

This has been fixed by correctly handling the cases, stop
between prepare and event, and stop inside radio advertising
event. The fix takes care of putting the radio active
callback and HF clock in the correct states.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
543acefc43 samples: bluetooth: hci: Fix TX memory leak
Whenever a buffer is sent to the driver via bt_raw using bt_send() the
buffer might not be consumed if an error is returned. In that case
unreference the buffer to avoid leaking the already allocated net_buf.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
f913f9b9f0 Bluetooth: controller: Issue Data Buffer Overflow event
Whenever the HCI ACL flow control is violated by the Host, a Data Buffer
Overflow event is now issued by the Controller (if enabled) to notify
the Host of the buffer overrun.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Ricardo Salveti
3a4fb6e24e pwm: stm32: Fix check for APB prescale
RCC_HCLK_DIV1 translates to 0x0 while apb_psc uses the value defined
by CONFIG_CLOCK_STM32_APB1/2_PRESCALER (range from 1 to 16).

Manually check if the defined prescaler is 1 or not and use that to
calculate the correct timer clock.

Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
2017-09-13 10:44:23 -05:00
40 changed files with 1984 additions and 755 deletions

View File

@@ -23,13 +23,16 @@ build:
- ${SHIPPABLE_BUILD_DIR}/ccache
pre_ci_boot:
image_name: zephyrprojectrtos/ci
image_tag: master.27
image_tag: v0.1
pull: true
options: "-e HOME=/home/buildslave --privileged=true --tty --net=bridge --user buildslave"
ci:
- export CCACHE_DIR=${SHIPPABLE_BUILD_DIR}/ccache/.ccache
- git rebase origin/${PULL_REQUEST_BASE_BRANCH}
- >
if [ "$IS_PULL_REQUEST" = "true" ]; then
git rebase origin/${PULL_REQUEST_BASE_BRANCH};
fi
- source zephyr-env.sh
- ccache -c -s --max-size=2000M
- make host-tools
@@ -54,19 +57,20 @@ build:
./scripts/ci/check-compliance.py --commits ${COMMIT_RANGE} || true;
fi;
- >
sudo pip3 install sh;
./scripts/ci/get_modified_tests.py --commits origin/${PULL_REQUEST_BASE_BRANCH}..HEAD > modified_tests.args;
./scripts/ci/get_modified_boards.py --commits origin/${PULL_REQUEST_BASE_BRANCH}..HEAD > modified_boards.args;
if [ "$IS_PULL_REQUEST" = "true" ]; then
./scripts/ci/get_modified_tests.py --commits origin/${PULL_REQUEST_BASE_BRANCH}..HEAD > modified_tests.args;
./scripts/ci/get_modified_boards.py --commits origin/${PULL_REQUEST_BASE_BRANCH}..HEAD > modified_boards.args;
if [ -s modified_boards.args ]; then
./scripts/sanitycheck --subset ${MATRIX_BUILD}/${MATRIX_BUILDS_EXTRA} +modified_boards.args || ./scripts/sanitycheck +modified_boards.args --only-failed;
cp ./scripts/sanity_chk/last_sanity.xml modified_boards.xml;
fi;
if [ -s modified_tests.args ]; then
./scripts/sanitycheck --subset ${MATRIX_BUILD}/${MATRIX_BUILDS_EXTRA} +modified_tests.args || ./scripts/sanitycheck +modified_tests.args --only-failed
cp ./scripts/sanity_chk/last_sanity.xml modified_tests.xml;
fi;
rm -f modified_tests.args modified_boards.args;
if [ -s modified_boards.args ]; then
./scripts/sanitycheck --subset ${MATRIX_BUILD}/${MATRIX_BUILDS_EXTRA} +modified_boards.args || ./scripts/sanitycheck +modified_boards.args --only-failed;
cp ./scripts/sanity_chk/last_sanity.xml modified_boards.xml;
fi;
if [ -s modified_tests.args ]; then
./scripts/sanitycheck --subset ${MATRIX_BUILD}/${MATRIX_BUILDS_EXTRA} +modified_tests.args || ./scripts/sanitycheck +modified_tests.args --only-failed;
cp ./scripts/sanity_chk/last_sanity.xml modified_tests.xml;
fi;
rm -f modified_tests.args modified_boards.args;
fi
- >
if [ "$MATRIX_BUILD" != "3" ]; then
./scripts/sanitycheck ${PLATFORMS} --subset ${MATRIX_BUILD}/${MATRIX_BUILDS} ${COVERAGE} ${SANITYCHECK_OPTIONS} || ./scripts/sanitycheck ${PLATFORMS} ${COVERAGE} ${SANITYCHECK_OPTIONS_RETRY} || ./scripts/sanitycheck ${PLATFORMS} ${COVERAGE} ${SANITYCHECK_OPTIONS_RETRY}

View File

@@ -1,6 +1,6 @@
VERSION_MAJOR = 1
VERSION_MINOR = 9
PATCHLEVEL = 0
PATCHLEVEL = 2
VERSION_RESERVED = 0
EXTRAVERSION =
NAME = Zephyr Kernel

View File

@@ -2,6 +2,42 @@
.. _zephyr_1.9:
Zephyr Kernel 1.9.2
###################
This is a maintenance release with fixes.
Kernel
******
* Generic queue item acquisition fixed to always return a valid item when
using K_FOREVER
Bluetooth
*********
* Multiple stability fixes for BLE Mesh
* Multiple stability fixes for the BLE Controller
Zephyr Kernel 1.9.1
###################
This is a maintenance release with fixes and a two new features in the
BLE Controller.
Drivers and Sensors
*******************
* mcux ethernet driver buffer overflow fixed
* STM32 PWM prescaler issue fixed
Networking
**********
* Support for IPv6 in DNS fixed
Bluetooth
*********
* Multiple stability fixes for the BLE Controller
* Support for PA/LNA amplifiers in the BLE Controller
* Support for additional VS commands in the BLE Controller
Zephyr Kernel 1.9.0
###################
@@ -39,9 +75,11 @@ Architectures
* xtensa: Added ESP32 support
* Stack sentinel: This places a sentinel value at the lowest 4 bytes of a stack
memory region and checks it at various intervals, including when servicing
interrupts or context switching. This is implemented on all arches except
ARC, which supports stack bounds checking directly in hardware.
* x86: enable MMU for application memory
interrupts or context switching.
* x86: Enable MMU for application memory
* ARC: Added initial MPU support, including stack sentinel checking for ARC
configurations not featuring hardware stack bounds checking
* ARC: Nested interrupt support for normal, non-FIRQ interrupts
Boards
******
@@ -55,6 +93,9 @@ Boards
* arm: Removed TI CC3200 LaunchXL board
* arm: Added VBLUno51 and VBLUno52 boards
* xtensa: Added ESP32 board support
* ARC: Added support for EMSK EM7D v2.2 version (incl. MPU)
* ARC: Board configuration restructuring, peripheral configs moved from soc to
board level
Drivers and Sensors
*******************
@@ -338,3 +379,4 @@ JIRA Related Items
* :jira:`ZEP-2576` - samples/net/sockets/echo, echo_async : fails to send the TCP packets
* :jira:`ZEP-2581` - CC3220 executable binary format support
* :jira:`ZEP-2584` - Update mbedTLS to 2.6.0
* :jira:`ZEP-713` - Implement preemptible regular IRQs on ARC

View File

@@ -17,7 +17,7 @@ notes pages listed below), or use Git clone and checkout commands, such as:
git clone https://github.com/zephyrproject-rtos/zephyr
cd zephyr
git checkout tags/v1.8.0
git checkout tags/v1.9.0
The project's technical documentation is also tagged to correspond with a
@@ -29,6 +29,7 @@ Zephyr Kernel Releases
.. toctree::
:maxdepth: 1
release-notes-1.9
release-notes-1.8
release-notes-1.7
release-notes-1.6

View File

@@ -38,7 +38,13 @@ static u32_t __get_tim_clk(u32_t bus_clk,
apb_psc = CONFIG_CLOCK_STM32_APB2_PRESCALER;
}
if (apb_psc == RCC_HCLK_DIV1) {
/*
* If the APB prescaler equals 1, the timer clock frequencies
* are set to the same frequency as that of the APB domain.
* Otherwise, they are set to twice (×2) the frequency of the
* APB domain.
*/
if (apb_psc == 1) {
tim_clk = bus_clk;
} else {
tim_clk = 2 * bus_clk;

View File

@@ -1438,6 +1438,15 @@ struct bt_hci_evt_link_key_notify {
u8_t key_type;
} __packed;
/* Overflow link types */
#define BT_OVERFLOW_LINK_SYNCH 0x00
#define BT_OVERFLOW_LINK_ACL 0x01
#define BT_HCI_EVT_DATA_BUF_OVERFLOW 0x1a
struct bt_hci_evt_data_buf_overflow {
u8_t link_type;
} __packed;
#define BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI 0x22
struct bt_hci_evt_inquiry_result_with_rssi {
bt_addr_t addr;

View File

@@ -292,9 +292,6 @@ extern const struct bt_mesh_model_op bt_mesh_cfg_op[];
struct bt_mesh_health {
struct bt_mesh_model *model;
/* Health Period (divider) */
u8_t period;
/* Fetch current faults */
int (*fault_get_cur)(struct bt_mesh_model *model, u8_t *test_id,
u16_t *company_id, u8_t *faults,

View File

@@ -292,7 +292,8 @@ static int _signal_poll_event(struct k_poll_event *event, u32_t state,
_unpend_thread(thread);
_abort_thread_timeout(thread);
_set_thread_return_value(thread, 0);
_set_thread_return_value(thread,
state == K_POLL_STATE_NOT_READY ? -EINTR : 0);
if (!_is_thread_ready(thread)) {
goto ready_event;

View File

@@ -68,11 +68,9 @@ static void prepare_thread_to_run(struct k_thread *thread, void *data)
#endif /* CONFIG_POLL */
/* returns 1 if a reschedule must take place, 0 otherwise */
static inline int handle_poll_events(struct k_queue *queue)
static inline int handle_poll_events(struct k_queue *queue, u32_t state)
{
#ifdef CONFIG_POLL
u32_t state = K_POLL_STATE_DATA_AVAILABLE;
return _handle_obj_poll_events(&queue->poll_events, state);
#else
return 0;
@@ -95,7 +93,7 @@ void k_queue_cancel_wait(struct k_queue *queue)
}
}
#else
if (handle_poll_events(queue)) {
if (handle_poll_events(queue, K_POLL_STATE_NOT_READY)) {
(void)_Swap(key);
return;
}
@@ -126,7 +124,7 @@ void k_queue_insert(struct k_queue *queue, void *prev, void *data)
sys_slist_insert(&queue->data_q, prev, data);
#if defined(CONFIG_POLL)
if (handle_poll_events(queue)) {
if (handle_poll_events(queue, K_POLL_STATE_DATA_AVAILABLE)) {
(void)_Swap(key);
return;
}
@@ -171,7 +169,7 @@ void k_queue_append_list(struct k_queue *queue, void *head, void *tail)
}
#else
sys_slist_append_list(&queue->data_q, head, tail);
if (handle_poll_events(queue)) {
if (handle_poll_events(queue, K_POLL_STATE_DATA_AVAILABLE)) {
(void)_Swap(key);
return;
}
@@ -199,20 +197,32 @@ static void *k_queue_poll(struct k_queue *queue, s32_t timeout)
{
struct k_poll_event event;
int err;
unsigned int key;
void *val;
k_poll_event_init(&event, K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY, queue);
event.state = K_POLL_STATE_NOT_READY;
do {
event.state = K_POLL_STATE_NOT_READY;
err = k_poll(&event, 1, timeout);
if (err) {
return NULL;
}
err = k_poll(&event, 1, timeout);
if (err) {
return NULL;
}
__ASSERT_NO_MSG(event.state == K_POLL_STATE_FIFO_DATA_AVAILABLE);
__ASSERT_NO_MSG(event.state ==
K_POLL_STATE_FIFO_DATA_AVAILABLE);
return sys_slist_get(&queue->data_q);
/* sys_slist_* aren't threadsafe, so must be always protected by
* irq_lock.
*/
key = irq_lock();
val = sys_slist_get(&queue->data_q);
irq_unlock(key);
} while (!val && timeout == K_FOREVER);
return val;
}
#endif /* CONFIG_POLL */

View File

@@ -225,7 +225,12 @@ static void bt_tx_thread(void *p1, void *p2, void *p3)
SYS_LOG_DBG("buf %p type %u len %u",
buf, bt_buf_get_type(buf), buf->len);
bt_send(buf);
ret = bt_send(buf);
if (ret) {
SYS_LOG_ERR("Unable to send (ret %d)", ret);
net_buf_unref(buf);
}
STACK_ANALYZE("tx_stack", bt_tx_thread_stack);
/* Make sure other threads get a chance to run */

View File

@@ -232,11 +232,16 @@ static void tx_thread(void *p1, void *p2, void *p3)
{
while (1) {
struct net_buf *buf;
int err;
/* Wait until a buffer is available */
buf = net_buf_get(&tx_queue, K_FOREVER);
/* Pass buffer to the stack */
bt_send(buf);
err = bt_send(buf);
if (err) {
SYS_LOG_ERR("Unable to send (err %d)", err);
net_buf_unref(buf);
}
/* Give other threads a chance to run if tx_queue keeps getting
* new data all the time.

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import sys
import subprocess
import re
@@ -69,7 +69,7 @@ def run_gitlint(tc, commit_range):
if msg != "":
failure = ET.SubElement(tc, 'failure', type="failure", message="commit message error on range: %s" %commit_range)
failure.text = (str(msg))
failure.text = (msg.decode('utf8'))
return 1
return 0
@@ -86,10 +86,10 @@ def run_checkpatch(tc, commit_range):
stderr=subprocess.STDOUT, shell=True)
except subprocess.CalledProcessError as ex:
m = re.search("([1-9][0-9]*) errors,", str(ex.output))
m = re.search("([1-9][0-9]*) errors,", ex.output.decode('utf8'))
if m:
failure = ET.SubElement(tc, 'failure', type="failure", message="checkpatch issues")
failure.text = (str(ex.output))
failure.text = (ex.output.decode('utf8'))
return 1
return 0
@@ -102,7 +102,7 @@ def check_doc(tc, range):
log = f.read()
failure = ET.SubElement(tc, 'failure', type="failure",
message="documentation issues")
failure.text = (str(log))
failure.text = (log.decode('utf8'))
return 1
return 0

View File

@@ -8,6 +8,13 @@
if BT_HCI
config BT_HCI_VS_EXT
bool "Zephyr HCI Vendor-Specific Extensions"
default y
help
Enable support for the Zephyr HCI Vendor-Specific Extensions in the
Host and/or Controller.
config BT_RPA
# Virtual/hidden option
bool

View File

@@ -30,12 +30,16 @@ endchoice
comment "BLE Controller configuration"
config BT_CTLR_HCI_VS_EXT
bool "Zephyr HCI Vendor-Specific Extensions"
default y
config BT_CTLR_HCI_VS_BUILD_INFO
string "Zephyr HCI VS Build Info string"
default ""
depends on BT_HCI_VS_EXT
help
Enable support for the Zephyr HCI Vendor-Specific Extensions in the
Controller.
User-defined string that will be returned by the Zephyr VS Read Build
Information command after the Zephyr version and build time. When
setting this to a value different from an empty string, a space
character is required at the beginning to separate it from the
already included information.
config BT_CTLR_DUP_FILTER_LEN
prompt "Number of addresses in the scan duplicate filter"
@@ -334,7 +338,7 @@ config BT_CTLR_SCHED_ADVANCED
config BT_CTLR_RADIO_ENABLE_FAST
bool "Use tTXEN/RXEN,FAST ramp-up"
depends on SOC_SERIES_NRF52X
default y if SOC_NRF52840
default y
help
Enable use of fast radio ramp-up mode.
@@ -386,6 +390,78 @@ config BT_CTLR_SCAN_REQ_RSSI
endmenu
comment "BLE Controller hardware configuration"
menuconfig BT_CTLR_GPIO_PA
bool "Power Amplifier GPIO interface"
depends on !SOC_SERIES_NRF51X
help
Enable GPIO interface to a Power Amplifier. This allows hardware
designs using PA to let the Controller toggle their state based on
radio activity.
if BT_CTLR_GPIO_PA
config BT_CTLR_GPIO_PA_PIN
prompt "Power Amplifier GPIO pin number"
int
help
GPIO Pin number connected to a Power Amplifier.
config BT_CTLR_GPIO_PA_POL_INV
bool "Inverted polarity for the PA pin"
help
Enable inverted polarity (active low) for the PA pin.
config BT_CTLR_GPIO_PA_OFFSET
prompt "Time from PA ON to Tx ready"
int
default 5
range 0 10
help
Time before Tx ready to turn on PA.
endif # BT_CTLR_GPIO_PA
menuconfig BT_CTLR_GPIO_LNA
bool "Low Noise Amplifier GPIO interface"
depends on !SOC_SERIES_NRF51X
help
Enable GPIO interface to a Low Noise Amplifier. This allows hardware
designs using LNAs to let the Controller toggle their state based on
radio activity.
if BT_CTLR_GPIO_LNA
config BT_CTLR_GPIO_LNA_PIN
prompt "Low Noise Amplifier GPIO pin number"
int
help
GPIO Pin number connected to a Low Noise Amplifier.
config BT_CTLR_GPIO_LNA_POL_INV
bool "Inverted polarity for the LNA pin"
help
Enable inverted polarity (active low) for the LNA pin.
config BT_CTLR_GPIO_LNA_OFFSET
prompt "Time from LNA ON to Rx ready"
int
default 5
range 0 10
help
Time before Rx ready to turn on LNA.
endif # BT_CTLR_GPIO_LNA
config BT_CTLR_PA_LNA_GPIOTE_CHAN
# Hidden "nRF5 GPIO PA/LNA GPIOTE Channel"
depends on SOC_FAMILY_NRF5 && (BT_CTLR_GPIO_PA || BT_CTLR_GPIO_LNA)
int
default 3
help
Select the nRF5 GPIOTE channel to use for PA/LNA GPIO feature.
comment "BLE Controller debug configuration"
config BT_CTLR_ASSERT_HANDLER
@@ -408,6 +484,7 @@ config BT_CTLR_PROFILE_ISR
config BT_CTLR_DEBUG_PINS
bool "Bluetooth Controller Debug Pins"
depends on BOARD_NRF51_PCA10028 || BOARD_NRF52_PCA10040 || BOARD_NRF52840_PCA10056
help
Turn on debug GPIO toggling for the BLE Controller. This is useful
when debugging with a logic analyzer or profiling certain sections of

View File

@@ -8,157 +8,202 @@
#ifndef _DEBUG_H_
#define _DEBUG_H_
#ifdef CONFIG_BT_CTLR_DEBUG_PINS
#if defined(CONFIG_BOARD_NRF52840_PCA10056)
#define DEBUG_PORT NRF_P1
#define DEBUG_PIN0 BIT(1)
#define DEBUG_PIN1 BIT(2)
#define DEBUG_PIN2 BIT(3)
#define DEBUG_PIN3 BIT(4)
#define DEBUG_PIN4 BIT(5)
#define DEBUG_PIN5 BIT(6)
#define DEBUG_PIN6 BIT(7)
#define DEBUG_PIN7 BIT(8)
#define DEBUG_PIN8 BIT(10)
#define DEBUG_PIN9 BIT(11)
#elif defined(CONFIG_BOARD_NRF52_PCA10040)
#define DEBUG_PORT NRF_GPIO
#define DEBUG_PIN0 BIT(11)
#define DEBUG_PIN1 BIT(12)
#define DEBUG_PIN2 BIT(13)
#define DEBUG_PIN3 BIT(14)
#define DEBUG_PIN4 BIT(15)
#define DEBUG_PIN5 BIT(16)
#define DEBUG_PIN6 BIT(17)
#define DEBUG_PIN7 BIT(18)
#define DEBUG_PIN8 BIT(19)
#define DEBUG_PIN9 BIT(20)
#elif defined(CONFIG_BOARD_NRF51_PCA10028)
#define DEBUG_PORT NRF_GPIO
#define DEBUG_PIN0 BIT(12)
#define DEBUG_PIN1 BIT(13)
#define DEBUG_PIN2 BIT(14)
#define DEBUG_PIN3 BIT(15)
#define DEBUG_PIN4 BIT(16)
#define DEBUG_PIN5 BIT(17)
#define DEBUG_PIN6 BIT(18)
#define DEBUG_PIN7 BIT(19)
#define DEBUG_PIN8 BIT(20)
#define DEBUG_PIN9 BIT(23)
#else
#error BT_CTLR_DEBUG_PINS not supported on this board.
#endif
#define DEBUG_PIN_MASK (DEBUG_PIN0 | DEBUG_PIN1 | DEBUG_PIN2 | DEBUG_PIN3 | \
DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6 | DEBUG_PIN7 | \
DEBUG_PIN8 | DEBUG_PIN9)
#define DEBUG_CLOSE_MASK (DEBUG_PIN3 | DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6)
/* below are some interesting macros referenced by controller
* which can be defined to SoC's GPIO toggle to observe/debug the
* controller's runtime behavior.
*/
#ifdef CONFIG_BT_CTLR_DEBUG_PINS
#define DEBUG_INIT() do { \
NRF_GPIO->DIRSET = 0x03FF0000; \
NRF_GPIO->OUTCLR = 0x03FF0000; } \
DEBUG_PORT->DIRSET = DEBUG_PIN_MASK; \
DEBUG_PORT->OUTCLR = DEBUG_PIN_MASK; } \
while (0)
#define DEBUG_CPU_SLEEP(flag) do { \
if (flag) { \
NRF_GPIO->OUTSET = BIT(16); \
NRF_GPIO->OUTCLR = BIT(16); } \
DEBUG_PORT->OUTSET = DEBUG_PIN0; \
DEBUG_PORT->OUTCLR = DEBUG_PIN0; } \
else { \
NRF_GPIO->OUTCLR = BIT(16); \
NRF_GPIO->OUTSET = BIT(16); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN0; \
DEBUG_PORT->OUTSET = DEBUG_PIN0; } \
} while (0)
#define DEBUG_TICKER_ISR(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(17); \
NRF_GPIO->OUTSET = BIT(17); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
DEBUG_PORT->OUTSET = DEBUG_PIN1; } \
else { \
NRF_GPIO->OUTSET = BIT(17); \
NRF_GPIO->OUTCLR = BIT(17); } \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; } \
} while (0)
#define DEBUG_TICKER_TASK(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(17); \
NRF_GPIO->OUTSET = BIT(17); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
DEBUG_PORT->OUTSET = DEBUG_PIN1; } \
else { \
NRF_GPIO->OUTSET = BIT(17); \
NRF_GPIO->OUTCLR = BIT(17); } \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; } \
} while (0)
#define DEBUG_TICKER_JOB(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(18); \
NRF_GPIO->OUTSET = BIT(18); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN2; \
DEBUG_PORT->OUTSET = DEBUG_PIN2; } \
else { \
NRF_GPIO->OUTSET = BIT(18); \
NRF_GPIO->OUTCLR = BIT(18); } \
DEBUG_PORT->OUTSET = DEBUG_PIN2; \
DEBUG_PORT->OUTCLR = DEBUG_PIN2; } \
} while (0)
#define DEBUG_RADIO_ISR(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(23); \
NRF_GPIO->OUTSET = BIT(23); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN7; \
DEBUG_PORT->OUTSET = DEBUG_PIN7; } \
else { \
NRF_GPIO->OUTSET = BIT(23); \
NRF_GPIO->OUTCLR = BIT(23); } \
DEBUG_PORT->OUTSET = DEBUG_PIN7; \
DEBUG_PORT->OUTCLR = DEBUG_PIN7; } \
} while (0)
#define DEBUG_RADIO_XTAL(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(24); \
NRF_GPIO->OUTSET = BIT(24); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN8; \
DEBUG_PORT->OUTSET = DEBUG_PIN8; } \
else { \
NRF_GPIO->OUTSET = BIT(24); \
NRF_GPIO->OUTCLR = BIT(24); } \
DEBUG_PORT->OUTSET = DEBUG_PIN8; \
DEBUG_PORT->OUTCLR = DEBUG_PIN8; } \
} while (0)
#define DEBUG_RADIO_ACTIVE(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(25); \
NRF_GPIO->OUTSET = BIT(25); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN9; \
DEBUG_PORT->OUTSET = DEBUG_PIN9; } \
else { \
NRF_GPIO->OUTSET = BIT(25); \
NRF_GPIO->OUTCLR = BIT(25); } \
DEBUG_PORT->OUTSET = DEBUG_PIN9; \
DEBUG_PORT->OUTCLR = DEBUG_PIN9; } \
} while (0)
#define DEBUG_RADIO_CLOSE(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = 0x00000000; \
NRF_GPIO->OUTSET = 0x00000000; } \
DEBUG_PORT->OUTCLR = 0x00000000; \
DEBUG_PORT->OUTSET = 0x00000000; } \
else { \
NRF_GPIO->OUTCLR = 0x00780000; } \
DEBUG_PORT->OUTCLR = DEBUG_CLOSE_MASK; } \
} while (0)
#define DEBUG_RADIO_PREPARE_A(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(19); \
NRF_GPIO->OUTSET = BIT(19); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
else { \
NRF_GPIO->OUTCLR = BIT(19); \
NRF_GPIO->OUTSET = BIT(19); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
} while (0)
#define DEBUG_RADIO_START_A(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(19); \
NRF_GPIO->OUTSET = BIT(19); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
else { \
NRF_GPIO->OUTCLR = BIT(19); \
NRF_GPIO->OUTSET = BIT(19); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
} while (0)
#define DEBUG_RADIO_PREPARE_S(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(20); \
NRF_GPIO->OUTSET = BIT(20); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
else { \
NRF_GPIO->OUTCLR = BIT(20); \
NRF_GPIO->OUTSET = BIT(20); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
} while (0)
#define DEBUG_RADIO_START_S(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(20); \
NRF_GPIO->OUTSET = BIT(20); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
else { \
NRF_GPIO->OUTCLR = BIT(20); \
NRF_GPIO->OUTSET = BIT(20); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
} while (0)
#define DEBUG_RADIO_PREPARE_O(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(21); \
NRF_GPIO->OUTSET = BIT(21); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
else { \
NRF_GPIO->OUTCLR = BIT(21); \
NRF_GPIO->OUTSET = BIT(21); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
} while (0)
#define DEBUG_RADIO_START_O(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(21); \
NRF_GPIO->OUTSET = BIT(21); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
else { \
NRF_GPIO->OUTCLR = BIT(21); \
NRF_GPIO->OUTSET = BIT(21); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
} while (0)
#define DEBUG_RADIO_PREPARE_M(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(22); \
NRF_GPIO->OUTSET = BIT(22); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
else { \
NRF_GPIO->OUTCLR = BIT(22); \
NRF_GPIO->OUTSET = BIT(22); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
} while (0)
#define DEBUG_RADIO_START_M(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(22); \
NRF_GPIO->OUTSET = BIT(22); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
else { \
NRF_GPIO->OUTCLR = BIT(22); \
NRF_GPIO->OUTSET = BIT(22); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
} while (0)
#else

View File

@@ -48,6 +48,63 @@ void radio_isr_set(radio_isr_fp fp_radio_isr)
irq_enable(RADIO_IRQn);
}
void radio_setup(void)
{
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
NRF_GPIO->DIRSET = BIT(CONFIG_BT_CTLR_GPIO_PA_PIN);
#if defined(CONFIG_BT_CTLR_GPIO_PA_POL_INV)
NRF_GPIO->OUTSET = BIT(CONFIG_BT_CTLR_GPIO_PA_PIN);
#else
NRF_GPIO->OUTCLR = BIT(CONFIG_BT_CTLR_GPIO_PA_PIN);
#endif
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
NRF_GPIO->DIRSET = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
radio_gpio_lna_off();
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
#if defined(CONFIG_SOC_SERIES_NRF52X)
struct {
u32_t volatile reserved_0[0x5a0 >> 2];
u32_t volatile bridge_type;
u32_t volatile reserved_1[((0xe00 - 0x5a0) >> 2) - 1];
struct {
u32_t volatile CPU0;
u32_t volatile SPIS1;
u32_t volatile RADIO;
u32_t volatile ECB;
u32_t volatile CCM;
u32_t volatile AAR;
u32_t volatile SAADC;
u32_t volatile UARTE;
u32_t volatile SERIAL0;
u32_t volatile SERIAL2;
u32_t volatile NFCT;
u32_t volatile I2S;
u32_t volatile PDM;
u32_t volatile PWM;
} RAMPRI;
} volatile *NRF_AMLI = (void volatile *)0x40000000UL;
NRF_AMLI->RAMPRI.CPU0 = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.SPIS1 = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.RADIO = 0x00000000UL;
NRF_AMLI->RAMPRI.ECB = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.CCM = 0x00000000UL;
NRF_AMLI->RAMPRI.AAR = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.SAADC = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.UARTE = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.SERIAL0 = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.SERIAL2 = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.NFCT = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.I2S = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.PDM = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.PWM = 0xFFFFFFFFUL;
#endif /* CONFIG_SOC_SERIES_NRF52X */
}
void radio_reset(void)
{
irq_disable(RADIO_IRQn);
@@ -78,11 +135,6 @@ void radio_phy_set(u8_t phy, u8_t flags)
#if defined(CONFIG_SOC_SERIES_NRF51X)
case BIT(1):
mode = RADIO_MODE_MODE_Nrf_2Mbit;
#if defined(CONFIG_SOC_NRF52840)
/* Workaround: nRF52840 Engineering A Errata ID 164 */
*(volatile u32_t *)0x4000173c &= ~0x80000000;
#endif /* CONFIG_SOC_NRF52840 */
break;
#elif defined(CONFIG_SOC_SERIES_NRF52X)
@@ -377,7 +429,7 @@ void radio_tx_enable(void)
void radio_disable(void)
{
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
NRF_PPI->CHENCLR = PPI_CHEN_CH8_Msk | PPI_CHEN_CH11_Msk;
NRF_PPI->CHENCLR = PPI_CHEN_CH9_Msk | PPI_CHEN_CH12_Msk;
NRF_PPI->TASKS_CHG[0].DIS = 1;
NRF_PPI->TASKS_CHG[1].DIS = 1;
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
@@ -452,19 +504,19 @@ static u8_t sw_tifs_toggle;
static void sw_switch(u8_t dir, u8_t phy_curr, u8_t flags_curr, u8_t phy_next,
u8_t flags_next)
{
u8_t ppi = 12 + sw_tifs_toggle;
u8_t ppi = 13 + sw_tifs_toggle;
u32_t delay;
NRF_TIMER1->EVENTS_COMPARE[sw_tifs_toggle] = 0;
NRF_PPI->CH[11].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[11].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[sw_tifs_toggle].EN);
NRF_PPI->CH[12].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[12].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[sw_tifs_toggle].EN);
NRF_PPI->CH[ppi].EEP = (u32_t)
&(NRF_TIMER1->EVENTS_COMPARE[sw_tifs_toggle]);
if (dir) {
delay = radio_tx_ready_delay_get(phy_next, flags_next) +
radio_rx_chain_delay_get(phy_curr, flags_curr);
radio_rx_chain_delay_get(phy_curr, 1);
NRF_PPI->CH[ppi].TEP = (u32_t)&(NRF_RADIO->TASKS_TXEN);
} else {
@@ -481,7 +533,7 @@ static void sw_switch(u8_t dir, u8_t phy_curr, u8_t flags_curr, u8_t phy_next,
NRF_TIMER1->CC[sw_tifs_toggle] = 1;
}
NRF_PPI->CHENSET = PPI_CHEN_CH8_Msk | PPI_CHEN_CH11_Msk;
NRF_PPI->CHENSET = PPI_CHEN_CH9_Msk | PPI_CHEN_CH12_Msk;
sw_tifs_toggle += 1;
sw_tifs_toggle &= 1;
@@ -521,7 +573,7 @@ void radio_switch_complete_and_disable(void)
(RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk);
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
NRF_PPI->CHENCLR = PPI_CHEN_CH8_Msk | PPI_CHEN_CH11_Msk;
NRF_PPI->CHENCLR = PPI_CHEN_CH9_Msk | PPI_CHEN_CH12_Msk;
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
}
@@ -607,7 +659,7 @@ void radio_tmr_status_reset(void)
NRF_PPI->CHENCLR =
(PPI_CHEN_CH0_Msk | PPI_CHEN_CH1_Msk | PPI_CHEN_CH2_Msk |
PPI_CHEN_CH3_Msk | PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk |
PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk);
PPI_CHEN_CH6_Msk | PPI_CHEN_CH15_Msk);
}
void radio_tmr_tifs_set(u32_t tifs)
@@ -643,19 +695,10 @@ u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder)
NRF_PPI->CH[1].TEP = (u32_t)&(NRF_TIMER0->TASKS_START);
NRF_PPI->CHENSET = PPI_CHEN_CH1_Msk;
if (trx) {
NRF_PPI->CH[0].EEP =
(u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP =
(u32_t)&(NRF_RADIO->TASKS_TXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
} else {
NRF_PPI->CH[0].EEP =
(u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP =
(u32_t)&(NRF_RADIO->TASKS_RXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
}
NRF_PPI->CH[0].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP = (trx) ? (u32_t)&(NRF_RADIO->TASKS_TXEN) :
(u32_t)&(NRF_RADIO->TASKS_RXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
NRF_TIMER1->TASKS_CLEAR = 1;
@@ -664,19 +707,17 @@ u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder)
NRF_TIMER1->BITMODE = 0; /* 16 bit */
NRF_TIMER1->TASKS_START = 1;
NRF_PPI->CH[8].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[8].TEP = (u32_t)&(NRF_TIMER1->TASKS_CLEAR);
NRF_PPI->CH[9].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[9].TEP = (u32_t)&(NRF_TIMER1->TASKS_CLEAR);
NRF_PPI->CH[9].EEP = (u32_t)
&(NRF_TIMER1->EVENTS_COMPARE[0]);
NRF_PPI->CH[9].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[0].DIS);
NRF_PPI->CH[10].EEP = (u32_t)&(NRF_TIMER1->EVENTS_COMPARE[0]);
NRF_PPI->CH[10].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[0].DIS);
NRF_PPI->CH[10].EEP = (u32_t)
&(NRF_TIMER1->EVENTS_COMPARE[1]);
NRF_PPI->CH[10].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[1].DIS);
NRF_PPI->CH[11].EEP = (u32_t)&(NRF_TIMER1->EVENTS_COMPARE[1]);
NRF_PPI->CH[11].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[1].DIS);
NRF_PPI->CHG[0] = PPI_CHG_CH9_Msk | PPI_CHG_CH12_Msk;
NRF_PPI->CHG[1] = PPI_CHG_CH10_Msk | PPI_CHG_CH13_Msk;
NRF_PPI->CHG[0] = PPI_CHG_CH10_Msk | PPI_CHG_CH13_Msk;
NRF_PPI->CHG[1] = PPI_CHG_CH11_Msk | PPI_CHG_CH14_Msk;
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
return remainder;
@@ -684,21 +725,45 @@ u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder)
void radio_tmr_start_us(u8_t trx, u32_t us)
{
if (trx) {
NRF_PPI->CH[0].EEP =
(u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP =
(u32_t)&(NRF_RADIO->TASKS_TXEN);
} else {
NRF_PPI->CH[0].EEP =
(u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP =
(u32_t)&(NRF_RADIO->TASKS_RXEN);
}
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
NRF_TIMER0->CC[0] = us;
NRF_TIMER0->EVENTS_COMPARE[0] = 0;
NRF_PPI->CH[0].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP = (trx) ? (u32_t)&(NRF_RADIO->TASKS_TXEN) :
(u32_t)&(NRF_RADIO->TASKS_RXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
}
u32_t radio_tmr_start_now(u8_t trx)
{
u32_t now, start;
/* Setup PPI for Radio start */
NRF_PPI->CH[0].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP = (trx) ? (u32_t)&(NRF_RADIO->TASKS_TXEN) :
(u32_t)&(NRF_RADIO->TASKS_RXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
/* Capture the current time */
NRF_TIMER0->TASKS_CAPTURE[1] = 1;
now = NRF_TIMER0->CC[1];
start = now;
/* Setup PPI while determining the latency in doing so */
do {
/* Set start to be, now plus the determined latency */
start = (now << 1) - start;
/* Setup compare event with min. 1 us offset */
NRF_TIMER0->CC[0] = start + 1;
NRF_TIMER0->EVENTS_COMPARE[0] = 0;
/* Capture the current time */
NRF_TIMER0->TASKS_CAPTURE[1] = 1;
now = NRF_TIMER0->CC[1];
} while (now > start);
return start;
}
void radio_tmr_stop(void)
@@ -714,14 +779,14 @@ void radio_tmr_stop(void)
void radio_tmr_hcto_configure(u32_t hcto)
{
NRF_TIMER0->CC[2] = hcto;
NRF_TIMER0->EVENTS_COMPARE[2] = 0;
NRF_TIMER0->CC[1] = hcto;
NRF_TIMER0->EVENTS_COMPARE[1] = 0;
NRF_PPI->CH[4].EEP = (u32_t)&(NRF_RADIO->EVENTS_ADDRESS);
NRF_PPI->CH[4].TEP = (u32_t)&(NRF_TIMER0->TASKS_CAPTURE[2]);
NRF_PPI->CH[5].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[2]);
NRF_PPI->CH[5].TEP = (u32_t)&(NRF_RADIO->TASKS_DISABLE);
NRF_PPI->CHENSET = (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk);
NRF_PPI->CH[3].EEP = (u32_t)&(NRF_RADIO->EVENTS_ADDRESS);
NRF_PPI->CH[3].TEP = (u32_t)&(NRF_TIMER0->TASKS_CAPTURE[1]);
NRF_PPI->CH[4].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[1]);
NRF_PPI->CH[4].TEP = (u32_t)&(NRF_RADIO->TASKS_DISABLE);
NRF_PPI->CHENSET = (PPI_CHEN_CH3_Msk | PPI_CHEN_CH4_Msk);
}
void radio_tmr_aa_capture(void)
@@ -733,21 +798,34 @@ void radio_tmr_aa_capture(void)
NRF_PPI->CHENSET = (PPI_CHEN_CH2_Msk | PPI_CHEN_CH3_Msk);
}
u32_t radio_tmr_aa_get(void)
{
return NRF_TIMER0->CC[1];
}
static u32_t radio_tmr_aa;
void radio_tmr_aa_save(u32_t aa)
{
radio_tmr_aa = aa;
}
u32_t radio_tmr_aa_restore(void)
{
/* NOTE: we dont need to restore for now, but return the saved value. */
return radio_tmr_aa;
}
u32_t radio_tmr_ready_get(void)
{
return NRF_TIMER0->CC[0];
}
u32_t radio_tmr_aa_get(void)
{
return (NRF_TIMER0->CC[1] - NRF_TIMER0->CC[0]);
}
void radio_tmr_end_capture(void)
{
NRF_PPI->CH[7].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[7].TEP = (u32_t)&(NRF_TIMER0->TASKS_CAPTURE[2]);
NRF_PPI->CHENSET = PPI_CHEN_CH7_Msk;
NRF_PPI->CH[5].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[5].TEP = (u32_t)&(NRF_TIMER0->TASKS_CAPTURE[2]);
NRF_PPI->CHENSET = PPI_CHEN_CH5_Msk;
}
u32_t radio_tmr_end_get(void)
@@ -765,19 +843,137 @@ u32_t radio_tmr_sample_get(void)
return NRF_TIMER0->CC[3];
}
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN) || \
defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
void radio_gpio_pa_setup(void)
{
NRF_GPIOTE->CONFIG[CONFIG_BT_CTLR_PA_LNA_GPIOTE_CHAN] =
(GPIOTE_CONFIG_MODE_Task <<
GPIOTE_CONFIG_MODE_Pos) |
(CONFIG_BT_CTLR_GPIO_PA_PIN <<
GPIOTE_CONFIG_PSEL_Pos) |
(GPIOTE_CONFIG_POLARITY_Toggle <<
GPIOTE_CONFIG_POLARITY_Pos) |
#if defined(CONFIG_BT_CTLR_GPIO_PA_POL_INV)
(GPIOTE_CONFIG_OUTINIT_High <<
GPIOTE_CONFIG_OUTINIT_Pos);
#else
(GPIOTE_CONFIG_OUTINIT_Low <<
GPIOTE_CONFIG_OUTINIT_Pos);
#endif
}
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
void radio_gpio_lna_setup(void)
{
NRF_GPIOTE->CONFIG[CONFIG_BT_CTLR_PA_LNA_GPIOTE_CHAN] =
(GPIOTE_CONFIG_MODE_Task <<
GPIOTE_CONFIG_MODE_Pos) |
(CONFIG_BT_CTLR_GPIO_LNA_PIN <<
GPIOTE_CONFIG_PSEL_Pos) |
(GPIOTE_CONFIG_POLARITY_Toggle <<
GPIOTE_CONFIG_POLARITY_Pos) |
#if defined(CONFIG_BT_CTLR_GPIO_LNA_POL_INV)
(GPIOTE_CONFIG_OUTINIT_High <<
GPIOTE_CONFIG_OUTINIT_Pos);
#else
(GPIOTE_CONFIG_OUTINIT_Low <<
GPIOTE_CONFIG_OUTINIT_Pos);
#endif
}
void radio_gpio_lna_on(void)
{
#if defined(CONFIG_BT_CTLR_GPIO_LNA_POL_INV)
NRF_GPIO->OUTCLR = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
#else
NRF_GPIO->OUTSET = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
#endif
}
void radio_gpio_lna_off(void)
{
#if defined(CONFIG_BT_CTLR_GPIO_LNA_POL_INV)
NRF_GPIO->OUTSET = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
#else
NRF_GPIO->OUTCLR = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
#endif
}
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
void radio_gpio_pa_lna_enable(u32_t trx_us)
{
NRF_TIMER0->CC[2] = trx_us;
NRF_TIMER0->EVENTS_COMPARE[2] = 0;
NRF_PPI->CH[7].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[2]);
NRF_PPI->CH[7].TEP = (u32_t)
&(NRF_GPIOTE->TASKS_OUT[CONFIG_BT_CTLR_PA_LNA_GPIOTE_CHAN]);
NRF_PPI->CH[8].EEP = (u32_t)&(NRF_RADIO->EVENTS_DISABLED);
NRF_PPI->CH[8].TEP = (u32_t)
&(NRF_GPIOTE->TASKS_OUT[CONFIG_BT_CTLR_PA_LNA_GPIOTE_CHAN]);
NRF_PPI->CHENSET = PPI_CHEN_CH7_Msk | PPI_CHEN_CH8_Msk;
}
void radio_gpio_pa_lna_disable(void)
{
NRF_PPI->CHENCLR = PPI_CHEN_CH7_Msk | PPI_CHEN_CH8_Msk;
}
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN || CONFIG_BT_CTLR_GPIO_LNA_PIN */
static u8_t MALIGN(4) _ccm_scratch[(RADIO_PDU_LEN_MAX - 4) + 16];
void *radio_ccm_rx_pkt_set(struct ccm *ccm, void *pkt)
void *radio_ccm_rx_pkt_set(struct ccm *ccm, u8_t phy, void *pkt)
{
u32_t mode;
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
NRF_CCM->MODE =
#if !defined(CONFIG_SOC_SERIES_NRF51X)
((CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
CCM_MODE_LENGTH_Msk) |
mode = (CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) &
CCM_MODE_MODE_Msk;
#if defined(CONFIG_SOC_SERIES_NRF52X)
/* Enable CCM support for 8-bit length field PDUs. */
mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
CCM_MODE_LENGTH_Msk;
/* Select CCM data rate based on current PHY in use. */
switch (phy) {
default:
case BIT(0):
mode |= (CCM_MODE_DATARATE_1Mbit <<
CCM_MODE_DATARATE_Pos) &
CCM_MODE_DATARATE_Msk;
break;
case BIT(1):
mode |= (CCM_MODE_DATARATE_2Mbit <<
CCM_MODE_DATARATE_Pos) &
CCM_MODE_DATARATE_Msk;
break;
#if defined(CONFIG_SOC_NRF52840)
case BIT(2):
mode |= (CCM_MODE_DATARATE_125Kbps <<
CCM_MODE_DATARATE_Pos) &
CCM_MODE_DATARATE_Msk;
NRF_CCM->RATEOVERRIDE =
(CCM_RATEOVERRIDE_RATEOVERRIDE_500Kbps <<
CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) &
CCM_RATEOVERRIDE_RATEOVERRIDE_Msk;
NRF_PPI->CH[15].EEP = (u32_t)&(NRF_RADIO->EVENTS_RATEBOOST);
NRF_PPI->CH[15].TEP = (u32_t)&(NRF_CCM->TASKS_RATEOVERRIDE);
NRF_PPI->CHENSET = PPI_CHEN_CH15_Msk;
break;
#endif /* CONFIG_SOC_NRF52840 */
}
#endif
((CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) &
CCM_MODE_MODE_Msk);
NRF_CCM->MODE = mode;
NRF_CCM->CNFPTR = (u32_t)ccm;
NRF_CCM->INPTR = (u32_t)_pkt_scratch;
NRF_CCM->OUTPTR = (u32_t)pkt;
@@ -798,15 +994,24 @@ void *radio_ccm_rx_pkt_set(struct ccm *ccm, void *pkt)
void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt)
{
u32_t mode;
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
NRF_CCM->MODE =
#if !defined(CONFIG_SOC_SERIES_NRF51X)
((CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
CCM_MODE_LENGTH_Msk) |
mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) &
CCM_MODE_MODE_Msk;
#if defined(CONFIG_SOC_SERIES_NRF52X)
/* Enable CCM support for 8-bit length field PDUs. */
mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
CCM_MODE_LENGTH_Msk;
/* NOTE: use fastest data rate as tx data needs to be prepared before
* radio Tx on any PHY.
*/
mode |= (CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos) &
CCM_MODE_DATARATE_Msk;
#endif
((CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) &
CCM_MODE_MODE_Msk);
NRF_CCM->MODE = mode;
NRF_CCM->CNFPTR = (u32_t)ccm;
NRF_CCM->INPTR = (u32_t)pkt;
NRF_CCM->OUTPTR = (u32_t)_pkt_scratch;
@@ -844,13 +1049,19 @@ static u8_t MALIGN(4) _aar_scratch[3];
void radio_ar_configure(u32_t nirk, void *irk)
{
NRF_AAR->ENABLE = 1;
NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos) &
AAR_ENABLE_ENABLE_Msk;
NRF_AAR->NIRK = nirk;
NRF_AAR->IRKPTR = (u32_t)irk;
NRF_AAR->ADDRPTR = (u32_t)NRF_RADIO->PACKETPTR - 1;
NRF_AAR->SCRATCHPTR = (u32_t)&_aar_scratch[0];
NRF_AAR->EVENTS_END = 0;
NRF_AAR->EVENTS_RESOLVED = 0;
NRF_AAR->EVENTS_NOTRESOLVED = 0;
radio_bc_configure(64);
radio_bc_status_reset();
NRF_PPI->CH[6].EEP = (u32_t)&(NRF_RADIO->EVENTS_BCMATCH);
NRF_PPI->CH[6].TEP = (u32_t)&(NRF_AAR->TASKS_START);
@@ -864,18 +1075,16 @@ u32_t radio_ar_match_get(void)
void radio_ar_status_reset(void)
{
if (radio_bc_has_match()) {
NRF_AAR->EVENTS_END = 0;
NRF_AAR->EVENTS_RESOLVED = 0;
NRF_AAR->EVENTS_NOTRESOLVED = 0;
}
radio_bc_status_reset();
NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos) &
AAR_ENABLE_ENABLE_Msk;
}
u32_t radio_ar_has_match(void)
{
return (radio_bc_has_match() &&
(NRF_AAR->EVENTS_END) &&
(NRF_AAR->EVENTS_RESOLVED));
NRF_AAR->EVENTS_END &&
NRF_AAR->EVENTS_RESOLVED &&
!NRF_AAR->EVENTS_NOTRESOLVED);
}

View File

@@ -13,6 +13,7 @@ typedef void (*radio_isr_fp) (void);
void isr_radio(void);
void radio_isr_set(radio_isr_fp fp_radio_isr);
void radio_setup(void);
void radio_reset(void);
void radio_phy_set(u8_t phy, u8_t flags);
void radio_tx_power_set(u32_t power);
@@ -67,17 +68,27 @@ void radio_tmr_status_reset(void);
void radio_tmr_tifs_set(u32_t tifs);
u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder);
void radio_tmr_start_us(u8_t trx, u32_t us);
u32_t radio_tmr_start_now(u8_t trx);
void radio_tmr_stop(void);
void radio_tmr_hcto_configure(u32_t hcto);
void radio_tmr_aa_capture(void);
u32_t radio_tmr_ready_get(void);
u32_t radio_tmr_aa_get(void);
void radio_tmr_aa_save(u32_t aa);
u32_t radio_tmr_aa_restore(void);
u32_t radio_tmr_ready_get(void);
void radio_tmr_end_capture(void);
u32_t radio_tmr_end_get(void);
void radio_tmr_sample(void);
u32_t radio_tmr_sample_get(void);
void *radio_ccm_rx_pkt_set(struct ccm *ccm, void *pkt);
void radio_gpio_pa_setup(void);
void radio_gpio_lna_setup(void);
void radio_gpio_lna_on(void);
void radio_gpio_lna_off(void);
void radio_gpio_pa_lna_enable(u32_t trx_us);
void radio_gpio_pa_lna_disable(void);
void *radio_ccm_rx_pkt_set(struct ccm *ccm, u8_t phy, void *pkt);
void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt);
u32_t radio_ccm_is_done(void);
u32_t radio_ccm_mic_is_valid(void);

View File

@@ -57,6 +57,7 @@ static u32_t dup_curr;
s32_t hci_hbuf_total;
u32_t hci_hbuf_sent;
u32_t hci_hbuf_acked;
u16_t hci_hbuf_pend[CONFIG_BT_MAX_CONN];
atomic_t hci_state_mask;
static struct k_poll_signal *hbuf_signal;
#endif
@@ -214,6 +215,7 @@ static void reset(struct net_buf *buf, struct net_buf **evt)
hci_hbuf_total = 0;
hci_hbuf_sent = 0;
hci_hbuf_acked = 0;
memset(hci_hbuf_pend, 0, sizeof(hci_hbuf_pend));
conn_count = 0;
if (buf) {
atomic_set_bit(&hci_state_mask, HCI_STATE_BIT_RESET);
@@ -261,6 +263,7 @@ static void set_ctl_to_host_flow(struct net_buf *buf, struct net_buf **evt)
hci_hbuf_sent = 0;
hci_hbuf_acked = 0;
memset(hci_hbuf_pend, 0, sizeof(hci_hbuf_pend));
hci_hbuf_total = -hci_hbuf_total;
}
@@ -310,7 +313,18 @@ static void host_num_completed_packets(struct net_buf *buf,
/* leave *evt == NULL so no event is generated */
for (i = 0; i < cmd->num_handles; i++) {
count += sys_le16_to_cpu(cmd->h[i].count);
u16_t h = sys_le16_to_cpu(cmd->h[i].handle);
u16_t c = sys_le16_to_cpu(cmd->h[i].count);
if ((h >= ARRAY_SIZE(hci_hbuf_pend)) ||
(c > hci_hbuf_pend[h])) {
ccst = cmd_complete(evt, sizeof(*ccst));
ccst->status = BT_HCI_ERR_INVALID_PARAM;
return;
}
hci_hbuf_pend[h] -= c;
count += c;
}
BT_DBG("FC: acked: %d", count);
@@ -1673,10 +1687,12 @@ static void vs_read_supported_commands(struct net_buf *buf,
/* Set Version Information, Supported Commands, Supported Features. */
rp->commands[0] |= BIT(0) | BIT(1) | BIT(2);
#if defined(CONFIG_BT_CTLR_HCI_VS_EXT)
#if defined(CONFIG_BT_HCI_VS_EXT)
/* Write BD_ADDR, Read Build Info */
rp->commands[0] |= BIT(5) | BIT(7);
/* Read Static Addresses, Read Key Hierarchy Roots */
rp->commands[1] |= BIT(0) | BIT(1);
#endif /* CONFIG_BT_CTLR_HCI_VS_EXT */
#endif /* CONFIG_BT_HCI_VS_EXT */
}
static void vs_read_supported_features(struct net_buf *buf,
@@ -1690,7 +1706,41 @@ static void vs_read_supported_features(struct net_buf *buf,
memset(&rp->features[0], 0x00, sizeof(rp->features));
}
#if defined(CONFIG_BT_CTLR_HCI_VS_EXT)
#if defined(CONFIG_BT_HCI_VS_EXT)
static void vs_write_bd_addr(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_cp_vs_write_bd_addr *cmd = (void *)buf->data;
struct bt_hci_evt_cc_status *ccst;
ll_addr_set(0, &cmd->bdaddr.val[0]);
ccst = cmd_complete(evt, sizeof(*ccst));
ccst->status = 0x00;
}
static void vs_read_build_info(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_rp_vs_read_build_info *rp;
#define BUILD_TIMESTAMP " " __DATE__ " " __TIME__
#define HCI_VS_BUILD_INFO "Zephyr OS v" \
KERNEL_VERSION_STRING BUILD_TIMESTAMP CONFIG_BT_CTLR_HCI_VS_BUILD_INFO
const char build_info[] = HCI_VS_BUILD_INFO;
#define BUILD_INFO_EVT_LEN (sizeof(struct bt_hci_evt_hdr) + \
sizeof(struct bt_hci_evt_cmd_complete) + \
sizeof(struct bt_hci_rp_vs_read_build_info) + \
sizeof(build_info))
BUILD_ASSERT(CONFIG_BT_RX_BUF_LEN >= BUILD_INFO_EVT_LEN);
rp = cmd_complete(evt, sizeof(*rp) + sizeof(build_info));
rp->status = 0x00;
memcpy(rp->info, build_info, sizeof(build_info));
}
static void vs_read_static_addrs(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_rp_vs_read_static_addrs *rp;
@@ -1707,6 +1757,7 @@ static void vs_read_static_addrs(struct net_buf *buf, struct net_buf **evt)
struct bt_hci_vs_static_addr *addr;
rp = cmd_complete(evt, sizeof(*rp) + sizeof(*addr));
rp->status = 0x00;
rp->num_addrs = 1;
addr = &rp->a[0];
@@ -1776,7 +1827,7 @@ static void vs_read_key_hierarchy_roots(struct net_buf *buf,
#endif /* CONFIG_SOC_FAMILY_NRF5 */
}
#endif /* CONFIG_BT_CTLR_HCI_VS_EXT */
#endif /* CONFIG_BT_HCI_VS_EXT */
static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd,
struct net_buf **evt)
@@ -1794,7 +1845,15 @@ static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd,
vs_read_supported_features(cmd, evt);
break;
#if defined(CONFIG_BT_CTLR_HCI_VS_EXT)
#if defined(CONFIG_BT_HCI_VS_EXT)
case BT_OCF(BT_HCI_OP_VS_READ_BUILD_INFO):
vs_read_build_info(cmd, evt);
break;
case BT_OCF(BT_HCI_OP_VS_WRITE_BD_ADDR):
vs_write_bd_addr(cmd, evt);
break;
case BT_OCF(BT_HCI_OP_VS_READ_STATIC_ADDRS):
vs_read_static_addrs(cmd, evt);
break;
@@ -1802,7 +1861,7 @@ static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd,
case BT_OCF(BT_HCI_OP_VS_READ_KEY_HIERARCHY_ROOTS):
vs_read_key_hierarchy_roots(cmd, evt);
break;
#endif /* CONFIG_BT_CTLR_HCI_VS_EXT */
#endif /* CONFIG_BT_HCI_VS_EXT */
default:
return -EINVAL;
@@ -1811,6 +1870,21 @@ static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd,
return 0;
}
static void data_buf_overflow(struct net_buf **buf)
{
struct bt_hci_evt_data_buf_overflow *ep;
if (!(event_mask & BT_EVT_MASK_DATA_BUFFER_OVERFLOW)) {
return;
}
*buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
evt_create(*buf, BT_HCI_EVT_DATA_BUF_OVERFLOW, sizeof(*ep));
ep = net_buf_add(*buf, sizeof(*ep));
ep->link_type = BT_OVERFLOW_LINK_ACL;
}
struct net_buf *hci_cmd_handle(struct net_buf *cmd)
{
struct bt_hci_evt_cc_status *ccst;
@@ -1869,7 +1943,7 @@ struct net_buf *hci_cmd_handle(struct net_buf *cmd)
return evt;
}
int hci_acl_handle(struct net_buf *buf)
int hci_acl_handle(struct net_buf *buf, struct net_buf **evt)
{
struct radio_pdu_node_tx *radio_pdu_node_tx;
struct bt_hci_acl_hdr *acl;
@@ -1878,6 +1952,8 @@ int hci_acl_handle(struct net_buf *buf)
u8_t flags;
u16_t len;
*evt = NULL;
if (buf->len < sizeof(*acl)) {
BT_ERR("No HCI ACL header");
return -EINVAL;
@@ -1900,6 +1976,7 @@ int hci_acl_handle(struct net_buf *buf)
radio_pdu_node_tx = radio_tx_mem_acquire();
if (!radio_pdu_node_tx) {
BT_ERR("Tx Buffer Overflow");
data_buf_overflow(evt);
return -ENOBUFS;
}
@@ -2314,6 +2391,13 @@ static void disconn_complete(struct pdu_data *pdu_data, u16_t handle,
ep->handle = sys_cpu_to_le16(handle);
ep->reason = *((u8_t *)pdu_data);
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
/* Clear any pending packets upon disconnection */
/* Note: This requires linear handle values starting from 0 */
LL_ASSERT(handle < ARRAY_SIZE(hci_hbuf_pend));
hci_hbuf_acked += hci_hbuf_pend[handle];
hci_hbuf_pend[handle] = 0;
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */
conn_count--;
}
@@ -2753,6 +2837,11 @@ void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf)
LL_ASSERT((hci_hbuf_sent - hci_hbuf_acked) <
hci_hbuf_total);
hci_hbuf_sent++;
/* Note: This requires linear handle values starting
* from 0
*/
LL_ASSERT(handle < ARRAY_SIZE(hci_hbuf_pend));
hci_hbuf_pend[handle]++;
}
#endif
break;

View File

@@ -186,11 +186,14 @@ static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx)
}
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
static inline struct net_buf *process_hbuf(void)
static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n)
{
/* shadow total count in case of preemption */
struct radio_pdu_node_rx *node_rx = NULL;
s32_t hbuf_total = hci_hbuf_total;
struct net_buf *buf = NULL;
sys_snode_t *node = NULL;
s8_t class;
int reset;
reset = atomic_test_and_clear_bit(&hci_state_mask, HCI_STATE_BIT_RESET);
@@ -199,67 +202,73 @@ static inline struct net_buf *process_hbuf(void)
sys_slist_init(&hbuf_pend);
}
if (hbuf_total > 0) {
struct radio_pdu_node_rx *node_rx = NULL;
s8_t class, next_class = -1;
sys_snode_t *node = NULL;
if (hbuf_total <= 0) {
hbuf_count = -1;
return NULL;
}
/* available host buffers */
/* available host buffers */
hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* host acked ACL packets, try to dequeue from hbuf */
node = sys_slist_peek_head(&hbuf_pend);
if (!node) {
return NULL;
}
/* Return early if this iteration already has a node to process */
node_rx = NODE_RX(node);
class = hci_get_class(node_rx);
if (n) {
if (class == HCI_CLASS_EVT_CONNECTION ||
(class == HCI_CLASS_ACL_DATA && hbuf_count)) {
/* node to process later, schedule an iteration */
BT_DBG("FC: signalling");
k_poll_signal(&hbuf_signal, 0x0);
}
return NULL;
}
switch (class) {
case HCI_CLASS_EVT_CONNECTION:
BT_DBG("FC: dequeueing event");
(void) sys_slist_get(&hbuf_pend);
break;
case HCI_CLASS_ACL_DATA:
if (hbuf_count) {
BT_DBG("FC: dequeueing ACL data");
(void) sys_slist_get(&hbuf_pend);
} else {
/* no buffers, HCI will signal */
node = NULL;
}
break;
case HCI_CLASS_EVT_DISCARDABLE:
case HCI_CLASS_EVT_REQUIRED:
default:
LL_ASSERT(0);
break;
}
if (node) {
buf = encode_node(node_rx, class);
/* Update host buffers after encoding */
hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* host acked ACL packets, try to dequeue from hbuf */
/* next node */
node = sys_slist_peek_head(&hbuf_pend);
if (node) {
node_rx = NODE_RX(node);
class = hci_get_class(node_rx);
switch (class) {
case HCI_CLASS_EVT_CONNECTION:
BT_DBG("FC: dequeueing event");
node = sys_slist_get(&hbuf_pend);
break;
case HCI_CLASS_ACL_DATA:
if (hbuf_count) {
BT_DBG("FC: dequeueing ACL data");
node = sys_slist_get(&hbuf_pend);
hbuf_count--;
} else {
/* no buffers, HCI will signal */
node = NULL;
}
break;
case HCI_CLASS_EVT_DISCARDABLE:
case HCI_CLASS_EVT_REQUIRED:
default:
LL_ASSERT(0);
break;
}
if (node) {
struct radio_pdu_node_rx *next;
bool empty = true;
node_rx = NODE_RX(node);
node = sys_slist_peek_head(&hbuf_pend);
if (node) {
next = NODE_RX(node);
next_class = hci_get_class(next);
}
empty = sys_slist_is_empty(&hbuf_pend);
buf = encode_node(node_rx, class);
if (!empty && (class == HCI_CLASS_EVT_CONNECTION ||
(class == HCI_CLASS_ACL_DATA &&
hbuf_count))) {
/* more to process, schedule an
* iteration
*/
BT_DBG("FC: signalling");
k_poll_signal(&hbuf_signal, 0x0);
}
if (class == HCI_CLASS_EVT_CONNECTION ||
(class == HCI_CLASS_ACL_DATA && hbuf_count)) {
/* more to process, schedule an
* iteration
*/
BT_DBG("FC: signalling");
k_poll_signal(&hbuf_signal, 0x0);
}
}
} else {
hbuf_count = -1;
}
return buf;
@@ -301,7 +310,7 @@ static void recv_thread(void *p1, void *p2, void *p3)
events[1].state = K_POLL_STATE_NOT_READY;
/* process host buffers first if any */
buf = process_hbuf();
buf = process_hbuf(node_rx);
#else
node_rx = k_fifo_get(&recv_fifo, K_FOREVER);
@@ -347,6 +356,22 @@ static int cmd_handle(struct net_buf *buf)
return 0;
}
#if defined(CONFIG_BT_CONN)
static int acl_handle(struct net_buf *buf)
{
struct net_buf *evt;
int err;
err = hci_acl_handle(buf, &evt);
if (evt) {
BT_DBG("Replying with event of %u bytes", evt->len);
bt_recv_prio(evt);
}
return err;
}
#endif /* CONFIG_BT_CONN */
static int hci_driver_send(struct net_buf *buf)
{
u8_t type;
@@ -363,9 +388,9 @@ static int hci_driver_send(struct net_buf *buf)
switch (type) {
#if defined(CONFIG_BT_CONN)
case BT_BUF_ACL_OUT:
err = hci_acl_handle(buf);
err = acl_handle(buf);
break;
#endif
#endif /* CONFIG_BT_CONN */
case BT_BUF_CMD:
err = cmd_handle(buf);
break;

View File

@@ -39,7 +39,7 @@ struct net_buf *hci_cmd_handle(struct net_buf *cmd);
void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf);
s8_t hci_get_class(struct radio_pdu_node_rx *node_rx);
#if defined(CONFIG_BT_CONN)
int hci_acl_handle(struct net_buf *acl);
int hci_acl_handle(struct net_buf *acl, struct net_buf **evt);
void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf);
void hci_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -175,17 +175,12 @@
****************************************************************************/
/* Minimum LL Payload support (Dont change). */
#define RADIO_LL_LENGTH_OCTETS_RX_MIN 27
#define RADIO_LL_LENGTH_TIME_RX_MIN (((RADIO_LL_LENGTH_OCTETS_RX_MIN) \
+ 14) * 8 \
)
/* Maximum LL Payload support (27 to 251). */
#ifndef RADIO_LL_LENGTH_OCTETS_RX_MAX
#define RADIO_LL_LENGTH_OCTETS_RX_MAX 251
#endif
#define RADIO_LL_LENGTH_TIME_RX_MAX (((RADIO_LL_LENGTH_OCTETS_RX_MAX) \
+ 14) * 8 \
)
/* Implementation default L2CAP MTU */
#ifndef RADIO_L2CAP_MTU_MAX
#define RADIO_L2CAP_MTU_MAX (RADIO_LL_LENGTH_OCTETS_RX_MAX - 4)

View File

@@ -165,6 +165,7 @@ struct connection {
#endif /* CONFIG_BT_CTLR_PHY */
struct {
u8_t initiate;
u8_t error_code;
u8_t rand[8];
u8_t ediv[2];

View File

@@ -9,8 +9,10 @@
#include <toolchain.h>
#include <zephyr/types.h>
#include <soc.h>
#include <clock_control.h>
#include "hal/cpu.h"
#include "hal/cntr.h"
#include "hal/ccm.h"
#include "hal/radio.h"
@@ -72,20 +74,25 @@ static const u8_t prbs9[] = {
/* TODO: fill correct prbs15 */
static const u8_t prbs15[255] = { 0x00, };
static u8_t tx_req;
static u8_t volatile tx_ack;
static void isr_tx(void)
{
u8_t trx_done;
u32_t l, i, s, t;
/* Read radio status and events */
trx_done = radio_is_done();
/* Clear radio status and events */
radio_status_reset();
radio_tmr_status_reset();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_lna_disable();
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
/* Exit if radio disabled */
if (!trx_done) {
if (((tx_req - tx_ack) & 0x01) == 0) {
tx_ack = tx_req;
return;
}
@@ -108,7 +115,14 @@ static void isr_tx(void)
radio_tmr_aa_capture();
radio_tmr_end_capture();
/* TODO: check for probable stall timer capture being set */
/* TODO: check for probable stale timer capture being set */
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(t + radio_tx_ready_delay_get(test_phy,
test_phy_flags) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
}
static void isr_rx(void)
@@ -171,6 +185,7 @@ static u32_t init(u8_t chan, u8_t phy, void (*isr)(void))
/* Setup Radio in Tx/Rx */
/* NOTE: No whitening in test mode. */
radio_phy_set(test_phy, test_phy_flags);
radio_tmr_tifs_set(150);
radio_tx_power_set(0);
radio_freq_chan_set((chan << 1) + 2);
radio_aa_set((u8_t *)&test_sync_word);
@@ -182,6 +197,7 @@ static u32_t init(u8_t chan, u8_t phy, void (*isr)(void))
u32_t ll_test_tx(u8_t chan, u8_t len, u8_t type, u8_t phy)
{
u32_t start_us;
u8_t *payload;
u8_t *pdu;
u32_t err;
@@ -195,6 +211,8 @@ u32_t ll_test_tx(u8_t chan, u8_t len, u8_t type, u8_t phy)
return err;
}
tx_req++;
pdu = radio_pkt_scratch_get();
payload = &pdu[2];
@@ -237,10 +255,20 @@ u32_t ll_test_tx(u8_t chan, u8_t len, u8_t type, u8_t phy)
radio_pkt_tx_set(pdu);
radio_switch_complete_and_disable();
radio_tmr_start(1, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
start_us = radio_tmr_start(1, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
radio_tmr_aa_capture();
radio_tmr_end_capture();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(start_us +
radio_tx_ready_delay_get(test_phy,
test_phy_flags) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#else /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
ARG_UNUSED(start_us);
#endif /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
started = true;
return 0;
@@ -263,6 +291,10 @@ u32_t ll_test_rx(u8_t chan, u8_t phy, u8_t mod_idx)
radio_switch_complete_and_rx(test_phy);
radio_tmr_start(0, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_on();
#endif /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
started = true;
return 0;
@@ -271,6 +303,7 @@ u32_t ll_test_rx(u8_t chan, u8_t phy, u8_t mod_idx)
u32_t ll_test_end(u16_t *num_rx)
{
struct device *hf_clock;
u8_t ack;
if (!started) {
return 1;
@@ -280,8 +313,17 @@ u32_t ll_test_end(u16_t *num_rx)
*num_rx = test_num_rx;
test_num_rx = 0;
/* Disable Radio */
radio_disable();
/* Disable Radio, if in Rx test */
ack = tx_ack;
if (tx_req == ack) {
radio_disable();
} else {
/* Wait for Tx to complete */
tx_req = ack + 2;
while (tx_req != tx_ack) {
cpu_sleep();
}
}
/* Stop packet timer */
radio_tmr_stop();
@@ -293,6 +335,10 @@ u32_t ll_test_end(u16_t *num_rx)
/* Stop coarse timer */
cntr_stop();
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_off();
#endif /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
started = false;
return 0;

View File

@@ -67,14 +67,6 @@ endif # BT_MESH_PROXY
endif # BT_CONN
config BT_MESH_LOCAL_INTERFACE
bool "Local network interface"
default y
help
This is needed in order to send messages between two local Mesh
elements. Only disable it if you're sure this will not be needed
(which helps save a little bit of memory).
config BT_MESH_SELF_TEST
bool "Perform self-tests"
help

View File

@@ -103,15 +103,15 @@ static void mod_publish(struct k_work *work)
BT_DBG("");
if (pub->func) {
pub->func(pub->mod);
}
period_ms = bt_mesh_model_pub_period_get(pub->mod);
BT_DBG("period %u ms", period_ms);
if (period_ms) {
k_delayed_work_submit(&pub->timer, period_ms);
}
if (pub->func) {
pub->func(pub->mod);
}
}
static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,

View File

@@ -83,6 +83,10 @@ static void hb_send(struct bt_mesh_model *model)
feat |= BT_MESH_FEAT_RELAY;
}
if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) {
feat |= BT_MESH_FEAT_PROXY;
}
if (bt_mesh_friend_get() == BT_MESH_FRIEND_ENABLED) {
feat |= BT_MESH_FEAT_FRIEND;
}
@@ -95,7 +99,7 @@ static void hb_send(struct bt_mesh_model *model)
hb.feat = sys_cpu_to_be16(feat);
BT_DBG("InitTTL %u feat 0x%02x", cfg->hb_pub.ttl, feat);
BT_DBG("InitTTL %u feat 0x%04x", cfg->hb_pub.ttl, feat);
bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), NULL);
}
@@ -143,6 +147,14 @@ static int comp_get_page_0(struct net_buf_simple *buf)
feat |= BT_MESH_FEAT_RELAY;
}
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
feat |= BT_MESH_FEAT_PROXY;
}
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
feat |= BT_MESH_FEAT_FRIEND;
}
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
feat |= BT_MESH_FEAT_LOW_POWER;
}
@@ -1212,11 +1224,7 @@ static void send_mod_sub_status(struct bt_mesh_model *model,
net_buf_simple_add_u8(msg, status);
net_buf_simple_add_le16(msg, elem_addr);
if (status) {
net_buf_simple_add_le16(msg, BT_MESH_ADDR_UNASSIGNED);
} else {
net_buf_simple_add_le16(msg, sub_addr);
}
net_buf_simple_add_le16(msg, sub_addr);
if (vnd) {
memcpy(net_buf_simple_add(msg, 4), mod_id, 4);
@@ -1694,7 +1702,7 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
u16_t elem_addr, sub_addr;
u16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED;
struct bt_mesh_model *mod;
struct bt_mesh_elem *elem;
u8_t *label_uuid;
@@ -2489,12 +2497,17 @@ static void lpn_timeout_get(struct bt_mesh_model *model,
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x lpn_addr 0x%02x",
ctx->net_idx, ctx->app_idx, ctx->addr, lpn_addr);
if (!BT_MESH_ADDR_IS_UNICAST(lpn_addr)) {
BT_WARN("Invalid LPNAddress; ignoring msg");
return;
}
bt_mesh_model_msg_init(msg, OP_LPN_TIMEOUT_STATUS);
net_buf_simple_add_le16(msg, lpn_addr);
memset(net_buf_simple_add(msg, 3), 0, 3);
if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
BT_ERR("Unable to send Friend Status");
BT_ERR("Unable to send LPN PollTimeout Status");
}
}
@@ -2577,7 +2590,7 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
} else if ((sub->kr_phase == BT_MESH_KR_PHASE_1 ||
sub->kr_phase == BT_MESH_KR_PHASE_2) &&
phase == BT_MESH_KR_PHASE_3) {
memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0]));
bt_mesh_net_revoke_keys(sub);
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) ||
IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
bt_mesh_friend_cred_refresh(ctx->net_idx);
@@ -2652,18 +2665,18 @@ send:
bt_mesh_model_send(model, ctx, msg, NULL, NULL);
}
static void hearbeat_pub_get(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
static void heartbeat_pub_get(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
BT_DBG("src 0x%04x", ctx->addr);
hb_pub_send_status(model, ctx, STATUS_SUCCESS, NULL);
}
static void hearbeat_pub_set(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
static void heartbeat_pub_set(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct hb_pub_param *param = (void *)buf->data;
struct bt_mesh_cfg *cfg = model->user_data;
@@ -2725,7 +2738,7 @@ static void hearbeat_pub_set(struct bt_mesh_model *model,
* as possible after the Heartbeat Publication Period state
* has been configured for periodic publishing.
*/
if (param->period_log) {
if (param->period_log && param->count_log) {
k_work_submit(&cfg->hb_pub.timer.work);
} else {
k_delayed_work_cancel(&cfg->hb_pub.timer);
@@ -2772,18 +2785,18 @@ static void hb_sub_send_status(struct bt_mesh_model *model,
bt_mesh_model_send(model, ctx, msg, NULL, NULL);
}
static void hearbeat_sub_get(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
static void heartbeat_sub_get(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
BT_DBG("src 0x%04x", ctx->addr);
hb_sub_send_status(model, ctx, STATUS_SUCCESS);
}
static void hearbeat_sub_set(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
static void heartbeat_sub_set(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_cfg *cfg = model->user_data;
u16_t sub_src, sub_dst;
@@ -2820,21 +2833,25 @@ static void hearbeat_sub_set(struct bt_mesh_model *model,
sub_period == 0x00) {
cfg->hb_sub.src = BT_MESH_ADDR_UNASSIGNED;
cfg->hb_sub.dst = BT_MESH_ADDR_UNASSIGNED;
cfg->hb_sub.min_hops = 0;
cfg->hb_sub.max_hops = 0;
period_ms = 0;
} else {
cfg->hb_sub.src = sub_src;
cfg->hb_sub.dst = sub_dst;
cfg->hb_sub.min_hops = 0x7f;
cfg->hb_sub.max_hops = 0;
period_ms = hb_pwr2(sub_period, 1) * 1000;
}
BT_DBG("period_ms %u", period_ms);
cfg->hb_sub.count = 0;
cfg->hb_sub.min_hops = 0x7f;
cfg->hb_sub.max_hops = 0;
if (period_ms) {
cfg->hb_sub.expiry = k_uptime_get() + period_ms;
} else {
cfg->hb_sub.expiry = 0;
}
hb_sub_send_status(model, ctx, STATUS_SUCCESS);
@@ -2884,10 +2901,10 @@ const struct bt_mesh_model_op bt_mesh_cfg_op[] = {
{ OP_LPN_TIMEOUT_GET, 2, lpn_timeout_get },
{ OP_KRP_GET, 2, krp_get },
{ OP_KRP_SET, 3, krp_set },
{ OP_HEARTBEAT_PUB_GET, 0, hearbeat_pub_get },
{ OP_HEARTBEAT_PUB_SET, 9, hearbeat_pub_set },
{ OP_HEARTBEAT_SUB_GET, 0, hearbeat_sub_get },
{ OP_HEARTBEAT_SUB_SET, 5, hearbeat_sub_set },
{ OP_HEARTBEAT_PUB_GET, 0, heartbeat_pub_get },
{ OP_HEARTBEAT_PUB_SET, 9, heartbeat_pub_set },
{ OP_HEARTBEAT_SUB_GET, 0, heartbeat_sub_get },
{ OP_HEARTBEAT_SUB_SET, 5, heartbeat_sub_set },
BT_MESH_MODEL_OP_END,
};
@@ -2899,7 +2916,7 @@ static void hb_publish(struct k_work *work)
struct bt_mesh_subnet *sub;
u16_t period_ms;
BT_DBG("");
BT_DBG("hb_pub.count: %u", cfg->hb_pub.count);
sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx);
if (!sub) {
@@ -2911,6 +2928,10 @@ static void hb_publish(struct k_work *work)
hb_send(model);
if (cfg->hb_pub.count == 0) {
return;
}
if (cfg->hb_pub.count != 0xffff) {
cfg->hb_pub.count--;
}
@@ -2960,7 +2981,7 @@ int bt_mesh_conf_init(struct bt_mesh_model *model, bool primary)
}
if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
cfg->frnd = BT_MESH_RELAY_NOT_SUPPORTED;
cfg->frnd = BT_MESH_FRIEND_NOT_SUPPORTED;
}
if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {

View File

@@ -66,7 +66,7 @@
#define OP_HEALTH_FAULT_TEST BT_MESH_MODEL_OP_2(0x80, 0x32)
#define OP_HEALTH_FAULT_TEST_UNREL BT_MESH_MODEL_OP_2(0x80, 0x33)
#define OP_HEALTH_PERIOD_GET BT_MESH_MODEL_OP_2(0x80, 0x34)
#define OP_HEALTH_PERIOD_SET BT_MESH_MODEL_OP_2(0x80, 0x34)
#define OP_HEALTH_PERIOD_SET BT_MESH_MODEL_OP_2(0x80, 0x35)
#define OP_HEALTH_PERIOD_SET_UNREL BT_MESH_MODEL_OP_2(0x80, 0x36)
#define OP_HEALTH_PERIOD_STATUS BT_MESH_MODEL_OP_2(0x80, 0x37)
#define OP_HEARTBEAT_PUB_GET BT_MESH_MODEL_OP_2(0x80, 0x38)

View File

@@ -79,6 +79,7 @@ static size_t health_get_current(struct bt_mesh_model *mod,
struct net_buf_simple *msg)
{
struct bt_mesh_health *srv = mod->user_data;
const struct bt_mesh_comp *comp;
u8_t *test_id, *company_ptr;
u16_t company_id;
u8_t fault_count;
@@ -88,6 +89,7 @@ static size_t health_get_current(struct bt_mesh_model *mod,
test_id = net_buf_simple_add(msg, 1);
company_ptr = net_buf_simple_add(msg, sizeof(company_id));
comp = bt_mesh_comp_get();
fault_count = net_buf_simple_tailroom(msg) - 4;
@@ -97,16 +99,17 @@ static size_t health_get_current(struct bt_mesh_model *mod,
&fault_count);
if (err) {
BT_ERR("Failed to get faults (err %d)", err);
sys_put_le16(0, company_ptr);
sys_put_le16(comp->cid, company_ptr);
*test_id = HEALTH_TEST_STANDARD;
fault_count = 0;
} else {
sys_put_le16(company_id, company_ptr);
net_buf_simple_add(msg, fault_count);
}
} else {
BT_WARN("No callback for getting faults");
net_buf_simple_push_u8(msg, HEALTH_TEST_STANDARD);
net_buf_simple_push_le16(msg, 0);
sys_put_le16(comp->cid, company_ptr);
*test_id = HEALTH_TEST_STANDARD;
fault_count = 0;
}
@@ -213,7 +216,13 @@ static void health_fault_test(struct bt_mesh_model *model,
BT_DBG("test 0x%02x company 0x%04x", test_id, company_id);
if (srv->fault_test) {
srv->fault_test(model, test_id, company_id);
int err;
err = srv->fault_test(model, test_id, company_id);
if (err) {
BT_WARN("Running fault test failed with err %d", err);
return;
}
}
health_get_registered(model, company_id, msg);
@@ -279,11 +288,10 @@ static void send_health_period_status(struct bt_mesh_model *model,
{
/* Needed size: opcode (2 bytes) + msg + MIC */
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4);
struct bt_mesh_health *srv = model->user_data;
bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_STATUS);
net_buf_simple_add_u8(msg, srv->period);
net_buf_simple_add_u8(msg, model->pub->period_div);
bt_mesh_model_send(model, ctx, msg, NULL, NULL);
}
@@ -301,7 +309,6 @@ static void health_period_set_unrel(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health *srv = model->user_data;
u8_t period;
period = net_buf_simple_pull_u8(buf);
@@ -312,7 +319,7 @@ static void health_period_set_unrel(struct bt_mesh_model *model,
BT_DBG("period %u", period);
srv->period = period;
model->pub->period_div = period;
}
static void health_period_set(struct bt_mesh_model *model,
@@ -344,16 +351,13 @@ const struct bt_mesh_model_op bt_mesh_health_op[] = {
static void health_pub(struct bt_mesh_model *mod)
{
struct net_buf_simple *msg = NET_BUF_SIMPLE(HEALTH_STATUS_SIZE);
struct bt_mesh_health *srv = mod->user_data;
size_t count;
int err;
BT_DBG("");
count = health_get_current(mod, msg);
if (count) {
mod->pub->period_div = srv->period;
} else {
if (!count) {
mod->pub->period_div = 0;
}

View File

@@ -12,6 +12,7 @@
#define BT_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000)
#define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00)
#define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000)
#define BT_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfffb)
struct bt_mesh_net;

View File

@@ -68,6 +68,7 @@ static u16_t msg_cache_next;
/* Singleton network context (the implementation only supports one) */
struct bt_mesh_net bt_mesh = {
.local_queue = _K_FIFO_INITIALIZER(bt_mesh.local_queue),
.sub = {
[0 ... (CONFIG_BT_MESH_SUBNET_COUNT - 1)] = {
.net_idx = BT_MESH_KEY_UNUSED,
@@ -470,6 +471,26 @@ int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
return 0;
}
void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub)
{
int i;
BT_DBG("idx 0x%04x", sub->net_idx);
memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0]));
for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
struct bt_mesh_app_key *key = &bt_mesh.app_keys[i];
if (key->net_idx != sub->net_idx || !key->updated) {
continue;
}
memcpy(&key->keys[0], &key->keys[1], sizeof(key->keys[0]));
key->updated = false;
}
}
bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key)
{
if (new_kr != sub->kr_flag && sub->kr_phase == BT_MESH_KR_NORMAL) {
@@ -501,8 +522,7 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key)
*/
case BT_MESH_KR_PHASE_2:
BT_DBG("KR Phase 0x%02x -> Normal", sub->kr_phase);
memcpy(&sub->keys[0], &sub->keys[1],
sizeof(sub->keys[0]));
bt_mesh_net_revoke_keys(sub);
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) ||
IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
bt_mesh_friend_cred_refresh(sub->net_idx);
@@ -677,7 +697,6 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
return 0;
}
#if defined(CONFIG_BT_MESH_LOCAL_INTERFACE)
static void bt_mesh_net_local(struct k_work *work)
{
struct net_buf *buf;
@@ -688,7 +707,6 @@ static void bt_mesh_net_local(struct k_work *work)
net_buf_unref(buf);
}
}
#endif
int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf,
bool proxy)
@@ -801,7 +819,6 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
}
}
#if defined(CONFIG_BT_MESH_LOCAL_INTERFACE)
/* Deliver to local network interface if necessary */
if (bt_mesh_fixed_group_match(tx->ctx->addr) ||
bt_mesh_elem_find(tx->ctx->addr)) {
@@ -813,9 +830,6 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
} else {
bt_mesh_adv_send(buf, cb);
}
#else
bt_mesh_adv_send(buf, cb);
#endif
done:
net_buf_unref(buf);
@@ -975,9 +989,6 @@ static int net_find_and_decrypt(const u8_t *data, size_t data_len,
return false;
}
#if (defined(CONFIG_BT_MESH_RELAY) || \
defined(CONFIG_BT_MESH_FRIEND) || \
defined(CONFIG_BT_MESH_GATT_PROXY))
static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
struct bt_mesh_net_rx *rx)
{
@@ -988,7 +999,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
BT_DBG("TTL %u CTL %u dst 0x%04x", rx->ctx.recv_ttl, CTL(sbuf->data),
rx->dst);
if (rx->ctx.recv_ttl <= 1) {
if (rx->net_if != BT_MESH_NET_IF_LOCAL && rx->ctx.recv_ttl <= 1) {
return;
}
@@ -1081,7 +1092,6 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
done:
net_buf_unref(buf);
}
#endif /* RELAY || FRIEND || GATT_PROXY */
int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if,
struct bt_mesh_net_rx *rx, struct net_buf_simple *buf,
@@ -1135,6 +1145,17 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if,
BT_DBG("Decryption successful. Payload len %u", buf->len);
if (net_if != BT_MESH_NET_IF_PROXY_CFG &&
rx->dst == BT_MESH_ADDR_UNASSIGNED) {
BT_ERR("Destination address is unassigned; dropping packet");
return -EBADMSG;
}
if (BT_MESH_ADDR_IS_RFU(rx->dst)) {
BT_ERR("Destination address is RFU; dropping packet");
return -EBADMSG;
}
if (net_if != BT_MESH_NET_IF_LOCAL && bt_mesh_elem_find(rx->ctx.addr)) {
BT_DBG("Dropping locally originated packet");
return -EBADMSG;
@@ -1181,12 +1202,8 @@ void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi,
}
}
#if (defined(CONFIG_BT_MESH_RELAY) || \
defined(CONFIG_BT_MESH_FRIEND) || \
defined(CONFIG_BT_MESH_GATT_PROXY))
net_buf_simple_restore(buf, &state);
bt_mesh_net_relay(buf, &rx);
#endif /* CONFIG_BT_MESH_RELAY || FRIEND || GATT_PROXY */
}
static void ivu_complete(struct k_work *work)
@@ -1201,7 +1218,5 @@ void bt_mesh_net_init(void)
{
k_delayed_work_init(&bt_mesh.ivu_complete, ivu_complete);
#if defined(CONFIG_BT_MESH_LOCAL_INTERFACE)
k_work_init(&bt_mesh.local_work, bt_mesh_net_local);
#endif
}

View File

@@ -166,11 +166,9 @@ struct bt_mesh_net {
s64_t last_update; /* Time since last IV Update change */
#if defined(CONFIG_BT_MESH_LOCAL_INTERFACE)
/* Local network interface */
struct k_work local_work;
struct k_fifo local_queue;
#endif
#if defined(CONFIG_BT_MESH_FRIEND)
struct bt_mesh_friend frnd; /* Friend state */
@@ -247,6 +245,8 @@ int bt_mesh_friend_cred_del(u16_t net_idx, u16_t addr);
bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key);
void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub);
int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub);
void bt_mesh_rpl_reset(void);

View File

@@ -617,7 +617,8 @@ static int prov_auth(u8_t method, u8_t action, u8_t size)
}
if (output == BT_MESH_DISPLAY_STRING) {
u8_t i, str[9];
char str[9];
u8_t i;
bt_rand(str, size);
@@ -1194,12 +1195,6 @@ static void prov_msg_recv(void)
BT_DBG("type 0x%02x len %u", type, link.rx.buf->len);
if (type != PROV_FAILED && type != link.expect) {
BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect);
prov_send_fail_msg(PROV_ERR_UNEXP_PDU);
return;
}
if (!bt_mesh_fcs_check(link.rx.buf, link.rx.fcs)) {
BT_ERR("Incorrect FCS");
return;
@@ -1209,6 +1204,12 @@ static void prov_msg_recv(void)
link.rx.prev_id = link.rx.id;
link.rx.id = 0;
if (type != PROV_FAILED && type != link.expect) {
BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect);
prov_send_fail_msg(PROV_ERR_UNEXP_PDU);
return;
}
if (type >= ARRAY_SIZE(prov_handlers)) {
BT_ERR("Unknown provisioning PDU type 0x%02x", type);
close_link(PROV_ERR_NVAL_PDU, CLOSE_REASON_FAILED);

View File

@@ -980,7 +980,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx)
}
/* Bail out early if we're not ready to receive such a large SDU */
if (!sdu_len_is_ok(&net_rx->ctx, seg_n)) {
if (!sdu_len_is_ok(net_rx->ctl, seg_n)) {
BT_ERR("Too big incoming SDU length");
send_ack(net_rx->sub, net_rx->dst, net_rx->ctx.addr,
net_rx->ctx.send_ttl, seq_zero, 0);

View File

@@ -287,11 +287,20 @@ static int dns_read(struct dns_resolve_context *ctx,
info->ai_addr.sa_family = AF_INET;
info->ai_addrlen = sizeof(struct sockaddr_in);
} else if (ctx->queries[query_idx].query_type == DNS_QUERY_TYPE_AAAA) {
/* We cannot resolve IPv6 address if IPv6 is disabled. The reason
* being that "struct sockaddr" does not have enough space for
* IPv6 address in that case.
*/
#if defined(CONFIG_NET_IPV6)
address_size = DNS_IPV6_LEN;
addr = (u8_t *)&net_sin6(&info->ai_addr)->sin6_addr;
info->ai_family = AF_INET6;
info->ai_addr.sa_family = AF_INET6;
info->ai_addrlen = sizeof(struct sockaddr_in6);
#else
ret = DNS_EAI_FAMILY;
goto quit;
#endif
} else {
ret = DNS_EAI_FAMILY;
goto quit;
@@ -608,10 +617,10 @@ int dns_resolve_name(struct dns_resolve_context *ctx,
void *user_data,
s32_t timeout)
{
struct net_buf *dns_data;
struct net_buf *dns_data = NULL;
struct net_buf *dns_qname = NULL;
struct sockaddr addr;
int ret, i, j = 0;
int ret, i = -1, j = 0;
int failure = 0;
if (!ctx || !ctx->is_used || !query || !cb) {
@@ -638,11 +647,16 @@ int dns_resolve_name(struct dns_resolve_context *ctx,
info.ai_addr.sa_family = AF_INET;
info.ai_addrlen = sizeof(struct sockaddr_in);
} else if (type == DNS_QUERY_TYPE_AAAA) {
#if defined(CONFIG_NET_IPV6)
memcpy(net_sin6(&info.ai_addr), net_sin6(&addr),
sizeof(struct sockaddr_in6));
info.ai_family = AF_INET6;
info.ai_addr.sa_family = AF_INET6;
info.ai_addrlen = sizeof(struct sockaddr_in6);
#else
ret = -EAFNOSUPPORT;
goto quit;
#endif
} else {
goto try_resolve;
}
@@ -729,11 +743,14 @@ try_resolve:
quit:
if (ret < 0) {
if (k_delayed_work_remaining_get(&ctx->queries[i].timer) > 0) {
k_delayed_work_cancel(&ctx->queries[i].timer);
}
if (i >= 0) {
if (k_delayed_work_remaining_get(
&ctx->queries[i].timer) > 0) {
k_delayed_work_cancel(&ctx->queries[i].timer);
}
ctx->queries[i].cb = NULL;
ctx->queries[i].cb = NULL;
}
if (dns_id) {
*dns_id = 0;

View File

@@ -0,0 +1,3 @@
CONFIG_ZTEST=y
CONFIG_IRQ_OFFLOAD=y
CONFIG_POLL=y

View File

@@ -1,3 +1,6 @@
tests:
- test:
tags: kernel
- test:
tags: kernel
- test_poll:
extra_args: CONF_FILE="prj_poll.conf"
tags: kernel

View File

@@ -0,0 +1,31 @@
CONFIG_NETWORKING=y
CONFIG_NET_TEST=y
CONFIG_RANDOM_GENERATOR=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NET_L2_DUMMY=y
CONFIG_DNS_RESOLVER=y
CONFIG_DNS_RESOLVER_MAX_SERVERS=2
CONFIG_DNS_NUM_OF_CONCUR_QUERIES=1
CONFIG_DNS_SERVER_IP_ADDRESSES=y
CONFIG_DNS_SERVER1="192.0.2.2"
CONFIG_DNS_SERVER2="192.0.2.2:5353"
CONFIG_NET_LOG=y
CONFIG_SYS_LOG_NET_LEVEL=2
CONFIG_SYS_LOG_SHOW_COLOR=y
#CONFIG_NET_DEBUG_DNS_RESOLVE=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=n
CONFIG_NET_IPV6_DAD=n
CONFIG_NET_IPV6_MLD=n
CONFIG_NET_IPV6_ND=n
CONFIG_NET_ARP=n
CONFIG_PRINTK=y
CONFIG_ZTEST=y
CONFIG_MAIN_STACK_SIZE=1344

View File

@@ -374,10 +374,12 @@ static void dns_query_ipv4_server_count(void)
continue;
}
if (ctx->servers[i].dns_server.sa_family == AF_INET) {
count++;
if (ctx->servers[i].dns_server.sa_family == AF_INET6) {
continue;
}
count++;
if (net_sin(&ctx->servers[i].dns_server)->sin_port ==
ntohs(53)) {
port++;
@@ -385,7 +387,7 @@ static void dns_query_ipv4_server_count(void)
}
zassert_equal(count, 2, "Invalid number of IPv4 servers");
zassert_equal(port, 2, "Invalid number of IPv4 servers with port 53");
zassert_equal(port, 1, "Invalid number of IPv4 servers with port 53");
}
static void dns_query_ipv6_server_count(void)
@@ -402,18 +404,25 @@ static void dns_query_ipv6_server_count(void)
continue;
}
if (ctx->servers[i].dns_server.sa_family == AF_INET6) {
count++;
if (ctx->servers[i].dns_server.sa_family == AF_INET) {
continue;
}
count++;
if (net_sin6(&ctx->servers[i].dns_server)->sin6_port ==
ntohs(53)) {
port++;
}
}
#if defined(CONFIG_NET_IPV6)
zassert_equal(count, 2, "Invalid number of IPv6 servers");
zassert_equal(port, 2, "Invalid number of IPv6 servers with port 53");
zassert_equal(port, 1, "Invalid number of IPv6 servers with port 53");
#else
zassert_equal(count, 0, "Invalid number of IPv6 servers");
zassert_equal(port, 0, "Invalid number of IPv6 servers with port 53");
#endif
}
static void dns_query_too_many(void)
@@ -671,10 +680,12 @@ void dns_result_numeric_cb(enum dns_resolve_status status,
}
if (info && info->ai_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
if (net_ipv6_addr_cmp(&net_sin6(&info->ai_addr)->sin6_addr,
&my_addr3) != true) {
zassert_true(false, "IPv6 address does not match");
}
#endif
}
k_sem_give(&wait_data2);

View File

@@ -3,3 +3,8 @@ tests:
tags: dns net
min_ram: 16
timeout: 600
- test-no-ipv6:
tags: dns net
min_ram: 16
timeout: 600
extra_args: CONF_FILE=prj-no-ipv6.conf